//Compile out Title Update changes to header functions. //Must be before includes. //CONST_INT USE_TU_CHANGES 0 // Removed by Kenneth R. USING "rage_builtins.sch" USING "globals.sch" USING "cutscene_public.sch" USING "commands_cutscene.sch" USING "commands_entity.sch" USING "commands_script.sch" USING "script_player.sch" USING "email_public.sch" USING "randomChar_public.sch" USING "RC_Helper_Functions.sch" USING "initial_scenes_Epsilon.sch" USING "commands_recording.sch" // ***************************************************************************************** // ***************************************************************************************** // ***************************************************************************************** // // MISSION NAME : Epsilon5.sc // AUTHOR : David Roberts // DESCRIPTION : MICHAEL meets MARNIE in a weird part of Vinewood. // // ***************************************************************************************** // ***************************************************************************************** // ***************************************************************************************** ENUM eRC_MainState RC_LEADIN, RC_INTRO ENDENUM ENUM eRC_SubState SS_ASSET_REQUEST, SS_SETUP, SS_UPDATE, SS_CLEANUP ENDENUM CONST_INT MARNIE 0 // Mission state eRC_MainState m_eState = RC_LEADIN eRC_SubState m_subState = SS_ASSET_REQUEST STRING sSceneHandleMarnie = "Marnie" g_structRCScriptArgs sRCLauncherDataLocal structPedsForConversation ConvStruct INT iCutsceneStage = 0 BOOL bDoneLeadinConv = FALSE BOOL bLeadInCloseStop = FALSE FLOAT fHintFov = 40.0 FLOAT fHintFollow = 0.35 FLOAT fHintPitchOrbit = 0.000 FLOAT fHintSide = 0.0 FLOAT fHintVert = 0.050 // =========================================================================================================== // Termination // =========================================================================================================== // ----------------------------------------------------------------------------------------------------------- // Script Cleanup // ----------------------------------------------------------------------------------------------------------- PROC Script_TextCleanup() // Could this be included in normal clean up? STOP_SCRIPTED_CONVERSATION(FALSE) CLEAR_PRINTS() ENDPROC /// PURPOSE: /// Safely cleans up the script PROC Script_Cleanup() // Ensure launcher is cleaned up RC_CLEANUP_LAUNCHER() // If the mission was triggered then additional mission cleanup will be required. IF (Random_Character_Cleanup_If_Triggered()) CPRINTLN(DEBUG_MISSION, "...Random Character Script was triggered so additional cleanup required") ENDIF IF IS_ENTITY_ALIVE(sRCLauncherDataLocal.pedID[MARNIE]) SET_PED_CAN_BE_TARGETTED(sRCLauncherDataLocal.pedID[MARNIE], FALSE) SET_PED_RELATIONSHIP_GROUP_HASH(sRCLauncherDataLocal.pedID[MARNIE], RELGROUPHASH_PLAYER) ENDIF //Cleanup the scene created by the launcher RC_CleanupSceneEntities(sRCLauncherDataLocal, FALSE) TERMINATE_THIS_THREAD() ENDPROC // ----------------------------------------------------------------------------------------------------------- // Script Pass // ----------------------------------------------------------------------------------------------------------- /// PURPOSE: /// Adds needed contacts, completion %, cleans up and passes script. PROC Script_Passed() Script_TextCleanup() ADD_HELP_TO_FLOW_QUEUE("EPSROBE_HE", FHP_MEDIUM, 0, FLOW_HELP_NEVER_EXPIRES, DEFAULT_HELP_TEXT_TIME, BIT_MICHAEL) FIRE_EMAIL_INTO_DYNAMIC_THREAD(DYNAMIC_THREAD_EPSILON_ROBES, EMAIL_ORDER_REMINDER, FALSE) //Set epsilon step stat INT iCurrent STAT_GET_INT(NUM_EPSILON_STEP,iCurrent) IF iCurrent < 14 STAT_SET_INT(NUM_EPSILON_STEP,14) SET_ACHIEVEMENT_PROGRESS_SAFE(ENUM_TO_INT(ACH20),14) CPRINTLN(debug_dan,"Epsilon progress:",14) ENDIF Random_Character_Passed() Script_Cleanup() ENDPROC // =========================================================================================================== // DEBUG FUNCTIONS // =========================================================================================================== #IF IS_DEBUG_BUILD /// PURPOSE: /// Check for Forced Pass or Fail PROC DEBUG_Check_Debug_Keys() // Check for Pass IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_S)) WAIT_FOR_CUTSCENE_TO_STOP() Script_Passed() ENDIF // Check for Fail IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_F)) WAIT_FOR_CUTSCENE_TO_STOP() Script_TextCleanup() Random_Character_Failed() Script_Cleanup() ENDIF ENDPROC #ENDIF FUNC BOOL CHECK_TO_BLEND_MICHAEL() IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Michael") FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_IDLE, FALSE, FAUS_CUTSCENE_EXIT) CPRINTLN(DEBUG_MISSION, "Force Michael motion state") RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Keep checking to see if we can blend Marnie PROC CHECK_TO_BLEND_MARNIE() IF IS_ENTITY_ALIVE(sRCLauncherDataLocal.pedID[MARNIE]) IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Marnie") CPRINTLN(DEBUG_MISSION, "Marnie exit state") SAFE_DELETE_PED(sRCLauncherDataLocal.pedID[MARNIE]) ENDIF ENDIF ENDPROC // =========================================================================================================== // MISSION FUNCTIONS & PROCEDURES // =========================================================================================================== PROC STATE_Leadin() RC_PLAYER_TRIGGER_SCENE_LOCK_IN() SWITCH m_subState CASE SS_ASSET_REQUEST REQUEST_ANIM_DICT("rcmepsilonism5") m_subState = SS_Setup BREAK CASE SS_SETUP IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), sRCLauncherDataLocal.pedID[MARNIE]) >= 4.5 IF NOT IS_GAMEPLAY_HINT_ACTIVE() IF IS_PLAYER_IN_FIRST_PERSON_CAMERA() SET_GAMEPLAY_ENTITY_HINT(sRCLauncherDataLocal.pedID[MARNIE], <<0,0,0.5>>, TRUE, 30000) ELSE SET_GAMEPLAY_ENTITY_HINT(sRCLauncherDataLocal.pedID[MARNIE], <<-1.0,0,0>>, FALSE, 30000) ENDIF SET_GAMEPLAY_HINT_FOV(fHintFov) SET_GAMEPLAY_HINT_FOLLOW_DISTANCE_SCALAR(fHintFollow) SET_GAMEPLAY_HINT_BASE_ORBIT_PITCH_OFFSET(fHintPitchOrbit) SET_GAMEPLAY_HINT_CAMERA_RELATIVE_SIDE_OFFSET(fHintSide) SET_GAMEPLAY_HINT_CAMERA_RELATIVE_VERTICAL_OFFSET(fHintVert) SET_GAMEPLAY_HINT_CAMERA_BLEND_TO_FOLLOW_PED_MEDIUM_VIEW_MODE(TRUE) ELSE STOP_GAMEPLAY_HINT_BEING_CANCELLED_THIS_UPDATE(TRUE) ENDIF ENDIF IF bLeadInCloseStop = FALSE IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), sRCLauncherDataLocal.pedID[MARNIE]) <= 2.5 // Turn player control off SET_PLAYER_CONTROL(PLAYER_ID(), FALSE, SPC_LEAVE_CAMERA_CONTROL_ON) TASK_TURN_PED_TO_FACE_ENTITY(PLAYER_PED_ID(), sRCLauncherDataLocal.pedID[MARNIE]) bLeadInCloseStop = TRUE CPRINTLN(DEBUG_MISSION, "Player too close to Mary Ann, making him stop") ENDIF ENDIF IF HAS_ANIM_DICT_LOADED("rcmepsilonism5") IF IS_ENTITY_ALIVE(sRCLauncherDataLocal.pedID[MARNIE]) IF IS_ENTITY_PLAYING_ANIM(sRCLauncherDataLocal.pedID[MARNIE], "rcm_epsilonism5", "ep_5_rcm_marnie_strokes_wall") IF GET_ENTITY_ANIM_CURRENT_TIME(sRCLauncherDataLocal.pedID[MARNIE], "rcm_epsilonism5", "ep_5_rcm_marnie_strokes_wall") <0.1 ADD_PED_FOR_DIALOGUE(ConvStruct, 4, sRCLauncherDataLocal.pedID[MARNIE], "MARNIE") ADD_PED_FOR_DIALOGUE(ConvStruct, 0, PLAYER_PED_ID(), "MICHAEL") TASK_LOOK_AT_ENTITY(sRCLauncherDataLocal.pedID[MARNIE], PLAYER_PED_ID(), -1, SLF_EXTEND_PITCH_LIMIT|SLF_EXTEND_YAW_LIMIT) TASK_PLAY_ANIM(sRCLauncherDataLocal.pedID[MARNIE], "rcmepsilonism5", "leadin_action", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_HOLD_LAST_FRAME) CPRINTLN(DEBUG_MISSION, "Do Marnie leadin") m_subState = SS_UPDATE ENDIF ENDIF ENDIF ENDIF BREAK CASE SS_UPDATE IF IS_ENTITY_ALIVE(sRCLauncherDataLocal.pedID[MARNIE]) IF IS_ENTITY_PLAYING_ANIM(sRCLauncherDataLocal.pedID[MARNIE], "rcmepsilonism5", "leadin_action") IF bDoneLeadinConv = FALSE IF GET_ENTITY_ANIM_CURRENT_TIME(sRCLauncherDataLocal.pedID[MARNIE], "rcmepsilonism5", "leadin_action") >= 0.38 IF CREATE_CONVERSATION(ConvStruct, "EPS5AUD", "EP5_RCM_LI", CONV_PRIORITY_HIGH) bDoneLeadinConv = TRUE CPRINTLN(DEBUG_MISSION, "Leadin conv launched") ENDIF ENDIF ENDIF IF GET_ENTITY_ANIM_CURRENT_TIME(sRCLauncherDataLocal.pedID[MARNIE], "rcmepsilonism5", "leadin_action") >= 0.95 CPRINTLN(DEBUG_MISSION, "Completed Marnie leadin") m_subState = SS_CLEANUP ENDIF IF bLeadInCloseStop = FALSE IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), sRCLauncherDataLocal.pedID[MARNIE]) <= 2.5 // Turn player control off SET_PLAYER_CONTROL(PLAYER_ID(), FALSE, SPC_LEAVE_CAMERA_CONTROL_ON) TASK_TURN_PED_TO_FACE_ENTITY(PLAYER_PED_ID(), sRCLauncherDataLocal.pedID[MARNIE]) bLeadInCloseStop = TRUE CPRINTLN(DEBUG_MISSION, "Player too close to Mary Ann, making him stop") ENDIF ENDIF ELSE CPRINTLN(DEBUG_MISSION, "Completed Marnie leadin") m_subState = SS_CLEANUP ENDIF ENDIF BREAK CASE SS_CLEANUP m_eState = RC_INTRO m_subState = SS_ASSET_REQUEST BREAK ENDSWITCH ENDPROC /// PURPOSE: /// Runs the intro cutscene state PROC STATE_Intro() SWITCH m_subState CASE SS_ASSET_REQUEST RC_REQUEST_CUTSCENE("ep_5_rcm") m_subState = SS_Setup BREAK CASE SS_Setup CPRINTLN(DEBUG_MISSION, "Init RC_INTRO") IF RC_IS_CUTSCENE_OK_TO_START() IF IS_ENTITY_ALIVE(sRCLauncherDataLocal.pedID[MARNIE]) REGISTER_ENTITY_FOR_CUTSCENE(sRCLauncherDataLocal.pedID[MARNIE], sSceneHandleMarnie, CU_ANIMATE_EXISTING_SCRIPT_ENTITY) ENDIF IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) REGISTER_ENTITY_FOR_CUTSCENE(PLAYER_PED_ID(), "Michael", CU_ANIMATE_EXISTING_SCRIPT_ENTITY) ENDIF // Ensure lead-in blip is cleaned up... RC_CLEANUP_LAUNCHER() iCutsceneStage = 0 TRIGGER_MUSIC_EVENT("EPS5_START") START_CUTSCENE() REPLAY_START_EVENT(REPLAY_IMPORTANCE_LOW) WAIT(0) STOP_GAMEPLAY_HINT() RESOLVE_VEHICLES_INSIDE_ANGLED_AREA_WITH_SIZE_LIMIT(<<638.724792,108.215866,87.003014>>, <<644.466736,124.222160,94.640419>>, 12.5, << 638.9150, 101.5370, 88.1472 >>, 331.3091, GET_DEFAULT_ALLOWABLE_VEHICLE_SIZE_VECTOR()) //RC_CleanupSceneEntities(sRCLauncherDataLocal) RC_START_CUTSCENE_MODE(<< 637.02, 119.7093, 89.50 >>, TRUE, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT) m_subState = SS_Update ENDIF BREAK CASE SS_Update IF iCutsceneStage = 0 // Keep spamming this until Michael's exit state to get the camera to blend behind Michael SET_GAMEPLAY_CAM_RELATIVE_PITCH() SET_GAMEPLAY_CAM_RELATIVE_HEADING() IF WAS_CUTSCENE_SKIPPED() SET_GAMEPLAY_CAM_RELATIVE_PITCH() SET_GAMEPLAY_CAM_RELATIVE_HEADING() iCutsceneStage = 1 ENDIF IF CHECK_TO_BLEND_MICHAEL() iCutsceneStage = 1 ENDIF CHECK_TO_BLEND_MARNIE() ELIF iCutsceneStage = 1 // Keep checking Marnie in case she hasn't blended yet CHECK_TO_BLEND_MARNIE() // Also check Michael in case the cutscene was skipped and the blend in stage 0 didn't fire CHECK_TO_BLEND_MICHAEL() IF WAS_CUTSCENE_SKIPPED() SET_GAMEPLAY_CAM_RELATIVE_PITCH() SET_GAMEPLAY_CAM_RELATIVE_HEADING() ENDIF IF NOT IS_CUTSCENE_ACTIVE() RC_END_CUTSCENE_MODE() m_subState = SS_Cleanup ENDIF ENDIF BREAK CASE SS_Cleanup REPLAY_STOP_EVENT() CPRINTLN(DEBUG_MISSION, "Cleaning up RC_INTRO") TRIGGER_MUSIC_EVENT("EPS5_STOP") RC_SET_ENTITY_PROOFS_FOR_CUTSCENE(sRCLauncherDataLocal, FALSE) Script_Passed() BREAK ENDSWITCH ENDPROC // =========================================================================================================== // Script Loop // =========================================================================================================== SCRIPT(g_structRCScriptArgs sRCLauncherDataIn) sRCLauncherDataLocal = sRCLauncherDataIn RC_TakeEntityOwnership(sRCLauncherDataLocal) SET_MISSION_FLAG(TRUE) // Setup callback when player is killed, arrested or goes to multiplayer IF (HAS_FORCE_CLEANUP_OCCURRED(DEFAULT_FORCE_CLEANUP_FLAGS|FORCE_CLEANUP_FLAG_DEBUG_MENU)) PRINT_LAUNCHER_DEBUG("Force cleanup [TERMINATING]") Random_Character_Failed() Script_Cleanup() TRIGGER_MUSIC_EVENT("EPS_FAIL") ENDIF IF Is_Replay_In_Progress() // Set up the initial scene for replays g_bSceneAutoTrigger = TRUE eInitialSceneStage = IS_REQUEST_SCENE WHILE NOT SetupScene_EPSILON_5(sRCLauncherDataLocal) WAIT(0) ENDWHILE g_bSceneAutoTrigger = FALSE ENDIF ADD_CONTACT_TO_PHONEBOOK(CHAR_MARNIE, MICHAEL_BOOK, FALSE) ADD_CONTACT_TO_PHONEBOOK(CHAR_JIMMY_BOSTON, MICHAEL_BOOK, FALSE) // Loop within here until the mission passes or fails WHILE(TRUE) REPLAY_CHECK_FOR_EVENT_THIS_FRAME("SF_BTT") WAIT(0) UPDATE_MISSION_NAME_DISPLAYING(sRCLauncherDataLocal.sIntroCutscene) SWITCH(m_eState) CASE RC_LEADIN STATE_Leadin() BREAK CASE RC_INTRO STATE_Intro() BREAK ENDSWITCH // Check debug completion/failure #IF IS_DEBUG_BUILD DEBUG_Check_Debug_Keys() #ENDIF ENDWHILE SCRIPT_ASSERT("Script should never reach here. Always terminate with cleanup function.") ENDSCRIPT