//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 "randomChar_public.sch" USING "replay_public.sch" USING "RC_Helper_Functions.sch" USING "RC_Threat_Public.sch" USING "initial_scenes_Maude.sch" USING "commands_recording.sch" #IF IS_DEBUG_BUILD USING "select_mission_stage.sch" #ENDIF // ***************************************************************************************** // ***************************************************************************************** // ***************************************************************************************** // // MISSION NAME : Maude1.sc // AUTHOR : Ahron M // DESCRIPTION : Trevor meets Maude which unlocks Bail Bonds oddjob // // ***************************************************************************************** // ***************************************************************************************** // ***************************************************************************************** //************************************************************************************************************************************************* // :ENUMS: //************************************************************************************************************************************************* ENUM MAUDE_1_MISSION_STAGE MISSION_STAGE_CUTSCENE, MISSION_STAGE_LEAVE_AREA, MISSION_STAGE_MISSION_FAILED_WAIT_FOR_FADE ENDENUM ENUM SUB_STAGE SS_SETUP, SS_UPDATE, SS_CLEANUP ENDENUM ENUM MAUDE_1_FAIL_REASON FAIL_REASON_MAUDE_DEAD, FAIL_REASON_MAUDE_SPOOKED, FAIL_REASON_DEFAULT ENDENUM //************************************************************************************************************************************************* // :STRUCTURES: //************************************************************************************************************************************************* //************************************************************************************************************************************************* // :CONSTANTS: //************************************************************************************************************************************************* CONST_INT MAUDE_1_MAUDE_SPEAKER_ID 4 // Conversation speaker ID CONST_INT MAUDE_1_Z_SKIP_START_CUTSCENE 0 CONST_INT MAUDE_1_Z_SKIP_LEAVE_AREA 1 CONST_INT MAUDE_1_Z_SKIP_MISSION_PASSED 2 //************************************************************************************************************************************************* // :VARIABLES: //************************************************************************************************************************************************* g_structRCScriptArgs sRCLauncherDataLocal MAUDE_1_MISSION_STAGE eMissionStage = MISSION_STAGE_CUTSCENE SUB_STAGE eSubStage = SS_SETUP MAUDE_1_FAIL_REASON eFailReason = FAIL_REASON_DEFAULT BOOL bHasSetExitStateFromIntroMocapForGameplayCam BOOL bSetMaudeFleeSyncSceneExit INT iMaudeSyncSceneIndex = -1 INT iFocusPushStage = 0 INT iFocusPushTimer = -1 INT iSyncScene_MaudeReact = -1 INT iMaxNumMaudeLeaveLines = 4 INT iTimer_MaudeDialogue = 0 INT iCounterMaudeLines = 0 OBJECT_INDEX objMaudeChair OBJECT_INDEX objMaudeLaptop OBJECT_INDEX objMaudeTable OBJECT_INDEX objMaudeRadio PED_INDEX pedMaude STRING sSceneHandle_Trevor = "Trevor" STRING sSceneHandle_Maude = "Maude" STRING sSceneHandle_MaudeChair = "maude_chair" STRING sSceneHandle_MaudeLaptop = "maude_laptop" structPedsForConversation sDialogue VEHICLE_INDEX vehIndex_MissionReplayRestore #IF IS_DEBUG_BUILD // stage skipping CONST_INT MAX_SKIP_MENU_LENGTH 3 MissionStageMenuTextStruct mSkipMenu[MAX_SKIP_MENU_LENGTH] #ENDIF VECTOR vRespotVehicleCoord // =========================================================================================================== // CLEANUP FUNCTIONS // =========================================================================================================== /// PURPOSE: /// initialise data needed for scene PROC INIT_DATA() // Stage skipping #IF IS_DEBUG_BUILD mSkipMenu[MAUDE_1_Z_SKIP_START_CUTSCENE].sTxtLabel = "Mocap: MAUDE_MCS_1" mSkipMenu[MAUDE_1_Z_SKIP_LEAVE_AREA].sTxtLabel = "Leave the area." mSkipMenu[MAUDE_1_Z_SKIP_MISSION_PASSED].sTxtLabel = "Mission Passed" #ENDIF eMissionStage = MISSION_STAGE_CUTSCENE eSubStage = SS_SETUP iMaudeSyncSceneIndex = -1 iFocusPushStage = 0 iFocusPushTimer = -1 iSyncScene_MaudeReact = -1 iMaxNumMaudeLeaveLines = 4 iTimer_MaudeDialogue = 0 iCounterMaudeLines = 0 bSetMaudeFleeSyncSceneExit = FALSE bHasSetExitStateFromIntroMocapForGameplayCam = FALSE SET_START_CHECKPOINT_AS_FINAL() // tells replay controller to display "skip mission" for shitskips ENDPROC /// PURPOSE: /// Deletes all of the mission entities checking if they exist /// Used in Mission Failed, when faded out. /// PARAMS: /// bDelete - if true all entities will be deleted, else released PROC CLEANUP_ALL_MISSION_ENTITIES(BOOL bDelete = FALSE) SAFE_DELETE_PED(pedMaude) // always make sure Maude is removed SAFE_RELEASE_OBJECT(objMaudeTable) // can't delete an object that was created from the world SAFE_RELEASE_OBJECT(objMaudeRadio) // can't delete an object that was created from the world IF bDelete SAFE_DELETE_OBJECT(objMaudeChair) SAFE_DELETE_OBJECT(objMaudeLaptop) ELSE SAFE_RELEASE_OBJECT(objMaudeChair) SAFE_RELEASE_OBJECT(objMaudeLaptop) ENDIF ENDPROC /// PURPOSE: /// Safely cleans up the script PROC MISSION_CLEANUP() IF IS_GAMEPLAY_HINT_ACTIVE() STOP_GAMEPLAY_HINT() ENDIF // proc from initial scene so they match up SETUP_AREA_FOR_MISSION(RC_MAUDE_1, FALSE) REMOVE_ANIM_DICT("special_ped@maude@base") CLEANUP_ALL_MISSION_ENTITIES() ENDPROC /// PURPOSE: /// Handles call to MISSION_CLEANUP and terminates the thread PROC Script_Cleanup() CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : 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, GET_THIS_SCRIPT_NAME(), " : Script triggered, additional cleanup required...") MISSION_CLEANUP() ENDIF //Cleanup the scene created by the launcher RC_CleanupSceneEntities(sRCLauncherDataLocal) TERMINATE_THIS_THREAD() ENDPROC /// PURPOSE: /// Adds needed contacts, completion %, cleans up and passes script. PROC Script_Passed() CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : Passed") ADD_HELP_TO_FLOW_QUEUE("BBONDS_UNLOCK", FHP_MEDIUM, 0, FLOW_HELP_NEVER_EXPIRES, DEFAULT_HELP_TEXT_TIME, BIT_TREVOR, CID_BLANK, CID_BLANK, FHF_SAVED) ADD_CONTACT_TO_PHONEBOOK(CHAR_MAUDE, TREVOR_BOOK) // Bail bond missions now open. Trevor will receive emails from Maude with further details. Random_Character_Passed(CP_RAND_C_MAU1) Script_Cleanup() ENDPROC /// PURPOSE: /// will return the enumSubtitlesState needed to allow a dialogue line to play /// without subtitles if a message is being displayed /// RETURNS: /// enumSubtitlesState FUNC enumSubtitlesState GET_SUBTITLES_STATE_FOR_NON_CLASH_WITH_MESSAGES() IF IS_MESSAGE_BEING_DISPLAYED() RETURN DO_NOT_DISPLAY_SUBTITLES ENDIF RETURN DISPLAY_SUBTITLES ENDFUNC /// PURPOSE: /// requests and checks if the assets are loaded /// RETURNS: /// TRUE if loaded FUNC BOOL HAVE_MISSION_ASSETS_LOADED() REQUEST_ANIM_DICT("special_ped@maude@base") REQUEST_ADDITIONAL_TEXT("MAUDE1", MISSION_TEXT_SLOT) IF HAS_ANIM_DICT_LOADED("special_ped@maude@base") AND HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT) RETURN TRUE ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// gets a handle to Maude's radio which is an object created by map data /// Need to set it as a mission entity to prevent bug 1712317 PROC GET_HANDLE_TO_MAUDES_RADIO() // get handle to Maude's Radio (done set as mission entity since created by map instead uses para on DOES_OBJECT_OF_TYPE_EXIST_AT_COORDS) IF NOT DOES_ENTITY_EXIST(objMaudeRadio) VECTOR vRadioPosition = << 2727.29, 4145.90, 44.16 >> MODEL_NAMES modelNameRadio = PROP_RADIO_01 IF IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), vRadioPosition, 150.0) IF DOES_OBJECT_OF_TYPE_EXIST_AT_COORDS(vRadioPosition, 10.0, modelNameRadio) objMaudeRadio = GET_CLOSEST_OBJECT_OF_TYPE(vRadioPosition, 10.0, modelNameRadio, TRUE) #IF IS_DEBUG_BUILD PRINTLN(DEBUG_MISSION, "GET_HANDLE_TO_MAUDES_RADIO : ", "grabbed handle to radio") #ENDIF ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: /// checks to see if Maude should flee /// PARAMS: /// bCheckPlayerWanted - if TRUE checks the player's wanted level and returns TRUE if he has one /// RETURNS: /// TRUE if reason for Maude to flee FUNC BOOL SHOULD_MAUDE_FLEE(BOOL bCheckPlayerWanted = FALSE) IF IS_PED_UNINJURED(pedMaude) // Check for Maude taking damage IF HAS_ENTITY_BEEN_DAMAGED_BY_ANY_PED(pedMaude) OR HAS_ENTITY_BEEN_DAMAGED_BY_ANY_VEHICLE(pedMaude) OR HAS_ENTITY_BEEN_DAMAGED_BY_ANY_OBJECT(pedMaude) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Maude took damage : FC = ", GET_FRAME_COUNT()) RETURN TRUE ENDIF // Check for player pushing them with their car IF IS_PED_SITTING_IN_ANY_VEHICLE(PLAYER_PED_ID()) // Ignore player knocking them with car door (in vehicle, but not sitting= must be exiting) IF IS_ENTITY_TOUCHING_ENTITY(PLAYER_PED_ID(), pedMaude) //OR HAS_ENTITY_COLLIDED_WITH_ANYTHING(objMaudeTable) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Maude pushed by player vehicle : FC = ", GET_FRAME_COUNT()) RETURN TRUE ENDIF IF DOES_ENTITY_EXIST(objMaudeChair) IF IS_ENTITY_TOUCHING_ENTITY(PLAYER_PED_ID(), objMaudeChair) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Maude's chair pushed by player vehicle : FC = ", GET_FRAME_COUNT()) RETURN TRUE ENDIF ENDIF IF DOES_ENTITY_EXIST(objMaudeTable) IF IS_ENTITY_TOUCHING_ENTITY(PLAYER_PED_ID(), objMaudeTable) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Maude's table pushed by player vehicle : FC = ", GET_FRAME_COUNT()) RETURN TRUE ENDIF ENDIF IF DOES_ENTITY_EXIST(objMaudeLaptop) IF IS_ENTITY_TOUCHING_ENTITY(PLAYER_PED_ID(), objMaudeLaptop) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Maude's laptop pushed by player vehicle : FC = ", GET_FRAME_COUNT()) RETURN TRUE ENDIF ENDIF ENDIF // code event check for EVENT_POTENTIAL_GET_RUN_OVER IF HAS_PED_RECEIVED_EVENT(pedMaude, EVENT_POTENTIAL_GET_RUN_OVER) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Maude's received event EVENT_POTENTIAL_GET_RUN_OVER : FC = ", GET_FRAME_COUNT()) RETURN TRUE ENDIF // check for ragdoll IF IS_PED_RAGDOLL(pedMaude) IF IS_ENTITY_AT_ENTITY(pedMaude, PLAYER_PED_ID(), <<3.0, 3.0, 3.0>>) // Player close (so they bumped into them) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Maude's ragdolled with player close by : FC = ", GET_FRAME_COUNT()) RETURN TRUE ENDIF ENDIF // code event check for EVENT_PED_COLLISION_WITH_PLAYER IF HAS_PED_RECEIVED_EVENT(pedMaude, EVENT_PED_COLLISION_WITH_PLAYER) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Maude's received event EVENT_PED_COLLISION_WITH_PLAYER : FC = ", GET_FRAME_COUNT()) RETURN TRUE ENDIF // check for player aiming at RC character IF IS_PLAYER_VISIBLY_TARGETTING_PED(pedMaude) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Player visibly targetting Maude : FC = ", GET_FRAME_COUNT()) RETURN TRUE ENDIF // Check for player shooting nearby IF IS_PLAYER_SHOOTING_NEAR_PED(pedMaude) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Player shooting near Maude : FC = ", GET_FRAME_COUNT()) RETURN TRUE ENDIF // Check for explosions nearby IF IS_EXPLOSION_IN_SPHERE(EXP_TAG_DONTCARE, GET_ENTITY_COORDS(pedMaude), 15) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Explosion near Maude : FC = ", GET_FRAME_COUNT()) RETURN TRUE ENDIF // code event check for EVENT_RESPONDED_TO_THREAT IF HAS_PED_RECEIVED_EVENT(pedMaude, EVENT_RESPONDED_TO_THREAT) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Maude's received event EVENT_RESPONDED_TO_THREAT : FC = ", GET_FRAME_COUNT()) RETURN TRUE ENDIF // flee if player is wanted IF bCheckPlayerWanted IF IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : player has wanted level : FC = ", GET_FRAME_COUNT()) RETURN TRUE ENDIF ENDIF ELSE CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Maude injured : FC = ", GET_FRAME_COUNT()) RETURN TRUE ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// task Maude with the exit from sync scene anim /// RETURNS: /// TRUE if anim was applied or if Maude isn't playing the sync scene to apply it FUNC BOOL SET_MAUDE_PLAY_FLEE_EXIT_ANIM() IF IS_PED_UNINJURED(pedMaude) IF IS_ENTITY_PLAYING_ANIM(pedMaude, "special_ped@maude@base", "base") //OR IsPedPerformingTask(pedMaude, SCRIPT_TASK_SYNCHRONIZED_SCENE) // removed since this still returned true when she was ragdolling IF NOT IS_PED_RAGDOLL(pedMaude) OR IS_PED_GETTING_UP(pedMaude) REQUEST_ANIM_DICT("special_ped@maude@exit_flee") IF HAS_ANIM_DICT_LOADED("special_ped@maude@exit_flee") iSyncScene_MaudeReact = CREATE_SYNCHRONIZED_SCENE(<< 2727.40, 4145.56, 43.68 >>, << 0.0, 0.0, -92.17 >>) SET_SYNCHRONIZED_SCENE_LOOPED(iSyncScene_MaudeReact, FALSE) SET_SYNCHRONIZED_SCENE_HOLD_LAST_FRAME(iSyncScene_MaudeReact, FALSE) IF IsPedPerformingTask(pedMaude, SCRIPT_TASK_SYNCHRONIZED_SCENE) STOP_SYNCHRONIZED_ENTITY_ANIM(pedMaude, INSTANT_BLEND_OUT, TRUE) ENDIF TASK_SYNCHRONIZED_SCENE(pedMaude, iSyncScene_MaudeReact, "special_ped@maude@exit_flee", "female_Flee_Table_Left_Maude", INSTANT_BLEND_IN, SLOW_BLEND_OUT, SYNCED_SCENE_ABORT_ON_WEAPON_DAMAGE | SYNCED_SCENE_ACTIVATE_RAGDOLL_ON_COLLISION | SYNCED_SCENE_VEHICLE_ABORT_ON_LARGE_IMPACT | SYNCED_SCENE_TAG_SYNC_OUT) //SYNCED_SCENE_ABORT_ON_WEAPON_DAMAGE | SYNCED_SCENE_USE_PHYSICS | SYNCED_SCENE_VEHICLE_ABORT_ON_LARGE_IMPACT | SYNCED_SCENE_TAG_SYNC_OUT) // SYNCED_SCENE_ACTIVATE_RAGDOLL_ON_COLLISION) FORCE_PED_AI_AND_ANIMATION_UPDATE(pedMaude) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : SET_MAUDE_PLAY_FLEE_EXIT_ANIM() Maude given exit sync scene this frame FC = ", GET_FRAME_COUNT()) IF IS_ENTITY_ALIVE(objMaudeChair) IF IS_ENTITY_PLAYING_ANIM(objMaudeChair, "special_ped@maude@base", "base_chair") STOP_SYNCHRONIZED_ENTITY_ANIM(objMaudeChair, FAST_BLEND_OUT, FALSE) ENDIF INT iEntitySyncedSceneFlags = 0 iEntitySyncedSceneFlags += ENUM_TO_INT(SYNCED_SCENE_ABORT_ON_WEAPON_DAMAGE) iEntitySyncedSceneFlags += ENUM_TO_INT(SYNCED_SCENE_LOOP_WITHIN_SCENE) iEntitySyncedSceneFlags += ENUM_TO_INT(SYNCED_SCENE_ACTIVATE_RAGDOLL_ON_COLLISION) iEntitySyncedSceneFlags += ENUM_TO_INT(SYNCED_SCENE_VEHICLE_ABORT_ON_LARGE_IMPACT) PLAY_SYNCHRONIZED_ENTITY_ANIM(objMaudeChair, iSyncScene_MaudeReact, "Female_Flee_Table_Left_Maude_Chair", "special_ped@maude@exit_flee", FAST_BLEND_IN, SLOW_BLEND_OUT, iEntitySyncedSceneFlags) ENDIF RETURN TRUE // needs to wait a frame for anim to register ELSE CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : SET_MAUDE_PLAY_FLEE_EXIT_ANIM() return FALSE loading anim dict...") ENDIF ELSE CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : SET_MAUDE_PLAY_FLEE_EXIT_ANIM() return TRUE Maude ragdoll / getting up so skipping exit anim") RETURN TRUE ENDIF ELSE CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : SET_MAUDE_PLAY_FLEE_EXIT_ANIM() return TRUE Maude not playing sync scene to exit from so skipping exit anim") RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// stop any ongoing Maude mission passed ambient dialogue /// PARAMS: /// bFinishCurrentLine - if TRUE ongoing convo is allowed to finish current line, otherwise gets cut off PROC KILL_ANY_ONGOING_MAUDE_MISSION_PASSED_DIALOGUE(BOOL bFinishCurrentLine = FALSE) IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() TEXT_LABEL_23 tlCurrentRoot = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT() //if current root matches passed in string return true IF ARE_STRINGS_EQUAL(tlCurrentRoot, "MAUDE_loiter") IF bFinishCurrentLine KILL_FACE_TO_FACE_CONVERSATION() ELSE KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() ENDIF CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : KILL_ANY_ONGOING_MAUDE_MISSION_PASSED_DIALOGUE - convo killed : ", tlCurrentRoot, " bFinishCurrentLine = ", bFinishCurrentLine) ENDIF ENDIF ENDPROC /// PURPOSE: /// triggers Maude's ambient dialogue lines /// PARAMS: /// vMaudeCoords - Maude's position used in proximity check /// vPlayerCoords - Player's position used in proximity check /// RETURNS: /// TRUE if Dialogue was added to the non critical standard buffer FUNC BOOL TRIGGER_MAUDE_AMBIENT_MISSION_PASSED_DIALOGUE(VECTOR vMaudeCoords, VECTOR vPlayerCoords, INT iTimeDelay = 18000, FLOAT fTriggerRange = 20.0) IF iCounterMaudeLines < iMaxNumMaudeLeaveLines IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF (VDIST2(vPlayerCoords, vMaudeCoords) < (fTriggerRange * fTriggerRange)) IF (GET_GAME_TIMER() - iTimer_MaudeDialogue) > (iTimeDelay + GET_RANDOM_INT_IN_RANGE(0, 2000)) ADD_PED_FOR_DIALOGUE(sDialogue, 3, pedMaude, "MAUDE") // vMAUDE_1_MAUDE_SPEAKER_ID - this one has been setup for 3 though ADD_NON_CRITICAL_STANDARD_CONVERSATION_TO_BUFFER(sDialogue, "MAUDEAU", "MAUDE_loiter", CONV_PRIORITY_MEDIUM) // I'd really appreciate the help, and you know how grateful I can be. // Don't let me hold you up, Trevor. I'll send you the file. // Go on now, I'll give you a nice share of the proceeds. // You best get goin'. I'm on the hook for that bond if he doesn't show. iTimer_MaudeDialogue = GET_GAME_TIMER() iCounterMaudeLines++ CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : TRIGGER_MAUDE_AMBIENT_DIALOGUE - return TRUE") RETURN TRUE ENDIF ENDIF ELSE iTimer_MaudeDialogue = GET_GAME_TIMER() ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// handes the calls resolve vehicles inside angled area and setting mission start vehicle as a vehicle gen PROC REPOSITION_PLAYER_VEHICLE_FOR_INTRO() VECTOR vResolveArea_Pos1, vResolveArea_Pos2, vVehRespotPosSizeLimit FLOAT fResolveArea_Width //GET_RESOLVE_VEHICLES_AT_MAUDE_ANGLED_AREA_VALUES(vResolveArea_Pos1, vResolveArea_Pos2, fResolveArea_Width) vResolveArea_Pos1 = <<2728.995117,4143.165039,41.029861>> vResolveArea_Pos2 = <<2719.125977,4144.691406,47.885429>> fResolveArea_Width = 13.0 vVehRespotPosSizeLimit = << 3.0, 11.0, 6.0 >> // GET_DEFAULT_ALLOWABLE_VEHICLE_SIZE_VECTOR() // set the vehicle the player triggered the mission in to regenerate and clear the area - use alternative location for bigger vehicles IF IS_REPLAY_START_VEHICLE_UNDER_SIZE_LIMIT(vVehRespotPosSizeLimit, FALSE) RESOLVE_VEHICLES_INSIDE_ANGLED_AREA(vResolveArea_Pos1, vResolveArea_Pos2, fResolveArea_Width, <<2719.87, 4143.46, 43.46>>, 261.91) SET_MISSION_START_VEHICLE_AS_VEHICLE_GEN(<<2719.87, 4143.46, 43.46>>, 261.91, FALSE) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : REPOSITION_PLAYER_VEHICLE_FOR_INTRO() - resolved vehicles in area and setup standard vehicle gen - framecount : ", GET_FRAME_COUNT()) vRespotVehicleCoord = <<2719.87, 4143.46, 43.46>> ELSE RESOLVE_VEHICLES_INSIDE_ANGLED_AREA(vResolveArea_Pos1, vResolveArea_Pos2, fResolveArea_Width, <<2710.6646, 4149.0752, 42.7026>>, 180.9488) SET_MISSION_START_VEHICLE_AS_VEHICLE_GEN(<<2710.6646, 4149.0752, 42.7026>>, 180.9488, FALSE) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : REPOSITION_PLAYER_VEHICLE_FOR_INTRO() - resolved vehicles in area and setup large vehicle gen - framecount : ", GET_FRAME_COUNT()) vRespotVehicleCoord = <<2710.6646, 4149.0752, 42.7026>> ENDIF ENDPROC /// PURPOSE: /// set everything up for retrying mission after fail - set to leave the area state PROC SETUP_FOR_REPLAY() // if a shit skip has been offered and accepted it will be to skip the mission so don't repawn Maude IF g_bShitskipAccepted CREATE_VEHICLE_FOR_REPLAY(vehIndex_MissionReplayRestore, <<2662.6438, 4284.5347, 43.5787>>, 19.8376, FALSE, FALSE, TRUE, FALSE, FALSE) START_REPLAY_SETUP(<<2672.4619, 4288.7773, 43.6070>>, 78.1133, FALSE) // position towards the main road away from Maudes RC_START_Z_SKIP() WAIT(500) // allow a frame for START_REPLAY_SETUP to process before calling END_REPLAY_SETUP() END_REPLAY_SETUP() RC_END_Z_SKIP() eMissionStage = MISSION_STAGE_LEAVE_AREA eSubStage = SS_CLEANUP // ensure we are fully faded in if we have skipped to the mission passed stage, since the mission passed GUI doesn't display if not (seems to need a frame wait too) SAFE_FADE_SCREEN_IN_FROM_BLACK() CPRINTLN(DEBUG_MISSION, " IS_REPLAY_IN_PROGRESS : SETUP_FOR_REPLAY() done setup for shit skip backup FADE UP!") ELSE //Set up the initial scene for replays g_bSceneAutoTrigger = TRUE eInitialSceneStage = IS_REQUEST_SCENE WHILE NOT SetupScene_MAUDE_1(sRCLauncherDataLocal) CPRINTLN(DEBUG_MISSION, " IS_REPLAY_IN_PROGRESS - SETUP_FOR_REPLAY() waiting on SetupScene_MAUDE_1") WAIT(0) ENDWHILE RC_SET_ENTITY_PROOFS_FOR_CUTSCENE(sRCLauncherDataLocal, FALSE) RC_TakeEntityOwnership(sRCLauncherDataLocal) // take ownership of the sync scene index from the initial scene (needs to happen before launcher terminates) // take ownership from the initial scene (needs to happen before launcher terminates) must check is running, could get here from replay and not be setup IF IS_SYNCHRONIZED_SCENE_RUNNING(sRCLauncherDataLocal.iSyncSceneIndex) TAKE_OWNERSHIP_OF_SYNCHRONIZED_SCENE(sRCLauncherDataLocal.iSyncSceneIndex) iMaudeSyncSceneIndex = sRCLauncherDataLocal.iSyncSceneIndex CPRINTLN(DEBUG_MISSION, " SETUP_FOR_REPLAY() - TAKE_OWNERSHIP_OF_SYNCHRONIZED_SCENE : sRCLauncherDataLocal.iSyncSceneIndex = ", sRCLauncherDataLocal.iSyncSceneIndex, " iMaudeSyncSceneIndex = ", iMaudeSyncSceneIndex) ENDIF g_bSceneAutoTrigger = FALSE ASSIGN_PED_INDEX(pedMaude, sRCLauncherDataLocal.pedID[0]) ASSIGN_OBJECT_INDEX(objMaudeChair, sRCLauncherDataLocal.objID[0]) ASSIGN_OBJECT_INDEX(objMaudeLaptop, sRCLauncherDataLocal.objID[1]) // B*1994227 - only needed if original is still present IF NOT DOES_ENTITY_EXIST(GET_MISSION_START_VEHICLE_INDEX()) CREATE_VEHICLE_FOR_REPLAY(vehIndex_MissionReplayRestore, <<2704.0776, 4152.2397, 42.2514>>, 175.1930, FALSE, FALSE, FALSE, FALSE, FALSE) // Across from Maude's CPRINTLN(DEBUG_MISSION, " IS_REPLAY_IN_PROGRESS - SETUP_FOR_REPLAY() creating vehicle for replay") ELSE CPRINTLN(DEBUG_MISSION, " IS_REPLAY_IN_PROGRESS - SETUP_FOR_REPLAY() skipped replay veh create since GET_MISSION_START_VEHICLE_INDEX() still exists") ENDIF START_REPLAY_SETUP(<<2718.6489, 4147.2075, 42.7043>>, 76.7892, FALSE) RC_START_Z_SKIP() // proc from initial scene so they match up REPOSITION_PLAYER_VEHICLE_FOR_INTRO() SETUP_AREA_FOR_MISSION(RC_MAUDE_1, TRUE, FALSE) // B*1544717 - reduce calls to clear areas this frame (not convinced this is a good idea since stuff might spawn in) WAIT(0) // allow a frame for START_REPLAY_SETUP to process before calling END_REPLAY_SETUP() WHILE NOT HAVE_MISSION_ASSETS_LOADED() CPRINTLN(DEBUG_MISSION, " SETUP_FOR_REPLAY() waiting on assets to load") WAIT(0) ENDWHILE END_REPLAY_SETUP() RC_END_Z_SKIP() eMissionStage = MISSION_STAGE_LEAVE_AREA eSubStage = SS_SETUP CPRINTLN(DEBUG_MISSION, " IS_REPLAY_IN_PROGRESS : SETUP_FOR_REPLAY() done setup after cutscene") ENDIF ENDPROC /// PURPOSE: /// handles the focus push when arriving to trigger the cutscene /// basically a gives player cam a hint to focus on Maude and gets player walking over there /// RETURNS: /// TRUE if it's done FUNC BOOL HAS_FOCUS_PUSH_FINSHED() // don't do anything for replay IF IS_REPLAY_IN_PROGRESS() OR IS_REPEAT_PLAY_ACTIVE() OR IS_REPLAY_BEING_SET_UP() RETURN TRUE ENDIF // setup the hint camera or just turn to face if close already IF iFocusPushStage = 0 IF IS_ENTITY_ALIVE(sRCLauncherDataLocal.pedID[0]) IF NOT IS_ENTITY_IN_RANGE_ENTITY(PLAYER_PED_ID(), sRCLauncherDataLocal.pedID[0], 7.0) // don't trigger if we are close SET_GAMEPLAY_ENTITY_HINT(sRCLauncherDataLocal.pedID[0], (<<0, 0, 0>>), TRUE, -1, DEFAULT_INTERP_IN_TIME) SET_GAMEPLAY_HINT_FOLLOW_DISTANCE_SCALAR(0.35) SET_GAMEPLAY_HINT_CAMERA_RELATIVE_SIDE_OFFSET(-0.8) // over left shoulder // -0.01) over right shoulder SET_GAMEPLAY_HINT_CAMERA_RELATIVE_VERTICAL_OFFSET(0.1) //-0.05) SET_GAMEPLAY_HINT_BASE_ORBIT_PITCH_OFFSET(0.0) SET_GAMEPLAY_HINT_FOV(35.0) SET_GAMEPLAY_HINT_CAMERA_BLEND_TO_FOLLOW_PED_MEDIUM_VIEW_MODE(TRUE) IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) TASK_FOLLOW_TO_OFFSET_OF_ENTITY(PLAYER_PED_ID(), sRCLauncherDataLocal.pedID[0], <<0, 1.2, 0>>, PEDMOVEBLENDRATIO_WALK) CPRINTLN(DEBUG_MISSION, " HAS_FOCUS_PUSH_FINSHED() : hint cam set with goto task ****") ENDIF iFocusPushTimer = GET_GAME_TIMER() ELSE IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) TASK_TURN_PED_TO_FACE_ENTITY(PLAYER_PED_ID(), sRCLauncherDataLocal.pedID[0]) CPRINTLN(DEBUG_MISSION, " HAS_FOCUS_PUSH_FINSHED() : turn to face task only") ENDIF iFocusPushTimer = -1 ENDIF TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), sRCLauncherDataLocal.pedID[0], 4000) ENDIF iFocusPushStage++ CPRINTLN(DEBUG_MISSION, " HAS_FOCUS_PUSH_FINSHED() : iFocusPushStage++ =", iFocusPushStage) // wait for the timer to finsh ELIF iFocusPushStage = 1 IF iFocusPushTimer = -1 OR (GET_GAME_TIMER() - iFocusPushTimer) > 3000 // hint needs to remain for a second (takes 3 seconds to interpolate) OR (IS_ENTITY_ALIVE(sRCLauncherDataLocal.pedID[0]) AND IS_ENTITY_IN_RANGE_ENTITY(PLAYER_PED_ID(), sRCLauncherDataLocal.pedID[0], 4.5)) // range at which player walks into scene from RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Starts up the vehicle engine after the intro if it is a plane /// Fixes B*1935165 - Parking a Besra at the mission trigger causes the plane to be non-functional after the cutscene PROC RESTART_PLAYER_PLANE_AFTER_CUTSCENE() VEHICLE_INDEX veh = GET_PLAYERS_LAST_VEHICLE() IF NOT IS_ENTITY_ALIVE(veh) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : RESTART_PLAYER_PLANE_AFTER_CUTSCENE() : FAILED - PLAYER'S LAST VEHICLE IS DEAD? - TRY RANDOM VEHICLE IN SPHERE - Framecount : ", GET_FRAME_COUNT()) veh = GET_RANDOM_VEHICLE_IN_SPHERE(vRespotVehicleCoord, 10.0, DUMMY_MODEL_FOR_SCRIPT, VEHICLE_SEARCH_FLAG_RETURN_PLANES_ONLY | VEHICLE_SEARCH_FLAG_RETURN_MISSION_VEHICLES | VEHICLE_SEARCH_FLAG_RETURN_RANDOM_VEHICLES) IF NOT IS_ENTITY_ALIVE(veh) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : RESTART_PLAYER_PLANE_AFTER_CUTSCENE() : FAILED - TRY RANDOM VEHICLE IN SPHERE IS NULL - Framecount : ", GET_FRAME_COUNT()) EXIT ENDIF ENDIF CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : RESTART_PLAYER_PLANE_AFTER_CUTSCENE() : TURNING VEHICLE ENGINE BACK ON - Framecount : ", GET_FRAME_COUNT()) SET_VEHICLE_ENGINE_ON(veh, TRUE, TRUE) ENDPROC /// PURPOSE: /// Plays the mocap cutscene - "maude_mcs_1" PROC STAGE_CUTSCENE() SWITCH eSubStage CASE SS_SETUP RC_REQUEST_CUTSCENE("MAUDE_MCS_1") IF IS_ENTITY_ALIVE(pedMaude) IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY() SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED(sSceneHandle_Maude, pedMaude) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : STAGE_CUTSCENE - SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED Maude set this frame : ", GET_FRAME_COUNT()) ENDIF ENDIF RC_PLAYER_TRIGGER_SCENE_LOCK_IN() // prevent player controls (keeps movement) whilst waiting for foucs push to finish and mocap to trigger IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) // B*1394562 - ensure player is out the veh before launching cutscene, RC_PLAYER_TRIGGER_SCENE_LOCK_IN handles exit vehicle IF HAS_FOCUS_PUSH_FINSHED() // see B*1424962 IF RC_IS_CUTSCENE_OK_TO_START(TRUE) // Grab Maude ped RC_SET_ENTITY_PROOFS_FOR_CUTSCENE(sRCLauncherDataLocal, FALSE) ASSIGN_PED_INDEX(pedMaude, sRCLauncherDataLocal.pedID[0]) ASSIGN_OBJECT_INDEX(objMaudeChair, sRCLauncherDataLocal.objID[0]) ASSIGN_OBJECT_INDEX(objMaudeLaptop, sRCLauncherDataLocal.objID[1]) GET_HANDLE_TO_MAUDES_RADIO() REGISTER_ENTITY_FOR_CUTSCENE(PLAYER_PED_ID(), sSceneHandle_Trevor, CU_ANIMATE_EXISTING_SCRIPT_ENTITY) IF IS_ENTITY_ALIVE(pedMaude) REGISTER_ENTITY_FOR_CUTSCENE(pedMaude, sSceneHandle_Maude, CU_ANIMATE_EXISTING_SCRIPT_ENTITY) ENDIF IF IS_ENTITY_ALIVE(objMaudeChair) REGISTER_ENTITY_FOR_CUTSCENE(objMaudeChair, sSceneHandle_MaudeChair, CU_ANIMATE_EXISTING_SCRIPT_ENTITY) ENDIF IF IS_ENTITY_ALIVE(objMaudeLaptop) REGISTER_ENTITY_FOR_CUTSCENE(objMaudeLaptop, sSceneHandle_MaudeLaptop, CU_ANIMATE_EXISTING_SCRIPT_ENTITY) ENDIF REPLAY_START_EVENT(REPLAY_IMPORTANCE_HIGHEST) START_CUTSCENE() WAIT(0) //needed because cutscene doesn't start straight away, causing player to see vehicles getting removed. IF IS_GAMEPLAY_HINT_ACTIVE() STOP_GAMEPLAY_HINT() ENDIF RC_CLEANUP_LAUNCHER() // ensure called same frame as mission blocking area are setup CPRINTLN(DEBUG_MISSION, "DOES SNAPSHOT VEHICLE EXIST = ", DOES_ENTITY_EXIST(g_startSnapshot.mVehicleIndex)) RC_START_CUTSCENE_MODE(<< 2727.58, 4144.19, 43.95 >>, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE) //has to be after start_cutscene and wait(0) REPOSITION_PLAYER_VEHICLE_FOR_INTRO() // proc from initial scene so they match up SETUP_AREA_FOR_MISSION(RC_MAUDE_1, TRUE, FALSE) // B*1544717 - reduce calls to clear areas this frame (not convinced this is a good idea since stuff might spawn in) HAVE_MISSION_ASSETS_LOADED() bHasSetExitStateFromIntroMocapForGameplayCam = FALSE eSubStage = SS_UPDATE CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : STAGE_CUTSCENE - ", "SS_SETUP done framecount : ", GET_FRAME_COUNT()) ENDIF ELSE SET_SCRIPTS_SAFE_FOR_CUTSCENE(TRUE) ENDIF ELSE SET_SCRIPTS_SAFE_FOR_CUTSCENE(TRUE) ENDIF BREAK CASE SS_UPDATE // set exit state for Maude on her chair IF IS_ENTITY_ALIVE(objMaudeChair) IF IS_PED_UNINJURED(pedMaude) // Set exit state for Maude IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY(sSceneHandle_Maude) AND CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY(sSceneHandle_MaudeChair) IF HAS_ANIM_DICT_LOADED("special_ped@maude@base") INT iEntitySyncedSceneFlags iMaudeSyncSceneIndex = CREATE_SYNCHRONIZED_SCENE(<< 2727.40, 4145.56, 43.68 >>, << 0.0, 0.0, -92.17 >>) SET_SYNCHRONIZED_SCENE_LOOPED(iMaudeSyncSceneIndex, TRUE) SET_SYNCHRONIZED_SCENE_HOLD_LAST_FRAME(iMaudeSyncSceneIndex, FALSE) TASK_SYNCHRONIZED_SCENE(pedMaude, iMaudeSyncSceneIndex, "special_ped@maude@base", "base", INSTANT_BLEND_IN, NORMAL_BLEND_OUT, SYNCED_SCENE_ABORT_ON_WEAPON_DAMAGE | SYNCED_SCENE_LOOP_WITHIN_SCENE | SYNCED_SCENE_ACTIVATE_RAGDOLL_ON_COLLISION | SYNCED_SCENE_VEHICLE_ABORT_ON_LARGE_IMPACT) iEntitySyncedSceneFlags = 0 iEntitySyncedSceneFlags = ENUM_TO_INT(SYNCED_SCENE_ABORT_ON_WEAPON_DAMAGE) iEntitySyncedSceneFlags = ENUM_TO_INT(SYNCED_SCENE_LOOP_WITHIN_SCENE) iEntitySyncedSceneFlags = ENUM_TO_INT(SYNCED_SCENE_ACTIVATE_RAGDOLL_ON_COLLISION) iEntitySyncedSceneFlags = ENUM_TO_INT(SYNCED_SCENE_VEHICLE_ABORT_ON_LARGE_IMPACT) PLAY_SYNCHRONIZED_ENTITY_ANIM(objMaudeChair, iMaudeSyncSceneIndex, "base_chair", "special_ped@maude@base", INSTANT_BLEND_IN, NORMAL_BLEND_OUT, iEntitySyncedSceneFlags) SET_PED_KEEP_TASK(pedMaude, TRUE) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : STAGE_INTRO_MOCAP_SCENE - set sync Scene pedMaude and sSceneHandle_MaudeChair - FC = ", GET_FRAME_COUNT()) ENDIF CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : STAGE_INTRO_MOCAP_SCENE - CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY - pedMaude and sSceneHandle_MaudeChair - FC = ", GET_FRAME_COUNT()) ENDIF ENDIF ENDIF // Set exit state for Trevor IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY(sSceneHandle_Trevor) REPLAY_STOP_EVENT() IF WAS_CUTSCENE_SKIPPED() AND IS_SCREEN_FADED_OUT() SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0) SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0) CPRINTLN(DEBUG_MISSION, "STAGE_CUTSCENE - ", "SS_UPDATE - Camera - set skipped mocap Frame Count : ", GET_FRAME_COUNT()) ENDIF FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_WALK, FALSE, FAUS_CUTSCENE_EXIT) SIMULATE_PLAYER_INPUT_GAIT(PLAYER_ID(), PEDMOVEBLENDRATIO_WALK, 2000) bHasSetExitStateFromIntroMocapForGameplayCam = TRUE // stop setting the gameplay cam now. CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : STAGE_CUTSCENE : ", "SS_UPDATE * done - bHasSetExitStateFromIntroMocapForGameplayCam set TRUE by can set exit state for Trevor framecount = ", GET_FRAME_COUNT()) ENDIF // unfortunately the only way to ensure the mocap camera blends out to gameplay cam at a sensible position is to spam this until the player's character exit state has fired IF NOT bHasSetExitStateFromIntroMocapForGameplayCam SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0) SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0) ENDIF IF NOT IS_CUTSCENE_PLAYING() eSubStage = SS_CLEANUP CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : STAGE_CUTSCENE - ", "SS_UPDATE done framecount : ", GET_FRAME_COUNT()) ENDIF BREAK CASE SS_CLEANUP IF IS_CUTSCENE_PLAYING() STOP_CUTSCENE() ELSE IF HAS_CUTSCENE_LOADED() REMOVE_CUTSCENE() ENDIF IF IS_GAMEPLAY_HINT_ACTIVE() STOP_GAMEPLAY_HINT() ENDIF RC_END_CUTSCENE_MODE() RESTART_PLAYER_PLANE_AFTER_CUTSCENE() CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : STAGE_CUTSCENE : ", "SS_CLEANUP * done framecount : ", GET_FRAME_COUNT()) eMissionStage = MISSION_STAGE_LEAVE_AREA eSubStage = SS_SETUP ENDIF BREAK ENDSWITCH ENDPROC /// PURPOSE: /// Additional state to leave Maude's after the mocap for B*1496815 PROC STAGE_LEAVE_THE_AREA() SWITCH eSubStage CASE SS_SETUP // get handle to Maude's table (done set as mission entity since created by map instead uses para on DOES_OBJECT_OF_TYPE_EXIST_AT_COORDS) IF NOT DOES_ENTITY_EXIST(objMaudeTable) IF DOES_OBJECT_OF_TYPE_EXIST_AT_COORDS(<< 2727.40, 4145.56, 43.68 >>, 10.0, prop_table_03b) objMaudeTable = GET_CLOSEST_OBJECT_OF_TYPE(<< 2727.40, 4145.56, 43.68 >>, 10.0, prop_table_03b, TRUE) IF IS_ENTITY_ALIVE(objMaudeTable) SET_ENTITY_COORDS(objMaudeTable, << 2727.40, 4145.56, 43.68 >>) SET_ENTITY_HEADING(objMaudeTable, -92.17) FREEZE_ENTITY_POSITION(objMaudeTable, TRUE) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : STAGE_CUTSCENE : ", " SS_CLEANUP :grabbed handle to table") ENDIF ENDIF ENDIF IF IS_PED_UNINJURED(pedMaude) IF NOT IS_PED_HEADTRACKING_PED(pedMaude, PLAYER_PED_ID()) TASK_LOOK_AT_ENTITY(pedMaude, PLAYER_PED_ID(), -1) ENDIF SET_PED_KEEP_TASK(pedMaude, TRUE) ENDIF REQUEST_ADDITIONAL_TEXT("MAUDE1", MISSION_TEXT_SLOT) IF HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT) PRINT_NOW("MAUDE_01", DEFAULT_GOD_TEXT_TIME, 0) // Leave the area. iTimer_MaudeDialogue = GET_GAME_TIMER() eSubStage = SS_UPDATE CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), GET_THIS_SCRIPT_NAME(), " : STAGE_LEAVE_AREA_MAUDES - SS_SETUP done framecount : ", GET_FRAME_COUNT()) ELSE CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), GET_THIS_SCRIPT_NAME(), " : STAGE_LEAVE_AREA_MAUDES - loading text slot framecount : ", GET_FRAME_COUNT()) ENDIF BREAK CASE SS_UPDATE VECTOR vMaudePos VECTOR vPlayerPos vPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID()) IF IS_PED_UNINJURED(pedMaude) vMaudePos = GET_ENTITY_COORDS(pedMaude, FALSE) IF NOT SHOULD_MAUDE_FLEE() IF VDIST2(vMaudePos, GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE)) > (120*120) IF NOT IS_SPHERE_VISIBLE(vMaudePos, 2.5) OR IS_ENTITY_OCCLUDED(pedMaude) eSubStage = SS_CLEANUP CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), GET_THIS_SCRIPT_NAME(), " : STAGE_LEAVE_AREA_MAUDES - SS_UPDATE done framecount : ", GET_FRAME_COUNT()) ENDIF ELSE TRIGGER_MAUDE_AMBIENT_MISSION_PASSED_DIALOGUE(vMaudePos, vPlayerPos) ENDIF ELSE CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : STAGE_LEAVE_THE_AREA -> ", "MISSION_STAGE_MISSION_FAILED_WAIT_FOR_FADE : Maude should flee framecount : ", GET_FRAME_COUNT()) eFailReason = FAIL_REASON_MAUDE_SPOOKED eMissionStage = MISSION_STAGE_MISSION_FAILED_WAIT_FOR_FADE eSubStage = SS_SETUP ENDIF ELSE IF DOES_ENTITY_EXIST(pedMaude) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : STAGE_LEAVE_THE_AREA -> ", "MISSION_STAGE_MISSION_FAILED_WAIT_FOR_FADE : Maude injured framecount : ", GET_FRAME_COUNT()) eFailReason = FAIL_REASON_MAUDE_DEAD eMissionStage = MISSION_STAGE_MISSION_FAILED_WAIT_FOR_FADE eSubStage = SS_SETUP ENDIF ENDIF BREAK CASE SS_CLEANUP KILL_ANY_ONGOING_MAUDE_MISSION_PASSED_DIALOGUE(FALSE) IF IS_THIS_PRINT_BEING_DISPLAYED("MAUDE_01") // Leave the area. CLEAR_THIS_PRINT("MAUDE_01") ENDIF SAFE_DELETE_PED(pedMaude) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), GET_THIS_SCRIPT_NAME(), " : STAGE_LEAVE_AREA_MAUDES - SS_CLEANUP done framecount : ", GET_FRAME_COUNT()) Script_Passed() BREAK ENDSWITCH ENDPROC /// PURPOSE: /// Waits for the screen to fade out then updates failed reason PROC STAGE_MISSION_FAILED_WAIT_FOR_FADE() STRING sFailReason = NULL SWITCH eSubStage CASE SS_SETUP CLEAR_PRINTS() CLEAR_HELP() KILL_ANY_ONGOING_MAUDE_MISSION_PASSED_DIALOGUE() IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() KILL_ANY_CONVERSATION() ENDIF //DELETE_ALL_MISSION_BLIPS() // ensure these aren't frozen for flee IF DOES_ENTITY_EXIST(objMaudeLaptop) FREEZE_ENTITY_POSITION(objMaudeLaptop, FALSE) ENDIF IF DOES_ENTITY_EXIST(objMaudeTable) FREEZE_ENTITY_POSITION(objMaudeTable, FALSE) ENDIF // set the fail reason IF eFailReason = FAIL_REASON_MAUDE_SPOOKED REQUEST_ANIM_DICT("special_ped@maude@exit_flee") // begin request for flee anim // flee comment from Maude IF IS_PED_UNINJURED(pedMaude) REMOVE_PED_FOR_DIALOGUE(sDialogue, 3) // leave area comments - remove Maude MAKE_PED_SCREAM(pedMaude, FALSE) IF NOT IS_AMBIENT_SPEECH_PLAYING(pedMaude) IF IS_ENTITY_IN_RANGE_COORDS(pedMaude, GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE), 35.0) STOP_PED_SPEAKING(pedMaude, FALSE) PLAY_PED_AMBIENT_SPEECH_WITH_VOICE(pedMaude, "GENERIC_FRIGHTENED_HIGH", "MAUDE", SPEECH_PARAMS_FORCE) // GENERIC_SHOCKED_HIGH CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : TRIGGER_MAUDE_FLEE_DIALOGUE_LINE - requested to trigger ambient speech line GENERIC_FRIGHTENED_HIGH") ENDIF ELSE CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : TRIGGER_MAUDE_FLEE_DIALOGUE_LINE - failed already ambient Maude speech playing") ENDIF ENDIF IF SET_MAUDE_PLAY_FLEE_EXIT_ANIM() bSetMaudeFleeSyncSceneExit = TRUE CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : STAGE_FAILED_WAIT_FOR_FADE : maude exit sync scene done") ENDIF sFailReason = "MAUDE_F1" // ~w~Maude was spooked.~s~ CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), "STAGE_FAILED_WAIT_FOR_FADE string set : BB_FAILED_MAUDE_ATTACKED") ELIF eFailReason = FAIL_REASON_MAUDE_DEAD sFailReason = "MAUDE_F2" // ~w~Maude died.~s~ CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), "STAGE_FAILED_WAIT_FOR_FADE string set : BB_FAILED_MAUDE_DIED") ELSE CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), "STAGE_FAILED_WAIT_FOR_FADE string set : FAIL_REASON_DEFAULT") ENDIF //Check if fail reason needs to be displayed IF eFailReason = FAIL_REASON_DEFAULT RANDOM_CHARACTER_FAILED() ELSE RANDOM_CHARACTER_FAILED_WITH_REASON(sFailReason) ENDIF eSubStage = SS_UPDATE CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), "STAGE_FAILED_WAIT_FOR_FADE - SS_SETUP done") BREAK CASE SS_UPDATE IF GET_MISSION_FLOW_SAFE_TO_CLEANUP() // Do a check here to see if we need to warp the player at all // (only set the fail warp locations if we can't leave the player where he was) //---- Do any specific cleanup here---- CLEANUP_ALL_MISSION_ENTITIES(TRUE) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), "STAGE_FAILED_WAIT_FOR_FADE - SS_UPDATE done") Script_Cleanup() ELSE // not finished fading out IF eFailReason = FAIL_REASON_MAUDE_SPOOKED IF IS_PED_UNINJURED(pedMaude) // Handle Maude's flee exit IF NOT bSetMaudeFleeSyncSceneExit REQUEST_ANIM_DICT("special_ped@maude@exit_flee") // begin request for flee anim IF SET_MAUDE_PLAY_FLEE_EXIT_ANIM() bSetMaudeFleeSyncSceneExit = TRUE CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : STAGE_FAILED_WAIT_FOR_FADE : maude exit sync scene done") ENDIF ELSE IF IS_PED_UNINJURED(pedMaude) IF NOT IsPedPerformingTask(pedMaude, SCRIPT_TASK_SMART_FLEE_PED) IF NOT IS_PED_FLEEING(pedMaude) IF NOT IS_ENTITY_PLAYING_ANIM(pedMaude, "special_ped@maude@exit_flee", "female_Flee_Table_Left_Maude") SET_PED_FLEE_ATTRIBUTES(pedMaude, FA_USE_VEHICLE, FALSE) SET_PED_FLEE_ATTRIBUTES(pedMaude, FA_RETURN_TO_ORIGNAL_POSITION_AFTER_FLEE, FALSE) SET_PED_FLEE_ATTRIBUTES(pedMaude, FA_DISABLE_HANDS_UP, FALSE) SET_PED_FLEE_ATTRIBUTES(pedMaude, FA_PREFER_PAVEMENTS, FALSE) SET_PED_FLEE_ATTRIBUTES(pedMaude, FA_USE_COVER, FALSE) SET_PED_FLEE_ATTRIBUTES(pedMaude, FA_LOOK_FOR_CROWDS, FALSE) SET_PED_COMBAT_ATTRIBUTES(pedMaude, CA_ALWAYS_FIGHT, FALSE) SET_PED_COMBAT_ATTRIBUTES(pedMaude, CA_ALWAYS_FLEE, TRUE) TASK_SMART_FLEE_PED(pedMaude, PLAYER_PED_ID(), 50, -1) // keep small to inprove latency path finding issue (should be faded by dist reached) SET_PED_KEEP_TASK(pedMaude, TRUE) // Keep scripted task CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : STAGE_FAILED_WAIT_FOR_FADE : maude flee task applied") ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF BREAK ENDSWITCH ENDPROC // =========================================================================================================== // DEBUG FUNCTIONS // =========================================================================================================== #IF IS_DEBUG_BUILD /// PURPOSE: /// reset's everything ready to retrigger the cutscene PROC RESET_CUTSCENE() WAIT_FOR_CUTSCENE_TO_STOP() RC_END_CUTSCENE_MODE() eMissionStage = MISSION_STAGE_CUTSCENE eSubStage = SS_SETUP // skip focus push iFocusPushStage = 1 iFocusPushTimer = -1 ENDPROC PROC DEBUG_Check_Debug_Keys() INT iNewStage IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_S) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : DEBUG: S Skip") WAIT_FOR_CUTSCENE_TO_STOP() Script_Passed() ELIF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_J) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : DEBUG: J Skip") IF eMissionStage = MISSION_STAGE_CUTSCENE IF eSubStage = SS_UPDATE //in script skips where we change the eSubStage, need to safe gaurd that the SS_SETUP has already had chance to run. IF IS_CUTSCENE_PLAYING() STOP_CUTSCENE() CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : DEBUG: J Skip MISSION_STAGE_CUTSCENE : STOPPING CUTSCENE framecount : ", GET_FRAME_COUNT()) ENDIF ENDIF ELIF eMissionStage = MISSION_STAGE_LEAVE_AREA IF eSubStage = SS_UPDATE eSubStage = SS_CLEANUP CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : DEBUG: J Skip MISSION_STAGE_LEAVE_AREA framecount : ", GET_FRAME_COUNT()) ENDIF ENDIF ELIF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_F)) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : DEBUG: F Skip") WAIT_FOR_CUTSCENE_TO_STOP() RC_END_CUTSCENE_MODE() eMissionStage = MISSION_STAGE_MISSION_FAILED_WAIT_FOR_FADE eSubStage = SS_SETUP ELIF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_P)) CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : DEBUG: P Skip") RESET_CUTSCENE() eSubStage = SS_SETUP ELIF LAUNCH_MISSION_STAGE_MENU(mSkipMenu, iNewStage) IF iNewStage = MAUDE_1_Z_SKIP_START_CUTSCENE CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : DEBUG: Z Skip to MAUDE_1_Z_SKIP_START_CUTSCENE") RESET_CUTSCENE() eSubStage = SS_SETUP ELIF iNewStage = MAUDE_1_Z_SKIP_LEAVE_AREA CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : DEBUG: Z Skip to SS_SETUP") WAIT_FOR_CUTSCENE_TO_STOP() SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0) SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0) eMissionStage = MISSION_STAGE_LEAVE_AREA eSubStage = SS_SETUP ELIF iNewStage = MAUDE_1_Z_SKIP_MISSION_PASSED CPRINTLN(DEBUG_MISSION, GET_THIS_SCRIPT_NAME(), " : DEBUG: Z Skip to SS_SETUP") WAIT_FOR_CUTSCENE_TO_STOP() eMissionStage = MISSION_STAGE_LEAVE_AREA eSubStage = SS_CLEANUP SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0) SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0) ENDIF ENDIF ENDPROC #ENDIF // =========================================================================================================== // Script Loop // =========================================================================================================== SCRIPT(g_structRCScriptArgs sRCLauncherDataIn) sRCLauncherDataLocal = sRCLauncherDataIn RC_TakeEntityOwnership(sRCLauncherDataLocal) // take ownership of the sync scene index from the initial scene (needs to happen before launcher terminates) // take ownership from the initial scene (needs to happen before launcher terminates) must check is running, could get here from replay and not be setup IF IS_SYNCHRONIZED_SCENE_RUNNING(sRCLauncherDataLocal.iSyncSceneIndex) TAKE_OWNERSHIP_OF_SYNCHRONIZED_SCENE(sRCLauncherDataLocal.iSyncSceneIndex) iMaudeSyncSceneIndex = sRCLauncherDataLocal.iSyncSceneIndex CPRINTLN(DEBUG_MISSION, " TAKE_OWNERSHIP_OF_SYNCHRONIZED_SCENE : sRCLauncherDataLocal.iSyncSceneIndex = ", sRCLauncherDataLocal.iSyncSceneIndex, " iMaudeSyncSceneIndex = ", iMaudeSyncSceneIndex) ENDIF 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() ENDIF INIT_DATA() IF IS_REPLAY_IN_PROGRESS() // handle replay checkpoints (only restart after intro available) SETUP_FOR_REPLAY() ENDIF // Loop within here until the mission passes or fails WHILE(TRUE) REPLAY_CHECK_FOR_EVENT_THIS_FRAME("SF_Maude") IF NOT IS_PED_INJURED(PLAYER_PED_ID()) IF eMissionStage = MISSION_STAGE_CUTSCENE STAGE_CUTSCENE() ELIF eMissionStage = MISSION_STAGE_LEAVE_AREA STAGE_LEAVE_THE_AREA() ELIF eMissionStage = MISSION_STAGE_MISSION_FAILED_WAIT_FOR_FADE STAGE_MISSION_FAILED_WAIT_FOR_FADE() ENDIF ENDIF // Check debug completion/failure #IF IS_DEBUG_BUILD IF eMissionStage != MISSION_STAGE_MISSION_FAILED_WAIT_FOR_FADE DEBUG_Check_Debug_Keys() ENDIF #ENDIF WAIT(0) ENDWHILE // Script should never reach here. Always terminate with cleanup function. ENDSCRIPT