//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 "commands_cutscene.sch" USING "commands_entity.sch" USING "commands_event.sch" USING "commands_script.sch" USING "cutscene_public.sch" USING "dialogue_public.sch" USING "randomChar_public.sch" USING "rgeneral_include.sch" USING "RC_Helper_Functions.sch" USING "replay_public.sch" USING "script_ped.sch" USING "script_player.sch" USING "shared_hud_displays.sch" USING "CompletionPercentage_public.sch" USING "RC_Threat_public.sch" USING "RC_Setup_public.sch" USING "initial_scenes_fanatic.sch" USING "cheat_controller_public.sch" USING "commands_recording.sch" #IF IS_DEBUG_BUILD USING "select_mission_stage.sch" #ENDIF // ***************************************************************************************** // ***************************************************************************************** // ***************************************************************************************** // // MISSION NAME : Fanatic1.sc // AUTHOR : Neil Beggs (originally)/Ian Gander (June 12 onwards) // DESCRIPTION : Foot race against Mary Ann, a fitness fanatic // // ***************************************************************************************** // ***************************************************************************************** // ***************************************************************************************** //---------------------- // CHECKPOINTS //---------------------- CONST_INT CP_AFTER_MOCAP 0 //------------------------------------------------------------------------------------------------------------------------------------------------- // ENUMS: //------------------------------------------------------------------------------------------------------------------------------------------------- ENUM MISSION_STAGE MS_LEADIN, MS_CUTSCENE, MS_START_RUNNING, MS_ROAD_RUNNING_SECTION, MS_STEPS_DOWN, MS_SPRINT_TO_FINISH, MS_DEBUG_NEAR_FINISH_LINE, MS_PLAYER_IN_VEHICLE, MS_END_CUTSCENE, MS_LOST_RACE, MS_FAIL_WAIT_FOR_FADE ENDENUM ENUM FINISH_TACTIC FINISHED_BY_STEROIDS, FINISHED_BY_SHORTCUT ENDENUM ENUM STAGE_STAGE SS_SETUP, SS_STAGE ENDENUM ENUM STUCK_STAGE STUCK_UPDATE, STUCK_LOOP, STUCK_FIX ENDENUM ENUM debugSkipToMissionStage DEBUG_TO_INTRO = 0, DEBUG_TO_START, DEBUG_TO_ROAD, DEBUG_TO_STEPS_DOWN, DEBUG_TO_BEACH, DEBUG_TO_FINISH_LINE, DEBUG_NEXT_TO_FINISH ENDENUM ENUM FAIL_REASON FAIL_FANATIC_KILLED, FAIL_FANATIC_INJURED, FAIL_FANATIC_SCARED, FAIL_IN_CAR, FAIL_YOU_DIDNT_KEEP_UP, FAIL_SHE_BEAT_YOU_TO_BIKE, FAIL_LEFT_RACE, REASON_SILENT ENDENUM ENUM CUTSCENE_ENUM CS_PLAYER_WINS, CS_WAIT_FOR_ANN, CS_MARY_ANN_LEAVES, CS_SAY_FINAL_LINE, CS_CUTSCENE_ENDS ENDENUM ENUM CAMERA_TARGET CAM_TARGET_PLAYER, CAM_MARY_ANN_LEAVES ENDENUM ENUM SPRINT_STATE SPRINT_WAITING, SPRINT_ACTIVE, SPRINT_REDUCE, SPRINT_COOLDOWN ENDENUM ENUM DRIVE_BY_STATE DRIVE_BY_LOAD, DRIVE_BY_PRE_TASK, DRIVE_BY_SET_DRIVE_TASK, DRIVE_BY_DRIVE, DRIVE_BY_SET_FINGER_TASK, DRIVE_BY_FINGERING, DRIVE_BY_RELEASE ENDENUM ENUM MARY_ANN_DIALOGUE_STATE MA_WITHIN_TALKING_RANGE, MA_OUT_OF_TALKING_RANGE, MA_SHOUTING_TO_KEEP_UP, MA_SAYING_YOU_CAUGHT_UP ENDENUM ENUM DOG_STATE_ENUM DOG_LOADING, DOG_WAITING, DOG_FOLLOWING_PLAYER ENDENUM ENUM CPR_STATE CPR_LOADING, CPR_WAITING, CPR_GOING_TO_SCENE, CPR_INTRO, CPR_IDLE, CPR_GETTING_UP, CPR_INTERUPTED, CPR_WATCHING_PLAYER, CPR_FLEE ENDENUM //------------------------------------------------------------------------------------------------------------------------------------------------- // :STRUCTS: //------------------------------------------------------------------------------------------------------------------------------------------------- STRUCT JOGGERS PED_INDEX thisIndex MODEL_NAMES thisModel VECTOR thisPosition VECTOR thisGoToPos1 VECTOR thisGoToPos2 Float thisHeading ENDSTRUCT STRUCT VEHICLE_STRUCT PED_INDEX Driver PED_INDEX Passenger VEHICLE_INDEX thisCarIndex MODEL_NAMES thisPedModel MODEL_NAMES thisCarModel VECTOR thisPosition VECTOR thisGoToPos Float thisHeading FLOAT thisSpeed ENDSTRUCT STRUCT CONV_STRUCT STRING rootLabel STRING dialogueLine BOOL hasBeenPlayed = FALSE BOOL hasBeenInterrupted = FALSE INT restartLine = -1 ENDSTRUCT STRUCT RANDOM_CONV_STRUCT STRING dialogueLine INT timesPlayed = 0 INT restartLine = -1 ENDSTRUCT STRUCT GOD_TEXT_STRUCT STRING textLabel BOOL hasBeenShown = FALSE ENDSTRUCT //------------------------------------------------------------------------------------------------------------------------------------------------- // :VARIABLES: //------------------------------------------------------------------------------------------------------------------------------------------------- // The Random Character - sRCLauncherDataLocal.pedID[0] g_structRCScriptArgs sRCLauncherDataLocal // Mission stuff STAGE_STAGE stageStage = SS_SETUP MISSION_STAGE missionStage = MS_LEADIN MISSION_STAGE currentMissionStage FAIL_REASON failReason FINISH_TACTIC finishReason = FINISHED_BY_STEROIDS BOOL b_LeadInConvo = FALSE BOOL b_CutsceneSkipped = FALSE BOOL b_MusicTriggered = FALSE BOOL b_DoneOutOfBreath = FALSE BOOL b_CheatedLine = FALSE BOOL b_IsTheRoadSwitchedOn = TRUE BOOL b_PlayerJumpedDownTheCliff = FALSE BOOL b_ForcePlayerRunningAtStart = TRUE BOOL b_ScriptedEnding = FALSE BOOL b_PlayerOnMAsBike = FALSE BOOL b_MaryAnnFinalOrdersGiven = FALSE BOOL b_DrivebyHorn = FALSE BOOL bHasChanged GOD_TEXT_STRUCT leftBehindWarning GOD_TEXT_STRUCT leftRaceWarning GOD_TEXT_STRUCT vehicleWarning REL_GROUP_HASH relGroupFriendly sequence_index seq structPedsForConversation MyLocalPedStruct // Mary Ann stuff MARY_ANN_DIALOGUE_STATE MADialogueState = MA_WITHIN_TALKING_RANGE PED_INDEX MARY_ANN BLIP_INDEX FANATIC_BLIP SPRINT_STATE MASprintState = SPRINT_WAITING INT iSprintTimer INT iSprintLength = 1800 INT iSprintDelay = 4500 FLOAT fMBRMax = 1.025 FLOAT fMBR_IncreaseRatio = fMBRMax FLOAT fMBR_MaxRunSpeed = 3.00 FLOAT fMBR_RunSpeed = fMBR_MaxRunSpeed FLOAT fMBR_SprintCap = -1.0 BOOL b_DoPedOvertake = FALSE BOOL b_LoadCollisionAroudMaryAnn = FALSE BOOL bMARY_ANN_CHASING_YOU_IN_CAR = FALSE BOOL bMARY_ANN_IS_GOING_TO_RUN_SCARED = FALSE STUCK_STAGE StuckStage = STUCK_UPDATE INT iStuckTimer INT iWaypointStuckCheck // Running Dialogue Stuff CONST_INT MAX_CHECKPOINTS 10 INT iHurryUpLineNumber = 0 CONST_INT iMAXHurryUpLineNumber 2 STRING HURRY_UP_LINE[iMAXHurryUpLineNumber] INT iCatchUpLineNumber = 0 CONST_INT iMAXCatchUpLineNumber 2 INT iRaceLineNumber = 0 CONST_INT iMAXRaceLineNumber 3 STRING RACE_LINE[iMAXRaceLineNumber] TEXT_LABEL tDialogueRoot RANDOM_CONV_STRUCT MikePushMALine RANDOM_CONV_STRUCT MikePushPedLine RANDOM_CONV_STRUCT OvertakeLines INT iOvertakeTimer BOOL bOvertaken BOOL bOvertakenSkip = FALSE BOOL bCatchupCheatLineSaid = FALSE INT iOneLinerSeq = 0 INT iOneLinerTimer INT iRoadCounter = 0 INT iRoadTimer CONV_STRUCT pushLine[3] CONV_STRUCT startRunConversation CONV_STRUCT road1Conversation CONV_STRUCT road2Conversation CONV_STRUCT raceConversation CONV_STRUCT cheatedRanAcrossGrass CONV_STRUCT cheatedLeaptFence CONV_STRUCT returnAfterCheatedLine // Mary Anns Bike stuff VEHICLE_INDEX MAS_BIKE VECTOR MAS_BIKE_POS = <<-2002.52, -503.53, 11.27>> FLOAT MAS_BIKE_DIR = 0.13 MODEL_NAMES MARYSBIKEMODEL = SCORCHER // Cutscene stuff CUTSCENE_ENUM cutsceneStage CAMERA_TARGET myCam = CAM_TARGET_PLAYER BOOL b_TIRED_ANIM_PLAYING = FALSE STRING dialogueOptionFinish CAMERA_INDEX camCutsceneStart INT iCutsceneStage = 0 //BOOL bCutsceneSkipped = FALSE ANIM_DATA adBreathEnter ANIM_DATA adBreathIdle1 ANIM_DATA adBreathIdle2 ANIM_DATA adBreathIdle3 // World filler stuff VEHICLE_STRUCT DRIVEBY_FINGER_CAR DRIVE_BY_STATE driveByState = DRIVE_BY_LOAD VEHICLE_STRUCT FOLLOWING_CAR JOGGERS OtherJoggers[4] MODEL_NAMES JOGGERMODEL = A_F_Y_FITNESS_01 BOOL b_FinalPedsStartedWalking = FALSE PED_INDEX QUAD_DRIVER PED_INDEX INJURED_PED PED_INDEX cprWatcher1 PED_INDEX cprWatcher2 VEHICLE_INDEX CHEAT_QUAD VECTOR vPos_CHEAT_QUAD = <<-1818.96, -751.50, 7.99>> VECTOR vPos_CPRScene VECTOR vRot_CPRScene INT CPRSynchSceneID INT IdleSynchSceneID INT NavBlockerID = -1 INT CutsceneNavBlockerID = -1 SCENARIO_BLOCKING_INDEX sbiCutscene // For the benches in the background that occasionally spawn peds in view around 15 secs into the cutscene SCENARIO_BLOCKING_INDEX sbiWallPeds SCENARIO_BLOCKING_INDEX sbiPathPeds SCENARIO_BLOCKING_INDEX sbiMobilePed PED_INDEX BEACH_DOG VECTOR vPos_DOG = <<-1957.213013,-555.261414,11.083831>> FLOAT fDir_DOG = -87.356987 DOG_STATE_ENUM beachDogState = DOG_LOADING // Race Stuff STRING sFANATIC_ROUTE = "Fanatic1MaryAnn" INT place INT iNum_WAYPOINTS INT iNum_PlayerClosestWaypoint INT iNum_NPCClosestWaypoint VECTOR vPos_PlayerClosestWaypoint VECTOR vPos_StartOfRoadRunning VECTOR vPos_StartOfBeachRunning VECTOR vPos_FinishLine = <<-2005.65, -508.08, 10.76>> BLIP_INDEX DESTINATION_BLIP BLIP_INDEX NEXT_DESTINATION_BLIP CHECKPOINT_INDEX Checkpoint CHECKPOINT_INDEX PrevCheckpoint INT iPrevAlpha INT iMaxRacePositions VECTOR RACE_POSITIONS[10] INT iCURRENT_RACE_POS = 0 INT iNPC_RACE_POS = 1 INT start_time = 0 INT iRollingStartTimer INT iConversationTimer INT iDrivebyTimer INT iVehicleFailTimer INT iHeartbeatAudioID BOOL bHeartbeatStarted = FALSE FLOAT fHintFov = 40.0 FLOAT fHintFollow = 0.35 FLOAT fHintPitchOrbit = 0.000 FLOAT fHintSide = -0.80 FLOAT fHintVert = -0.050 // Debug Stuff #if IS_DEBUG_BUILD CONST_INT MAX_SKIP_MENU_LENGTH 7 INT i_debug_jump_stage = 0 MissionStageMenuTextStruct s_skip_menu[MAX_SKIP_MENU_LENGTH] BOOL bDebug_PrintToTTY = TRUE BOOL bDebug_SpeedDebug = FALSE FLOAT fPlayerSprintRemaining WIDGET_GROUP_ID widgetGroup #ENDIF CPR_STATE cprState = CPR_LOADING // =========================================================================================================== // Debug prints // =========================================================================================================== /// PURPOSE: Print a string to the console PROC DEBUG_PRINTSTRING(STRING s) #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, s) ENDIF #ENDIF // Stop release compile error s = s ENDPROC /// PURPOSE: Print a string with a float to the console PROC DEBUG_PRINTSF(STRING s, FLOAT f) #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, s, f) ENDIF #ENDIF // Stop release compile error s = s f = f ENDPROC /// PURPOSE: Print a string with an int to the console PROC DEBUG_PRINTSI(STRING s, INT i) #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, s, i) ENDIF #ENDIF // Stop release compile error s = s i = i ENDPROC //PURPOSE: Checks that a particular conversation root is currently playing. //PARAMS: RootToCheck - The conversation root we want to check is playing. //RETURNS: TRUE if the root is currently playing, FALSE otherwise. FUNC BOOL IS_THIS_CONVERSATION_ROOT_PLAYING(STRING RootToCheck) TEXT_LABEL_23 blah blah = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT() IF ARE_STRINGS_EQUAL(blah,RootToCheck) RETURN TRUE ENDIF RETURN FALSE ENDFUNC // =========================================================================================================== // Termination // =========================================================================================================== // ----------------------------------------------------------------------------------------------------------- // Script Cleanup // ----------------------------------------------------------------------------------------------------------- //PURPOSE: general cutscene cleanup PROC FINISH_CUTSCENE(BOOL bInterp = TRUE, BOOL bResetGamePlayCamera = TRUE) CLEAR_HELP() DISPLAY_HUD(TRUE) DISPLAY_RADAR(TRUE) SET_WIDESCREEN_BORDERS(FALSE, 500) RENDER_SCRIPT_CAMS(FALSE, bInterp) IF DOES_CAM_EXIST(camCutsceneStart) SET_CAM_ACTIVE(camCutsceneStart, FALSE) DESTROY_CAM (camCutsceneStart) ENDIF IF bResetGamePlayCamera SET_GAMEPLAY_CAM_RELATIVE_HEADING() SET_GAMEPLAY_CAM_RELATIVE_PITCH(-5) ENDIF IF NOT IS_PED_INJURED(PLAYER_PED_ID()) SET_PLAYER_CONTROL(PLAYER_ID(), TRUE) ENDIF // RC_SETUP_SCRIPT_FOR_CUTSCENE(FALSE, <<0,0,0>>, <<0,0,0>>, 0) ENDPROC /// PURPOSE: Cleanup peds and resources loaded for the CPR synced scene PROC CLEANUP_QUAD_SCENE() SAFE_RELEASE_PED(QUAD_DRIVER) SAFE_RELEASE_PED(INJURED_PED) SAFE_RELEASE_PED(cprWatcher1) SAFE_RELEASE_PED(cprWatcher2) REMOVE_ANIM_DICT("mini@cpr@char_a@cpr_def") REMOVE_ANIM_DICT("mini@cpr@char_b@cpr_def") REMOVE_ANIM_DICT("mini@cpr@char_a@cpr_str") REMOVE_ANIM_DICT("mini@cpr@char_b@cpr_str") REMOVE_ANIM_DICT("rcmfanatic1") SET_PED_PATHS_IN_AREA(<<-1875.16, -630.82, 10.00>>, <<-1867.90, -625.78, 10.25>>, TRUE) DISABLE_NAVMESH_IN_AREA(<<-1875.16, -630.82, 10.00>>, <<-1867.90, -625.78, 10.25>>, FALSE) ENDPROC /// PURPOSE: Turn the road where the driveby fingering occurs back on PROC TURN_ROADS_ON(BOOL on = TRUE) IF b_IsTheRoadSwitchedOn <> on SET_ROADS_IN_ANGLED_AREA(<<-1708.313965,-574.026611,36.873383>>, <<-2044.766357,-370.916718,9.152167>>, 27.250000, FALSE, on) b_IsTheRoadSwitchedOn = on ENDIF ENDPROC PROC Script_Cleanup() // Ensure launcher is terminated RC_CLEANUP_LAUNCHER() // If the mission was triggered then additional mission cleanup will be required. IF (Random_Character_Cleanup_If_Triggered()) DEBUG_PRINTSTRING("...Random Character Script was triggered so additional cleanup required") ENDIF IF IS_ENTITY_ALIVE(MARY_ANN) SET_PED_CAN_BE_KNOCKED_OFF_VEHICLE(MARY_ANN, KNOCKOFFVEHICLE_DEFAULT) ENDIF REMOVE_RELATIONSHIP_GROUP(relGroupFriendly) IF IS_AUDIO_SCENE_ACTIVE("FANATIC_MIX_SCENE") IF DOES_ENTITY_EXIST(MARY_ANN) REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(MARY_ANN) ENDIF STOP_AUDIO_SCENE("FANATIC_MIX_SCENE") ENDIF TRIGGER_MUSIC_EVENT("RC6A_FAIL") // In case this wasn't triggered before SAFE_RELEASE_VEHICLE(MAS_BIKE) SAFE_RELEASE_PED(MARY_ANN) SAFE_REMOVE_BLIP(DESTINATION_BLIP) SAFE_REMOVE_BLIP(FANATIC_BLIP) INT j FOR j = 0 TO 3 SAFE_RELEASE_PED(OtherJoggers[j].thisIndex) ENDFOR SAFE_RELEASE_PED(DRIVEBY_FINGER_CAR.Driver) IF IS_ENTITY_ALIVE(DRIVEBY_FINGER_CAR.Passenger) SET_PED_COMBAT_ATTRIBUTES(DRIVEBY_FINGER_CAR.Passenger, CA_LEAVE_VEHICLES, TRUE) SAFE_RELEASE_PED(DRIVEBY_FINGER_CAR.Passenger) ENDIF SAFE_RELEASE_VEHICLE(DRIVEBY_FINGER_CAR.thisCarIndex) SAFE_RELEASE_PED(BEACH_DOG) REMOVE_WAYPOINT_RECORDING(sFANATIC_ROUTE) REMOVE_WAYPOINT_RECORDING("Fanatic1RollingStart") // REMOVE_ANIM_DICT("GESTURES@MALE") REMOVE_ANIM_DICT("rcmfanatic1out_of_breath") REMOVE_ANIM_DICT("move_f@runner") REMOVE_ANIM_DICT("rcmfanatic1") REMOVE_ANIM_SET("FEMALE_FAST_RUNNER") SET_MODEL_AS_NO_LONGER_NEEDED(JOGGERMODEL) SET_MODEL_AS_NO_LONGER_NEEDED(A_M_Y_BEACH_01) SET_MODEL_AS_NO_LONGER_NEEDED(A_F_Y_BEACH_01) SET_MODEL_AS_NO_LONGER_NEEDED(BANSHEE) SET_MODEL_AS_NO_LONGER_NEEDED(MARYSBIKEMODEL) SET_MODEL_AS_NO_LONGER_NEEDED(A_C_ROTTWEILER) SET_MODEL_AS_NO_LONGER_NEEDED(BLAZER2) SET_MODEL_AS_NO_LONGER_NEEDED(S_M_Y_BayWatch_01) SET_MODEL_AS_NO_LONGER_NEEDED(G_M_Y_SALVAGOON_01) SET_MODEL_AS_NO_LONGER_NEEDED(A_M_M_TRAMPBEAC_01) SET_MODEL_AS_NO_LONGER_NEEDED(IG_MARYANN) CLEANUP_QUAD_SCENE() TURN_ROADS_ON() //Re-enable vehicle generators near steps SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<<-1842.30, -517.70, 26.68>>, <<-1823.52, -515.43, 29.27>>, TRUE) SET_PED_PATHS_BACK_TO_ORIGINAL(<<-1864.08, -632.07, 10.09>>, <<-1863.31, -631.53, 10.15>>) SET_PED_PATHS_BACK_TO_ORIGINAL(<<-1820.57, -552.41, 17.40>>, <<-1865.76, -617.48, 10.58>>) CLEAR_PED_NON_CREATION_AREA() REMOVE_SCENARIO_BLOCKING_AREA(sbiWallPeds) REMOVE_SCENARIO_BLOCKING_AREA(sbiPathPeds) REMOVE_SCENARIO_BLOCKING_AREA(sbiMobilePed) REMOVE_SCENARIO_BLOCKING_AREAS() STOP_SOUND(iHeartbeatAudioID) CLEAR_ADDITIONAL_TEXT(MISSION_TEXT_SLOT, TRUE) DISABLE_CHEAT(CHEAT_TYPE_FAST_RUN, FALSE) RC_CleanupSceneEntities(sRCLauncherDataLocal, FALSE) TERMINATE_THIS_THREAD() ENDPROC /// PURPOSE: Snap a given ped the closest Z-coord PROC SET_PED_ON_THE_GROUND(PED_INDEX ped) IF IS_PED_UNINJURED(ped) VECTOR pos = GET_ENTITY_COORDS(ped) FLOAT zCoord GET_GROUND_Z_FOR_3D_COORD(pos, zCoord) SET_ENTITY_COORDS(ped, <>) ENDIF ENDPROC // ----------------------------------------------------------------------------------------------------------- // Script Pass // ----------------------------------------------------------------------------------------------------------- PROC Script_Passed() IF IS_SCRIPTED_CONVERSATION_ONGOING() DEBUG_PRINTSTRING("Stopping scripted convo at script_passed") KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() ENDIF IF finishReason <> FINISHED_BY_SHORTCUT INFORM_STAT_SYSTEM_OF_BOOL_STAT_HAPPENED(FA1_SHORTCUT_USED) ENDIF CLEAR_PRINTS() ADD_CONTACT_TO_PHONEBOOK(CHAR_MARY_ANN, MICHAEL_BOOK, TRUE) Random_Character_Passed(CP_RAND_C_FAN1) Script_Cleanup() ENDPROC /// PURPOSE: Check whether the player has jumped down the cliff instead of going down the stairs, and start a conversation for this PROC CHECK_IF_PLAYER_JUMPS_THE_CLIFF() IF b_PlayerJumpedDownTheCliff = FALSE IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-1827.530396,-538.121277,21.831240>>, <<-1805.926025,-555.623901,31.773228>>, 2.000000) IF MADialogueState = MA_WITHIN_TALKING_RANGE IF IS_SCRIPTED_CONVERSATION_ONGOING() DEBUG_PRINTSTRING("Stopping scripted convo at check if player jumps off cliff") KILL_ANY_CONVERSATION() CLEAR_PRINTS() ENDIF IF CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_5", CONV_PRIORITY_MEDIUM) finishReason = FINISHED_BY_SHORTCUT b_PlayerJumpedDownTheCliff = TRUE ENDIF ENDIF g_savedGlobals.sRandomChars.g_bFanaticCheated = TRUE // Set this even if the conversation doesn't trigger ENDIF ENDIF ENDPROC /// PURPOSE: Load the resources for the driveby sequence, and return TRUE when finished loading FUNC BOOL LOAD_DRIVEBY() REQUEST_MODEL(G_M_Y_SALVAGOON_01) REQUEST_MODEL(BANSHEE) IF HAS_MODEL_LOADED(G_M_Y_SALVAGOON_01) AND HAS_MODEL_LOADED(BANSHEE) RETURN TRUE ENDIF RETURN FALSE ENDFUNC /// PURPOSE: Load the resources for the CPR synced scene, and return TRUE when finished loading FUNC BOOL LOAD_CPR() REQUEST_ANIM_DICT("mini@cpr@char_a@cpr_def") REQUEST_ANIM_DICT("mini@cpr@char_b@cpr_def") REQUEST_ANIM_DICT("mini@cpr@char_a@cpr_str") REQUEST_ANIM_DICT("mini@cpr@char_b@cpr_str") REQUEST_ANIM_DICT("rcmfanatic1") REQUEST_WAYPOINT_RECORDING("Fanatic1Quad") REQUEST_MODEL(BLAZER2) REQUEST_MODEL(A_F_Y_BEACH_01) REQUEST_MODEL(S_M_Y_BayWatch_01) REQUEST_MODEL(A_M_M_Beach_01) IF HAS_ANIM_DICT_LOADED("mini@cpr@char_a@cpr_def") AND HAS_ANIM_DICT_LOADED("mini@cpr@char_b@cpr_def") AND HAS_ANIM_DICT_LOADED("mini@cpr@char_a@cpr_str") AND HAS_ANIM_DICT_LOADED("mini@cpr@char_b@cpr_str") AND HAS_ANIM_DICT_LOADED("rcmfanatic1") AND GET_IS_WAYPOINT_RECORDING_LOADED("Fanatic1Quad") AND HAS_MODEL_LOADED(A_F_Y_BEACH_01) AND HAS_MODEL_LOADED(S_M_Y_BayWatch_01) AND HAS_MODEL_LOADED(A_M_M_Beach_01) AND HAS_MODEL_LOADED(BLAZER2) RETURN TRUE ENDIF RETURN FALSE ENDFUNC /// PURPOSE: Load the resources for the dog on the final stretch, and return TRUE when finished loading FUNC BOOL LOAD_DOG() REQUEST_MODEL(A_C_ROTTWEILER) IF HAS_MODEL_LOADED(A_C_ROTTWEILER) RETURN TRUE ENDIF RETURN FALSE ENDFUNC /// PURPOSE: Load the basic resources needed for the mission, such as Mary Ann's model, animations and route PROC LOAD_OTHER_ASSETS() REQUEST_ANIM_DICT("rcmfanatic1") REQUEST_ANIM_DICT("rcmfanatic1celebrate") REQUEST_ANIM_DICT("rcmfanatic1yell") REQUEST_ANIM_DICT("move_f@runner") REQUEST_ANIM_SET("FEMALE_FAST_RUNNER") REQUEST_WAYPOINT_RECORDING(sFANATIC_ROUTE) REQUEST_WAYPOINT_RECORDING("Fanatic1RollingStart") REQUEST_ADDITIONAL_TEXT("FATIC1", MISSION_TEXT_SLOT) REQUEST_MODEL(IG_MARYANN) WHILE NOT HAS_ANIM_DICT_LOADED("rcmfanatic1") OR NOT HAS_ANIM_DICT_LOADED("rcmfanatic1celebrate") OR NOT HAS_ANIM_DICT_LOADED("rcmfanatic1yell") OR NOT HAS_ANIM_DICT_LOADED("move_f@runner") OR NOT HAS_ANIM_SET_LOADED("FEMALE_FAST_RUNNER") OR NOT GET_IS_WAYPOINT_RECORDING_LOADED(sFANATIC_ROUTE) OR NOT GET_IS_WAYPOINT_RECORDING_LOADED("Fanatic1RollingStart") OR NOT HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT) OR NOT HAS_MODEL_LOADED(IG_MARYANN) DEBUG_PRINTSTRING("Loading other assets") WAIT(0) ENDWHILE ENDPROC /// PURPOSE: Load the resources and create the joggers on the final stretch if they don't already exist PROC CREATE_JOGGERS() IF NOT IS_ENTITY_ALIVE(OtherJoggers[0].thisIndex) REQUEST_MODEL(JOGGERMODEL) REQUEST_MODEL(A_M_Y_BEACH_01) REQUEST_MODEL(A_F_Y_BEACH_01) IF HAS_MODEL_LOADED(JOGGERMODEL) AND HAS_MODEL_LOADED(A_M_Y_BEACH_01) AND HAS_MODEL_LOADED(A_F_Y_BEACH_01) IF NOT DOES_ENTITY_EXIST(OtherJoggers[0].thisIndex) // 1ST JOGGER OtherJoggers[0].thisPosition = <<-1951.48, -556.16, 11.71>> OtherJoggers[0].thisHeading = -121.42 OtherJoggers[0].thisGoToPos1 = <<-1910.10, -591.56, 10.67>> OtherJoggers[0].thisGoToPos2 = <<-1843.73, -649.16, 9.53>> OtherJoggers[0].thisModel = JOGGERMODEL OtherJoggers[0].thisIndex = CREATE_PED(PEDTYPE_CIVFEMALE, OtherJoggers[0].thisModel, OtherJoggers[0].thisPosition, OtherJoggers[0].thisHeading) SET_PED_COMBAT_MOVEMENT(OtherJoggers[0].thisIndex, CM_WILLRETREAT) SET_PED_COMBAT_ATTRIBUTES(OtherJoggers[0].thisIndex, CA_ALWAYS_FLEE, TRUE) SET_PED_ON_THE_GROUND(OtherJoggers[0].thisIndex) IF IS_PED_UNINJURED(OtherJoggers[0].thisIndex) OPEN_SEQUENCE_TASK(seq) TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, OtherJoggers[0].thisGoToPos1, 2.0, DEFAULT_TIME_BEFORE_WARP) TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, OtherJoggers[0].thisGoToPos2, 2.0, DEFAULT_TIME_BEFORE_WARP) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(OtherJoggers[0].thisIndex, seq) CLEAR_SEQUENCE_TASK(seq) ENDIF ENDIF IF NOT DOES_ENTITY_EXIST(OtherJoggers[1].thisIndex) // 2ND JOGGER OtherJoggers[1].thisPosition = <<-1953.85, -555.66, 11>> OtherJoggers[1].thisHeading = -121.42 OtherJoggers[1].thisGoToPos1 = <<-1911.54, -591.70, 10.61>> OtherJoggers[1].thisGoToPos2 = <<-1839.87, -651.49, 9.53>> OtherJoggers[1].thisModel = JOGGERMODEL OtherJoggers[1].thisIndex = CREATE_PED(PEDTYPE_CIVFEMALE, OtherJoggers[1].thisModel, OtherJoggers[1].thisPosition, OtherJoggers[1].thisHeading) SET_PED_COMBAT_MOVEMENT(OtherJoggers[1].thisIndex, CM_WILLRETREAT) SET_PED_COMBAT_ATTRIBUTES(OtherJoggers[1].thisIndex, CA_ALWAYS_FLEE, TRUE) IF IS_PED_UNINJURED(OtherJoggers[1].thisIndex) OPEN_SEQUENCE_TASK(seq) TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, OtherJoggers[1].thisGoToPos1, 2.05, DEFAULT_TIME_BEFORE_WARP) TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, OtherJoggers[1].thisGoToPos2, 2.05, DEFAULT_TIME_BEFORE_WARP) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(OtherJoggers[1].thisIndex, seq) CLEAR_SEQUENCE_TASK(seq) ENDIF ENDIF IF NOT DOES_ENTITY_EXIST(OtherJoggers[2].thisIndex) // GIRL WALKER AT END OtherJoggers[2].thisPosition = <<-1999.40, -508.02, 11>> OtherJoggers[2].thisHeading = 167.30 OtherJoggers[2].thisGoToPos1 = <<-1997.21, -517.17, 10.73>> OtherJoggers[2].thisGoToPos2 = <<-1961.31, -547.96, 10.70>> OtherJoggers[2].thisModel = A_F_Y_BEACH_01 OtherJoggers[2].thisIndex = CREATE_PED(PEDTYPE_CIVFEMALE, OtherJoggers[2].thisModel, OtherJoggers[2].thisPosition, OtherJoggers[2].thisHeading) SET_PED_COMBAT_MOVEMENT(OtherJoggers[2].thisIndex, CM_WILLRETREAT) SET_PED_COMBAT_ATTRIBUTES(OtherJoggers[2].thisIndex, CA_ALWAYS_FLEE, TRUE) SET_PED_ON_THE_GROUND(OtherJoggers[2].thisIndex) ELSE IF IS_PED_UNINJURED(OtherJoggers[2].thisIndex) CLEAR_PED_TASKS_IMMEDIATELY(OtherJoggers[2].thisIndex) SET_ENTITY_COORDS(OtherJoggers[2].thisIndex, OtherJoggers[2].thisPosition) SET_ENTITY_HEADING(OtherJoggers[2].thisIndex, OtherJoggers[2].thisHeading) SET_PED_ON_THE_GROUND(OtherJoggers[2].thisIndex) ENDIF ENDIF IF NOT DOES_ENTITY_EXIST(OtherJoggers[3].thisIndex) // GUY WALKER AT END OtherJoggers[3].thisPosition = <<-2000.19, -507.37, 11>> OtherJoggers[3].thisHeading = 83.65 OtherJoggers[3].thisGoToPos1 = <<-1998.27, -517.46, 10.67>> OtherJoggers[3].thisGoToPos2 = <<-1962.75, -549.56, 10.62>> OtherJoggers[3].thisModel = A_M_Y_BEACH_01 OtherJoggers[3].thisIndex = CREATE_PED(PEDTYPE_CIVMALE, OtherJoggers[3].thisModel, OtherJoggers[3].thisPosition, OtherJoggers[3].thisHeading) SET_PED_COMBAT_MOVEMENT(OtherJoggers[3].thisIndex, CM_WILLRETREAT) SET_PED_COMBAT_ATTRIBUTES(OtherJoggers[3].thisIndex, CA_ALWAYS_FLEE, TRUE) SET_PED_ON_THE_GROUND(OtherJoggers[3].thisIndex) ELSE IF IS_PED_UNINJURED(OtherJoggers[3].thisIndex) CLEAR_PED_TASKS_IMMEDIATELY(OtherJoggers[3].thisIndex) SET_ENTITY_COORDS(OtherJoggers[3].thisIndex, OtherJoggers[3].thisPosition) SET_ENTITY_HEADING(OtherJoggers[3].thisIndex, OtherJoggers[3].thisHeading) SET_PED_ON_THE_GROUND(OtherJoggers[3].thisIndex) ENDIF ENDIF SET_MODEL_AS_NO_LONGER_NEEDED(A_F_Y_BEACH_01) SET_MODEL_AS_NO_LONGER_NEEDED(A_M_Y_BEACH_01) SET_MODEL_AS_NO_LONGER_NEEDED(JOGGERMODEL) ENDIF ENDIF ENDPROC /// PURPOSE: Create Mary Ann's bike at the end of the mission PROC CREATE_MARY_ANNS_BIKE() IF NOT IS_VEHICLE_OK(MAS_BIKE) REQUEST_MODEL(MARYSBIKEMODEL) IF HAS_MODEL_LOADED(MARYSBIKEMODEL) MAS_BIKE = CREATE_VEHICLE(MARYSBIKEMODEL, MAS_BIKE_POS, MAS_BIKE_DIR) SET_MODEL_AS_NO_LONGER_NEEDED(MARYSBIKEMODEL) ENDIF ENDIF ENDPROC /// PURPOSE: Load and create the resources for the driveby sequence PROC CREATE_CARS() REQUEST_MODEL(G_M_Y_SALVAGOON_01) REQUEST_MODEL(BANSHEE) REQUEST_MODEL(REGINA) WHILE NOT HAS_MODEL_LOADED(G_M_Y_SALVAGOON_01) OR NOT HAS_MODEL_LOADED(BANSHEE) OR NOT HAS_MODEL_LOADED(REGINA) WAIT(0) ENDWHILE CLEAR_AREA_OF_VEHICLES(<<1829.384277, -516.190002, 27.857389>>, 7.0) // Try and delete any vehicle parked where checkpoint 4 is IF NOT IS_VEHICLE_OK(DRIVEBY_FINGER_CAR.thisCarIndex) // PARKED HONKING CAR DRIVEBY_FINGER_CAR.thisPosition = <<-1833.329956,-513.388306,28.210709>> DRIVEBY_FINGER_CAR.thisHeading = 286.3430 DRIVEBY_FINGER_CAR.thisGoToPos = <<-1721.02, -559.70, 37.46>> DRIVEBY_FINGER_CAR.thisSpeed = 18 DRIVEBY_FINGER_CAR.thisCarModel = BANSHEE DRIVEBY_FINGER_CAR.thisCarIndex = CREATE_VEHICLE(DRIVEBY_FINGER_CAR.thisCarModel, DRIVEBY_FINGER_CAR.thisPosition, DRIVEBY_FINGER_CAR.thisHeading) SET_VEHICLE_COLOURS(DRIVEBY_FINGER_CAR.thisCarIndex, 1, 1) DRIVEBY_FINGER_CAR.Driver = CREATE_PED_INSIDE_VEHICLE(DRIVEBY_FINGER_CAR.thisCarIndex, PEDTYPE_CIVMALE, G_M_Y_SALVAGOON_01) DRIVEBY_FINGER_CAR.Passenger = CREATE_PED_INSIDE_VEHICLE(DRIVEBY_FINGER_CAR.thisCarIndex, PEDTYPE_CIVMALE, G_M_Y_SALVAGOON_01, VS_FRONT_RIGHT) SET_PED_COMBAT_ATTRIBUTES(DRIVEBY_FINGER_CAR.Passenger, CA_LEAVE_VEHICLES, FALSE) SET_PED_COMBAT_ATTRIBUTES(DRIVEBY_FINGER_CAR.Passenger, CA_CAN_TAUNT_IN_VEHICLE, TRUE) SET_PED_COMBAT_ATTRIBUTES(DRIVEBY_FINGER_CAR.Driver, CA_ALWAYS_FLEE, TRUE) /* ELSE IF IS_PED_UNINJURED(DRIVEBY_FINGER_CAR.Driver) IF IS_VEHICLE_OK(DRIVEBY_FINGER_CAR.thisCarIndex) CLEAR_PED_TASKS_IMMEDIATELY(DRIVEBY_FINGER_CAR.Driver) SET_ENTITY_COORDS(DRIVEBY_FINGER_CAR.thisCarIndex, DRIVEBY_FINGER_CAR.thisPosition) SET_ENTITY_HEADING(DRIVEBY_FINGER_CAR.thisCarIndex, DRIVEBY_FINGER_CAR.thisHeading) IF NOT IS_PED_IN_VEHICLE(DRIVEBY_FINGER_CAR.Driver, DRIVEBY_FINGER_CAR.thisCarIndex) TASK_WARP_PED_INTO_VEHICLE(DRIVEBY_FINGER_CAR.Driver, DRIVEBY_FINGER_CAR.thisCarIndex) ENDIF ENDIF ELSE DRIVEBY_FINGER_CAR.Driver = CREATE_PED_INSIDE_VEHICLE(DRIVEBY_FINGER_CAR.thisCarIndex, PEDTYPE_CIVMALE, G_M_Y_SALVAGOON_01) ENDIF */ ENDIF IF NOT IS_VEHICLE_OK(FOLLOWING_CAR.thisCarIndex) // PARKED HONKING CAR FOLLOWING_CAR.thisPosition = <<-2000.79, -494.35, 11.09>> FOLLOWING_CAR.thisHeading = 321.61 FOLLOWING_CAR.thisGoToPos = <<-1719.08, -559.41, 36.33>> FOLLOWING_CAR.thisSpeed = 12 FOLLOWING_CAR.thisCarModel = REGINA FOLLOWING_CAR.thisCarIndex = CREATE_VEHICLE(FOLLOWING_CAR.thisCarModel, FOLLOWING_CAR.thisPosition, FOLLOWING_CAR.thisHeading) FOLLOWING_CAR.Driver = CREATE_PED_INSIDE_VEHICLE(FOLLOWING_CAR.thisCarIndex, PEDTYPE_CIVMALE, G_M_Y_SALVAGOON_01) FOLLOWING_CAR.Passenger = CREATE_PED_INSIDE_VEHICLE(FOLLOWING_CAR.thisCarIndex, PEDTYPE_CIVMALE, G_M_Y_SALVAGOON_01, VS_FRONT_RIGHT) SET_PED_COMBAT_ATTRIBUTES(FOLLOWING_CAR.Driver, CA_ALWAYS_FLEE, TRUE) SET_PED_COMBAT_ATTRIBUTES(FOLLOWING_CAR.Passenger, CA_ALWAYS_FLEE, TRUE) ENDIF SET_MODEL_AS_NO_LONGER_NEEDED(G_M_Y_SALVAGOON_01) SET_MODEL_AS_NO_LONGER_NEEDED(BANSHEE) SET_MODEL_AS_NO_LONGER_NEEDED(REGINA) ENDPROC /// PURPOSE: Create the dog on the final stretch PROC CREATE_DOGS() IF NOT IS_ENTITY_ALIVE(BEACH_DOG) BEACH_DOG = CREATE_PED(PEDTYPE_MISSION, A_C_ROTTWEILER, vPos_DOG, fDir_DOG) SET_PED_CAN_RAGDOLL(BEACH_DOG, TRUE) ENDIF ENDPROC /// PURPOSE: Create the peds and vehicles for the CPR synced scene, and return TRUE when finished loading PROC CREATE_QUAD_BIKE_SCENE(BOOL fromStart = TRUE) IF NOT IS_VEHICLE_OK(CHEAT_QUAD) SET_PED_PATHS_IN_AREA(<<-1875.16, -630.82, 10.00>>, <<-1867.90, -625.78, 10.25>>, FALSE) DISABLE_NAVMESH_IN_AREA(<<-1875.16, -630.82, 10.00>>, <<-1867.90, -625.78, 10.25>>, TRUE) IF NavBlockerID > -1 REMOVE_NAVMESH_BLOCKING_OBJECT(NavBlockerID) NavBlockerID = -1 ENDIF NavBlockerID = ADD_NAVMESH_BLOCKING_OBJECT(<<-1870.54, -628.10, 10.09>>, <<4, 4, 4>>, 0) IF NavBlockerID = -1 SCRIPT_ASSERT("Failed to add a navmesh blocking object to CPR scene! You may see peds walking through it. Please send a message to Ian Gander @ Leeds about this...") ENDIF INJURED_PED = CREATE_PED(PEDTYPE_CIVMALE, A_M_M_Beach_01, <<-1870.54, -628.10, 10.09>>, 80) SET_ENTITY_LOAD_COLLISION_FLAG(INJURED_PED, TRUE) CLEAR_PED_TASKS_IMMEDIATELY(INJURED_PED) SET_PED_MONEY(INJURED_PED, 0) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(INJURED_PED, TRUE) SET_PED_CAN_BE_TARGETTED(INJURED_PED, FALSE) vPos_CPRScene = GET_ENTITY_COORDS(INJURED_PED) GET_GROUND_Z_FOR_3D_COORD(GET_ENTITY_COORDS(INJURED_PED), vPos_CPRScene.z) vRot_CPRScene = GET_ENTITY_ROTATION(INJURED_PED) IdleSynchSceneID = CREATE_SYNCHRONIZED_SCENE(vPos_CPRScene, vRot_CPRScene) TASK_SYNCHRONIZED_SCENE (INJURED_PED, IdleSynchSceneID, "mini@cpr@char_b@cpr_def", "cpr_intro", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, SYNCED_SCENE_NONE, RBF_PLAYER_IMPACT) SET_SYNCHRONIZED_SCENE_RATE(IdleSynchSceneID, 0.0) cprWatcher1 = CREATE_PED(PEDTYPE_CIVFEMALE, A_F_Y_BEACH_01, <<-1869.76, -627.70, 10.10>>) SET_PED_COMBAT_ATTRIBUTES(cprWatcher1, CA_ALWAYS_FLEE, TRUE) OPEN_SEQUENCE_TASK(seq) TASK_TURN_PED_TO_FACE_ENTITY(NULL, INJURED_PED) TASK_PLAY_ANIM(null, "rcmfanatic1", "idle_a", SLOW_BLEND_IN, SLOW_BLEND_OUT) TASK_PLAY_ANIM(null, "rcmfanatic1", "base", NORMAL_BLEND_IN, SLOW_BLEND_OUT) TASK_PLAY_ANIM(null, "rcmfanatic1", "base", NORMAL_BLEND_IN, SLOW_BLEND_OUT) TASK_PLAY_ANIM(null, "rcmfanatic1", "idle_C", NORMAL_BLEND_IN, SLOW_BLEND_OUT) TASK_PLAY_ANIM(null, "rcmfanatic1", "base", NORMAL_BLEND_IN, SLOW_BLEND_OUT) TASK_PLAY_ANIM(null, "rcmfanatic1", "idle_b", NORMAL_BLEND_IN, SLOW_BLEND_OUT) TASK_PLAY_ANIM(null, "rcmfanatic1", "base", NORMAL_BLEND_IN, SLOW_BLEND_OUT) TASK_PLAY_ANIM(null, "rcmfanatic1", "base", NORMAL_BLEND_IN, SLOW_BLEND_OUT) TASK_PLAY_ANIM(null, "rcmfanatic1", "base", NORMAL_BLEND_IN, SLOW_BLEND_OUT) TASK_PLAY_ANIM(null, "rcmfanatic1", "idle_b", NORMAL_BLEND_IN, SLOW_BLEND_OUT) SET_SEQUENCE_TO_REPEAT(seq, REPEAT_FOREVER) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(cprWatcher1, seq) CLEAR_SEQUENCE_TASK(seq) cprWatcher2 = CREATE_PED(PEDTYPE_CIVFEMALE, A_F_Y_BEACH_01, <<-1873.61, -628.88, 11.16>>) SET_PED_COMBAT_ATTRIBUTES(cprWatcher2, CA_ALWAYS_FLEE, TRUE) OPEN_SEQUENCE_TASK(seq) TASK_TURN_PED_TO_FACE_ENTITY(NULL, INJURED_PED) TASK_PLAY_ANIM(null, "rcmfanatic1", "base", SLOW_BLEND_IN, SLOW_BLEND_OUT) TASK_PLAY_ANIM(null, "rcmfanatic1", "idle_b", NORMAL_BLEND_IN, SLOW_BLEND_OUT) TASK_PLAY_ANIM(null, "rcmfanatic1", "idle_a", NORMAL_BLEND_IN, SLOW_BLEND_OUT) TASK_PLAY_ANIM(null, "rcmfanatic1", "base", NORMAL_BLEND_IN, SLOW_BLEND_OUT) TASK_PLAY_ANIM(null, "rcmfanatic1", "base", NORMAL_BLEND_IN, SLOW_BLEND_OUT) TASK_PLAY_ANIM(null, "rcmfanatic1", "idle_a", NORMAL_BLEND_IN, SLOW_BLEND_OUT) TASK_PLAY_ANIM(null, "rcmfanatic1", "idle_b", NORMAL_BLEND_IN, SLOW_BLEND_OUT) TASK_PLAY_ANIM(null, "rcmfanatic1", "base", NORMAL_BLEND_IN, SLOW_BLEND_OUT) TASK_PLAY_ANIM(null, "rcmfanatic1", "base", NORMAL_BLEND_IN, SLOW_BLEND_OUT) SET_SEQUENCE_TO_REPEAT(seq, REPEAT_FOREVER) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(cprWatcher2, seq) CLEAR_SEQUENCE_TASK(seq) if fromStart CHEAT_QUAD = CREATE_VEHICLE(BLAZER2, vPos_CHEAT_QUAD, 36.64) SET_VEHICLE_ON_GROUND_PROPERLY(CHEAT_QUAD) SET_ENTITY_LOAD_COLLISION_FLAG(CHEAT_QUAD, TRUE) QUAD_DRIVER = CREATE_PED_INSIDE_VEHICLE(CHEAT_QUAD, PEDTYPE_MEDIC, S_M_Y_BAYWATCH_01) cprState = CPR_WAITING ELSE CHEAT_QUAD = CREATE_VEHICLE(BLAZER2, <<-1871.55, -640.01, 10.65>>, 297.76) SET_VEHICLE_ON_GROUND_PROPERLY(CHEAT_QUAD) SET_ENTITY_LOAD_COLLISION_FLAG(CHEAT_QUAD, TRUE) QUAD_DRIVER = CREATE_PED_INSIDE_VEHICLE(CHEAT_QUAD, PEDTYPE_CIVMALE, S_M_Y_BAYWATCH_01) OPEN_SEQUENCE_TASK(seq) TASK_LOOK_AT_ENTITY(NULL, INJURED_PED, -1) TASK_LEAVE_VEHICLE(NULL, CHEAT_QUAD) TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, GET_ENTITY_COORDS(INJURED_PED), 1.8) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(QUAD_DRIVER, seq) CLEAR_SEQUENCE_TASK(seq) cprState = CPR_GOING_TO_SCENE ENDIF SET_PED_COMBAT_ATTRIBUTES(QUAD_DRIVER, CA_ALWAYS_FLEE, TRUE) SET_ENTITY_LOAD_COLLISION_FLAG(QUAD_DRIVER, TRUE) SET_PED_KEEP_TASK(INJURED_PED, TRUE) ENDIF SET_MODEL_AS_NO_LONGER_NEEDED(BLAZER2) SET_MODEL_AS_NO_LONGER_NEEDED(A_F_Y_BEACH_01) SET_MODEL_AS_NO_LONGER_NEEDED(S_M_Y_BayWatch_01) SET_MODEL_AS_NO_LONGER_NEEDED(A_M_M_Beach_01) ENDPROC /// PURPOSE: Works out which checkpoint type is needed based upon angle between checkpoints FUNC CHECKPOINT_TYPE GET_RACE_CHECKPOINT_TYPE(INT iCheckNum) VECTOR pos, pos2, pos3 VECTOR vec1, vec2 FLOAT fReturnAngle FLOAT fChevron1 = 180.0 FLOAT fChevron2 = 140.0 FLOAT fChevron3 = 80.0 pos = RACE_POSITIONS[iCheckNum] // If we're checking the last checkpoint of the current array, just return the appropriate flag checkpoint, we don't care about angles IF (iCheckNum = iMaxRacePositions-1) RETURN CHECKPOINT_RACE_GROUND_FLAG ELSE // Otherwise, we need to do the angle shit // If this is the first checkpoint, we need to check a position behind it IF iCheckNum = 0 pos3 = <<-1869.12, -445.17, 45.17>> pos2 = RACE_POSITIONS[iCheckNum + 1] ELSE // The checkpoint is neither first nor last, wooo, straightforward pos3 = RACE_POSITIONS[iCheckNum - 1] pos2 = RACE_POSITIONS[iCheckNum + 1] ENDIF ENDIF // Create some vectors via maths magic vec1 = pos3 - pos vec2 = pos2 - pos // Get the final angle value via code magic fReturnAngle = GET_ANGLE_BETWEEN_2D_VECTORS(vec1.x, vec1.y, vec2.x, vec2.y) // Make sure reflex angles don't break things via more maths magic IF fReturnAngle > 180 fReturnAngle = (360.0 - fReturnAngle) ENDIF // We have our angles through MAGIC!!!!, now to return the correct checkpoint type IF fReturnAngle < fChevron3 RETURN CHECKPOINT_RACE_GROUND_CHEVRON_3 ELIF fReturnAngle < fChevron2 RETURN CHECKPOINT_RACE_GROUND_CHEVRON_2 ELIF fReturnAngle < fChevron1 RETURN CHECKPOINT_RACE_GROUND_CHEVRON_1 ELSE RETURN CHECKPOINT_RACE_GROUND_CHEVRON_1 ENDIF // If we've got here, return this as a default, even though we REALLY REALLY SHOULDN'T and this would concern me greatly RETURN CHECKPOINT_RACE_GROUND_CHEVRON_1 ENDFUNC /// PURPOSE: Gets appropriate checkpoint colour based on chevron type FUNC HUD_COLOURS GET_RACE_CHECKPOINT_COLOUR(CHECKPOINT_TYPE cpType) // IF cpType = CHECKPOINT_RACE_GROUND_CHEVRON_3 // RETURN HUD_COLOUR_YELLOWDARK // // ELIF cpType = CHECKPOINT_RACE_GROUND_CHEVRON_2 // OR cpType = CHECKPOINT_RACE_GROUND_FLAG // RETURN HUD_COLOUR_YELLOWLIGHT // ELSE // RETURN HUD_COLOUR_YELLOWLIGHT // ENDIF // Returning YELLOWDARK for all checkpoints (B*1454575) cpType = cpType // Compile fix RETURN HUD_COLOUR_YELLOWLIGHT ENDFUNC /// PURPOSE: Work out and update the coord of the waypoint the player is closest to on Mary Ann's route, /// and update which number waypoint the player and Mary Ann is closest to PROC DETERMINE_CLOSEST_WAYPOINTS() IF GET_IS_WAYPOINT_RECORDING_LOADED(sFANATIC_ROUTE) WAYPOINT_RECORDING_GET_CLOSEST_WAYPOINT(sFANATIC_ROUTE, GET_ENTITY_COORDS(PLAYER_PED_ID()), iNum_PlayerClosestWaypoint) WAYPOINT_RECORDING_GET_CLOSEST_WAYPOINT(sFANATIC_ROUTE, GET_ENTITY_COORDS(MARY_ANN), iNum_NPCClosestWaypoint) IF iCURRENT_RACE_POS < iMaxRacePositions WAYPOINT_RECORDING_GET_COORD(sFANATIC_ROUTE, iNum_PlayerClosestWaypoint, vPos_PlayerClosestWaypoint) ENDIF ENDIF ENDPROC /// PURPOSE: Work out the coord of the NEXT waypoint on Mary Ann's route to the one Mary Ann is currently closest to FUNC VECTOR GET_COORD_FURTHER_ALONG_ROUTE() DETERMINE_CLOSEST_WAYPOINTS() VECTOR vPos IF iNum_NPCClosestWaypoint < iNum_WAYPOINTS - 1 WAYPOINT_RECORDING_GET_COORD(sFANATIC_ROUTE, iNum_NPCClosestWaypoint + 1, vPos) ELSE WAYPOINT_RECORDING_GET_COORD(sFANATIC_ROUTE, iNum_WAYPOINTS - 1, vPos) ENDIF RETURN vPos ENDFUNC /// PURPOSE: Return the number of Mary Ann's NEXT waypoint FUNC INT GET_MARY_ANNS_NEXT_WAYPOINT() INT i WAYPOINT_RECORDING_GET_CLOSEST_WAYPOINT(sFANATIC_ROUTE, GET_COORD_FURTHER_ALONG_ROUTE(), i) RETURN i ENDFUNC /// PURPOSE: /// Debug function to keep Mary Ann running after skipping /// PARAMS: /// nextMS - sets the mission stage that we are skipping to PROC KEEP_RUNNING(MISSION_STAGE nextMS, BOOL bSkipping = TRUE) IF IS_PED_UNINJURED(MARY_ANN) IF NOT IS_STRING_NULL(sFANATIC_ROUTE) IF GET_IS_WAYPOINT_RECORDING_LOADED(sFANATIC_ROUTE) OPEN_SEQUENCE_TASK(seq) TASK_SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(NULL, TRUE) TASK_FOLLOW_WAYPOINT_RECORDING(NULL, sFANATIC_ROUTE, GET_MARY_ANNS_NEXT_WAYPOINT(), EWAYPOINT_START_FROM_CLOSEST_POINT | EWAYPOINT_VEHICLES_USE_AI_SLOWDOWN | EWAYPOINT_ALLOW_STEERING_AROUND_PEDS | EWAYPOINT_NAVMESH_BACK_TO_WAYPOINT_IF_LEFT_ROUTE , -1) TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1) TASK_PLAY_ANIM(null, "move_f@runner", "idle", SLOW_BLEND_IN, SLOW_BLEND_OUT, -1, AF_LOOPING) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(MARY_ANN, seq) CLEAR_SEQUENCE_TASK(seq) ENDIF ENDIF DEBUG_PRINTSTRING("Keep Running used") SET_PED_CAN_RAGDOLL_FROM_PLAYER_IMPACT(MARY_ANN, FALSE) IF bSkipping = TRUE stageStage = SS_SETUP missionStage = nextMS ENDIF ENDIF ENDPROC /// PURPOSE: /// Makes Mary Ann say a single line, possibly interrupt conversation /// PARAMS: /// blockOfText - blockOfText /// rootLabel - rootLabel /// bShouldInterrupt - if true will stop the conversation to play line FUNC BOOL CAN_MARY_ANN_SAY_SINGLE_LINE(STRING blockOfText, STRING rootLabel, BOOL bShouldInterrupt, INT& interruptedLine) IF MADialogueState = MA_WITHIN_TALKING_RANGE AND NOT IS_MESSAGE_BEING_DISPLAYED() if bShouldInterrupt IF IS_SCRIPTED_CONVERSATION_ONGOING() interruptedLine = GET_CURRENT_SCRIPTED_CONVERSATION_LINE() DEBUG_PRINTSTRING("Stopping scripted convo at can Mary Ann say single line") KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() CLEAR_PRINTS() ENDIF IF PLAY_SINGLE_LINE_FROM_CONVERSATION(MyLocalPedStruct, "FAN1AU", blockOfText, rootLabel, CONV_PRIORITY_MEDIUM) RETURN TRUE ENDIF ELSE IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF PLAY_SINGLE_LINE_FROM_CONVERSATION(MyLocalPedStruct, "FAN1AU", blockOfText, rootLabel, CONV_PRIORITY_MEDIUM) RETURN TRUE ENDIF ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Tries to create a conversation with the given root label and returns true if it triggers - for random lines during the mission /// PARAMS: /// rootLabel - the label we're trying to play /// RETURNS: /// TRUE if the conversation plays, FALSE if it fails or can't be played FUNC BOOL CAN_MARY_ANN_SAY_RANDOM_LINE(STRING rootLabel) IF MADialogueState = MA_WITHIN_TALKING_RANGE AND NOT IS_MESSAGE_BEING_DISPLAYED() IF CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", rootLabel, CONV_PRIORITY_MEDIUM) RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: Checks if she can start her standard run conversation, not random comment FUNC BOOL CAN_CREATE_RUNNING_CONVERSATION() IF MADialogueState = MA_WITHIN_TALKING_RANGE AND NOT IS_MESSAGE_BEING_DISPLAYED() AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() RETURN TRUE ELSE RETURN FALSE ENDIF ENDFUNC /// PURPOSE: /// Play a one-liner for Mary Ann PROC PLAY_MARY_ANN_ONE_LINER() IF place = 2 // only do a Mary Ann one-liner if the player is behind IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() AND MADialogueState = MA_WITHIN_TALKING_RANGE AND NOT IS_MESSAGE_BEING_DISPLAYED() IF CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_TAUNT", CONV_PRIORITY_MEDIUM) iOneLinerSeq++ iOneLinerTimer = GET_GAME_TIMER() ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: /// Play a one-liner for Michael PROC PLAY_MICHAEL_ONE_LINER() IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() AND MADialogueState = MA_WITHIN_TALKING_RANGE AND NOT IS_MESSAGE_BEING_DISPLAYED() IF CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_ONELIN", CONV_PRIORITY_MEDIUM) iOneLinerSeq++ iOneLinerTimer = GET_GAME_TIMER() ENDIF ENDIF ENDPROC /// PURPOSE: /// Try and play a one-liner for one of the characters PROC TRY_ONE_LINER() IF (GET_GAME_TIMER() - iOneLinerTimer) > 10000 // Possibly randomise this value a bit? SWITCH iOneLinerSeq CASE 0 PLAY_MARY_ANN_ONE_LINER() BREAK CASE 1 PLAY_MICHAEL_ONE_LINER() BREAK CASE 2 PLAY_MARY_ANN_ONE_LINER() BREAK CASE 3 PLAY_MICHAEL_ONE_LINER() BREAK CASE 4 PLAY_MARY_ANN_ONE_LINER() BREAK CASE 5 PLAY_MICHAEL_ONE_LINER() BREAK CASE 6 PLAY_MARY_ANN_ONE_LINER() BREAK CASE 7 PLAY_MICHAEL_ONE_LINER() BREAK CASE 8 PLAY_MARY_ANN_ONE_LINER() BREAK CASE 9 PLAY_MICHAEL_ONE_LINER() BREAK DEFAULT // No more lines available to play BREAK ENDSWITCH ENDIF ENDPROC /// PURPOSE: /// Keeps trying to play the keep up or catch up lines while we're waiting for any prior conversation to finish PROC TRY_KEEPUP_OR_CATCHUP_LINES() IF MADialogueState = MA_SHOUTING_TO_KEEP_UP IF iHurryUpLineNumber < iMAXHurryUpLineNumber IF (cheatedRanAcrossGrass.hasBeenPlayed OR cheatedLeaptFence.hasBeenPlayed) AND missionStage = MS_START_RUNNING MADialogueState = MA_OUT_OF_TALKING_RANGE DEBUG_PRINTSTRING("MA Dialogue: Now in MA_OUT_OF_TALKING_RANGE") ELSE IF place = 2 // Only say this if the player is behind IF PLAY_SINGLE_LINE_FROM_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_FALLB", HURRY_UP_LINE[iHurryUpLineNumber], CONV_PRIORITY_HIGH) iHurryUpLineNumber++ MADialogueState = MA_OUT_OF_TALKING_RANGE DEBUG_PRINTSTRING("MA Dialogue: Played keep up line, now in MA_OUT_OF_TALKING_RANGE") ENDIF ELSE MADialogueState = MA_OUT_OF_TALKING_RANGE DEBUG_PRINTSTRING("MA Dialogue: Player in 1st place so no need for keep up line, now in MA_OUT_OF_TALKING_RANGE") ENDIF ENDIF ELSE DEBUG_PRINTSTRING("MA Dialogue: Said all keep up lines, now in MA_OUT_OF_TALKING_RANGE") MADialogueState = MA_OUT_OF_TALKING_RANGE ENDIF ELIF MADialogueState = MA_SAYING_YOU_CAUGHT_UP IF iCatchUpLineNumber < iMAXCatchUpLineNumber IF (cheatedRanAcrossGrass.hasBeenPlayed OR cheatedLeaptFence.hasBeenPlayed) AND missionStage = MS_START_RUNNING IF bCatchupCheatLineSaid = FALSE IF CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_CATCHC", CONV_PRIORITY_HIGH) bCatchupCheatLineSaid = TRUE b_CheatedLine = FALSE // Stop the other cheated line from playing if we've done this instead ENDIF ENDIF MADialogueState = MA_WITHIN_TALKING_RANGE DEBUG_PRINTSTRING("MA Dialogue: Now in MA_WITHIN_TALKING_RANGE") ELSE IF place = 2 // Only say this if the player is behind IF CAN_MARY_ANN_SAY_RANDOM_LINE("FAN1_CATCHU") iCatchUpLineNumber++ MADialogueState = MA_WITHIN_TALKING_RANGE DEBUG_PRINTSTRING("MA Dialogue: Played catchup line, now in MA_WITHIN_TALKING_RANGE") ENDIF ELSE MADialogueState = MA_WITHIN_TALKING_RANGE DEBUG_PRINTSTRING("MA Dialogue: Player in 1st place so no need for catchup line, now in MA_WITHIN_TALKING_RANGE") ENDIF ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: /// This function switches her Dialogue State and plays a "Catch up" line if player gets too far, or "Welcome back" line if they catch up. /// The dialogue state is used to make sure she is nearby before talking PROC SET_MARY_ANN_DIALOGUE_STATE(MARY_ANN_DIALOGUE_STATE newState) IF MADialogueState <> newState SWITCH MADialogueState CASE MA_WITHIN_TALKING_RANGE IF newstate = MA_OUT_OF_TALKING_RANGE IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() KILL_ANY_CONVERSATION() ENDIF DEBUG_PRINTSTRING("MA Dialogue: Kill convo, switch to MA_OUT_OF_TALKING_RANGE, trying keep up line if possible") MADialogueState = MA_SHOUTING_TO_KEEP_UP ENDIF BREAK CASE MA_OUT_OF_TALKING_RANGE IF newstate = MA_WITHIN_TALKING_RANGE IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() KILL_ANY_CONVERSATION() ENDIF DEBUG_PRINTSTRING("MA Dialogue: Kill convo, switch to MA_WITHIN_TALKING_RANGE, trying you caught up line if possible") MADialogueState = MA_SAYING_YOU_CAUGHT_UP ENDIF BREAK // Shouting to keep up and Saying you caught up now handled in TRY_KEEPUP_OR_CATCHUP_LINES() ENDSWITCH ENDIF ENDPROC PROC TELEPORT_STUCK_MARY_ANN(int iTeleportTo) VECTOR vTeleCoord FLOAT fNewHeading WAYPOINT_RECORDING_GET_COORD(sFANATIC_ROUTE, iTeleportTo, vTeleCoord) VECTOR vNextCoord WAYPOINT_RECORDING_GET_COORD(sFANATIC_ROUTE, iTeleportTo+1, vNextCoord) fNewHeading = GET_HEADING_FROM_COORDS(vTeleCoord, vNextCoord) SAFE_TELEPORT_ENTITY(MARY_ANN, vTeleCoord, fNewHeading, TRUE) IF iTeleportTo < 6 iNPC_RACE_POS = 1 ELIF iTeleportTo < 30 iNPC_RACE_POS = 1 ELIF iTeleportTo < 36 iNPC_RACE_POS = 2 ELIF iTeleportTo < 48 iNPC_RACE_POS = 3 ELIF iTeleportTo < 62 iNPC_RACE_POS = 4 ELIF iTeleportTo < 81 iNPC_RACE_POS = 5 ELIF iTeleportTo < 95 iNPC_RACE_POS = 6 ELIF iTeleportTo < 106 iNPC_RACE_POS = 7 ELSE iNPC_RACE_POS = 8 ENDIF ENDPROC PROC CHECK_FOR_GETTING_STUCK() switch StuckStage CASE STUCK_UPDATE // Change the waypoint we're checking to Mary Ann's the nearest one iWaypointStuckCheck = iNum_NPCClosestWaypoint iStuckTimer = GET_GAME_TIMER() StuckStage = STUCK_LOOP BREAK CASE STUCK_LOOP IF iWaypointStuckCheck = iNum_NPCClosestWaypoint IF (GET_GAME_TIMER() - iStuckTimer) > 20000 // If Mary Ann's closest waypoint doesn't change for 20 secs, something needs fixing DEBUG_PRINTSTRING("Mary Ann got stuck!") StuckStage = STUCK_FIX ENDIF ELSE StuckStage = STUCK_UPDATE // If the closest waypoint doesn't match anymore, update it ENDIF BREAK CASE STUCK_FIX INT iMaxPoints WAYPOINT_RECORDING_GET_NUM_POINTS(sFANATIC_ROUTE, iMaxPoints) IF (iWaypointStuckCheck+4) > iMaxPoints TELEPORT_STUCK_MARY_ANN(iMaxPoints-1) // Teleport to the one before last waypoint so there's somewhere to go ELSE TELEPORT_STUCK_MARY_ANN(iWaypointStuckCheck+4) ENDIF KEEP_RUNNING(missionStage, FALSE) // This isn't a debug teleport, so don't do the stage-skippy stuff StuckStage = STUCK_UPDATE BREAK ENDSWITCH ENDPROC /// PURPOSE: Speed Mary Ann up where required at a constantly increasing ratio until it hits a cap PROC SPEED_MARY_ANN_UP() fMBR_IncreaseRatio += GET_FRAME_TIME()/20 IF fMBR_IncreaseRatio > fMBRMax fMBR_IncreaseRatio = fMBRMax ENDIF #IF IS_DEBUG_BUILD IF bDebug_SpeedDebug //DEBUG_PRINTSF("SPEED UP: fMBR_IncreaseRatio = ", fMBR_IncreaseRatio) ENDIF #ENDIF fMBR_RunSpeed += 0.02 IF fMBR_RunSpeed > fMBR_MaxRunSpeed fMBR_RunSpeed = fMBR_MaxRunSpeed ENDIF // #IF IS_DEBUG_BUILD IF bDebug_SpeedDebug IF MASprintState <> SPRINT_ACTIVE DEBUG_PRINTSF("SPEED UP: fMBR_RunSpeed = ", fMBR_RunSpeed) ENDIF ENDIF #ENDIF ENDPROC /// PURPOSE: Slow Mary Ann down where required at a constantly increasing ratio until it hits a cap PROC SLOW_MARY_ANN_DOWN() IF fMBR_IncreaseRatio > 1 fMBR_IncreaseRatio -= 0.02 ELSE fMBR_IncreaseRatio = 1 ENDIF // Re-cap IF fMBR_IncreaseRatio > fMBRMax fMBR_IncreaseRatio = fMBRMax ENDIF FLOAT slowDownValue slowDownValue = 4.5 - (GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), MARY_ANN)/2) IF slowDownValue < 1.8 slowDownValue = 1.8 ELIF slowDownValue > fMBR_MaxRunSpeed slowDownValue = fMBR_MaxRunSpeed ENDIF IF fMBR_RunSpeed > slowDownValue fMBR_RunSpeed -= 0.01 ELSE fMBR_RunSpeed = slowDownValue ENDIF #IF IS_DEBUG_BUILD IF bDebug_SpeedDebug IF MASprintState <> SPRINT_ACTIVE DEBUG_PRINTSF("SLOW DOWN: fMBR_RunSpeed = ", fMBR_RunSpeed) ENDIF ENDIF #ENDIF ENDPROC /// PURPOSE: /// Because of B*886738, we need to keep Mary Ann sprinting for a few seconds whenever she goes >2.5 MBR, so she doesn't quickly slow down again and keep jerking /// back and forth between her running and sprint animations as her MBR keeps flicking above and below 2.5MBR PROC HANDLE_SPRINT_BOOST() SWITCH MASprintState CASE SPRINT_WAITING IF IS_ENTITY_ALIVE(MARY_ANN) // Don't do the sprint if Mary Ann is in this area (basically on the steps down to the bridge) - tries to prevent B*1426943 IF NOT IS_ENTITY_IN_ANGLED_AREA(MARY_ANN, <<-1809.172852,-549.010559,14.031675>>, <<-1841.728638,-529.457520,33.641205>>, 21.75) IF fMBR_RunSpeed >= 2.5 IF IS_ENTITY_ALIVE(MARY_ANN) TASK_LOOK_AT_ENTITY(MARY_ANN, PLAYER_PED_ID(), 1500, SLF_WIDEST_PITCH_LIMIT|SLF_WIDEST_YAW_LIMIT|SLF_USE_TORSO|SLF_WHILE_NOT_IN_FOV, SLF_LOOKAT_VERY_HIGH) ENDIF fMBR_SprintCap = fMBR_RunSpeed MASprintState = SPRINT_ACTIVE iSprintTimer = GET_GAME_TIMER() #IF IS_DEBUG_BUILD IF bDebug_SpeedDebug DEBUG_PRINTSTRING("*** SPRINT BOOST ACTIVE") ENDIF #ENDIF ENDIF ENDIF ENDIF BREAK CASE SPRINT_ACTIVE IF (GET_GAME_TIMER() - iSprintTimer) < iSprintLength IF fMBR_SprintCap < fMBR_RunSpeed fMBR_SprintCap = fMBR_RunSpeed ENDIF ELSE fMBR_RunSpeed = fMBR_SprintCap #IF IS_DEBUG_BUILD IF bDebug_SpeedDebug DEBUG_PRINTSTRING("*** SPRINT BOOST REDUCE") ENDIF #ENDIF MASprintState = SPRINT_REDUCE ENDIF BREAK CASE SPRINT_REDUCE // Gradually reduce Mary Ann's speed if she's ahead IF place = 2 IF fMBR_RunSpeed > 2.49 fMBR_RunSpeed -= 0.002 ELSE #IF IS_DEBUG_BUILD IF bDebug_SpeedDebug DEBUG_PRINTSTRING("*** SPRINT BOOST COOLDOWN") ENDIF #ENDIF MASprintState = SPRINT_COOLDOWN iSprintTimer = GET_GAME_TIMER() ENDIF ENDIF BREAK CASE SPRINT_COOLDOWN IF (GET_GAME_TIMER() - iSprintTimer) > iSprintDelay DEBUG_PRINTSTRING("*** SPRINT BOOST WAITING") MASprintState = SPRINT_WAITING ENDIF BREAK ENDSWITCH ENDPROC /// PURPOSE: /// Handles the rubber-banding behaviour in the final section PROC DO_MA_FINISH_SPRINT_STYLE() CONST_FLOAT fBehindMaxSpeed 2.55 IF IS_ENTITY_ALIVE(MARY_ANN) IF place = 2 // IF IS_PED_SPRINTING(PLAYER_PED_ID()) // FLOAT fSprintTimeLeft = GET_PLAYER_SPRINT_TIME_REMAINING(PLAYER_ID()) // // ENDIF FLOAT fDistance = GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), MARY_ANN) IF fDistance < 15 FLOAT fSpeedReduce = fDistance / 100 IF fMBR_RunSpeed > 2.42 fMBR_RunSpeed -= fSpeedReduce ENDIF ELSE IF fMBR_RunSpeed < 2.52 fMBR_RunSpeed += 0.002 ENDIF ENDIF ELSE FLOAT fDistance = GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), MARY_ANN) // FLOAT fPlayerMBR = GET_PED_DESIRED_MOVE_BLEND_RATIO(PLAYER_PED_ID()) FLOAT fSpeedModifier = fDistance / 300 IF fDistance < 10 // IF fMBR_RunSpeed < fPlayerMBR // fMBR_RunSpeed += fSpeedModifier // ELIF fMBR_RunSpeed > fPlayerMBR // fMBR_RunSpeed -= fSpeedModifier // ENDIF // Have a minimum speed that Mary Ann can run at, so the player can't jog and win IF fMBR_RunSpeed < 2.487 fMBR_RunSpeed += 0.002 // But also have a max speed so she can be outrun ELIF fMBR_RunSpeed > 2.492 fMBR_RunSpeed -= 0.002 ENDIF ELSE IF fMBR_RunSpeed < fBehindMaxSpeed fMBR_RunSpeed += fSpeedModifier ELIF fMBR_RunSpeed > fBehindMaxSpeed fMBR_RunSpeed -= fSpeedModifier ENDIF IF fMBR_RunSpeed > 3.0 fMBR_RunSpeed = 3.0 ENDIF ENDIF ENDIF #IF IS_DEBUG_BUILD IF bDebug_SpeedDebug DEBUG_PRINTSF("RACE TO FINISH SPEED: fMBR_RunSpeed = ", fMBR_RunSpeed) ENDIF #ENDIF ENDIF ENDPROC /// PURPOSE: /// Handles the normal rubber-banding behaviour PROC DO_MA_RUBBER_BANDING() IF iNum_PlayerClosestWaypoint = iNum_NPCClosestWaypoint vector nextPoint WAYPOINT_RECORDING_GET_COORD(sFANATIC_ROUTE, iNum_NPCClosestWaypoint + 1, nextPoint) IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), nextPoint) < GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(MARY_ANN, nextPoint) SPEED_MARY_ANN_UP() ELSE SLOW_MARY_ANN_DOWN() ENDIF ELIF iNum_PlayerClosestWaypoint > iNum_NPCClosestWaypoint SPEED_MARY_ANN_UP() ELSE SLOW_MARY_ANN_DOWN() ENDIF ENDPROC /// PURPOSE: Update Mary Ann's running speed every frame PROC UPDATE_HER_RUN_SPEED() IF missionStage <> MS_END_CUTSCENE IF missionStage = MS_SPRINT_TO_FINISH MASprintState = SPRINT_COOLDOWN // Ensure the sprint boost is never active here DO_MA_FINISH_SPRINT_STYLE() ELSE // Don't do the normal rubber banding stuff if Mary Ann is reducing her speed IF MASprintState <> SPRINT_REDUCE DO_MA_RUBBER_BANDING() // Otherwise, if she's meant to be reducing her speed but is behind the player, do the rubber banding stuff anyway ELIF place = 1 DO_MA_RUBBER_BANDING() ENDIF // The SPRINT_REDUCE stage will skip over reducing her speed if she's behind HANDLE_SPRINT_BOOST() ENDIF // Prints for Mary Ann #IF IS_DEBUG_BUILD IF bDebug_SpeedDebug IF MASprintState = SPRINT_WAITING //DEBUG_PRINTSF("SPRINT WAITING SPEED: fMBR_RunSpeed = ", fMBR_RunSpeed) ELIF MASprintState = SPRINT_ACTIVE DEBUG_PRINTSF("SPRINT ACTIVE SPEED: fMBR_SprintCap = ", fMBR_SprintCap) ELIF MASprintState = SPRINT_REDUCE DEBUG_PRINTSF("SPRINT REDUCE SPEED: fMBR_RunSpeed = ", fMBR_RunSpeed) ELIF MASprintState = SPRINT_COOLDOWN //DEBUG_PRINTSF("SPRINT COOLDOWN SPEED: fMBR_RunSpeed = ", fMBR_RunSpeed) ENDIF ENDIF #ENDIF IF IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_PED(MARY_ANN) // If the sprint boost (to stop 886738) is active, use the sprint cap value instead of the calculated fMBR_RunSpeed IF MASprintState = SPRINT_ACTIVE WAYPOINT_PLAYBACK_OVERRIDE_SPEED(MARY_ANN, fMBR_SprintCap) ELSE WAYPOINT_PLAYBACK_OVERRIDE_SPEED(MARY_ANN, fMBR_RunSpeed) ENDIF ENDIF // SHE HAS A MINIMUM SPEED SO THAT SHE CAN RUN DOWN THE STEPS QUICKLY LIKE THE PLAYER. SHOULD BE A TEMP FIX WHILE CODE SORTS THIS SET_PED_MIN_MOVE_BLEND_RATIO(MARY_ANN, fMBR_RunSpeed - 0.5) SET_PED_MOVE_RATE_OVERRIDE(MARY_ANN, fMBR_IncreaseRatio) ENDIF ENDPROC /// PURPOSE: Check to make a ped ragdoll if Mary Ann collides with them PROC CHECK_IF_MARY_ANN_RUNS_INTO_A_PED() IF HAS_ENTITY_COLLIDED_WITH_ANYTHING(MARY_ANN) PED_INDEX ped GET_CLOSEST_PED(GET_ENTITY_COORDS(MARY_ANN), 0.75, TRUE, TRUE, ped) IF DOES_ENTITY_EXIST(ped) AND NOT IS_ENTITY_DEAD(ped) IF NOT IS_PED_RAGDOLL(ped) AND IS_ENTITY_TOUCHING_ENTITY(MARY_ANN, ped) CLEAR_PED_TASKS(ped) SET_PED_TO_RAGDOLL(ped, 800, 1500, TASK_NM_BALANCE) VECTOR pushDir = -GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(MARY_ANN, GET_ENTITY_COORDS(ped)) APPLY_FORCE_TO_ENTITY(ped, APPLY_TYPE_IMPULSE, pushDir, <<0,0,0>>, GET_PED_RAGDOLL_BONE_INDEX(ped, RAGDOLL_SPINE), FALSE, FALSE, TRUE) if not IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF PED_HAS_SEXINESS_FLAG_SET(ped, SF_HOT_PERSON) IF pushLine[2].hasBeenPlayed = FALSE INT temp IF CAN_MARY_ANN_SAY_SINGLE_LINE("FAN1_PUSH", pushLine[2].dialogueLine, FALSE, temp) pushLine[2].hasBeenPlayed = TRUE ENDIF ELSE IF pushLine[0].hasBeenPlayed = FALSE INT temp IF CAN_MARY_ANN_SAY_SINGLE_LINE("FAN1_PUSH", pushLine[0].dialogueLine, FALSE, temp) pushLine[0].hasBeenPlayed = TRUE ENDIF ENDIF ENDIF ELSE IF pushLine[1].hasBeenPlayed = FALSE INT temp IF CAN_MARY_ANN_SAY_SINGLE_LINE("FAN1_PUSH", pushLine[1].dialogueLine, FALSE, temp) pushLine[1].hasBeenPlayed = TRUE ENDIF ELSE IF pushLine[0].hasBeenPlayed = FALSE INT temp IF CAN_MARY_ANN_SAY_SINGLE_LINE("FAN1_PUSH", pushLine[0].dialogueLine, FALSE, temp) pushLine[0].hasBeenPlayed = TRUE ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF //DEBUG_PRINTSTRING("SHE COLLIDED WITH SOMETHING") ENDIF ENDPROC /// PURPOSE: Large, encompassing process to control Mary Ann's behaviour throughout the mission PROC DEAL_WITH_MARY_ANN() IF IS_PED_UNINJURED(MARY_ANN) IF missionStage <> MS_END_CUTSCENE CHECK_IF_MARY_ANN_RUNS_INTO_A_PED() ELSE // B*1765019 - If player manages to make Mary Ann quit her task, keep retasking her until she gets on the goddamn bike IF cutsceneStage >= CS_SAY_FINAL_LINE IF NOT IsPedPerformingTask(MARY_ANN, SCRIPT_TASK_PERFORM_SEQUENCE) AND NOT b_PlayerOnMAsBike IF IS_VEHICLE_OK(MAS_BIKE) OPEN_SEQUENCE_TASK(seq) TASK_ENTER_VEHICLE(NULL, MAS_BIKE, DEFAULT_TIME_BEFORE_WARP, VS_DRIVER, PEDMOVEBLENDRATIO_RUN) TASK_CLEAR_LOOK_AT(NULL) TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), 2000) TASK_VEHICLE_DRIVE_TO_COORD(NULL, MAS_BIKE, <<-2018.17, -461.00, 10.56>>, 10, DRIVINGSTYLE_NORMAL, MARYSBIKEMODEL, DF_SteerAroundStationaryCars, 3, 50) TASK_VEHICLE_DRIVE_TO_COORD(NULL, MAS_BIKE, <<-2014.96, -455.47, 10.48>>, 10, DRIVINGSTYLE_NORMAL, MARYSBIKEMODEL, DF_SteerAroundStationaryCars, 3, 50) TASK_VEHICLE_DRIVE_WANDER(NULL, MAS_BIKE, 10, DRIVINGMODE_AVOIDCARS_STOPFORPEDS_OBEYLIGHTS) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(MARY_ANN, seq) CLEAR_SEQUENCE_TASK(seq) SET_PED_KEEP_TASK(MARY_ANN, TRUE) DEBUG_PRINTSTRING("Emergency retasked Mary Ann!") ENDIF ENDIF ENDIF ENDIF TRY_KEEPUP_OR_CATCHUP_LINES() // Keep trying to play these lines if we're waiting for a prior conversation to finish // If she gets far from the player we need to load the world around her so that she keeps running IF GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), MARY_ANN) > 80 IF b_LoadCollisionAroudMaryAnn = FALSE SET_ENTITY_LOAD_COLLISION_FLAG(MARY_ANN, TRUE) b_LoadCollisionAroudMaryAnn = TRUE ENDIF ELSE IF b_LoadCollisionAroudMaryAnn = TRUE SET_ENTITY_LOAD_COLLISION_FLAG(MARY_ANN, FALSE) b_LoadCollisionAroudMaryAnn = FALSE ENDIF ENDIF IF missionStage <> MS_END_CUTSCENE AND missionStage <> MS_PLAYER_IN_VEHICLE AND missionStage <> MS_LOST_RACE IF MADialogueState <> MA_OUT_OF_TALKING_RANGE IF GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), MARY_ANN) > 25 SET_MARY_ANN_DIALOGUE_STATE(MA_OUT_OF_TALKING_RANGE) ENDIF ENDIF ENDIF IF MADialogueState <> MA_WITHIN_TALKING_RANGE IF GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), MARY_ANN) < 24 SET_MARY_ANN_DIALOGUE_STATE(MA_WITHIN_TALKING_RANGE) ENDIF ENDIF UPDATE_HER_RUN_SPEED() IF missionStage <> MS_END_CUTSCENE AND missionStage <> MS_CUTSCENE AND missionStage <> MS_LOST_RACE IF NOT IS_ENTITY_IN_ANGLED_AREA(MARY_ANN, <<-1809.172852,-549.010559,14.031675>>, <<-1841.728638,-529.457520,33.641205>>, 21.75) IF b_DoPedOvertake = FALSE SET_PED_STEERS_AROUND_PEDS(MARY_ANN, true) b_DoPedOvertake = TRUE DEBUG_PRINTSTRING("Set Mary Ann to steer round peds") ENDIF ELSE IF b_DoPedOvertake = TRUE SET_PED_STEERS_AROUND_PEDS(MARY_ANN, FALSE) b_DoPedOvertake = FALSE DEBUG_PRINTSTRING("Unset Mary Ann to steer round peds") ENDIF ENDIF CHECK_FOR_GETTING_STUCK() ENDIF ENDIF ENDPROC /// PURPOSE: Set all the models we may have requested as no longer needed PROC UNLOAD_ALL_MODELS() SET_MODEL_AS_NO_LONGER_NEEDED(G_M_Y_SALVAGOON_01) SET_MODEL_AS_NO_LONGER_NEEDED(JOGGERMODEL) SET_MODEL_AS_NO_LONGER_NEEDED(A_M_Y_BEACH_01) SET_MODEL_AS_NO_LONGER_NEEDED(A_F_Y_BEACH_01) SET_MODEL_AS_NO_LONGER_NEEDED(A_C_ROTTWEILER) SET_MODEL_AS_NO_LONGER_NEEDED(S_M_Y_BayWatch_01) SET_MODEL_AS_NO_LONGER_NEEDED(IG_MARYANN) SET_MODEL_AS_NO_LONGER_NEEDED(MARYSBIKEMODEL) SET_MODEL_AS_NO_LONGER_NEEDED(BLAZER2) SET_MODEL_AS_NO_LONGER_NEEDED(BANSHEE) SET_MODEL_AS_NO_LONGER_NEEDED(REGINA) ENDPROC /// PURPOSE: /// Part of the race tracking might check the distance between Michael and Mary Ann's next checkpoint in order to determine who is in front /// The problem is that if the player is just in front and has just hit a CP, Mary Ann may be very close to that CP behind Michael, /// so the check thinks that Mary Ann in 1st position because she is closer to "her" CP (until she hits it, and it starts checking the same CP again) /// Instead of checking each individual's CP, let's check the one furthest away and return that /// RETURNS: /// The furthest away checkpoint FUNC INT RETURN_FURTHEST_CHECKPOINT() IF iCURRENT_RACE_POS > iNPC_RACE_POS IF iCURRENT_RACE_POS >= MAX_CHECKPOINTS RETURN 9 ELSE RETURN iCURRENT_RACE_POS ENDIF ELSE IF iNPC_RACE_POS >= MAX_CHECKPOINTS RETURN 9 ELSE RETURN iNPC_RACE_POS ENDIF ENDIF ENDFUNC /// PURPOSE: Control the race checkpoints througout the mission as it progresses PROC DEAL_WITH_RACE_BLIPS() HUD_COLOURS currentCPColour INT iR, iG, iB, iA INT PreviR, PreviG, PreviB IF iCURRENT_RACE_POS < iMaxRacePositions IF iCURRENT_RACE_POS < iMaxRacePositions - 1 IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), RACE_POSITIONS[iCURRENT_RACE_POS], <<4,4,3>>) OR NOT DOES_BLIP_EXIST(DESTINATION_BLIP) SAFE_REMOVE_BLIP(DESTINATION_BLIP) SAFE_REMOVE_BLIP(NEXT_DESTINATION_BLIP) IF checkPoint != NULL DEBUG_PRINTSTRING("Create prev CP") iPrevAlpha = 180 currentCPColour = HUD_COLOUR_WHITE GET_HUD_COLOUR(currentCPColour, PreviR, PreviG, PreviB, iPrevAlpha) PrevCheckpoint = CREATE_CHECKPOINT(GET_RACE_CHECKPOINT_TYPE(iCURRENT_RACE_POS), RACE_POSITIONS[iCURRENT_RACE_POS]+<<0, 0, 2.0>>, RACE_POSITIONS[iCURRENT_RACE_POS + 1], 3.2, PreviR, PreviG, PreviB, iPrevAlpha) SET_CHECKPOINT_RGBA(PrevCheckpoint, PreviR, PreviG, PreviB, iPrevAlpha) SET_CHECKPOINT_RGBA2(PrevCheckpoint, PreviR,PreviG, PreviB, iPrevAlpha) ENDIF DELETE_CHECKPOINT(checkPoint) IF iCURRENT_RACE_POS != 0 // Play the checkpoint sound - only want to do this after the very first pass through, otherwise we get the sfx after the cutscene PLAY_SOUND_FRONTEND(-1, "CHECKPOINT_NORMAL", "HUD_MINI_GAME_SOUNDSET", FALSE) ENDIF iCURRENT_RACE_POS++ // If we're not at the final checkpoint, do a small blip for the next one too IF iCURRENT_RACE_POS < iMaxRacePositions - 1 checkpoint = CREATE_CHECKPOINT(GET_RACE_CHECKPOINT_TYPE(iCURRENT_RACE_POS), RACE_POSITIONS[iCURRENT_RACE_POS]+<<0, 0, 2.0>>, RACE_POSITIONS[iCURRENT_RACE_POS + 1], 3.2, iR, iG, iB, iA) SET_CHECKPOINT_CYLINDER_HEIGHT(checkpoint,1.6,1.6,100) currentCPColour = HUD_COLOUR_YELLOWLIGHT GET_HUD_COLOUR(currentCPColour, iR, iG, iB, iA) SET_CHECKPOINT_RGBA(checkpoint, iR, iG, iB, iA) currentCPColour = HUD_COLOUR_NORTH_BLUE GET_HUD_COLOUR(currentCPColour, iR, iG, iB, iA) SET_CHECKPOINT_RGBA2(checkpoint, iR, iG, iB, iA) DESTINATION_BLIP = ADD_BLIP_FOR_COORD(RACE_POSITIONS[iCURRENT_RACE_POS]) SHOW_HEIGHT_ON_BLIP(DESTINATION_BLIP, FALSE) SET_BLIP_SCALE(DESTINATION_BLIP, 1.2) NEXT_DESTINATION_BLIP = ADD_BLIP_FOR_COORD(RACE_POSITIONS[iCURRENT_RACE_POS + 1]) IF (iCURRENT_RACE_POS + 1) = iMaxRacePositions - 1 SET_BLIP_SCALE(NEXT_DESTINATION_BLIP, 1.2) // The final next-checkpoint blip has a scale of 1.2 SET_BLIP_SPRITE(NEXT_DESTINATION_BLIP, RADAR_TRACE_RACEFLAG) SHOW_HEIGHT_ON_BLIP(NEXT_DESTINATION_BLIP, FALSE) ELSE SET_BLIP_SCALE(NEXT_DESTINATION_BLIP, 0.7) SHOW_HEIGHT_ON_BLIP(NEXT_DESTINATION_BLIP, FALSE) ENDIF ELIF iCURRENT_RACE_POS = iMaxRacePositions - 1 currentCPColour = GET_RACE_CHECKPOINT_COLOUR(GET_RACE_CHECKPOINT_TYPE(iCURRENT_RACE_POS)) GET_HUD_COLOUR(currentCPColour, iR, iG, iB, iA) checkpoint = CREATE_CHECKPOINT(GET_RACE_CHECKPOINT_TYPE(iCURRENT_RACE_POS), RACE_POSITIONS[iCURRENT_RACE_POS]+<<0, 0, 2.0>>, RACE_POSITIONS[iCURRENT_RACE_POS], 3.2, iR, iG, iB, iA) SET_CHECKPOINT_CYLINDER_HEIGHT(checkpoint,1.6,1.6,100) DESTINATION_BLIP = ADD_BLIP_FOR_COORD(RACE_POSITIONS[iCURRENT_RACE_POS]) SET_BLIP_SCALE(DESTINATION_BLIP, 1.2) SET_BLIP_SPRITE(DESTINATION_BLIP, RADAR_TRACE_RACEFLAG) SHOW_HEIGHT_ON_BLIP(DESTINATION_BLIP, FALSE) ENDIF ENDIF ELSE IF iCURRENT_RACE_POS = iMaxRacePositions - 1 IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), vPos_FinishLine) < 4 IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) IF checkPoint != NULL DEBUG_PRINTSTRING("Create prev CP") iPrevAlpha = 180 currentCPColour = HUD_COLOUR_WHITE GET_HUD_COLOUR(currentCPColour, PreviR, PreviG, PreviB, iPrevAlpha) PrevCheckpoint = CREATE_CHECKPOINT(CHECKPOINT_RACE_GROUND_FLAG, RACE_POSITIONS[iCURRENT_RACE_POS]+<<0, 0, 2.0>>, RACE_POSITIONS[iCURRENT_RACE_POS], 3.2, PreviR, PreviG, PreviB, iPrevAlpha) SET_CHECKPOINT_RGBA(PrevCheckpoint, PreviR, PreviG, PreviB, iPrevAlpha) SET_CHECKPOINT_RGBA2(PrevCheckpoint, PreviR,PreviG, PreviB, iPrevAlpha) ENDIF // Play the checkpoint sound PLAY_SOUND_FRONTEND(-1, "CHECKPOINT_NORMAL", "HUD_MINI_GAME_SOUNDSET", FALSE) cutsceneStage = CS_WAIT_FOR_ANN stageStage = SS_SETUP missionStage = MS_END_CUTSCENE DEBUG_PRINTSTRING("PLAYER_AT_FINISH_LINE") ENDIF ENDIF ENDIF ENDIF ENDIF IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID()) FLOAT fDis = GET_DISTANCE_BETWEEN_COORDS(RACE_POSITIONS[iCURRENT_RACE_POS],GET_ENTITY_COORDS(PLAYER_PED_ID())) IF checkpoint != NULL // Make sure the checkpoint exists first IF fDis > 100.0 iA = 240 currentCPColour = HUD_COLOUR_YELLOWLIGHT GET_HUD_COLOUR(currentCPColour, iR, iG, iB, iA) SET_CHECKPOINT_RGBA(checkpoint, iR, iG, iB, iA) currentCPColour = HUD_COLOUR_NORTH_BLUE GET_HUD_COLOUR(currentCPColour, iR, iG, iB, iA) SET_CHECKPOINT_RGBA2(checkpoint, iR, iG, iB, iA) ELSE //DEBUG_PRINTSTRING("Dim current CP") currentCPColour = HUD_COLOUR_YELLOWLIGHT GET_HUD_COLOUR(currentCPColour, iR, iG, iB, iA) iA = ROUND(fDis*2.4) IF iA < 60 iA = 60 ENDIF SET_CHECKPOINT_RGBA(checkpoint, iR, iG, iB, iA) currentCPColour = HUD_COLOUR_NORTH_BLUE GET_HUD_COLOUR(currentCPColour, iR, iG, iB, iA) iA = ROUND(fDis*2.4) IF iA < 60 iA = 60 ENDIF SET_CHECKPOINT_RGBA2(checkpoint, iR, iG, iB, iA) ENDIF ENDIF ENDIF IF PrevCheckpoint != NULL //DEBUG_PRINTSTRING("Fade previous CP") iPrevAlpha -= 25 IF iPrevAlpha > 0 GET_HUD_COLOUR(HUD_COLOUR_WHITE, PreviR, PreviG, PreviB, iA) SET_CHECKPOINT_RGBA(PrevCheckpoint, PreviR, PreviG, PreviB, iPrevAlpha) SET_CHECKPOINT_RGBA2(PrevCheckpoint, PreviR, PreviG, PreviB, iPrevAlpha) ELSE DELETE_CHECKPOINT(PrevCheckpoint) ENDIF ENDIF IF iNPC_RACE_POS < iMaxRacePositions IF IS_ENTITY_AT_COORD(MARY_ANN, RACE_POSITIONS[iNPC_RACE_POS], <<3,3,3>>) iNPC_RACE_POS++ ENDIF ENDIF /* DEBUG_PRINTSI("current player pos - ",iCURRENT_RACE_POS) DEBUG_PRINTSI("current NPC pos - ",iNPC_RACE_POS) DEBUG_PRINTSI("MAX POSITIONS - ",iMaxRacePositions) */ ENDPROC /// PURPOSE: Track the locations of the player and Mary Ann and update the race positions accordingly PROC DEAL_WITH_THE_RACE_TRACKING() IF IS_PED_UNINJURED(MARY_ANN) IF ENUM_TO_INT(missionStage) < ENUM_TO_INT(MS_END_CUTSCENE) AND ENUM_TO_INT(missionStage) > ENUM_TO_INT(MS_CUTSCENE) DEAL_WITH_RACE_BLIPS() UPDATE_CHASE_BLIP(FANATIC_BLIP, MARY_ANN, 70, 0.72) IF iNum_PlayerClosestWaypoint > iNum_NPCClosestWaypoint IF place != 1 place = 1 IF (GET_GAME_TIMER() - iOvertakeTimer) > 3000 DEBUG_PRINTSTRING("Trying an overtake line...") bOvertaken = TRUE iOvertakeTimer = GET_GAME_TIMER() ELSE DEBUG_PRINTSI("Can't do overtake line, overtake timer is = ", (GET_GAME_TIMER() - iOvertakeTimer)) ENDIF ENDIF ELIF iNum_PlayerClosestWaypoint < iNum_NPCClosestWaypoint IF place != 2 place = 2 ENDIF ELSE IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(MARY_ANN), RACE_POSITIONS[RETURN_FURTHEST_CHECKPOINT()]) < GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), RACE_POSITIONS[RETURN_FURTHEST_CHECKPOINT()]) IF place != 2 place = 2 ENDIF ELSE IF place != 1 place = 1 IF (GET_GAME_TIMER() - iOvertakeTimer) > 3000 DEBUG_PRINTSTRING("Trying an overtake line...") bOvertaken = TRUE iOvertakeTimer = GET_GAME_TIMER() ELSE DEBUG_PRINTSI("Can't do overtake line, overtake timer is = ", (GET_GAME_TIMER() - iOvertakeTimer)) ENDIF ENDIF ENDIF ENDIF // IF iNPC_RACE_POS > iCURRENT_RACE_POS // IF place != 2 // place = 2 // ENDIF // ELIF iNPC_RACE_POS < iCURRENT_RACE_POS // IF place != 1 // place = 1 // IF (GET_GAME_TIMER() - iOvertakeTimer) > 3000 // DEBUG_PRINTSTRING("Trying an overtake line...") // bOvertaken = TRUE // iOvertakeTimer = GET_GAME_TIMER() // ENDIF // ENDIF // ELSE // IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(MARY_ANN), RACE_POSITIONS[iNPC_RACE_POS]) < GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), RACE_POSITIONS[iCURRENT_RACE_POS]) // IF place != 2 // place = 2 // ENDIF // ELSE // IF place != 1 // place = 1 // IF (GET_GAME_TIMER() - iOvertakeTimer) > 3000 // DEBUG_PRINTSTRING("Trying an overtake line...") // bOvertaken = TRUE // iOvertakeTimer = GET_GAME_TIMER() // ENDIF // ENDIF // ENDIF // ENDIF //DRAW_BIG_DOUBLE_SCORE_HUD(iCURRENT_RACE_POS, iMaxRacePositions, "FATIC1_CP", HUD_COLOUR_YELLOWLIGHT ) SET_FAR_RIGHT_TITLE_POSITION_HUD_THIS_FRAME() DRAW_RACE_HUD((GET_GAME_TIMER() - start_time), "", -1, -1, "", place, 2, "", DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, TRUE) // turn milliseconds off! ENDIF ENDIF ENDPROC /// PURPOSE: Delete every entity in the mission PROC DELETE_EVERYTHING() IF IS_AUDIO_SCENE_ACTIVE("FANATIC_MIX_SCENE") REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(MARY_ANN) ENDIF SAFE_DELETE_PED(MARY_ANN) SAFE_DELETE_PED(QUAD_DRIVER) SAFE_DELETE_PED(cprWatcher1) SAFE_DELETE_PED(cprWatcher2) SAFE_DELETE_PED(INJURED_PED) SAFE_DELETE_PED(BEACH_DOG) SAFE_DELETE_PED(OtherJoggers[0].thisIndex) SAFE_DELETE_PED(OtherJoggers[1].thisIndex) SAFE_DELETE_PED(OtherJoggers[2].thisIndex) SAFE_DELETE_PED(OtherJoggers[3].thisIndex) SAFE_DELETE_PED(DRIVEBY_FINGER_CAR.Driver) SAFE_DELETE_PED(DRIVEBY_FINGER_CAR.Passenger) SAFE_DELETE_PED(FOLLOWING_CAR.Driver) SAFE_DELETE_PED(FOLLOWING_CAR.Passenger) SAFE_DELETE_VEHICLE(DRIVEBY_FINGER_CAR.thisCarIndex) SAFE_DELETE_VEHICLE(FOLLOWING_CAR.thisCarIndex) SAFE_DELETE_VEHICLE(CHEAT_QUAD) SAFE_DELETE_VEHICLE(MAS_BIKE) ENDPROC /// PURPOSE: Reset all of the bools used to track which conversations have been said to the default PROC RESET_DIALOGUE_BOOLS() bCatchupCheatLineSaid = FALSE bOvertaken = FALSE iOvertakeTimer = GET_GAME_TIMER() iOneLinerTimer = GET_GAME_TIMER() iRoadTimer = GET_GAME_TIMER() iRoadCounter = 0 OvertakeLines.timesPlayed = 0 MikePushMALine.timesPlayed = 0 MikePushPedLine.timesPlayed = 0 pushLine[0].hasBeenPlayed = FALSE pushLine[1].hasBeenPlayed = FALSE pushLine[2].hasBeenPlayed = FALSE cheatedLeaptFence.hasBeenPlayed = FALSE cheatedRanAcrossGrass.hasBeenPlayed = FALSE returnAfterCheatedLine.hasBeenPlayed = FALSE startRunConversation.hasBeenPlayed = FALSE road1Conversation.hasBeenPlayed = FALSE road2Conversation.hasBeenPlayed = FALSE raceConversation.hasBeenPlayed = FALSE leftRaceWarning.hasBeenShown = FALSE leftBehindWarning.hasBeenShown = FALSE vehicleWarning.hasBeenShown = FALSE iHurryUpLineNumber = 0 iCatchUpLineNumber = 0 ENDPROC /// PURPOSE: Handle Z-skipping from stage to stage in a mission PROC JUMP_TO_STAGE(debugSkipToMissionStage newStage) RC_START_Z_SKIP() CLEAR_PRINTS() SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 0) FINISH_CUTSCENE(FALSE, TRUE) DISPLAY_RADAR(TRUE) STOP_SOUND(iHeartbeatAudioID) bHeartbeatStarted = FALSE CLEAR_PED_TASKS(PLAYER_PED_ID()) RESET_PLAYER_STAMINA(PLAYER_ID()) b_FinalPedsStartedWalking = FALSE b_DrivebyHorn = FALSE SAFE_REMOVE_BLIP(DESTINATION_BLIP) SAFE_REMOVE_BLIP(NEXT_DESTINATION_BLIP) DELETE_CHECKPOINT(checkPoint) IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() DEBUG_PRINTSTRING("Stopping scripted convo at jump_to_stage") KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() ENDIF REMOVE_RELATIONSHIP_GROUP(relGroupFriendly) ADD_RELATIONSHIP_GROUP("FRIENDLIES", relGroupFriendly) SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, relGroupFriendly, RELGROUPHASH_PLAYER) SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, RELGROUPHASH_PLAYER, relGroupFriendly) REQUEST_MODEL(IG_MARYANN) WHILE NOT HAS_MODEL_LOADED(IG_MARYANN) WAIT(0) ENDWHILE DELETE_EVERYTHING() RESET_DIALOGUE_BOOLS() iOvertakeTimer = GET_GAME_TIMER() iOneLinerTimer = GET_GAME_TIMER() bOvertaken = FALSE MARY_ANN = CREATE_PED(PEDTYPE_MISSION, IG_MARYANN, <<-1865.90, -448.81, 45.13>>, -143.87) SET_PED_RELATIONSHIP_GROUP_HASH(MARY_ANN, relGroupFriendly) SET_PED_MOVEMENT_CLIPSET(MARY_ANN, "FEMALE_FAST_RUNNER") SET_PED_COMPONENT_VARIATION(MARY_ANN, PED_COMP_LEG, 1, 0) ADD_PED_FOR_DIALOGUE(MyLocalPedStruct, 3, MARY_ANN, "MARYANN") IF newStage <= DEBUG_TO_STEPS_DOWN iSprintLength = 1800 iSprintDelay = 4500 ENDIF IF newStage = DEBUG_TO_INTRO IF IS_AUDIO_SCENE_ACTIVE("FANATIC_MIX_SCENE") REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(MARY_ANN) STOP_AUDIO_SCENE("FANATIC_MIX_SCENE") ENDIF ELSE IF NOT IS_AUDIO_SCENE_ACTIVE("FANATIC_MIX_SCENE") START_AUDIO_SCENE("FANATIC_MIX_SCENE") IF IS_ENTITY_ALIVE(MARY_ANN) ADD_ENTITY_TO_AUDIO_MIX_GROUP(MARY_ANN,"FANATIC_MIX_MARY_ANNE") ENDIF ENDIF ENDIF SWITCH newStage CASE DEBUG_TO_INTRO RC_REQUEST_CUTSCENE("ef_1_rcm") IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY() DEBUG_PRINTSTRING("Trying to set Mary Ann component variation") SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Mary_Ann", MARY_ANN, CS_MARYANN) ENDIF iCURRENT_RACE_POS = 0 iNPC_RACE_POS = 1 REMOVE_RELATIONSHIP_GROUP(relGroupFriendly) TURN_ROADS_ON(FALSE) LOAD_OTHER_ASSETS() CREATE_CARS() UNLOAD_ALL_MODELS() stageStage = SS_SETUP missionStage = MS_CUTSCENE BREAK CASE DEBUG_TO_START iCURRENT_RACE_POS = 0 iNPC_RACE_POS = 1 IF NOT IS_REPLAY_BEING_SET_UP() SET_ENTITY_COORDS(PLAYER_PED_ID(), <<-1878.2344, -439.6985, 45.0299>>) SET_ENTITY_HEADING(PLAYER_PED_ID(), 241.0468) ENDIF CLEAR_AREA_OF_PEDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), 7) SET_ENTITY_COORDS(MARY_ANN, <<-1869.24, -444.99, 45.17>>) SET_ENTITY_HEADING(MARY_ANN, -143.87) TURN_ROADS_ON(FALSE) LOAD_OTHER_ASSETS() CREATE_CARS() UNLOAD_ALL_MODELS() KEEP_RUNNING(MS_START_RUNNING) IF NOT IS_REPLAY_BEING_SET_UP() // Can't do these while a replay is being set up, will do them at the end instead // This is to keep Michael running when the mission is replayed after a fail (or a skip I guess) FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_RUN, TRUE, FAUS_DEFAULT) SIMULATE_PLAYER_INPUT_GAIT(PLAYER_ID(), PEDMOVEBLENDRATIO_RUN, 5000) SET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_UNARMED, TRUE) ENDIF BREAK CASE DEBUG_TO_ROAD iCURRENT_RACE_POS = 3 iNPC_RACE_POS = 4 CLEAR_PED_TASKS(PLAYER_PED_ID()) SET_ENTITY_COORDS(PLAYER_PED_ID(), <<-1731.05, -549.78, 36.40>>) SET_ENTITY_HEADING(PLAYER_PED_ID(), 104.26) CLEAR_PED_TASKS(MARY_ANN) SET_ENTITY_COORDS(MARY_ANN, <<-1732.880493,-551.763245,36.5>>) SET_ENTITY_HEADING(MARY_ANN, 115.26) TURN_ROADS_ON(FALSE) CLEAR_AREA_OF_VEHICLES(<<-1806.495483,-525.869629,29.925911>> , 100) LOAD_OTHER_ASSETS() CREATE_CARS() UNLOAD_ALL_MODELS() KEEP_RUNNING(MS_ROAD_RUNNING_SECTION) BREAK CASE DEBUG_TO_STEPS_DOWN iCURRENT_RACE_POS = 5 iNPC_RACE_POS = 6 CLEAR_PED_TASKS(PLAYER_PED_ID()) SET_ENTITY_COORDS(PLAYER_PED_ID(), <<-1832.52, -519.37, 27.89>>) SET_ENTITY_HEADING(PLAYER_PED_ID(), 162.59) CLEAR_PED_TASKS(MARY_ANN) SET_ENTITY_COORDS(MARY_ANN, <<-1833.81, -523.70, 28.14>>) SET_ENTITY_HEADING(MARY_ANN, 172.66) LOAD_OTHER_ASSETS() WHILE NOT LOAD_CPR() OR NOT LOAD_DOG() WAIT(0) ENDWHILE CREATE_DOGS() CREATE_QUAD_BIKE_SCENE() CREATE_JOGGERS() UNLOAD_ALL_MODELS() TURN_ROADS_ON() KEEP_RUNNING(MS_STEPS_DOWN) BREAK CASE DEBUG_TO_BEACH iCURRENT_RACE_POS = 6 iNPC_RACE_POS = 7 CLEAR_PED_TASKS(PLAYER_PED_ID()) SET_ENTITY_COORDS(PLAYER_PED_ID(), <<-1850.10, -592.21, 18.2>>) SET_ENTITY_HEADING(PLAYER_PED_ID(), 124.19) CLEAR_PED_TASKS(MARY_ANN) SET_ENTITY_COORDS(MARY_ANN, <<-1849.61, -592.90, 18.2>>) SET_ENTITY_HEADING(MARY_ANN, 135.16) LOAD_OTHER_ASSETS() WHILE NOT LOAD_CPR() OR NOT LOAD_DOG() WAIT(0) ENDWHILE CREATE_DOGS() CREATE_QUAD_BIKE_SCENE(FALSE) CREATE_JOGGERS() IF IS_PED_UNINJURED(INJURED_PED) ADD_SHOCKING_EVENT_FOR_ENTITY(EVENT_SHOCKING_INJURED_PED, INJURED_PED, -1) ENDIF UNLOAD_ALL_MODELS() TURN_ROADS_ON() IF IS_OUTFIT_SUITABLE_FOR_FANATIC_MISSION(1) CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_BCHB", CONV_PRIORITY_MEDIUM) ELSE CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_BCHA", CONV_PRIORITY_MEDIUM) ENDIF KEEP_RUNNING(MS_SPRINT_TO_FINISH) BREAK CASE DEBUG_TO_FINISH_LINE iCURRENT_RACE_POS = 8 iNPC_RACE_POS = 9 LOAD_OTHER_ASSETS() WHILE NOT LOAD_CPR() OR NOT LOAD_DOG() WAIT(0) ENDWHILE CREATE_DOGS() CREATE_QUAD_BIKE_SCENE() CREATE_JOGGERS() UNLOAD_ALL_MODELS() CLEAR_PED_TASKS(PLAYER_PED_ID()) SET_ENTITY_COORDS(PLAYER_PED_ID(), vPos_FinishLine) SET_ENTITY_HEADING(PLAYER_PED_ID(), 19.95) IF IS_PED_UNINJURED(MARY_ANN) CLEAR_PED_TASKS(MARY_ANN) SET_ENTITY_COORDS(MARY_ANN, <<-1986.93, -526.39, 11.70>>) SET_ENTITY_HEADING(MARY_ANN, 44.46) ENDIF TURN_ROADS_ON() KEEP_RUNNING(MS_DEBUG_NEAR_FINISH_LINE) BREAK CASE DEBUG_NEXT_TO_FINISH // This is a special option in case you want to let Mary Ann win, and see the "you lost" cutscene. iCURRENT_RACE_POS = 8 iNPC_RACE_POS = 9 LOAD_OTHER_ASSETS() WHILE NOT LOAD_CPR() OR NOT LOAD_DOG() WAIT(0) ENDWHILE CREATE_DOGS() CREATE_QUAD_BIKE_SCENE() CREATE_JOGGERS() UNLOAD_ALL_MODELS() CLEAR_PED_TASKS(PLAYER_PED_ID()) SET_ENTITY_COORDS(PLAYER_PED_ID(), <<-2001.27, -514.18, 11>>) SET_ENTITY_HEADING(PLAYER_PED_ID(), 19.95) IF IS_PED_UNINJURED(MARY_ANN) CLEAR_PED_TASKS(MARY_ANN) SET_ENTITY_COORDS(MARY_ANN, <<-1986.93, -526.39, 11.70>>) SET_ENTITY_HEADING(MARY_ANN, 44.46) ENDIF TURN_ROADS_ON() KEEP_RUNNING(MS_DEBUG_NEAR_FINISH_LINE) BREAK ENDSWITCH SET_PED_ON_THE_GROUND(MARY_ANN) SET_PED_ON_THE_GROUND(PLAYER_PED_ID()) IF DOES_ENTITY_EXIST(MARY_ANN) AND DOES_ENTITY_EXIST(PLAYER_PED_ID()) DETERMINE_CLOSEST_WAYPOINTS() DEAL_WITH_THE_RACE_TRACKING() ENDIF IF IS_REPLAY_BEING_SET_UP() DEBUG_PRINTSTRING("JUMP_TO_STAGE: replay being set up") END_REPLAY_SETUP() // This stuff wouldn't be done before because of the replay being set up SIMULATE_PLAYER_INPUT_GAIT(PLAYER_ID(), PEDMOVEBLENDRATIO_RUN, 5000) FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_RUN, TRUE, FAUS_DEFAULT) SET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_UNARMED, TRUE) wait(1000) RC_END_Z_SKIP() ELSE DEBUG_PRINTSTRING("JUMP_TO_STAGE: replay not being set up") IF missionStage = MS_CUTSCENE WHILE NOT RC_IS_CUTSCENE_OK_TO_START() IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY() IF IS_ENTITY_ALIVE(MARY_ANN) DEBUG_PRINTSTRING("Trying to set Mary Ann component variation") SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Mary_Ann", MARY_ANN, CS_MARYANN) ENDIF ENDIF RC_REQUEST_CUTSCENE("ef_1_rcm") WAIT(0) ENDWHILE ELSE wait(1000) RC_END_Z_SKIP() ENDIF ENDIF ENDPROC // =========================================================================================================== // DEBUG FUNCTIONS // =========================================================================================================== /// PURPOSE: Check for Forced Pass or Fail PROC DEBUG_Check_Debug_Keys() #IF IS_DEBUG_BUILD // Check for Pass IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_S)) WAIT_FOR_CUTSCENE_TO_STOP() IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) CLEAR_PED_TASKS(PLAYER_PED_ID()) ENDIF Script_Passed() ENDIF // Check for Fail IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_F)) WAIT_FOR_CUTSCENE_TO_STOP() TRIGGER_MUSIC_EVENT("RC6A_FAIL") failReason = REASON_SILENT stageStage = SS_SETUP missionStage = MS_FAIL_WAIT_FOR_FADE ENDIF IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_J) SWITCH missionStage CASE MS_CUTSCENE WAIT_FOR_CUTSCENE_TO_STOP() JUMP_TO_STAGE(DEBUG_TO_START) BREAK CASE MS_START_RUNNING JUMP_TO_STAGE(DEBUG_TO_ROAD) BREAK CASE MS_ROAD_RUNNING_SECTION JUMP_TO_STAGE(DEBUG_TO_STEPS_DOWN) BREAK CASE MS_STEPS_DOWN JUMP_TO_STAGE(DEBUG_TO_BEACH) BREAK CASE MS_SPRINT_TO_FINISH IF NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-2015.758545,-501.566437,10.732570>>, <<-1992.435425,-522.269409,11.678237>>, 17.750000, FALSE, FALSE) JUMP_TO_STAGE(DEBUG_TO_FINISH_LINE) ELSE RC_END_CUTSCENE_MODE() IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) CLEAR_PED_TASKS(PLAYER_PED_ID()) ENDIF Script_Passed() ENDIF BREAK CASE MS_DEBUG_NEAR_FINISH_LINE RC_END_CUTSCENE_MODE() IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) CLEAR_PED_TASKS(PLAYER_PED_ID()) ENDIF Script_Passed() BREAK CASE MS_END_CUTSCENE RC_END_CUTSCENE_MODE() IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) CLEAR_PED_TASKS(PLAYER_PED_ID()) ENDIF Script_Passed() BREAK ENDSWITCH ENDIF IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_P) SWITCH missionStage CASE MS_START_RUNNING JUMP_TO_STAGE(DEBUG_TO_INTRO) BREAK CASE MS_ROAD_RUNNING_SECTION JUMP_TO_STAGE(DEBUG_TO_START) BREAK CASE MS_STEPS_DOWN JUMP_TO_STAGE(DEBUG_TO_ROAD) BREAK CASE MS_SPRINT_TO_FINISH IF NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-2015.758545,-501.566437,10.732570>>, <<-1992.435425,-522.269409,11.678237>>, 17.750000, FALSE, FALSE) JUMP_TO_STAGE(DEBUG_TO_STEPS_DOWN) ELSE JUMP_TO_STAGE(DEBUG_TO_BEACH) ENDIF BREAK CASE MS_DEBUG_NEAR_FINISH_LINE JUMP_TO_STAGE(DEBUG_TO_BEACH) BREAK CASE MS_END_CUTSCENE JUMP_TO_STAGE(DEBUG_TO_BEACH) BREAK ENDSWITCH ENDIF IF LAUNCH_MISSION_STAGE_MENU(s_skip_menu, i_debug_jump_stage) WAIT_FOR_CUTSCENE_TO_STOP() INT e_stage = i_debug_jump_stage JUMP_TO_STAGE(INT_TO_ENUM(debugSkipToMissionStage, e_stage)) ENDIF // Update the amount of sprint time remaining in the RAG widget fPlayerSprintRemaining = GET_PLAYER_SPRINT_TIME_REMAINING(PLAYER_ID()) #ENDIF ENDPROC /// PURPOSE: Handle the behaviour of the dog on the final stretch PROC DEAL_WITH_THE_DOG() IF IS_PED_UNINJURED(BEACH_DOG) SWITCH beachDogState CASE DOG_LOADING IF LOAD_DOG() IF NOT IS_ENTITY_ALIVE(BEACH_DOG) BEACH_DOG = CREATE_PED(PEDTYPE_MISSION, A_C_ROTTWEILER, vPos_DOG, fDir_DOG) SET_PED_CAN_RAGDOLL(BEACH_DOG, TRUE) ENDIF SET_MODEL_AS_NO_LONGER_NEEDED(A_C_ROTTWEILER) DEBUG_PRINTSTRING("Loaded and created dog - progressing") beachDogState = DOG_WAITING ENDIF BREAK CASE DOG_WAITING IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) IF iNum_PlayerClosestWaypoint = 109 TASK_FOLLOW_TO_OFFSET_OF_ENTITY(BEACH_DOG, PLAYER_PED_ID(), <<-2, 2, 0>>, 2.5, -1, 0.2) beachDogState = DOG_FOLLOWING_PLAYER ENDIF ENDIF BREAK ENDSWITCH ENDIF ENDPROC /// PURPOSE: Check to see if the player has threatened any ped involved in the CPR synced scene FUNC BOOL HAS_PLAYER_THREATENED_THE_CPR_SCENE() IF HAS_PLAYER_THREATENED_PED(QUAD_DRIVER) OR HAS_PLAYER_THREATENED_PED(INJURED_PED) OR HAS_PLAYER_THREATENED_PED(cprWatcher1) OR HAS_PLAYER_THREATENED_PED(cprWatcher2) RETURN TRUE ENDIF RETURN FALSE ENDFUNC /// PURPOSE: Handle the overall behaviour and events in the CPR synced scene by the beach PROC DEAL_WITH_THE_QUAD() SWITCH cprState CASE CPR_LOADING IF LOAD_CPR() DEBUG_PRINTSTRING("CPR scene resources loaded - progressing") CREATE_QUAD_BIKE_SCENE() cprState = CPR_WAITING ENDIF BREAK CASE CPR_WAITING IF iCURRENT_RACE_POS >= 7 IF IS_VEHICLE_OK(CHEAT_QUAD) IF IS_PED_UNINJURED(QUAD_DRIVER) AND IS_PED_UNINJURED(INJURED_PED) OPEN_SEQUENCE_TASK(seq) TASK_VEHICLE_FOLLOW_WAYPOINT_RECORDING(NULL, CHEAT_QUAD, "Fanatic1Quad", DF_SteerAroundPeds, 14) TASK_LEAVE_VEHICLE(NULL, CHEAT_QUAD) TASK_LOOK_AT_ENTITY(NULL, INJURED_PED, -1) TASK_GO_STRAIGHT_TO_COORD(NULL, GET_ENTITY_COORDS(INJURED_PED), 1.8)//GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(INJURED_PED, <<-0.5, 0, 0>>), 1.8) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(QUAD_DRIVER, seq) CLEAR_SEQUENCE_TASK(seq) SET_VEHICLE_FORWARD_SPEED(CHEAT_QUAD, 5) SET_VEHICLE_AS_NO_LONGER_NEEDED(CHEAT_QUAD) cprState = CPR_GOING_TO_SCENE ENDIF ENDIF ENDIF BREAK CASE CPR_GOING_TO_SCENE IF IS_PED_UNINJURED(QUAD_DRIVER) AND IS_PED_UNINJURED(INJURED_PED) IF IS_PED_RAGDOLL(INJURED_PED) cprState = CPR_INTERUPTED ENDIF IF GET_DISTANCE_BETWEEN_ENTITIES(INJURED_PED, QUAD_DRIVER) < 2 SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(QUAD_DRIVER, TRUE) CPRSynchSceneID = CREATE_SYNCHRONIZED_SCENE(vPos_CPRScene, vRot_CPRScene) TASK_SYNCHRONIZED_SCENE(QUAD_DRIVER, CPRSynchSceneID, "mini@cpr@char_a@cpr_def", "cpr_intro", SLOW_BLEND_IN, NORMAL_BLEND_OUT, SYNCED_SCENE_USE_PHYSICS, RBF_NONE, SLOW_BLEND_IN) TASK_SYNCHRONIZED_SCENE(INJURED_PED, CPRSynchSceneID, "mini@cpr@char_b@cpr_def", "cpr_intro", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, SYNCED_SCENE_DONT_INTERRUPT) cprState = CPR_INTRO ENDIF ENDIF BREAK CASE CPR_INTRO IF IS_PED_UNINJURED(QUAD_DRIVER) AND IS_PED_UNINJURED(INJURED_PED) IF IS_PED_RAGDOLL(QUAD_DRIVER) OR IS_PED_RAGDOLL(INJURED_PED) cprState = CPR_INTERUPTED ELSE IF GET_SYNCHRONIZED_SCENE_PHASE(CPRSynchSceneID) > 0.99 CPRSynchSceneID = CREATE_SYNCHRONIZED_SCENE(vPos_CPRScene, vRot_CPRScene) TASK_SYNCHRONIZED_SCENE(QUAD_DRIVER, CPRSynchSceneID, "mini@cpr@char_a@cpr_str", "cpr_pumpchest", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, SYNCED_SCENE_USE_PHYSICS, RBF_NONE) TASK_SYNCHRONIZED_SCENE (INJURED_PED, CPRSynchSceneID, "mini@cpr@char_b@cpr_str", "cpr_pumpchest", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, SYNCED_SCENE_DONT_INTERRUPT, RBF_NONE) SET_SYNCHRONIZED_SCENE_LOOPED(CPRSynchSceneID, TRUE) cprState = CPR_IDLE ENDIF ENDIF IF HAS_PLAYER_THREATENED_THE_CPR_SCENE() IF GET_SYNCHRONIZED_SCENE_PHASE(CPRSynchSceneID) > 0.23 cprState = CPR_GETTING_UP ELSE OPEN_SEQUENCE_TASK(seq) TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1) TASK_SMART_FLEE_PED(NULL, PLAYER_PED_ID(), 80, -1) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(QUAD_DRIVER, seq) CLEAR_SEQUENCE_TASK(seq) IF IS_PED_UNINJURED(cprWatcher1) OPEN_SEQUENCE_TASK(seq) TASK_PAUSE(NULL, 200) TASK_SMART_FLEE_PED(NULL, PLAYER_PED_ID(), 80, -1) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(cprWatcher1, seq) CLEAR_SEQUENCE_TASK(seq) ENDIF IF IS_PED_UNINJURED(cprWatcher2) OPEN_SEQUENCE_TASK(seq) TASK_PAUSE(NULL, 500) TASK_SMART_FLEE_PED(NULL, PLAYER_PED_ID(), 80, -1) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(cprWatcher2, seq) CLEAR_SEQUENCE_TASK(seq) ENDIF cprState = CPR_FLEE ENDIF ENDIF ENDIF BREAK CASE CPR_IDLE IF IS_PED_UNINJURED(QUAD_DRIVER) AND IS_PED_UNINJURED(INJURED_PED) IF IS_PED_RAGDOLL(QUAD_DRIVER) OR IS_PED_RAGDOLL(INJURED_PED) cprState = CPR_INTERUPTED ELSE IF HAS_PLAYER_THREATENED_THE_CPR_SCENE() cprState = CPR_GETTING_UP ENDIF ENDIF ENDIF BREAK CASE CPR_GETTING_UP IF IS_PED_UNINJURED(QUAD_DRIVER) AND NOT IS_PED_FLEEING(QUAD_DRIVER) OPEN_SEQUENCE_TASK(seq) TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1) TASK_PLAY_ANIM(NULL, "rcmfanatic1", "KNEEL_EXIT", SLOW_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_EXIT_AFTER_INTERRUPTED) TASK_SMART_FLEE_PED(NULL, PLAYER_PED_ID(), 80, -1) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(QUAD_DRIVER, seq) CLEAR_SEQUENCE_TASK(seq) ENDIF IF IS_PED_UNINJURED(cprWatcher1) AND NOT IS_PED_FLEEING(cprWatcher1) OPEN_SEQUENCE_TASK(seq) TASK_PAUSE(NULL, 200) TASK_SMART_FLEE_PED(NULL, PLAYER_PED_ID(), 80, -1) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(cprWatcher1, seq) CLEAR_SEQUENCE_TASK(seq) ENDIF IF IS_PED_UNINJURED(cprWatcher2) AND NOT IS_PED_FLEEING(cprWatcher2) OPEN_SEQUENCE_TASK(seq) TASK_PAUSE(NULL, 500) TASK_SMART_FLEE_PED(NULL, PLAYER_PED_ID(), 80, -1) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(cprWatcher2, seq) CLEAR_SEQUENCE_TASK(seq) ENDIF IF IS_PED_UNINJURED(INJURED_PED) SET_ENTITY_HEALTH(INJURED_PED, 0) ENDIF cprState = CPR_FLEE BREAK CASE CPR_INTERUPTED IF IS_PED_UNINJURED(QUAD_DRIVER) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(QUAD_DRIVER, FALSE) OPEN_SEQUENCE_TASK(seq) IF NOT IS_PED_RAGDOLL(QUAD_DRIVER) TASK_PLAY_ANIM(NULL, "rcmfanatic1", "KNEEL_EXIT", SLOW_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_EXIT_AFTER_INTERRUPTED) ENDIF TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1) TASK_TURN_PED_TO_FACE_ENTITY(NULL, PLAYER_PED_ID(), 0) // TASK_PLAY_ANIM(NULL, "GESTURES@MALE", "HOW_COULD_YOU", NORMAL_BLEND_IN, SLOW_BLEND_OUT, -1, AF_UPPERBODY) TASK_LOOK_AT_ENTITY(NULL, INJURED_PED, -1) IF GET_DISTANCE_BETWEEN_ENTITIES(QUAD_DRIVER, INJURED_PED) > 2 TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, GET_ENTITY_COORDS(INJURED_PED), 1, DEFAULT_TIME_BEFORE_WARP, 1.5) ENDIF TASK_TURN_PED_TO_FACE_ENTITY(NULL, INJURED_PED, 0) TASK_USE_MOBILE_PHONE_TIMED(NULL, 10000) TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1) TASK_TURN_PED_TO_FACE_ENTITY(NULL, PLAYER_PED_ID(), -1) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(QUAD_DRIVER, seq) CLEAR_SEQUENCE_TASK(seq) ENDIF IF IS_PED_UNINJURED(cprWatcher1) STOP_ANIM_PLAYBACK(cprWatcher1, AF_PRIORITY_LOW) TASK_LOOK_AT_ENTITY(cprWatcher1, INJURED_PED, 2000) TASK_TURN_PED_TO_FACE_ENTITY(cprWatcher1, INJURED_PED) SAFE_RELEASE_PED(cprWatcher1) ENDIF IF IS_PED_UNINJURED(cprWatcher2) STOP_ANIM_PLAYBACK(cprWatcher2, AF_PRIORITY_LOW) TASK_LOOK_AT_ENTITY(cprWatcher2, INJURED_PED, 2000) TASK_TURN_PED_TO_FACE_ENTITY(cprWatcher2, INJURED_PED) SAFE_RELEASE_PED(cprWatcher2) ENDIF IF IS_PED_UNINJURED(INJURED_PED) SET_ENTITY_HEALTH(INJURED_PED, 0) ENDIF cprState = CPR_WATCHING_PLAYER BREAK CASE CPR_WATCHING_PLAYER IF IS_PED_UNINJURED(QUAD_DRIVER) if GET_SCRIPT_TASK_STATUS(QUAD_DRIVER, SCRIPT_TASK_DUCK) <> PERFORMING_TASK AND GET_SCRIPT_TASK_STATUS(QUAD_DRIVER, SCRIPT_TASK_DUCK) <> WAITING_TO_START_TASK AND IS_PED_RAGDOLL(QUAD_DRIVER) OPEN_SEQUENCE_TASK(seq) TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1) TASK_TURN_PED_TO_FACE_ENTITY(NULL, PLAYER_PED_ID(), 0) // TASK_PLAY_ANIM(NULL, "GESTURES@MALE", "HOW_COULD_YOU", NORMAL_BLEND_IN, SLOW_BLEND_OUT, -1, AF_UPPERBODY) TASK_LOOK_AT_ENTITY(NULL, INJURED_PED, -1) IF GET_DISTANCE_BETWEEN_ENTITIES(QUAD_DRIVER, INJURED_PED) > 2 TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, GET_ENTITY_COORDS(INJURED_PED), 1, DEFAULT_TIME_BEFORE_WARP, 1.5) ENDIF TASK_TURN_PED_TO_FACE_ENTITY(NULL, INJURED_PED, 0) TASK_USE_MOBILE_PHONE_TIMED(NULL, 10000) TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1) TASK_TURN_PED_TO_FACE_ENTITY(NULL, PLAYER_PED_ID(), -1) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(QUAD_DRIVER, seq) CLEAR_SEQUENCE_TASK(seq) ENDIF ENDIF IF HAS_PLAYER_THREATENED_THE_CPR_SCENE() IF IS_PED_UNINJURED(QUAD_DRIVER) AND NOT IS_PED_FLEEING(QUAD_DRIVER) TASK_SMART_FLEE_PED(QUAD_DRIVER, PLAYER_PED_ID(), 80, -1) ENDIF IF IS_PED_UNINJURED(cprWatcher1) AND NOT IS_PED_FLEEING(cprWatcher1) TASK_SMART_FLEE_PED(cprWatcher1, PLAYER_PED_ID(), 80, -1) ENDIF IF IS_PED_UNINJURED(cprWatcher2) AND NOT IS_PED_FLEEING(cprWatcher2) TASK_SMART_FLEE_PED(cprWatcher2, PLAYER_PED_ID(), 80, -1) ENDIF cprState = CPR_FLEE ENDIF BREAK CASE CPR_FLEE BREAK ENDSWITCH IF IS_PED_UNINJURED(cprWatcher1) and NOT IS_PED_FLEEING(cprWatcher1) IF IS_PED_RAGDOLL(cprWatcher1) CLEAR_PED_TASKS(cprWatcher1) SAFE_RELEASE_PED(cprWatcher1) ENDIF ENDIF IF IS_PED_UNINJURED(cprWatcher2) and NOT IS_PED_FLEEING(cprWatcher2) IF IS_PED_RAGDOLL(cprWatcher2) CLEAR_PED_TASKS(cprWatcher2) SAFE_RELEASE_PED(cprWatcher2) ENDIF ENDIF IF IS_PED_UNINJURED(INJURED_PED) ADD_SHOCKING_EVENT_FOR_ENTITY(EVENT_SHOCKING_DEAD_BODY, INJURED_PED, 1) ENDIF ENDPROC /// PURPOSE: Handle the two final jogging peds at the end of the final stretch of the race PROC DEAL_WITH_THE_TWO_FINAL_PEDS() // Use this function to check the first set of two joggers near the start and make them flee if the player bumps into them INT j FOR j = 0 TO 1 IF IS_PED_UNINJURED(OtherJoggers[j].thisIndex) AND IS_PED_RAGDOLL(OtherJoggers[j].thisIndex) CLEAR_PED_TASKS(OtherJoggers[j].thisIndex) OPEN_SEQUENCE_TASK(seq) IF GET_DISTANCE_BETWEEN_ENTITIES(OtherJoggers[j].thisIndex, PLAYER_PED_ID()) < GET_DISTANCE_BETWEEN_ENTITIES(OtherJoggers[j].thisIndex, MARY_ANN) TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1) TASK_TURN_PED_TO_FACE_ENTITY(NULL, PLAYER_PED_ID(), 0) ELSE TASK_LOOK_AT_ENTITY(NULL, MARY_ANN, -1) TASK_TURN_PED_TO_FACE_ENTITY(NULL, MARY_ANN, 0) ENDIF TASK_PAUSE(NULL, 3000) TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, OtherJoggers[j].thisGoToPos2, 0.7, DEFAULT_TIME_BEFORE_WARP, 1, ENAV_NO_STOPPING) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(OtherJoggers[j].thisIndex, seq) CLEAR_SEQUENCE_TASK(seq) ENDIF IF IS_ENTITY_ALIVE(OtherJoggers[j].thisIndex) IF IS_ENTITY_TOUCHING_ENTITY(PLAYER_PED_ID(), OtherJoggers[j].thisIndex) CLEAR_PED_TASKS(OtherJoggers[j].thisIndex) TASK_SMART_FLEE_PED(OtherJoggers[j].thisIndex, PLAYER_PED_ID(), 200, -1, TRUE) SAFE_RELEASE_PED(OtherJoggers[j].thisIndex) ENDIF ENDIF ENDFOR IF b_FinalPedsStartedWalking = FALSE IF iNum_PlayerClosestWaypoint > 114 IF IS_PED_UNINJURED(OtherJoggers[2].thisIndex) AND IS_PED_UNINJURED(OtherJoggers[3].thisIndex) INT k FOR k = 2 TO 3 OPEN_SEQUENCE_TASK(seq) TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, OtherJoggers[k].thisGoToPos1, 0.7, DEFAULT_TIME_BEFORE_WARP, 1, ENAV_NO_STOPPING) TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, OtherJoggers[k].thisGoToPos2, 0.7, DEFAULT_TIME_BEFORE_WARP, 1, ENAV_NO_STOPPING) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(OtherJoggers[k].thisIndex, seq) CLEAR_SEQUENCE_TASK(seq) ENDFOR TASK_LOOK_AT_ENTITY(OtherJoggers[2].thisIndex, OtherJoggers[3].thisIndex, -1) TASK_LOOK_AT_ENTITY(OtherJoggers[3].thisIndex, OtherJoggers[2].thisIndex, -1) ENDIF IF IS_PED_UNINJURED(BEACH_DOG) CLEAR_PED_TASKS(BEACH_DOG) ENDIF b_FinalPedsStartedWalking = TRUE ENDIF ELSE INT k FOR k = 2 TO 3 IF IS_PED_UNINJURED(OtherJoggers[k].thisIndex) AND IS_PED_RAGDOLL(OtherJoggers[k].thisIndex) CLEAR_PED_TASKS(OtherJoggers[k].thisIndex) OPEN_SEQUENCE_TASK(seq) IF GET_DISTANCE_BETWEEN_ENTITIES(OtherJoggers[k].thisIndex, PLAYER_PED_ID()) < GET_DISTANCE_BETWEEN_ENTITIES(OtherJoggers[k].thisIndex, MARY_ANN) TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1) TASK_TURN_PED_TO_FACE_ENTITY(NULL, PLAYER_PED_ID(), 0) ELSE TASK_LOOK_AT_ENTITY(NULL, MARY_ANN, -1) TASK_TURN_PED_TO_FACE_ENTITY(NULL, MARY_ANN, 0) ENDIF TASK_PAUSE(NULL, 3000) TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, OtherJoggers[k].thisGoToPos2, 0.7, DEFAULT_TIME_BEFORE_WARP, 1, ENAV_NO_STOPPING) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(OtherJoggers[k].thisIndex, seq) CLEAR_SEQUENCE_TASK(seq) ENDIF IF IS_ENTITY_ALIVE(OtherJoggers[k].thisIndex) IF IS_ENTITY_TOUCHING_ENTITY(PLAYER_PED_ID(), OtherJoggers[k].thisIndex) CLEAR_PED_TASKS(OtherJoggers[k].thisIndex) TASK_SMART_FLEE_PED(OtherJoggers[k].thisIndex, PLAYER_PED_ID(), 200, -1, TRUE) SAFE_RELEASE_PED(OtherJoggers[k].thisIndex) ENDIF ENDIF ENDFOR ENDIF ENDPROC /// PURPOSE: Handle the behaviour and events for the driveby fingering near the steps PROC UPDATE_DRIVEBY_FINGERING() IF IS_PED_UNINJURED(DRIVEBY_FINGER_CAR.Passenger) AND IS_VEHICLE_OK(DRIVEBY_FINGER_CAR.thisCarIndex) AND IS_PED_UNINJURED(DRIVEBY_FINGER_CAR.Driver) SWITCH driveByState CASE DRIVE_BY_LOAD IF LOAD_DRIVEBY() DEBUG_PRINTSTRING("Driveby scene resources loaded - progressing") driveByState = DRIVE_BY_PRE_TASK ENDIF BREAK CASE DRIVE_BY_PRE_TASK // Wait here until told to progress in ROAD_RUNNING_SECTION BREAK CASE DRIVE_BY_SET_DRIVE_TASK OPEN_SEQUENCE_TASK(seq) TASK_PAUSE(NULL, 1500) TASK_VEHICLE_DRIVE_TO_COORD(NULL, DRIVEBY_FINGER_CAR.thisCarIndex, DRIVEBY_FINGER_CAR.thisGoToPos, DRIVEBY_FINGER_CAR.thisSpeed, DRIVINGSTYLE_NORMAL, DRIVEBY_FINGER_CAR.thisCarModel, DF_SteerAroundPeds, 10, 10) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(DRIVEBY_FINGER_CAR.Driver, seq) CLEAR_SEQUENCE_TASK(seq) b_DrivebyHorn = FALSE driveByState = DRIVE_BY_DRIVE BREAK CASE DRIVE_BY_DRIVE IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(DRIVEBY_FINGER_CAR.thisCarIndex), GET_ENTITY_COORDS(MARY_ANN)) <= 45 IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() KILL_FACE_TO_FACE_CONVERSATION() ENDIF IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(DRIVEBY_FINGER_CAR.thisCarIndex), GET_ENTITY_COORDS(MARY_ANN)) <= 20 IF b_DrivebyHorn = FALSE START_VEHICLE_HORN(DRIVEBY_FINGER_CAR.thisCarIndex, 4500) IF IS_PED_UNINJURED(MARY_ANN) TASK_LOOK_AT_ENTITY(MARY_ANN, DRIVEBY_FINGER_CAR.thisCarIndex, 3000, SLF_WIDEST_PITCH_LIMIT|SLF_WIDEST_YAW_LIMIT|SLF_USE_TORSO) ENDIF b_DrivebyHorn = TRUE ENDIF IF MADialogueState = MA_WITHIN_TALKING_RANGE IF NOT IS_MESSAGE_BEING_DISPLAYED() IF CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", road2Conversation.rootLabel, CONV_PRIORITY_VERY_HIGH) road2Conversation.hasBeenPlayed = TRUE DEBUG_PRINTSTRING("Doing Mary Ann's anim...") TASK_PLAY_ANIM(MARY_ANN, "rcmfanatic1yell", "yell_d", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_UPPERBODY|AF_SECONDARY) driveByState = DRIVE_BY_SET_FINGER_TASK MADialogueState = MA_WITHIN_TALKING_RANGE IF MASprintState = SPRINT_ACTIVE MASprintState = SPRINT_REDUCE ENDIF ENDIF ENDIF ELSE IF CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", road2Conversation.rootLabel, CONV_PRIORITY_VERY_HIGH, DO_NOT_DISPLAY_SUBTITLES) road2Conversation.hasBeenPlayed = TRUE DEBUG_PRINTSTRING("Doing Mary Ann's anim...") TASK_PLAY_ANIM(MARY_ANN, "rcmfanatic1yell", "yell_d", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_UPPERBODY|AF_SECONDARY) driveByState = DRIVE_BY_SET_FINGER_TASK MADialogueState = MA_OUT_OF_TALKING_RANGE IF MASprintState = SPRINT_ACTIVE MASprintState = SPRINT_REDUCE ENDIF ENDIF ENDIF ENDIF ENDIF BREAK CASE DRIVE_BY_SET_FINGER_TASK CLEAR_PED_TASKS(DRIVEBY_FINGER_CAR.Driver) OPEN_SEQUENCE_TASK(seq) TASK_VEHICLE_DRIVE_WANDER(NULL, DRIVEBY_FINGER_CAR.thisCarIndex, 6, DF_SteerAroundPeds) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(DRIVEBY_FINGER_CAR.Driver, seq) CLEAR_SEQUENCE_TASK(seq) TASK_DRIVE_BY(DRIVEBY_FINGER_CAR.Passenger, MARY_ANN, NULL, <<0,0,0>>, 25, 100, FALSE, FIRING_PATTERN_FULL_AUTO) iOneLinerTimer = GET_GAME_TIMER() - 3000 // Reset the one-liner timer so there's a gap after Mary Ann finishes her above line driveByState = DRIVE_BY_FINGERING BREAK CASE DRIVE_BY_FINGERING IF IS_ENTITY_PLAYING_ANIM(MARY_ANN, "rcmfanatic1yell", "yell_d") IF GET_ENTITY_ANIM_CURRENT_TIME(MARY_ANN, "rcmfanatic1yell", "yell_d") > 0.44 CLEAR_PED_SECONDARY_TASK(MARY_ANN) iDrivebyTimer = GET_GAME_TIMER() driveByState = DRIVE_BY_RELEASE TURN_ROADS_ON() ENDIF ELSE // Just in case the anim doesn't play for some reason... iDrivebyTimer = GET_GAME_TIMER() driveByState = DRIVE_BY_RELEASE TURN_ROADS_ON() ENDIF BREAK CASE DRIVE_BY_RELEASE IF (GET_GAME_TIMER() - iDrivebyTimer) > 3000 IF IS_PED_UNINJURED(DRIVEBY_FINGER_CAR.Driver) IF IS_VEHICLE_OK(DRIVEBY_FINGER_CAR.thisCarIndex) // IF IS_PED_UNINJURED(DRIVEBY_FINGER_CAR.Passenger) // CLEAR_PED_TASKS(DRIVEBY_FINGER_CAR.Passenger) // ENDIF CLEAR_PED_TASKS(DRIVEBY_FINGER_CAR.Driver) CLEAR_PED_SECONDARY_TASK(DRIVEBY_FINGER_CAR.Driver) TASK_VEHICLE_DRIVE_WANDER(DRIVEBY_FINGER_CAR.Driver, DRIVEBY_FINGER_CAR.thisCarIndex, 15, DF_SteerAroundPeds | DRIVINGMODE_AVOIDCARS_OBEYLIGHTS) SET_PED_KEEP_TASK(DRIVEBY_FINGER_CAR.Driver, TRUE) SAFE_RELEASE_PED(DRIVEBY_FINGER_CAR.Driver) SAFE_RELEASE_VEHICLE(DRIVEBY_FINGER_CAR.thisCarIndex) ENDIF ENDIF SAFE_RELEASE_PED(DRIVEBY_FINGER_CAR.Passenger) SAFE_RELEASE_PED(FOLLOWING_CAR.Driver) IF IS_PED_UNINJURED(FOLLOWING_CAR.Passenger) DEBUG_PRINTSTRING("*** Clearing driveby task and releasing") CLEAR_PED_TASKS(FOLLOWING_CAR.Passenger) SAFE_RELEASE_PED(FOLLOWING_CAR.Passenger, TRUE) ENDIF SAFE_RELEASE_VEHICLE(FOLLOWING_CAR.thisCarIndex) ENDIF BREAK ENDSWITCH ENDIF ENDPROC /// PURPOSE: /// Manages the playback of the dynamic heartbeat audio during the mission PROC DEAL_WITH_HEARTBEAT_AUDIO() IF NOT bHeartbeatStarted IF iCURRENT_RACE_POS > 3 PLAY_SOUND_FRONTEND(iHeartbeatAudioID, "HEARTBEAT", "FANATIC_SOUNDSET") bHeartbeatStarted = TRUE ENDIF ENDIF ENDPROC SEQUENCE_INDEX seq_michael PROC DEAL_WITH_MICHAEL_OUT_OF_BREATH() ANIM_DATA none IF b_DoneOutOfBreath = FALSE IF GET_SCRIPT_TASK_STATUS(PLAYER_PED_ID(), SCRIPT_TASK_PERFORM_SEQUENCE) != PERFORMING_TASK AND GET_SCRIPT_TASK_STATUS(PLAYER_PED_ID(), SCRIPT_TASK_PERFORM_SEQUENCE) != WAITING_TO_START_TASK OPEN_SEQUENCE_TASK(seq_michael) TASK_SCRIPTED_ANIMATION(NULL, adBreathEnter, none, none) TASK_SCRIPTED_ANIMATION(NULL, adBreathIdle1, none, none) TASK_SCRIPTED_ANIMATION(NULL, adBreathIdle2, none, none) TASK_SCRIPTED_ANIMATION(NULL, adBreathIdle3, none, none) // TASK_PLAY_ANIM(NULL, "rcmfanatic1out_of_breath", "p_zero_tired_enter", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_SECONDARY|AF_UPPERBODY|AF_PRIORITY_MEDIUM) // TASK_PLAY_ANIM(NULL, "rcmfanatic1out_of_breath", "p_zero_tired_01", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_SECONDARY|AF_UPPERBODY|AF_PRIORITY_MEDIUM) // TASK_PLAY_ANIM(NULL, "rcmfanatic1out_of_breath", "p_zero_tired_02", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_SECONDARY|AF_UPPERBODY|AF_PRIORITY_MEDIUM) // TASK_PLAY_ANIM(NULL, "rcmfanatic1out_of_breath", "p_zero_tired_01", NORMAL_BLEND_IN, SLOW_BLEND_OUT, -1, AF_SECONDARY|AF_UPPERBODY|AF_LOOPING|AF_PRIORITY_MEDIUM) CLOSE_SEQUENCE_TASK(seq_michael) TASK_PERFORM_SEQUENCE(PLAYER_PED_ID(), seq_michael) //SET_ANIM_FILTER(PLAYER_PED_ID(), "UpperbodyFeathered_NoLeftArm_filter" , AF_PRIORITY_MEDIUM, TRUE) DEBUG_PRINTSTRING("Starting out of breath anim loop") b_DoneOutOfBreath = TRUE CLEAR_SEQUENCE_TASK(seq_michael) ENDIF ELSE //SET_ANIM_FILTER(PLAYER_PED_ID(), "UpperbodyFeathered_NoLeftArm_filter" , AF_PRIORITY_MEDIUM, TRUE) IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), MAS_BIKE, TRUE) IF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "rcmfanatic1out_of_breath", "p_zero_tired_enter") OR IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "rcmfanatic1out_of_breath", "p_zero_tired_01") OR IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "rcmfanatic1out_of_breath", "p_zero_tired_02") CLEAR_PED_TASKS(PLAYER_PED_ID()) ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: /// Make Mary Ann continually face the player if she's playing her "jogging_on_spot" animation PROC DEAL_WITH_MARY_ANN_FACING_PLAYER() IF IS_ENTITY_ALIVE(MARY_ANN) IF IS_ENTITY_PLAYING_ANIM(MARY_ANN, "rcmfanatic1", "jogging_on_spot") // MATHS VECTOR n VECTOR b = NORMALISE_VECTOR(GET_ENTITY_COORDS(PLAYER_PED_ID()) - GET_ENTITY_COORDS(MARY_ANN)) VECTOR a = GET_ENTITY_FORWARD_VECTOR(MARY_ANN) FLOAT t = 0.25 // AARON IS A FUCKING MATHS WIZARD n = a + ((b - a) * t) SET_ENTITY_HEADING(MARY_ANN, GET_HEADING_FROM_COORDS(<<0, 0, 0>>, n)) ENDIF ENDIF ENDPROC /// PURPOSE: Handle things if the player decides to jack a vehicle during the race PROC STAGE_PLAYER_IN_VEHICLE() SWITCH stageStage CASE SS_SETUP DEBUG_PRINTSTRING("SETUP PLAYER IN VEHICLE STATE") IF IS_SCRIPTED_CONVERSATION_ONGOING() PAUSE_SCRIPTED_CONVERSATION(FALSE) ENDIF IF DOES_BLIP_EXIST(DESTINATION_BLIP) SET_BLIP_ALPHA(DESTINATION_BLIP, 0) ENDIF CLEAR_PRINTS() IF IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_PED(MARY_ANN) WAYPOINT_PLAYBACK_PAUSE(MARY_ANN, TRUE) ENDIF TASK_FOLLOW_TO_OFFSET_OF_ENTITY(MARY_ANN, PLAYER_PED_ID(), <<0,0,0>>, 3, -1, 3) iVehicleFailTimer = GET_GAME_TIMER() IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() DEBUG_PRINTSTRING("stop scripted conversation at STAGE_PLAYER_IN_VEHICLE") KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() ENDIF bMARY_ANN_CHASING_YOU_IN_CAR = TRUE DEBUG_PRINTSTRING("STARTING PLAYER IN VEHICLE LOOP") stageStage = SS_STAGE BREAK CASE SS_STAGE IF bMARY_ANN_CHASING_YOU_IN_CAR IF GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), MARY_ANN) < 4 CLEAR_PED_TASKS(MARY_ANN) TASK_TURN_PED_TO_FACE_ENTITY(MARY_ANN, PLAYER_PED_ID(), -1) bMARY_ANN_CHASING_YOU_IN_CAR = FALSE ENDIF ELSE IF GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), MARY_ANN) > 5 CLEAR_PED_TASKS(MARY_ANN) TASK_FOLLOW_TO_OFFSET_OF_ENTITY(MARY_ANN, PLAYER_PED_ID(), <<0,0,0>>, 3, -1, 3) bMARY_ANN_CHASING_YOU_IN_CAR = TRUE ENDIF ENDIF IF (GET_GAME_TIMER() - iVehicleFailTimer) > 4000 TRIGGER_MUSIC_EVENT("RC6A_FAIL") failReason = FAIL_IN_CAR stageStage = SS_SETUP missionstage = MS_FAIL_WAIT_FOR_FADE ENDIF IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) CLEAR_PRINTS() IF NOT IS_STRING_NULL(sFANATIC_ROUTE) IF GET_IS_WAYPOINT_RECORDING_LOADED(sFANATIC_ROUTE) OPEN_SEQUENCE_TASK(seq) TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1, SLF_DEFAULT) TASK_FOLLOW_NAV_MESH_TO_COORD(null, GET_COORD_FURTHER_ALONG_ROUTE(), 3) TASK_FOLLOW_WAYPOINT_RECORDING(NULL, sFANATIC_ROUTE, GET_MARY_ANNS_NEXT_WAYPOINT(), EWAYPOINT_DEFAULT | EWAYPOINT_VEHICLES_USE_AI_SLOWDOWN | EWAYPOINT_ALLOW_STEERING_AROUND_PEDS, -1) TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1) TASK_PLAY_ANIM(null, "move_f@runner", "idle", SLOW_BLEND_IN, SLOW_BLEND_OUT, -1, AF_LOOPING) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(MARY_ANN, seq) CLEAR_SEQUENCE_TASK(seq) ENDIF ENDIF stageStage = SS_STAGE missionStage = currentMissionStage IF DOES_BLIP_EXIST(DESTINATION_BLIP) SET_BLIP_ALPHA(DESTINATION_BLIP, 255) ENDIF RESTART_SCRIPTED_CONVERSATION() ENDIF BREAK ENDSWITCH ENDPROC /// PURPOSE: Check if the player has skipped a checkpoint, and return true if the distance between them is over the distance passed in FUNC BOOL PLAYER_SKIPPED_CHECKPOINT(FLOAT distance) IF iCURRENT_RACE_POS < iMaxRacePositions - 1 INT closestWaypointToBlip WAYPOINT_RECORDING_GET_CLOSEST_WAYPOINT(sFANATIC_ROUTE, RACE_POSITIONS[iCURRENT_RACE_POS], closestWaypointToBlip) if closestWaypointToBlip < iNum_PlayerClosestWaypoint IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), RACE_POSITIONS[iCURRENT_RACE_POS]) > distance RETURN TRUE ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: Check if the player has abandoned the race route by a significant margin, or if the distance between them and Mary Ann /// has gotten too great PROC CHECK_IF_PLAYER_LEFT_THE_COURSE_OR_MARY_ANN() // THIS CHECKS IF YOU LEAVE THE ROUTE BY DISTANCE CHECKING THE CLOSEST POINT ON THE WAYPOINT REC // OR IF THE PLAYER RUNS PAST A CHECKPOINT AND CONTINUES ON THE COURSE IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), vPos_PlayerClosestWaypoint) > 60 OR PLAYER_SKIPPED_CHECKPOINT(60) TRIGGER_MUSIC_EVENT("RC6A_FAIL") failReason = FAIL_LEFT_RACE stageStage = SS_SETUP missionstage = MS_FAIL_WAIT_FOR_FADE ELSE IF leftRaceWarning.hasBeenShown = FALSE IF NOT IS_THIS_PRINT_BEING_DISPLAYED(leftBehindWarning.textLabel) IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), vPos_PlayerClosestWaypoint) > 40 OR PLAYER_SKIPPED_CHECKPOINT(40) IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() DEBUG_PRINTSTRING("stop scripted conversation at CHECK_IF_PLAYER_LEFT_THE_COURSE_OR_MARY_ANN") KILL_ANY_CONVERSATION() ENDIF CLEAR_PRINTS() PRINT(leftRaceWarning.textLabel, DEFAULT_GOD_TEXT_TIME, 1) //Return to the ~y~race. leftRaceWarning.hasBeenShown = TRUE ENDIF ENDIF ENDIF ENDIF // IF THE PLAYER IS BEHIND MARY ANN CHECK HOW FAR IF iNum_PlayerClosestWaypoint < iNum_NPCClosestWaypoint IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(MARY_ANN)) > 70 TRIGGER_MUSIC_EVENT("RC6A_FAIL") failReason = FAIL_YOU_DIDNT_KEEP_UP stageStage = SS_SETUP missionstage = MS_FAIL_WAIT_FOR_FADE ELIF leftBehindWarning.hasBeenShown = FALSE AND NOT IS_THIS_PRINT_BEING_DISPLAYED(leftRaceWarning.textLabel) IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(MARY_ANN)) > 50 PRINT_NOW(leftBehindWarning.textLabel, DEFAULT_GOD_TEXT_TIME, 1) //Catch up with ~b~Mary Ann. leftBehindWarning.hasBeenShown = TRUE ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: Check if the player has got into a vehicle during the mission PROC CHECK_IF_PLAYER_IS_IN_A_VEHICLE() IF missionStage <> MS_PLAYER_IN_VEHICLE AND missionStage <> MS_FAIL_WAIT_FOR_FADE AND missionStage <> MS_END_CUTSCENE AND missionStage <> MS_FAIL_WAIT_FOR_FADE AND missionStage <> MS_LOST_RACE IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) IF vehicleWarning.hasBeenShown = FALSE PRINT_HELP(vehicleWarning.textLabel) vehicleWarning.hasBeenShown = TRUE ENDIF IF CAN_PED_SEE_PLAYER(MARY_ANN) OR GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), MARY_ANN) < 7 currentMissionStage = missionstage stageStage = SS_SETUP missionStage = MS_PLAYER_IN_VEHICLE ENDIF ENDIF ELIF missionStage = MS_END_CUTSCENE // If we're in here, this is being called from END_CUTSCENE() and we need to check for the player dicking about during the unscripted scene IF cutsceneStage <> CS_CUTSCENE_ENDS IF IS_VEHICLE_OK(MAS_BIKE) IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), MAS_BIKE) b_PlayerOnMAsBike = TRUE // IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() // KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() // ENDIF // IF PLAY_SINGLE_LINE_FROM_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_AGGRO", "FAN1_AGGRO_1", CONV_PRIORITY_VERY_HIGH) // CLEAR_PED_TASKS(MARY_ANN) // TASK_SMART_FLEE_PED(MARY_ANN, PLAYER_PED_ID(), 150, -1) // cutsceneStage = CS_CUTSCENE_ENDS // ENDIF ENDIF ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: /// Checks for Michael bumping into anyone and plays an appropriate line of dialogue if possible PROC CHECK_PLAYER_COLLISIONS() IF HAS_ENTITY_COLLIDED_WITH_ANYTHING(PLAYER_PED_ID()) PED_INDEX ped[32] IF GET_PED_NEARBY_PEDS(PLAYER_PED_ID(), ped) > 0 // If the ped index exists, the player probably bumped into a ped rather than an object or whatever IF DOES_ENTITY_EXIST(ped[0]) AND NOT IS_ENTITY_DEAD(ped[0]) IF IS_ENTITY_TOUCHING_ENTITY(PLAYER_PED_ID(), ped[0]) // Do different things depending on whether the ped is Mary Ann or an ambient civvie IF ped[0] = MARY_ANN DEBUG_PRINTSTRING("Player touched Mary Ann!") if not IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF MikePushMALine.timesPlayed <= 3 IF CAN_MARY_ANN_SAY_RANDOM_LINE(MikePushMALine.dialogueLine) DEBUG_PRINTSI("Saying MikePushMALine #", MikePushMALine.timesPlayed) MikePushMALine.timesPlayed++ ENDIF ENDIF ENDIF ELSE DEBUG_PRINTSTRING("Player touched a civ!") IF NOT IS_PED_IN_ANY_VEHICLE(ped[0]) // Ignore if in a vehicle, otherwise it asserts... // We can't do this to Mary Ann very easily, but we can for civvies without causing horribleness! IF NOT IS_PED_RAGDOLL(ped[0]) CLEAR_PED_TASKS(ped[0]) SET_PED_TO_RAGDOLL(ped[0], 800, 1500, TASK_NM_BALANCE) VECTOR pushDir = -GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(PLAYER_PED_ID(), GET_ENTITY_COORDS(ped[0])) APPLY_FORCE_TO_ENTITY(ped[0], APPLY_TYPE_IMPULSE, pushDir, <<0,0,0>>, GET_PED_RAGDOLL_BONE_INDEX(ped[0], RAGDOLL_SPINE), FALSE, FALSE, TRUE) ENDIF if not IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF MikePushPedLine.timesPlayed <= 3 IF CAN_MARY_ANN_SAY_RANDOM_LINE(MikePushPedLine.dialogueLine) DEBUG_PRINTSI("Said MikePushPedLine #", MikePushPedLine.timesPlayed) MikePushPedLine.timesPlayed++ ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: /// If the player's just overtaken Mary Ann, make her try and say an overtake line if possible PROC TRY_OVERTAKE_LINE() IF bOvertaken = TRUE AND (GET_GAME_TIMER() - iOvertakeTimer) < 1500 // If it's been less than 1.5s since we overtook Mary Ann, do the line if not IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF OvertakeLines.timesPlayed <= 3 IF bOvertakenSkip = FALSE IF CAN_MARY_ANN_SAY_RANDOM_LINE(OvertakeLines.dialogueLine) DEBUG_PRINTSI("Said OvertakeLines #", OvertakeLines.timesPlayed) OvertakeLines.timesPlayed++ bOvertaken = FALSE bOvertakenSkip = true // Skip the next time we overtake to reduce frequency of dialogue (B*1416011) iOvertakeTimer = GET_GAME_TIMER() // Make sure we can't keep playing the overtake line over and over ENDIF ELSE bOvertakenSkip = FALSE bOvertaken = FALSE iOvertakeTimer = GET_GAME_TIMER() ENDIF ELSE bOvertaken = FALSE iOvertakeTimer = GET_GAME_TIMER() ENDIF ELSE bOvertaken = FALSE iOvertakeTimer = GET_GAME_TIMER() ENDIF ELSE IF bOvertaken = TRUE // Only do this reset if necessary! (or it keeps resetting the timer and we never get any overtake lines...) bOvertaken = FALSE iOvertakeTimer = GET_GAME_TIMER() ENDIF ENDIF ENDPROC /// PURPOSE: Check if the player has threatened, injured or killed Mary Ann PROC CHECK_IF_MARY_ANN_IS_INJURED_KILLED_OR_SCARED() IF IS_ENTITY_DEAD(MARY_ANN) IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() DEBUG_PRINTSTRING("stop scripted conversation at CHECK_IF_MARY_ANN_IS_INJURED_KILLED_OR_SCARED 1") KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() ENDIF DEBUG_PRINTSTRING("Mary Ann killed") TRIGGER_MUSIC_EVENT("RC6A_FAIL") failReason = FAIL_FANATIC_KILLED stageStage = SS_SETUP missionstage = MS_FAIL_WAIT_FOR_FADE ELSE IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(MARY_ANN, PLAYER_PED_ID()) IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() DEBUG_PRINTSTRING("stop scripted conversation at CHECK_IF_MARY_ANN_IS_INJURED_KILLED_OR_SCARED 2") KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() ENDIF DEBUG_PRINTSTRING("Mary Ann injured by player") TRIGGER_MUSIC_EVENT("RC6A_FAIL") failReason = FAIL_FANATIC_INJURED stageStage = SS_SETUP missionstage = MS_FAIL_WAIT_FOR_FADE ENDIF IF HAS_PED_BEEN_DAMAGED_BY_WEAPON(MARY_ANN, WEAPONTYPE_INVALID, GENERALWEAPON_TYPE_ANYWEAPON) IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() DEBUG_PRINTSTRING("stop scripted conversation at CHECK_IF_MARY_ANN_IS_INJURED_KILLED_OR_SCARED 3") KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() ENDIF DEBUG_PRINTSTRING("Mary Ann injured by some form of weapon") TRIGGER_MUSIC_EVENT("RC6A_FAIL") failReason = FAIL_FANATIC_INJURED stageStage = SS_SETUP missionstage = MS_FAIL_WAIT_FOR_FADE ENDIF ENDIF IF bMARY_ANN_IS_GOING_TO_RUN_SCARED = TRUE DEBUG_PRINTSTRING("Mary Ann scared") IF IS_ENTITY_ALIVE(MARY_ANN) CLEAR_PED_TASKS(MARY_ANN) ENDIF TRIGGER_MUSIC_EVENT("RC6A_FAIL") failReason = FAIL_FANATIC_SCARED stageStage = SS_SETUP missionstage = MS_FAIL_WAIT_FOR_FADE ELSE IF IS_ENTITY_ALIVE(MARY_ANN) IF IS_PLAYER_SHOOTING_NEAR_PED(MARY_ANN) OR HAS_PLAYER_THREATENED_PED(MARY_ANN) OR IS_BULLET_IN_AREA(GET_ENTITY_COORDS(MARY_ANN), 10, FALSE) IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() DEBUG_PRINTSTRING("Killing any convo before scared convo") KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() ENDIF bMARY_ANN_IS_GOING_TO_RUN_SCARED = TRUE ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: Check if Mary Ann has beaten the player to the finish line PROC CHECK_IF_MARY_ANN_WINS_RACE() IF missionStage <> MS_LOST_RACE // Don't want to keep resetting the Lost Race state once it's been triggered! AND missionStage <> MS_FAIL_WAIT_FOR_FADE IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(MARY_ANN, vPos_FinishLine) < 3 DEBUG_PRINTSTRING("Detected Mary Ann won race") failReason = FAIL_SHE_BEAT_YOU_TO_BIKE stageStage = SS_SETUP missionstage = MS_LOST_RACE ENDIF ENDIF ENDPROC /// PURPOSE: Check for all fail possibilities during the mission PROC CHECK_FAIL_POSSIBILITIES() IF ENUM_TO_INT(missionStage) <> ENUM_TO_INT(MS_END_CUTSCENE) AND ENUM_TO_INT(missionStage) <> ENUM_TO_INT(MS_FAIL_WAIT_FOR_FADE) AND ENUM_TO_INT(missionStage) > ENUM_TO_INT(MS_CUTSCENE) IF DOES_ENTITY_EXIST(MARY_ANN) CHECK_IF_MARY_ANN_IS_INJURED_KILLED_OR_SCARED() CHECK_IF_PLAYER_IS_IN_A_VEHICLE() DETERMINE_CLOSEST_WAYPOINTS() CHECK_IF_PLAYER_LEFT_THE_COURSE_OR_MARY_ANN() CHECK_IF_MARY_ANN_WINS_RACE() ENDIF ENDIF ENDPROC PROC CLEAR_RACE_ROUTE_OF_VEHICLES() IF GET_IS_WAYPOINT_RECORDING_LOADED(sFANATIC_ROUTE) INT iMaxPoints = 0 WAYPOINT_RECORDING_GET_NUM_POINTS(sFANATIC_ROUTE, iMaxPoints) INT i = 0 FOR i = 0 to iMaxPoints VECTOR vNewCoord = <<0,0,0>> WAYPOINT_RECORDING_GET_COORD(sFANATIC_ROUTE, i, vNewCoord) CLEAR_AREA_OF_VEHICLES(vNewCoord, 4) DEBUG_PRINTSI("Clearing area around waypoint", i) ENDFOR ENDIF ENDPROC //PURPOSE: general cutscene setup PROC GO_TO_CUTSCENE() camCutsceneStart = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", TRUE) SET_CAM_PARAMS(camCutsceneStart,<<-2006.4041, -505.1258, 12.1679>>, <<-8.4110, 0.0000, -152.3152>>, 50)//<<-2004.4519, -496.6223, 12.3469>>, << -11.3454, -0.0000, -160.9836 >>, 50) RENDER_SCRIPT_CAMS(TRUE, FALSE) SET_CAM_ACTIVE(camCutsceneStart, TRUE) ENDPROC //PURPOSE: Once Mary Ann reaches this position the next stage of the race begins FUNC BOOL RACE_LEG_FINISHED(VECTOR pos) IF IS_ENTITY_AT_COORD(MARY_ANN, pos, <<3,3,2>>) RETURN TRUE ENDIF return FALSE ENDFUNC /// PURPOSE: /// Handles whether the player needs to see the global stamina help message low on stamina. B*1416022. PROC HANDLE_GLOBAL_STAMINA_HELP() IF NOT g_savedGlobals.sRandomChars.g_bFanaticStamina IF GET_PLAYER_SPRINT_TIME_REMAINING(PLAYER_ID()) <= 5.0 IF NOT IS_HELP_MESSAGE_BEING_DISPLAYED() PRINT_HELP("AM_H_NOSTAM") g_savedGlobals.sRandomChars.g_bFanaticStamina = TRUE ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: Initialise some basic elements of the mission such as the Z-skip list, the race checkpoints, and environment settings PROC INIT() CLEAR_PRINTS() DEBUG_PRINTSTRING("IN INIT") #IF IS_DEBUG_BUILD s_skip_menu[0].sTxtLabel = "INTRO CUTSCENE" s_skip_menu[1].sTxtLabel = "START THE RUN" s_skip_menu[2].sTxtLabel = "RUNNING ON ROAD" s_skip_menu[3].sTxtLabel = "RUNNING DOWN STEPS" s_skip_menu[4].sTxtLabel = "RACE TO THE FINISH" s_skip_menu[5].sTxtLabel = "END OF RACE" s_skip_menu[6].sTxtLabel = "***DEBUG: Next to finish line" #ENDIF sFANATIC_ROUTE = "Fanatic1MaryAnn" // CLEARS THE ROUTE OF VEHICLES, IN CASE PLAYER HAS DROPPED ANY CLEAR_ANGLED_AREA_OF_VEHICLES(<<-1877.022217,-439.566315,47.061394>>, <<-1809.614868,-493.493958,39.585079>>, 12.750000, TRUE) CLEAR_ANGLED_AREA_OF_VEHICLES(<<-1816.865234,-492.408051,42.839161>>, <<-1792.158447,-470.209503,38.512688>>, 12.750000, TRUE) CLEAR_ANGLED_AREA_OF_VEHICLES(<<-1792.193726,-470.231934,42.514709>>, <<-1726.926392,-552.837463,35.241489>>, 12.750000, TRUE) CLEAR_ANGLED_AREA_OF_VEHICLES(<<-1728.023682,-561.872070,39.497372>>, <<-1835.284546,-514.933289,26.335573>>, 19.750000, TRUE) CLEAR_ANGLED_AREA_OF_VEHICLES(<<-1822.225586,-535.309204,31.955553>>, <<-1890.278320,-616.276367,9.657555>>, 39.750000, TRUE) CLEAR_ANGLED_AREA_OF_VEHICLES(<<-1867.242798,-622.763000,13.383512>>, <<-2013.266968,-497.979950,9.736394>>, 23.750000, TRUE) REMOVE_RELATIONSHIP_GROUP(relGroupFriendly) ADD_RELATIONSHIP_GROUP("FRIENDLIES", relGroupFriendly) SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, relGroupFriendly, RELGROUPHASH_PLAYER) SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, RELGROUPHASH_PLAYER, relGroupFriendly) ADD_PED_FOR_DIALOGUE(MyLocalPedStruct, 0, PLAYER_PED_ID(), "MICHAEL") LOAD_OTHER_ASSETS() //SET_PLAYER_HAS_CHANGE_CLOTHES_ON_MISSION(CHAR_MICHAEL) IF IS_ENTITY_ALIVE(MARY_ANN) SET_PED_RELATIONSHIP_GROUP_HASH(MARY_ANN, relGroupFriendly) SET_PED_SEEING_RANGE(MARY_ANN, 25.0) SET_PED_MOVEMENT_CLIPSET(MARY_ANN, "FEMALE_FAST_RUNNER") ENDIF CLEAR_RACE_ROUTE_OF_VEHICLES() CREATE_CARS() //UNLOAD_ALL_MODELS() TURN_ROADS_ON(FALSE) sbiWallPeds = ADD_SCENARIO_BLOCKING_AREA(<<-1979.0620, -534.3250, 10.4558>>, <<-1973.3320, -528.2116, 13.7014>>) sbiPathPeds = ADD_SCENARIO_BLOCKING_AREA(<<-1914.7804, -591.1177, 9.8302>>, <<-1910.3289, -586.7218, 12.0195>>) sbiMobilePed = ADD_SCENARIO_BLOCKING_AREA(<<-1991.0669, -523.5920, 10.4269>>, <<-1989.1447, -521.6824, 11.3735>>) adBreathEnter.type = APT_SINGLE_ANIM adBreathEnter.dictionary0 = "rcmfanatic1out_of_breath" adBreathEnter.anim0 = "p_zero_tired_enter" adBreathEnter.blendInDelta = REALLY_SLOW_BLEND_IN adBreathEnter.blendOutDelta = NORMAL_BLEND_OUT adBreathEnter.flags = AF_SECONDARY|AF_UPPERBODY adBreathEnter.filter = GET_HASH_KEY("UpperbodyFeathered_NoLefttArm_filter") adBreathIdle1.type = APT_SINGLE_ANIM adBreathIdle1.dictionary0 = "rcmfanatic1out_of_breath" adBreathIdle1.anim0 = "p_zero_tired_01" adBreathIdle1.blendInDelta = NORMAL_BLEND_IN adBreathIdle1.blendOutDelta = NORMAL_BLEND_OUT adBreathIdle1.flags = AF_SECONDARY|AF_UPPERBODY adBreathIdle1.filter = GET_HASH_KEY("UpperbodyFeathered_NoLefttArm_filter") adBreathIdle2.type = APT_SINGLE_ANIM adBreathIdle2.dictionary0 = "rcmfanatic1out_of_breath" adBreathIdle2.anim0 = "p_zero_tired_02" adBreathIdle2.blendInDelta = NORMAL_BLEND_IN adBreathIdle2.blendOutDelta = NORMAL_BLEND_OUT adBreathIdle2.flags = AF_SECONDARY|AF_UPPERBODY adBreathIdle2.filter = GET_HASH_KEY("UpperbodyFeathered_NoLefttArm_filter") adBreathIdle3.type = APT_SINGLE_ANIM adBreathIdle3.dictionary0 = "rcmfanatic1out_of_breath" adBreathIdle3.anim0 = "p_zero_tired_01" adBreathIdle3.blendInDelta = NORMAL_BLEND_IN adBreathIdle3.blendOutDelta = INSTANT_BLEND_OUT adBreathIdle3.flags = AF_SECONDARY|AF_UPPERBODY|AF_LOOPING adBreathIdle3.filter = GET_HASH_KEY("UpperbodyFeathered_NoLefttArm_filter") vPos_StartOfRoadRunning = <<-1730.2838, -551.7269, 36.3939>> vPos_StartOfBeachRunning = <<-1870.6702, -616.2423, 10.8184>> WAYPOINT_RECORDING_GET_NUM_POINTS(sFANATIC_ROUTE, iNum_WAYPOINTS) RACE_POSITIONS[0] = <<-1868.36, -447.84, 45.20>> RACE_POSITIONS[1] = <<-1835.81, -468.73, 43.45>> RACE_POSITIONS[2] = <<-1753.45, -523.30, 37.35>> RACE_POSITIONS[3] = vPos_StartOfRoadRunning RACE_POSITIONS[4] = <<-1755.65, -558.99, 36.11>> RACE_POSITIONS[5] = <<-1828.99, -516.33, 27.87>> // CLOSEST TO STEPS RACE_POSITIONS[6] = <<-1819.20, -555.86, 15.77>> RACE_POSITIONS[7] = vPos_StartOfBeachRunning RACE_POSITIONS[8] = <<-1918.04, -583.45, 10.76>> RACE_POSITIONS[9] = vPos_FinishLine iMaxRacePositions = COUNT_OF(RACE_POSITIONS) HURRY_UP_LINE[0] = "FAN1_FALLB_1" HURRY_UP_LINE[1] = "FAN1_FALLB_2" RACE_LINE[0] = "FAN1_FAST_1" RACE_LINE[1] = "FAN1_FAST_2" RACE_LINE[2] = "FAN1_FAST_3" MikePushMALine.dialogueLine = "FAN1_RUNIN" MikePushPedLine.dialogueLine = "FAN1_RUNIN2" OvertakeLines.dialogueLine = "FAN1_OVERT" pushLine[0].dialogueLine = "FAN1_PUSH_1" pushLine[1].dialogueLine = "FAN1_PUSH_2" pushLine[2].dialogueLine = "FAN1_PUSH_3" cheatedLeaptFence.dialogueLine = "FAN1_CHEAT_1" cheatedLeaptFence.rootLabel = "FAN1_CHEAT" cheatedRanAcrossGrass.dialogueLine = "FAN1_CHEAT_2" cheatedRanAcrossGrass.rootLabel = "FAN1_CHEAT" returnAfterCheatedLine.dialogueLine = "FAN1_CATCHC_1" returnAfterCheatedLine.rootLabel = "FAN1_CATCHC" IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) IF IS_OUTFIT_SUITABLE_FOR_FANATIC_MISSION(1) startRunConversation.rootLabel = "FAN1_STRTB" raceConversation.rootLabel = "FAN1_BCHB" ELSE startRunConversation.rootLabel = "FAN1_STRTA" raceConversation.rootLabel = "FAN1_BCHA" ENDIF ENDIF road1Conversation.rootLabel = "FAN1_RD1" road2Conversation.rootLabel = "FAN1_RD2" leftRaceWarning.textLabel = "FATIC1_7" leftBehindWarning.textLabel = "FATIC1_6" vehicleWarning.textLabel = "FATIC1_H" DEBUG_PRINTSTRING("end of init") ENDPROC /// PURPOSE: /// Main state for doing the lead-in PROC LEADIN() // Disable controls and exit current vehicle RC_PLAYER_TRIGGER_SCENE_LOCK_IN() SWITCH stageStage CASE SS_SETUP IF NOT Is_Replay_In_Progress() IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), MARY_ANN) <= 1.2 // Kill the leadin convo early if it's started IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() ENDIF DEBUG_PRINTSTRING("Player too close to Mary Ann, starting cutscene early") stageStage = SS_SETUP missionStage = MS_CUTSCENE ENDIF IF NOT IS_GAMEPLAY_HINT_ACTIVE() SET_GAMEPLAY_ENTITY_HINT(MARY_ANN, <<0,0,0>>, TRUE, 30000) 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 REQUEST_ANIM_DICT("rcmfanatic1") // Check for the anim dict being loaded, then if Mary Ann is in an early phase of her idle loop, then try to do the lead in convo and anims... IF HAS_ANIM_DICT_LOADED("rcmfanatic1") AND missionStage = MS_LEADIN // Ensure the stage is still lead-in in case the cutscene skip above occurred IF IS_ENTITY_ALIVE(MARY_ANN) IF IS_ENTITY_PLAYING_ANIM(MARY_ANN, "rcmfanatic1", "ef_1_rcm_mary_ann_streching_base") IF GET_ENTITY_ANIM_CURRENT_TIME(MARY_ANN, "rcmfanatic1", "ef_1_rcm_mary_ann_streching_base") <0.1 FREEZE_ENTITY_POSITION(MARY_ANN, FALSE) ADD_PED_FOR_DIALOGUE(MyLocalPedStruct, 3, MARY_ANN, "MARYANN") ADD_PED_FOR_DIALOGUE(MyLocalPedStruct, 0, PLAYER_PED_ID(), "MICHAEL") TASK_PLAY_ANIM_ADVANCED(MARY_ANN, "rcmfanatic1", "ef_1_rcm_mary_ann_leadin", <<-1878.223022,-440.518127,46.039829>>, <<0, 0, 159.97>>, NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_HOLD_LAST_FRAME|AF_USE_KINEMATIC_PHYSICS|AF_NOT_INTERRUPTABLE) DEBUG_PRINTSTRING("Done Mary Ann leadin anim") stageStage = SS_STAGE ELSE DEBUG_PRINTSTRING("Waiting to blend the lead-in...") ENDIF ENDIF ENDIF ENDIF ELSE DEBUG_PRINTSTRING("Replay in progress or in wrong area - skipping to intro") missionStage = MS_CUTSCENE ENDIF BREAK CASE SS_STAGE IF IS_PED_UNINJURED(MARY_ANN) IF NOT IS_GAMEPLAY_HINT_ACTIVE() SET_GAMEPLAY_ENTITY_HINT(MARY_ANN, <<0,0,0>>, TRUE, 30000) 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 IF IS_ENTITY_PLAYING_ANIM(MARY_ANN, "rcmfanatic1", "ef_1_rcm_mary_ann_leadin") IF b_LeadInConvo = FALSE IF CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_LDI", CONV_PRIORITY_HIGH) DEBUG_PRINTSTRING("Done Mary Ann leadin conv") b_LeadInConvo = TRUE ENDIF ELSE IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() DEBUG_PRINTSTRING("Mary Ann leadin conv over") WAIT(250) // Short wait just to add a more natural sounding pause after the final line before the CS starts stageStage = SS_SETUP missionStage = MS_CUTSCENE ENDIF ENDIF // IF GET_ENTITY_ANIM_CURRENT_TIME(MARY_ANN, "rcmfanatic1", "ef_1_rcm_mary_ann_leadin") > 0.90 // DEBUG_PRINTSTRING("Mary Ann leadin anim over") // stageStage = SS_SETUP // missionStage = MS_CUTSCENE // ENDIF ELSE DEBUG_PRINTSTRING("Mary Ann not playing leadin anim anymore - skip to cutscene for safety") stageStage = SS_SETUP missionStage = MS_CUTSCENE ENDIF // If player gets within 4m of Mary Ann, stop the player and make them face Mary Ann (B*231024) IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), MARY_ANN) <= 4.0 SET_PLAYER_CONTROL(PLAYER_ID(), FALSE) IF NOT IsPedPerformingTask(PLAYER_PED_ID(), SCRIPT_TASK_TURN_PED_TO_FACE_ENTITY) TASK_TURN_PED_TO_FACE_ENTITY(PLAYER_PED_ID(), MARY_ANN) TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), MARY_ANN, -1) ENDIF ENDIF ENDIF BREAK ENDSWITCH ENDPROC FUNC BOOL DO_MICHAEL_BLEND() IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Michael") DEBUG_PRINTSTRING("*** Forcing Michael's move state") FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_RUN, FALSE, FAUS_CUTSCENE_EXIT) SIMULATE_PLAYER_INPUT_GAIT(PLAYER_ID(), PEDMOVEBLENDRATIO_RUN, 5000) RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC PROC DO_MARY_ANN_BLEND() IF IS_ENTITY_ALIVE(MARY_ANN) IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Mary_Ann", IG_MARYANN) DEBUG_PRINTSTRING("*** Forcing Mary Ann's move state") DEBUG_PRINTSTRING("SET MARY ANNS TASK") IF b_CutsceneSkipped SAFE_TELEPORT_ENTITY(MARY_ANN, <<-1867.64, -446.01, 45.16>>, 229.3557) ENDIF OPEN_SEQUENCE_TASK(seq) TASK_SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(NULL, TRUE) TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1, SLF_DEFAULT) TASK_FOLLOW_WAYPOINT_RECORDING(NULL, sFANATIC_ROUTE, 1, EWAYPOINT_START_FROM_CLOSEST_POINT | EWAYPOINT_VEHICLES_USE_AI_SLOWDOWN | EWAYPOINT_ALLOW_STEERING_AROUND_PEDS | EWAYPOINT_NAVMESH_BACK_TO_WAYPOINT_IF_LEFT_ROUTE , -1) TASK_PLAY_ANIM(null, "move_f@runner", "idle", SLOW_BLEND_IN, SLOW_BLEND_OUT, -1, AF_LOOPING) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(MARY_ANN, seq) CLEAR_SEQUENCE_TASK(seq) FORCE_PED_MOTION_STATE(MARY_ANN, MS_ON_FOOT_RUN, FALSE, FAUS_CUTSCENE_EXIT) ENDIF ENDIF ENDPROC /// PURPOSE: Main process to handle the intro cutscene PROC INTRO_CUTSCENE() SWITCH stageStage CASE SS_SETUP DEBUG_PRINTSTRING("Intro Cutscene") RC_REQUEST_CUTSCENE("ef_1_rcm", TRUE) IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY() DEBUG_PRINTSTRING("Trying to set Mary Ann component variation") SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Mary_Ann", MARY_ANN, CS_MARYANN) ENDIF iCutsceneStage = 0 b_MusicTriggered = FALSE IF CutsceneNavBlockerID = -1 CutsceneNavBlockerID = ADD_NAVMESH_BLOCKING_OBJECT(<<-1877.30, -439.70, 45.05>>, <<4, 6, 2>>, 45.0) ENDIF IF RC_IS_CUTSCENE_OK_TO_START() IF IS_ENTITY_ALIVE(MARY_ANN) REGISTER_ENTITY_FOR_CUTSCENE(MARY_ANN, "Mary_Ann", CU_ANIMATE_EXISTING_SCRIPT_ENTITY, IG_MARYANN) DEBUG_PRINTSTRING("Registered Mary Ann") ENDIF IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) REGISTER_ENTITY_FOR_CUTSCENE(PLAYER_PED_ID(), "Michael", CU_ANIMATE_EXISTING_SCRIPT_ENTITY) DEBUG_PRINTSTRING("Registered Michael") ENDIF sbiCutscene = ADD_SCENARIO_BLOCKING_AREA(<<-1926.6536, -387.8897, 46.7354>>, <<-1897.3219, -374.5802, 51.0241>>) // Cleanup launcher which will remove lead-in blip RC_CLEANUP_LAUNCHER() RESET_PLAYER_STAMINA(PLAYER_ID()) STOP_GAMEPLAY_HINT() REPLAY_START_EVENT(REPLAY_IMPORTANCE_LOW) //CLEAR_AREA_OF_VEHICLES(<<-1793.82, -472.73, 39.58>>, 40.0, DEFAULT, DEFAULT, TRUE, TRUE) START_CUTSCENE() WAIT(0) SAFE_FADE_SCREEN_IN_FROM_BLACK(DEFAULT, FALSE) RESOLVE_VEHICLES_INSIDE_ANGLED_AREA_WITH_SIZE_LIMIT(<<-1873.525513,-441.621063,44.693626>>, <<-1882.030029,-436.991730,47.483791>>, 7.0, <<-1875.09, -431.08, 45.21>>, 236.42, GET_DEFAULT_ALLOWABLE_VEHICLE_SIZE_VECTOR()) RESOLVE_VEHICLES_INSIDE_ANGLED_AREA_WITH_SIZE_LIMIT(<<-1875.814819,-443.119110,49.135151>>, <<-1808.560669,-491.788696,36.580292>>, 11.0, <<-1875.09, -431.08, 45.21>>, 236.42, GET_DEFAULT_ALLOWABLE_VEHICLE_SIZE_VECTOR()) RC_START_CUTSCENE_MODE(<<-1877.23, -440.46, 45.07>>, TRUE, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT) INIT() CLEAR_ANGLED_AREA_OF_VEHICLES(<<-1799.513428,-467.645935,43.138790>>, <<-1789.602783,-476.661560,36.837288>>, 7.50) b_CutsceneSkipped = FALSE DEBUG_PRINTSTRING("Going into cutscene main loop now") stageStage = SS_STAGE ELSE DEBUG_PRINTSTRING("Waiting for cutscene to be OK to start...") ENDIF BREAK CASE SS_STAGE IF iCutsceneStage = 0 IF GET_CUTSCENE_TIME() >= 31000 IF NOT b_MusicTriggered IF TRIGGER_MUSIC_EVENT("RC6A_START") DEBUG_PRINTSTRING("Starting music") b_MusicTriggered = TRUE ENDIF ENDIF ENDIF // Keep spamming for the blend SET_GAMEPLAY_CAM_RELATIVE_PITCH() SET_GAMEPLAY_CAM_RELATIVE_HEADING() IF WAS_CUTSCENE_SKIPPED() DEBUG_PRINTSTRING("*** Cutscene skip detected") DEBUG_PRINTSTRING("*** Cam exit state pitch/heading on skip") SET_GAMEPLAY_CAM_RELATIVE_PITCH() SET_GAMEPLAY_CAM_RELATIVE_HEADING() IF IS_ENTITY_ALIVE(MARY_ANN) SET_ENTITY_COORDS(MARY_ANN, <<-1869.24, -444.99, 45.17>>) SET_ENTITY_HEADING(MARY_ANN, -143.87) ENDIF b_CutsceneSkipped = TRUE iCutsceneStage = 1 ENDIF // IF CAN_SET_EXIT_STATE_FOR_CAMERA() // IF b_CutsceneSkipped // DEBUG_PRINTSTRING("*** Cam exit state pitch/heading") // SET_GAMEPLAY_CAM_RELATIVE_PITCH() // SET_GAMEPLAY_CAM_RELATIVE_HEADING() // ENDIF // ENDIF // Move on if blend happens IF DO_MICHAEL_BLEND() iCutsceneStage = 1 ENDIF // Keep checking DO_MARY_ANN_BLEND() ELIF iCutsceneStage = 1 IF GET_CUTSCENE_TIME() >= 31000 IF NOT b_MusicTriggered IF TRIGGER_MUSIC_EVENT("RC6A_START") DEBUG_PRINTSTRING("Starting music") b_MusicTriggered = TRUE ENDIF ENDIF ENDIF IF WAS_CUTSCENE_SKIPPED() DEBUG_PRINTSTRING("*** Cutscene skip detected") DEBUG_PRINTSTRING("*** Cam exit state pitch/heading on skip") SET_GAMEPLAY_CAM_RELATIVE_PITCH() SET_GAMEPLAY_CAM_RELATIVE_HEADING() IF IS_ENTITY_ALIVE(MARY_ANN) SET_ENTITY_COORDS(MARY_ANN, <<-1869.24, -444.99, 45.17>>) SET_ENTITY_HEADING(MARY_ANN, -143.87) ENDIF IF NOT b_MusicTriggered IF TRIGGER_MUSIC_EVENT("RC6A_START") DEBUG_PRINTSTRING("Starting music from skip") b_MusicTriggered = TRUE ENDIF ENDIF ENDIF // Keep checking in case we skipped DO_MARY_ANN_BLEND() // Keep checking in case missed in previous stage DO_MICHAEL_BLEND() IF NOT IS_CUTSCENE_ACTIVE() REPLAY_STOP_EVENT() REMOVE_NAVMESH_BLOCKING_OBJECT(CutsceneNavBlockerID) CutsceneNavBlockerID = -1 // Reset so can be used again if we skip REMOVE_SCENARIO_BLOCKING_AREA(sbiCutscene) iOvertakeTimer = GET_GAME_TIMER() stageStage = SS_SETUP missionStage = MS_START_RUNNING ENDIF ENDIF BREAK ENDSWITCH ENDPROC /// PURPOSE: Main process to handle the race immediately following the intro cutscene PROC START_RUNNING() SWITCH stageStage CASE SS_SETUP DEBUG_PRINTSTRING("Setup START_RUNNING") REMOVE_VEHICLES_FROM_GENERATORS_IN_AREA(<<-1835.529785,-518.723816,25.116776>>, <<-1822.431030,-513.893311,30.386765>>) SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<<-1835.529785,-518.723816,25.116776>>, <<-1822.431030,-513.893311,30.386765>>, FALSE) //CLEAR_AREA_OF_VEHICLES(<<-1793.82, -472.73, 39.58>>, 15.0) // IF DOES_ENTITY_EXIST(MARY_ANN) // SET_ENTITY_COORDS(MARY_ANN, <<-1865.90, -448.81, 45.2>>) // SET_ENTITY_HEADING(MARY_ANN, -143.87) // SET_PED_ON_THE_GROUND(MARY_ANN) // ENDIF IF NOT IS_AUDIO_SCENE_ACTIVE("FANATIC_MIX_SCENE") START_AUDIO_SCENE("FANATIC_MIX_SCENE") IF IS_ENTITY_ALIVE(MARY_ANN) ADD_ENTITY_TO_AUDIO_MIX_GROUP(MARY_ANN,"FANATIC_MIX_MARY_ANNE") ENDIF ENDIF // In case the cutscene gets skipped or the trigger just somehow misses, do it here IF NOT b_MusicTriggered IF TRIGGER_MUSIC_EVENT("RC6A_START") DEBUG_PRINTSTRING("Starting music - start_running() init") b_MusicTriggered = TRUE ENDIF ENDIF ADD_PED_FOR_DIALOGUE(MyLocalPedStruct, 3, MARY_ANN, "MARYANN") RC_END_CUTSCENE_MODE(TRUE, FALSE) RC_SET_ENTITY_PROOFS_FOR_CUTSCENE(sRCLauncherDataLocal, FALSE) IF IS_ENTITY_ALIVE(MARY_ANN) SET_ENTITY_PROOFS(MARY_ANN, FALSE, FALSE, FALSE, FALSE, FALSE) ENDIF start_time = GET_GAME_TIMER() IF NOT DOES_BLIP_EXIST(FANATIC_BLIP) FANATIC_BLIP = CREATE_PED_BLIP(MARY_ANN, TRUE, TRUE) SET_BLIP_AS_FRIENDLY(FANATIC_BLIP, TRUE) ENDIF IF IS_PED_UNINJURED(MARY_ANN) SET_PED_CAN_RAGDOLL_FROM_PLAYER_IMPACT(MARY_ANN, FALSE) //FORCE_PED_MOTION_STATE(MARY_ANN, MS_ON_FOOT_RUN, true, FAUS_CUTSCENE_EXIT ) ENDIF MASprintState = SPRINT_COOLDOWN iSprintTimer = GET_GAME_TIMER() IF GET_IS_WAYPOINT_RECORDING_LOADED("Fanatic1RollingStart") DEBUG_PRINTSTRING("*** Using assisted movement...") USE_WAYPOINT_RECORDING_AS_ASSISTED_MOVEMENT_ROUTE("Fanatic1RollingStart", TRUE, 2, 0.7) ENDIF b_ForcePlayerRunningAtStart = TRUE iRollingStartTimer = GET_GAME_TIMER() iConversationTimer = GET_GAME_TIMER() DEBUG_PRINTSTRING("GOING INTO START_RUNNING LOOP") REPLAY_RECORD_BACK_FOR_TIME(0.0, 10.0, REPLAY_IMPORTANCE_LOW) stageStage = SS_STAGE BREAK CASE SS_STAGE // B*1422947 IF NOT g_savedGlobals.sRandomChars.g_bFanaticHelp IF NOT IS_HELP_MESSAGE_BEING_DISPLAYED() PRINT_HELP("FAN_HELP") g_savedGlobals.sRandomChars.g_bFanaticHelp = TRUE ENDIF ENDIF IF b_ForcePlayerRunningAtStart = TRUE if (GET_GAME_TIMER() - iRollingStartTimer) < 5000 IF (GET_GAME_TIMER() - iRollingStartTimer) > 1000 IF IS_SCREEN_FADED_OUT() DEBUG_PRINTSTRING("FADING IN NOW") SAFE_FADE_SCREEN_IN_FROM_BLACK(500, FALSE) RC_END_CUTSCENE_MODE(TRUE, FALSE) ENDIF ENDIF //DEBUG_PRINTSTRING("USING ASSISTED ROUTE") ELSE b_ForcePlayerRunningAtStart = FALSE DEBUG_PRINTSTRING("TURNING OFF ASSISTED ROUTE") USE_WAYPOINT_RECORDING_AS_ASSISTED_MOVEMENT_ROUTE("Fanatic1RollingStart", FALSE) REMOVE_WAYPOINT_RECORDING("Fanatic1RollingStart") ENDIF ENDIF IF IS_ENTITY_ALIVE(MARY_ANN) if GET_SCRIPT_TASK_STATUS(MARY_ANN, SCRIPT_TASK_PERFORM_SEQUENCE) != PERFORMING_TASK DEBUG_PRINTSTRING("Re-set Mary Ann's task post-cutscene") OPEN_SEQUENCE_TASK(seq) TASK_SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(NULL, TRUE) TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1, SLF_DEFAULT) TASK_FOLLOW_WAYPOINT_RECORDING(NULL, sFANATIC_ROUTE, 1, EWAYPOINT_START_FROM_CLOSEST_POINT | EWAYPOINT_VEHICLES_USE_AI_SLOWDOWN | EWAYPOINT_ALLOW_STEERING_AROUND_PEDS | EWAYPOINT_NAVMESH_BACK_TO_WAYPOINT_IF_LEFT_ROUTE, -1) TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1) TASK_PLAY_ANIM(null, "move_f@runner", "idle", SLOW_BLEND_IN, SLOW_BLEND_OUT, -1, AF_LOOPING) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(MARY_ANN, seq) CLEAR_SEQUENCE_TASK(seq) ENDIF ENDIF IF cheatedLeaptFence.hasBeenPlayed = FALSE IF iNum_NPCClosestWaypoint < 17 IF IS_PLAYER_CLIMBING(PLAYER_ID()) IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-1799.070801,-468.659149,40.074013>>, <<-1820.118530,-492.413879,41.743690>>, 18.250000) IF NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-1798.075562,-468.229706,39.025360>>, <<-1816.664307,-484.317017,43.642105>>, 12.500000) IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() KILL_ANY_CONVERSATION() ENDIF IF CAN_MARY_ANN_SAY_SINGLE_LINE(cheatedLeaptFence.rootLabel, cheatedLeaptFence.dialogueLine, FALSE, startRunConversation.restartLine) IF startRunConversation.restartLine != -1 startRunConversation.hasBeenInterrupted = TRUE DEBUG_PRINTSTRING("*** startRunConversation interrupted!") DEBUG_PRINTSI("*** startRunConversation will restart on line: ",startRunConversation.restartLine) ENDIF finishReason = FINISHED_BY_SHORTCUT b_CheatedLine = TRUE // Do a returnAfterCheatedLine cheatedLeaptFence.hasBeenPlayed = TRUE g_savedGlobals.sRandomChars.g_bFanaticCheated = TRUE ELSE DEBUG_PRINTSTRING("*** Waiting for prior conversation to end before can play cheated line!") ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF IF cheatedRanAcrossGrass.hasBeenPlayed = FALSE IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-1772.761719,-532.997131,35.589294>>, <<-1797.245850,-492.129211,39.270397>>, 26.000000) OR GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), <<-1812.910278,-468.525330,41.320290>>) < 10 IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() KILL_ANY_CONVERSATION() ENDIF IF CAN_MARY_ANN_SAY_SINGLE_LINE(cheatedRanAcrossGrass.rootLabel, cheatedRanAcrossGrass.dialogueLine, FALSE, startRunConversation.restartLine) IF startRunConversation.restartLine != -1 startRunConversation.hasBeenInterrupted = TRUE DEBUG_PRINTSTRING("*** startRunConversation interrupted!") DEBUG_PRINTSI("*** startRunConversation will restart on line: ",startRunConversation.restartLine) ENDIF finishReason = FINISHED_BY_SHORTCUT b_CheatedLine = TRUE // Do a returnAfterCheatedLine cheatedRanAcrossGrass.hasBeenPlayed = TRUE g_savedGlobals.sRandomChars.g_bFanaticCheated = TRUE ELSE DEBUG_PRINTSTRING("*** Waiting for prior conversation to end before can play cheated line!") ENDIF ENDIF ENDIF IF b_CheatedLine = TRUE // Player has cheated, do a return line IF returnAfterCheatedLine.hasBeenPlayed = FALSE if GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), MARY_ANN) < 10 INT temp IF CAN_MARY_ANN_SAY_SINGLE_LINE(returnAfterCheatedLine.rootLabel, returnAfterCheatedLine.dialogueLine, FALSE, temp) returnAfterCheatedLine.hasBeenPlayed = TRUE b_CheatedLine = FALSE iOneLinerTimer = GET_GAME_TIMER() ENDIF ENDIF ENDIF ENDIF IF CAN_CREATE_RUNNING_CONVERSATION() IF startRunConversation.hasBeenPlayed = FALSE AND (GET_GAME_TIMER() - iConversationTimer) > 3500 CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", startRunConversation.rootLabel, CONV_PRIORITY_MEDIUM) DEBUG_PRINTSTRING("SETTING UP THE CONVERSATION") startRunConversation.hasBeenPlayed = TRUE iOneLinerTimer = GET_GAME_TIMER() ELSE IF startRunConversation.hasBeenInterrupted = TRUE IF returnAfterCheatedLine.hasBeenPlayed = TRUE // We want to wait for the return after cheated line to be played first tDialogueRoot = startRunConversation.rootLabel tDialogueRoot += "_" tDialogueRoot += startRunConversation.restartLine IF CREATE_CONVERSATION_FROM_SPECIFIC_LINE(MyLocalPedStruct, "FAN1AU", startRunConversation.rootLabel, tDialogueRoot, CONV_PRIORITY_MEDIUM) startRunConversation.hasBeenInterrupted = FALSE ENDIF ENDIF ENDIF ENDIF ENDIF // if the main conversation has been played, try doing the one-liners IF startRunConversation.hasBeenPlayed TRY_ONE_LINER() ENDIF IF RACE_LEG_FINISHED(vPos_StartOfRoadRunning) fMBR_IncreaseRatio = 1.15 stageStage = SS_SETUP missionStage = MS_ROAD_RUNNING_SECTION ENDIF BREAK ENDSWITCH ENDPROC /// PURPOSE: Main process to handle the road running section PROC ROAD_RUNNING_SECTION() SWITCH stageStage CASE SS_SETUP DEBUG_PRINTSTRING("SETUP ROAD_RUNNING_SECTION") IF NOT DOES_BLIP_EXIST(FANATIC_BLIP) FANATIC_BLIP = CREATE_PED_BLIP(MARY_ANN, TRUE, TRUE) SET_BLIP_AS_FRIENDLY(FANATIC_BLIP, TRUE) ENDIF IF b_IsTheRoadSwitchedOn = TRUE TURN_ROADS_ON(FALSE) ENDIF b_PlayerJumpedDownTheCliff = FALSE iRoadTimer = GET_GAME_TIMER() IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() DEBUG_PRINTSTRING("stop scripted conversation at ROAD_RUNNING_SECTION") KILL_ANY_CONVERSATION() ENDIF IF IS_VEHICLE_OK(FOLLOWING_CAR.thisCarIndex) AND IS_PED_UNINJURED(FOLLOWING_CAR.Driver) SET_ENTITY_COORDS(FOLLOWING_CAR.thisCarIndex, <<-1934.15, -438.19, 19.60>>) SET_ENTITY_HEADING(FOLLOWING_CAR.thisCarIndex, 237.78) SET_VEHICLE_ON_GROUND_PROPERLY(FOLLOWING_CAR.thisCarIndex) TASK_VEHICLE_MISSION_COORS_TARGET(FOLLOWING_CAR.Driver, FOLLOWING_CAR.thisCarIndex, FOLLOWING_CAR.thisGoToPos, MISSION_GOTO, FOLLOWING_CAR.thisSpeed, DRIVINGMODE_AVOIDCARS_STOPFORPEDS_OBEYLIGHTS, 3, 3) SET_ENTITY_LOAD_COLLISION_FLAG(FOLLOWING_CAR.Driver, TRUE) ENDIF DEBUG_PRINTSTRING("GOING INTO ROAD_RUNNING_SECTION LOOP") driveByState = DRIVE_BY_PRE_TASK stageStage = SS_STAGE BREAK CASE SS_STAGE SET_PED_DENSITY_MULTIPLIER_THIS_FRAME(0.5) IF CAN_CREATE_RUNNING_CONVERSATION() IF road1Conversation.hasBeenPlayed = FALSE INT i IF IS_ENTITY_ALIVE(MARY_ANN) WAYPOINT_RECORDING_GET_CLOSEST_WAYPOINT(sFANATIC_ROUTE, GET_ENTITY_COORDS(MARY_ANN), i) ENDIF IF i <= 52 // Only try and play the road conversation is Mary Ann is earlier or at the 54th waypoint, otherwise it's too late IF cheatedLeaptFence.hasBeenPlayed = FALSE AND cheatedRanAcrossGrass.hasBeenPlayed = FALSE AND place = 2 // Only do the full one if the player is in second place CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", road1Conversation.rootLabel, CONV_PRIORITY_MEDIUM) ELSE CREATE_CONVERSATION_FROM_SPECIFIC_LINE(MyLocalPedStruct, "FAN1AU", road1Conversation.rootLabel, "FAN1_RD1_3", CONV_PRIORITY_MEDIUM) ENDIF road1Conversation.hasBeenPlayed = TRUE ENDIF ENDIF ENDIF IF driveByState = DRIVE_BY_PRE_TASK IF iNum_NPCClosestWaypoint > 41 driveByState = DRIVE_BY_SET_DRIVE_TASK ENDIF ENDIF // Only try this stuff if the main road conversations haven't been played IF road1Conversation.hasBeenPlayed = TRUE AND road2Conversation.hasBeenPlayed = TRUE // Try and do a Mary Ann road rage conversation if a vehicle passes by VECTOR vOffset VEHICLE_INDEX vIdx IF IS_ENTITY_ALIVE(MARY_ANN) vOffset = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(MARY_ANN, <<0,6,0>>) vIdx = GET_CLOSEST_VEHICLE(vOffset, 8, DUMMY_MODEL_FOR_SCRIPT, 2) // 2 = Return mission vehicles if vIdx <> NULL IF MADialogueState = MA_WITHIN_TALKING_RANGE AND iRoadTimer > 2000 AND iRoadCounter < 5 // Max number of road rage lines IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_RD3", CONV_PRIORITY_MEDIUM) iRoadCounter++ iRoadTimer = GET_GAME_TIMER() ENDIF ENDIF ENDIF ELSE vIdx = GET_CLOSEST_VEHICLE(vOffset, 8, DUMMY_MODEL_FOR_SCRIPT, 4) if vIdx <> NULL IF MADialogueState = MA_WITHIN_TALKING_RANGE AND iRoadTimer > 2000 AND iRoadCounter < 5 // Max number of road rage lines IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_RD3", CONV_PRIORITY_MEDIUM) iRoadCounter++ iRoadTimer = GET_GAME_TIMER() ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF // If a road rage conversation above hasn't fired, try doing a one liner TRY_ONE_LINER() ENDIF CHECK_IF_PLAYER_JUMPS_THE_CLIFF() UPDATE_DRIVEBY_FINGERING() IF iNum_NPCClosestWaypoint > 61 stageStage = SS_SETUP missionStage = MS_STEPS_DOWN ENDIF BREAK ENDSWITCH ENDPROC /// PURPOSE: Main process to handle the steps down the cliff and over the freeway bridge PROC STEPS_DOWN() SWITCH stageStage CASE SS_SETUP DEBUG_PRINTSTRING("STEPS DOWN SETUP") IF NOT DOES_BLIP_EXIST(FANATIC_BLIP) FANATIC_BLIP = CREATE_PED_BLIP(MARY_ANN, TRUE, TRUE) SET_BLIP_AS_FRIENDLY(FANATIC_BLIP, TRUE) ENDIF SET_PED_NON_CREATION_AREA(<<-1865.76, -617.48, 10.58>>, <<-1820.57, -552.41, 17.40>>) //ADD_SCENARIO_BLOCKING_AREA(<<-1865.76, -617.48, 10.58>>, <<-1820.57, -552.41, 17.40>>) SET_PED_PATHS_IN_AREA(<<-1865.76, -617.48, 10.58>>, <<-1820.57, -552.41, 17.40>>, FALSE) IF IS_PED_UNINJURED(DRIVEBY_FINGER_CAR.Driver) CLEAR_PED_TASKS(DRIVEBY_FINGER_CAR.Driver) SAFE_RELEASE_PED(DRIVEBY_FINGER_CAR.Driver) ENDIF IF IS_VEHICLE_OK(DRIVEBY_FINGER_CAR.thisCarIndex) SAFE_RELEASE_VEHICLE(DRIVEBY_FINGER_CAR.thisCarIndex) ENDIF DEBUG_PRINTSTRING("GOING INTO STEPS_DOWN MAIN LOOP") stageStage = SS_STAGE BREAK CASE SS_STAGE DEAL_WITH_THE_QUAD() TRY_ONE_LINER() SET_PED_DENSITY_MULTIPLIER_THIS_FRAME(0.5) IF b_PlayerJumpedDownTheCliff = FALSE CHECK_IF_PLAYER_JUMPS_THE_CLIFF() ENDIF IF RACE_LEG_FINISHED(vPos_StartOfBeachRunning) fMBR_IncreaseRatio = 1.15 stageStage = SS_SETUP missionStage = MS_SPRINT_TO_FINISH ENDIF BREAK ENDSWITCH ENDPROC /// PURPOSE: Main process to handle the final beach sprint PROC SPRINT_TO_FINISH() SWITCH stageStage CASE SS_SETUP DEBUG_PRINTSTRING("SETUP SPRINT_TO_FINISH") IF NOT DOES_BLIP_EXIST(FANATIC_BLIP) FANATIC_BLIP = CREATE_PED_BLIP(MARY_ANN, TRUE, TRUE) SET_BLIP_AS_FRIENDLY(FANATIC_BLIP, TRUE) ENDIF beachDogState = DOG_LOADING stageStage = SS_STAGE DEBUG_PRINTSTRING("GOING INTO SPRINT_TO_FINISH MAIN LOOP") BREAK CASE SS_STAGE SET_PED_DENSITY_MULTIPLIER_THIS_FRAME(0.5) IF raceConversation.hasBeenPlayed = FALSE AND iNum_NPCClosestWaypoint < 105 IF CAN_CREATE_RUNNING_CONVERSATION() AND GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), MARY_ANN) < 25 IF CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", raceConversation.rootLabel, CONV_PRIORITY_MEDIUM) raceConversation.hasBeenPlayed = TRUE TASK_PLAY_ANIM(MARY_ANN, "rcmfanatic1yell", "yell_c", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_UPPERBODY|AF_SECONDARY) ENDIF ENDIF ENDIF IF IS_THIS_CONVERSATION_ROOT_PLAYING(raceConversation.rootLabel) IF GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), MARY_ANN) > 30 KILL_ANY_CONVERSATION() ENDIF ENDIF CREATE_JOGGERS() CREATE_MARY_ANNS_BIKE() DEAL_WITH_THE_DOG() DEAL_WITH_THE_QUAD() DEAL_WITH_THE_TWO_FINAL_PEDS() IF iRaceLineNumber < iMAXRaceLineNumber AND iNum_NPCClosestWaypoint < 117 AND iNum_PlayerClosestWaypoint < 117 IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF (GET_GAME_TIMER() - iConversationTimer) > 3000 int temp if CAN_MARY_ANN_SAY_SINGLE_LINE("FAN1_FAST", RACE_LINE[iRaceLineNumber], FALSE, temp) iRaceLineNumber++ ENDIF ENDIF ELSE iConversationTimer = GET_GAME_TIMER() ENDIF ENDIF BREAK ENDSWITCH ENDPROC /// PURPOSE: Special process to debug move the player close to the finish line rather than directly on top of it PROC DEBUG_NEAR_FINISH_LINE() SWITCH stageStage CASE SS_SETUP IF NOT DOES_BLIP_EXIST(FANATIC_BLIP) FANATIC_BLIP = CREATE_PED_BLIP(MARY_ANN, TRUE, TRUE) SET_BLIP_AS_FRIENDLY(FANATIC_BLIP, TRUE) ENDIF stageStage = SS_STAGE BREAK CASE SS_STAGE CREATE_MARY_ANNS_BIKE() DEAL_WITH_THE_TWO_FINAL_PEDS() BREAK ENDSWITCH ENDPROC /// PURPOSE: Main process to handle the end cutscene, either realtime or scripted PROC END_CUTSCENE() // handle the previous checkpoint in here to fade it out IF PrevCheckpoint != NULL INT PreviR, PreviG, PreviB, iA DEBUG_PRINTSTRING("Fade previous CP") iPrevAlpha -= 25 IF iPrevAlpha > 0 GET_HUD_COLOUR(HUD_COLOUR_WHITE, PreviR, PreviG, PreviB, iA) SET_CHECKPOINT_RGBA(PrevCheckpoint, PreviR, PreviG, PreviB, iPrevAlpha) SET_CHECKPOINT_RGBA2(PrevCheckpoint, PreviR, PreviG, PreviB, iPrevAlpha) ELSE DELETE_CHECKPOINT(PrevCheckpoint) ENDIF ENDIF SWITCH stageStage CASE SS_SETUP SAFE_REMOVE_BLIP(DESTINATION_BLIP) DELETE_CHECKPOINT(checkPoint) IF IS_PED_UNINJURED(BEACH_DOG) CLEAR_PED_TASKS(BEACH_DOG) TASK_SMART_FLEE_PED(BEACH_DOG, PLAYER_PED_ID(), 40, -1) ENDIF IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() DEBUG_PRINTSTRING("stop scripted conversation at END_CUTSCENE") KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() ENDIF IF IS_ENTITY_ALIVE(MARY_ANN) SET_ENTITY_LOAD_COLLISION_FLAG(MARY_ANN, TRUE) SET_PED_CAN_BE_KNOCKED_OFF_VEHICLE(MARY_ANN, KNOCKOFFVEHICLE_NEVER) ENDIF b_DoneOutOfBreath = FALSE TRIGGER_MUSIC_EVENT("RC6A_FINISH") WEAPON_TYPE currentWeapon GET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), currentWeapon, FALSE) IF currentWeapon != WEAPONTYPE_UNARMED SET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_UNARMED, TRUE) // Force player to be unarmed so anim looks right ENDIF IF b_ScriptedEnding CLEAR_AREA_OF_PEDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), 30) RESOLVE_VEHICLES_INSIDE_ANGLED_AREA_WITH_SIZE_LIMIT(<<-2010.692993,-504.882050,9.529695>>, <<-1995.946777,-517.249390,13.764661>>, 10.0, <<-2008.54, -494.10, 11.04>>, 48.19, GET_DEFAULT_ALLOWABLE_VEHICLE_SIZE_VECTOR()) RC_START_CUTSCENE_MODE(vPos_FinishLine, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, FALSE) GO_TO_CUTSCENE() IF GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), MARY_ANN) > 32 SET_ENTITY_COORDS(MARY_ANN, <<-1986.20, -526.22, 11>>) SET_ENTITY_HEADING(MARY_ANN, 58.26) OPEN_SEQUENCE_TASK(seq) TASK_FOLLOW_WAYPOINT_RECORDING(NULL, sFANATIC_ROUTE, GET_MARY_ANNS_NEXT_WAYPOINT(), EWAYPOINT_DEFAULT | EWAYPOINT_VEHICLES_USE_AI_SLOWDOWN | EWAYPOINT_ALLOW_STEERING_AROUND_PEDS, -1) TASK_PLAY_ANIM(null, "move_f@runner", "idle", SLOW_BLEND_IN, SLOW_BLEND_OUT, -1, AF_LOOPING) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(MARY_ANN, seq) CLEAR_SEQUENCE_TASK(seq) FORCE_PED_MOTION_STATE(MARY_ANN, MS_ON_FOOT_RUN, true, FAUS_CUTSCENE_EXIT ) ENDIF TASK_LOOK_AT_ENTITY(MARY_ANN, PLAYER_PED_ID(), -1) OPEN_SEQUENCE_TASK(seq) TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, vPos_FinishLine, 1, DEFAULT_TIME_BEFORE_WARP, 0.5, ENAV_DEFAULT) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(PLAYER_PED_ID(), seq) CLEAR_SEQUENCE_TASK(seq) FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_RUN, TRUE, FAUS_DEFAULT) REQUEST_ANIM_DICT("rcmfanatic1out_of_breath") WHILE NOT HAS_ANIM_DICT_LOADED("rcmfanatic1out_of_breath") DEBUG_PRINTSTRING("Loading ANIMS") WAIT(0) ENDWHILE b_TIRED_ANIM_PLAYING = FALSE SET_EVERYONE_IGNORE_PLAYER(PLAYER_ID(), TRUE) ELSE REQUEST_ANIM_DICT("rcmfanatic1out_of_breath") WHILE NOT HAS_ANIM_DICT_LOADED("rcmfanatic1out_of_breath") DEBUG_PRINTSTRING("Loading ANIMS") WAIT(0) ENDWHILE ENDIF IF NOT DOES_ENTITY_EXIST(MAS_BIKE) REQUEST_MODEL(MARYSBIKEMODEL) WHILE NOT HAS_MODEL_LOADED(MARYSBIKEMODEL) DEBUG_PRINTSTRING("Loading MARYSBIKE MODEL") WAIT(0) ENDWHILE MAS_BIKE = CREATE_VEHICLE(MARYSBIKEMODEL, MAS_BIKE_POS, MAS_BIKE_DIR) SET_MODEL_AS_NO_LONGER_NEEDED(MARYSBIKEMODEL) ENDIF INT p FOR p = 0 TO 3 IF IS_PED_UNINJURED(OtherJoggers[p].thisIndex) IF IS_PED_IN_MELEE_COMBAT(OtherJoggers[p].thisIndex) OR IS_PED_RESPONDING_TO_EVENT(OtherJoggers[p].thisIndex, EVENT_PED_TO_CHASE) OR IS_PED_RESPONDING_TO_EVENT(OtherJoggers[p].thisIndex, EVENT_MELEE_ACTION) CLEAR_PED_TASKS(OtherJoggers[p].thisIndex) OPEN_SEQUENCE_TASK(seq) TASK_TURN_PED_TO_FACE_ENTITY(NULL, PLAYER_PED_ID()) TASK_PAUSE(NULL, 2000) TASK_WANDER_STANDARD(NULL) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(OtherJoggers[p].thisIndex, seq) CLEAR_SEQUENCE_TASK(seq) SAFE_RELEASE_PED(OtherJoggers[p].thisIndex) ENDIF ENDIF ENDFOR myCam = CAM_TARGET_PLAYER stageStage = SS_STAGE BREAK CASE SS_STAGE DEAL_WITH_THE_TWO_FINAL_PEDS() RC_DISABLE_CONTROL_ACTIONS_FOR_LEAD_IN() // Disable these actions while we're playing the outro DISABLE_CELLPHONE_THIS_FRAME_ONLY() // Disable the phone too DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_COVER) // Make the player unable to get into cover SWITCH cutsceneStage CASE CS_WAIT_FOR_ANN IF b_ScriptedEnding IF GET_SCRIPT_TASK_STATUS(PLAYER_PED_ID(), SCRIPT_TASK_PERFORM_SEQUENCE) = FINISHED_TASK IF b_TIRED_ANIM_PLAYING = FALSE OPEN_SEQUENCE_TASK(seq) TASK_PLAY_ANIM(NULL, "rcmfanatic1out_of_breath", "base", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_LOOPING) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(PLAYER_PED_ID(), seq) CLEAR_SEQUENCE_TASK(seq) b_TIRED_ANIM_PLAYING = TRUE ENDIF ENDIF IF IS_ENTITY_AT_COORD(MARY_ANN, vPos_FinishLine, <<5,5,3>>) AND b_TIRED_ANIM_PLAYING = TRUE IF finishReason = FINISHED_BY_STEROIDS dialogueOptionFinish = "FAN1_DONE_2" ELIF finishReason = FINISHED_BY_SHORTCUT dialogueOptionFinish = "FAN1_DONE_3" ENDIF IF CREATE_MULTIPART_CONVERSATION_WITH_4_LINES(MyLocalPedStruct, "FAN1AU", "FAN1_DONE", "FAN1_DONE_1", "FAN1_DONE", dialogueOptionFinish, "FAN1_DONE", "FAN1_DONE_4", "FAN1_DONE", "FAN1_DONE_5", CONV_PRIORITY_MEDIUM) cutsceneStage = CS_MARY_ANN_LEAVES ENDIF ENDIF ELSE // Keep looping this to make sure Michael's playing his out of breath anims DEAL_WITH_MICHAEL_OUT_OF_BREATH() INT i IF IS_ENTITY_ALIVE(MARY_ANN) WAYPOINT_RECORDING_GET_CLOSEST_WAYPOINT(sFANATIC_ROUTE, GET_ENTITY_COORDS(MARY_ANN), i) IF i >=125 OPEN_SEQUENCE_TASK(seq) TASK_PLAY_ANIM(NULL, "rcmfanatic1", "jogging_up", NORMAL_BLEND_IN, FAST_BLEND_OUT, -1, AF_USE_KINEMATIC_PHYSICS) TASK_PLAY_ANIM(NULL, "rcmfanatic1", "jogging_on_spot", FAST_BLEND_IN, SLOW_BLEND_OUT, -1, AF_LOOPING|AF_USE_KINEMATIC_PHYSICS) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(MARY_ANN, seq) TASK_LOOK_AT_ENTITY(MARY_ANN, PLAYER_PED_ID(), -1) IF finishReason = FINISHED_BY_STEROIDS dialogueOptionFinish = "FAN1_DONE_2" ELIF finishReason = FINISHED_BY_SHORTCUT dialogueOptionFinish = "FAN1_DONE_3" ENDIF IF CREATE_MULTIPART_CONVERSATION_WITH_4_LINES(MyLocalPedStruct, "FAN1AU", "FAN1_DONE", "FAN1_DONE_1", "FAN1_DONE", dialogueOptionFinish, "FAN1_DONE", "FAN1_DONE_4", "FAN1_DONE", "FAN1_DONE_5", CONV_PRIORITY_MEDIUM) REPLAY_RECORD_BACK_FOR_TIME(10.0, 10.0, REPLAY_IMPORTANCE_LOW) cutsceneStage = CS_MARY_ANN_LEAVES TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), MARY_ANN, 4000) cutsceneStage = CS_MARY_ANN_LEAVES ENDIF ENDIF ENDIF ENDIF BREAK CASE CS_MARY_ANN_LEAVES IF b_ScriptedEnding switch myCam CASE CAM_TARGET_PLAYER IF GET_CURRENT_SCRIPTED_CONVERSATION_LINE() > 2 DETACH_CAM(camCutsceneStart) STOP_CAM_POINTING(camCutsceneStart) SET_CAM_PARAMS(camCutsceneStart,<<-2008.2262, -508.2978, 12.2798>>, <<-9.0657, -0.0000, -70.4730>>, 50.0) myCam = CAM_MARY_ANN_LEAVES ENDIF BREAK CASE CAM_MARY_ANN_LEAVES IF IS_VEHICLE_OK(MAS_BIKE) OPEN_SEQUENCE_TASK(seq) TASK_LOOK_AT_ENTITY(NULL, MAS_BIKE, -1) //TASK_PLAY_ANIM(NULL, "rcmfanatic1", "jogging_exit", FAST_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_TAG_SYNC_OUT|AF_USE_KINEMATIC_PHYSICS) TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, <<-2003.36, -503.77, 10.48>>, PEDMOVEBLENDRATIO_RUN, DEFAULT, 1.0, ENAV_NO_STOPPING|ENAV_DONT_AVOID_PEDS|ENAV_SUPPRESS_EXACT_STOP) TASK_ENTER_VEHICLE(NULL, MAS_BIKE, DEFAULT_TIME_BEFORE_WARP, VS_DRIVER, 1) TASK_CLEAR_LOOK_AT(NULL) TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), 2000) TASK_VEHICLE_DRIVE_TO_COORD(NULL, MAS_BIKE, <<-2014.96, -455.47, 10.48>>, 10, DRIVINGSTYLE_NORMAL, MARYSBIKEMODEL, DF_SteerAroundStationaryCars, 3, 50) TASK_VEHICLE_DRIVE_WANDER(NULL, MAS_BIKE, 10, DRIVINGMODE_AVOIDCARS_STOPFORPEDS_OBEYLIGHTS) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(MARY_ANN, seq) CLEAR_SEQUENCE_TASK(seq) SET_PED_KEEP_TASK(MARY_ANN, TRUE) SET_ANIM_LOOPED(PLAYER_PED_ID(), FALSE) OPEN_SEQUENCE_TASK(seq) TASK_PLAY_ANIM(NULL, "rcmfanatic1out_of_breath", "base", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1) TASK_LOOK_AT_ENTITY(NULL, MARY_ANN, -1) TASK_TURN_PED_TO_FACE_COORD(NULL, <<-2000.81, -496.56, 10.56>>) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(PLAYER_PED_ID(), seq) CLEAR_SEQUENCE_TASK(seq) ENDIF cutsceneStage = CS_SAY_FINAL_LINE BREAK ENDSWITCH ELSE DEAL_WITH_MICHAEL_OUT_OF_BREATH() DEAL_WITH_MARY_ANN_FACING_PLAYER() // Keep Mary Ann facing the player while this is playing out IF GET_CURRENT_SCRIPTED_CONVERSATION_LINE() > 2 IF NOT b_PlayerOnMAsBike IF IS_VEHICLE_OK(MAS_BIKE) OPEN_SEQUENCE_TASK(seq) TASK_CLEAR_LOOK_AT(NULL) TASK_LOOK_AT_ENTITY(NULL, MAS_BIKE, -1) //TASK_PLAY_ANIM(NULL, "rcmfanatic1", "jogging_exit", SLOW_BLEND_IN, FAST_BLEND_OUT, -1, AF_TAG_SYNC_OUT|AF_USE_KINEMATIC_PHYSICS) TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, <<-2003.36, -503.77, 10.48>>, PEDMOVEBLENDRATIO_RUN, DEFAULT, 1.0, ENAV_NO_STOPPING|ENAV_DONT_AVOID_PEDS) TASK_ENTER_VEHICLE(NULL, MAS_BIKE, DEFAULT_TIME_BEFORE_WARP, VS_DRIVER, PEDMOVEBLENDRATIO_RUN) TASK_CLEAR_LOOK_AT(NULL) TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), 2000) TASK_VEHICLE_DRIVE_TO_COORD(NULL, MAS_BIKE, <<-2018.17, -461.00, 10.56>>, 10, DRIVINGSTYLE_NORMAL, MARYSBIKEMODEL, DF_SteerAroundStationaryCars, 3, 50) TASK_VEHICLE_DRIVE_TO_COORD(NULL, MAS_BIKE, <<-2014.96, -455.47, 10.48>>, 10, DRIVINGSTYLE_NORMAL, MARYSBIKEMODEL, DF_SteerAroundStationaryCars, 3, 50) TASK_VEHICLE_DRIVE_WANDER(NULL, MAS_BIKE, 10, DRIVINGMODE_AVOIDCARS_STOPFORPEDS_OBEYLIGHTS) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(MARY_ANN, seq) CLEAR_SEQUENCE_TASK(seq) SET_PED_KEEP_TASK(MARY_ANN, TRUE) ENDIF ELSE OPEN_SEQUENCE_TASK(seq) TASK_CLEAR_LOOK_AT(NULL) TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), 2000) TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, <<-1954.10, -450.90, 16.77>>, PEDMOVEBLENDRATIO_RUN, DEFAULT_TIME_BEFORE_WARP) TASK_WANDER_STANDARD(NULL) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(MARY_ANN, seq) CLEAR_SEQUENCE_TASK(seq) SET_PED_KEEP_TASK(MARY_ANN, TRUE) ENDIF TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), MARY_ANN, 6000) cutsceneStage = CS_SAY_FINAL_LINE ENDIF ENDIF BREAK CASE CS_SAY_FINAL_LINE IF b_ScriptedEnding IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), MARY_ANN, <<5,5,3>>) cutsceneStage = CS_CUTSCENE_ENDS ENDIF ENDIF ELSE DEAL_WITH_MICHAEL_OUT_OF_BREATH() IF b_PlayerOnMAsBike IF NOT b_MaryAnnFinalOrdersGiven IF IS_ENTITY_ALIVE(MARY_ANN) CLEAR_PED_TASKS(MARY_ANN) OPEN_SEQUENCE_TASK(seq) TASK_CLEAR_LOOK_AT(NULL) TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, <<-1954.10, -450.90, 16.77>>, PEDMOVEBLENDRATIO_RUN, DEFAULT_TIME_BEFORE_WARP) TASK_WANDER_STANDARD(NULL) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(MARY_ANN, seq) CLEAR_SEQUENCE_TASK(seq) SET_PED_KEEP_TASK(MARY_ANN, TRUE) b_MaryAnnFinalOrdersGiven = TRUE ENDIF ENDIF ENDIF IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), MARY_ANN, <<5,5,3>>) cutsceneStage = CS_CUTSCENE_ENDS ENDIF ENDIF ENDIF BREAK CASE CS_CUTSCENE_ENDS IF b_ScriptedEnding IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), MARY_ANN, <<5,5,3>>) CLEAR_PED_TASKS(PLAYER_PED_ID()) TASK_CLEAR_LOOK_AT(PLAYER_PED_ID()) SET_GAMEPLAY_CAM_RELATIVE_HEADING() RENDER_SCRIPT_CAMS(FALSE, TRUE) RC_END_CUTSCENE_MODE() Script_Passed() ENDIF ENDIF ELSE IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), MARY_ANN, <<5,5,3>>) TASK_CLEAR_LOOK_AT(PLAYER_PED_ID()) //CLEAR_PED_TASKS(PLAYER_PED_ID()) TASK_PLAY_ANIM(PLAYER_PED_ID(), "rcmfanatic1out_of_breath", "p_zero_tired_exit", INSTANT_BLEND_IN, REALLY_SLOW_BLEND_OUT, -1, AF_SECONDARY|AF_UPPERBODY) FORCE_PED_AI_AND_ANIMATION_UPDATE(PLAYER_PED_ID()) Script_Passed() ENDIF ENDIF ENDIF BREAK ENDSWITCH IF b_ScriptedEnding IF IS_CUTSCENE_SKIP_BUTTON_JUST_PRESSED_WITH_DELAY() CLEAR_PED_TASKS(PLAYER_PED_ID()) TASK_CLEAR_LOOK_AT(PLAYER_PED_ID()) SET_GAMEPLAY_CAM_RELATIVE_HEADING() RENDER_SCRIPT_CAMS(FALSE, FALSE) RC_END_CUTSCENE_MODE() INSTANTLY_FILL_VEHICLE_POPULATION() Script_Passed() ENDIF ELSE // Do Mary Ann checks here IF IS_ENTITY_ALIVE(MARY_ANN) CHECK_IF_MARY_ANN_IS_INJURED_KILLED_OR_SCARED() CHECK_IF_PLAYER_IS_IN_A_VEHICLE() // If the player gets too far away after the convo starts, kill the convo, make Mary Ann go away IF cutsceneStage > CS_WAIT_FOR_ANN IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), MARY_ANN) > 15 // If the player's too far away and they're NOT on the bike... IF NOT b_PlayerOnMAsBike // ... and Mary Ann isn't in the bike herself... IF NOT IS_PED_IN_ANY_VEHICLE(MARY_ANN, TRUE) // ... make her go away! IF cutsceneStage <= CS_MARY_ANN_LEAVES IF IS_VEHICLE_OK(MAS_BIKE) OPEN_SEQUENCE_TASK(seq) TASK_LOOK_AT_ENTITY(NULL, MAS_BIKE, -1) TASK_ENTER_VEHICLE(NULL, MAS_BIKE, DEFAULT_TIME_BEFORE_WARP, VS_DRIVER, 1) TASK_CLEAR_LOOK_AT(NULL) TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), 2000) TASK_VEHICLE_DRIVE_TO_COORD(NULL, MAS_BIKE, <<-2018.17, -461.00, 10.56>>, 10, DRIVINGSTYLE_NORMAL, MARYSBIKEMODEL, DF_SteerAroundStationaryCars, 3, 50) TASK_VEHICLE_DRIVE_TO_COORD(NULL, MAS_BIKE, <<-2024.98, -479.55, 10.57>>, 10, DRIVINGSTYLE_NORMAL, MARYSBIKEMODEL, DF_SteerAroundStationaryCars, 3, 50) TASK_VEHICLE_DRIVE_WANDER(NULL, MAS_BIKE, 10, DRIVINGMODE_AVOIDCARS_STOPFORPEDS_OBEYLIGHTS) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(MARY_ANN, seq) CLEAR_SEQUENCE_TASK(seq) SET_PED_KEEP_TASK(MARY_ANN, TRUE) ENDIF ENDIF ENDIF ELSE // The player's on her bike, so make Mary Ann run away instead IF NOT b_MaryAnnFinalOrdersGiven IF IS_ENTITY_ALIVE(MARY_ANN) CLEAR_PED_TASKS(MARY_ANN) OPEN_SEQUENCE_TASK(seq) TASK_CLEAR_LOOK_AT(NULL) TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, <<-1954.10, -450.90, 16.77>>, PEDMOVEBLENDRATIO_RUN, DEFAULT_TIME_BEFORE_WARP) TASK_WANDER_STANDARD(NULL) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(MARY_ANN, seq) CLEAR_SEQUENCE_TASK(seq) SET_PED_KEEP_TASK(MARY_ANN, TRUE) b_MaryAnnFinalOrdersGiven = TRUE ENDIF ENDIF ENDIF // Kill the convo regardless of what Mary Ann is doing KILL_ANY_CONVERSATION() cutsceneStage = CS_CUTSCENE_ENDS ENDIF ENDIF ENDIF ENDIF ENDIF BREAK ENDSWITCH ENDPROC PROC LOST_RACE() SWITCH stageStage CASE SS_SETUP DEBUG_PRINTSTRING("In setup for Lost Race") // remove blips SAFE_REMOVE_BLIP(FANATIC_BLIP) SAFE_REMOVE_BLIP(DESTINATION_BLIP) SAFE_REMOVE_BLIP(NEXT_DESTINATION_BLIP) DELETE_CHECKPOINT(checkPoint) BOOL bWhichConv // Use a random bool to determine which losing convo for Mary Ann to play bWhichConv = GET_RANDOM_BOOL() IF MADialogueState = MA_WITHIN_TALKING_RANGE IF bWhichConv = TRUE CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_LOSE", CONV_PRIORITY_HIGH) DEBUG_PRINTSTRING("Doing 'FAN1_LOSE'") ELSE CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_LOSE2", CONV_PRIORITY_HIGH) DEBUG_PRINTSTRING("Doing 'FAN1_LOSE2'") ENDIF ENDIF OPEN_SEQUENCE_TASK(seq) TASK_LOOK_AT_ENTITY(null, PLAYER_PED_ID(), -1) TASK_PLAY_ANIM(null, "rcmfanatic1celebrate", "celebrate", SLOW_BLEND_IN, FAST_BLEND_OUT, -1, AF_EXIT_AFTER_INTERRUPTED|AF_USE_KINEMATIC_PHYSICS|AF_TAG_SYNC_IN) TASK_PLAY_ANIM(null, "move_f@runner", "idle", FAST_BLEND_IN, SLOW_BLEND_OUT, -1, AF_LOOPING|AF_EXIT_AFTER_INTERRUPTED|AF_USE_KINEMATIC_PHYSICS) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(MARY_ANN, seq) CLEAR_SEQUENCE_TASK(seq) DEBUG_PRINTSTRING("Going into loop for Lost Race") stageStage = SS_STAGE BREAK CASE SS_STAGE IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() DEBUG_PRINTSTRING("No conversation going in Lost Race, failing properly now") TRIGGER_MUSIC_EVENT("RC6A_FAIL") failReason = FAIL_SHE_BEAT_YOU_TO_BIKE stageStage = SS_SETUP missionstage = MS_FAIL_WAIT_FOR_FADE ENDIF BREAK ENDSWITCH ENDPROC /// PURPOSE: Main process to handle mission failure and the fade out PROC FAIL_WAIT_FOR_FADE() SWITCH stageStage CASE SS_SETUP CLEAR_PRINTS() CLEAR_HELP() IF FailReason <> FAIL_FANATIC_SCARED IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() DEBUG_PRINTSTRING("Killing conversation in fail state") KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() ENDIF ELSE IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_AGGRO", CONV_PRIORITY_VERY_HIGH) DEBUG_PRINTSTRING("Playing aggro convo with subs") ENDIF ELSE DEBUG_PRINTSTRING("Convo already active when failing for scaring Mary Ann - playing without subs asap?") KILL_ANY_CONVERSATION() ADD_NON_CRITICAL_STANDARD_CONVERSATION_TO_BUFFER(MyLocalPedStruct, "FAN1AU", "FAN1_AGGRO", CONV_PRIORITY_HIGH) ENDIF ENDIF // remove blips SAFE_REMOVE_BLIP(FANATIC_BLIP) SAFE_REMOVE_BLIP(DESTINATION_BLIP) SAFE_REMOVE_BLIP(NEXT_DESTINATION_BLIP) DELETE_CHECKPOINT(checkPoint) // handle Mary Ann IF FailReason = FAIL_FANATIC_INJURED OR FailReason = FAIL_FANATIC_KILLED OR FailReason = FAIL_FANATIC_SCARED IF IS_ENTITY_ALIVE(MARY_ANN) TASK_SMART_FLEE_PED(MARY_ANN, PLAYER_PED_ID(), 80, -1) ENDIF ENDIF STRING fText SWITCH FailReason CASE FAIL_FANATIC_KILLED fText = "FATIC1_F8" BREAK CASE FAIL_FANATIC_SCARED fText = "FATIC1_F2" BREAK CASE FAIL_FANATIC_INJURED fText = "FATIC1_F1" BREAK CASE FAIL_IN_CAR fText = "FATIC1_F5" BREAK CASE FAIL_YOU_DIDNT_KEEP_UP fText = "FATIC1_F3" BREAK CASE FAIL_SHE_BEAT_YOU_TO_BIKE fText = "FATIC1_F7" BREAK CASE FAIL_LEFT_RACE fText = "FATIC1_F6" BREAK DEFAULT BREAK ENDSWITCH IF NOT IS_STRING_NULL_OR_EMPTY(fText) Random_Character_Failed_With_Reason(fText) ELSE Random_Character_Failed() ENDIF stageStage = SS_STAGE BREAK CASE SS_STAGE 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) //MISSION_FLOW_SET_FAIL_WARP_LOCATION(<< -1860.4117, -416.5467, 44.9804 >>, 143.1230) //SET_REPLAY_DECLINED_VEHICLE_WARP_LOCATION(<< -1856.55, -413.59, 45.32 >>, -120.328) // finished fading out DELETE_EVERYTHING() TURN_ROADS_ON() RESET_PLAYER_HAS_CHANGE_CLOTHES_ON_MISSION(CHAR_MICHAEL, bHasChanged) Script_Cleanup() ELSE // not finished fading out // you may want to handle dialogue etc here. ENDIF 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]") TRIGGER_MUSIC_EVENT("RC6A_FAIL") Random_Character_Failed() Script_Cleanup() ENDIF IF Is_Replay_In_Progress() // Set up the initial scene for replays OR IS_REPEAT_PLAY_ACTIVE() g_bSceneAutoTrigger = TRUE eInitialSceneStage = IS_REQUEST_SCENE WHILE NOT SetupScene_FANATIC_1(sRCLauncherDataLocal) WAIT(0) ENDWHILE g_bSceneAutoTrigger = FALSE ENDIF DISABLE_CHEAT(CHEAT_TYPE_FAST_RUN, TRUE) MARY_ANN = sRCLauncherDataLocal.pedID[0] bHasChanged = GET_PLAYER_HAS_CHANGE_CLOTHES_ON_MISSION(CHAR_MICHAEL) #IF IS_DEBUG_BUILD IF NOT DOES_WIDGET_GROUP_EXIST(widgetGroup) widgetGroup= START_WIDGET_GROUP("Fanatic 1 widgets") ADD_WIDGET_FLOAT_SLIDER("Maximum MBR rate increase", fMBRMax, 1.01, 1.15, 0.005) ADD_WIDGET_FLOAT_SLIDER("Maximum MBR speed", fMBR_MaxRunSpeed, 2.5, 3.0, 0.01) ADD_WIDGET_INT_SLIDER("Mary Ann sprint length (ms)", iSprintLength, 500, 5000, 100) ADD_WIDGET_INT_SLIDER("Mary Ann sprint cooldown delay (ms)", iSprintDelay, 500, 10000, 100) ADD_WIDGET_BOOL("TTY Toggle - Print Mission Debug Info", bDebug_PrintToTTY) ADD_WIDGET_BOOL("TTY Toggle - Print Mary Ann Speed debug", bDebug_SpeedDebug) ADD_WIDGET_FLOAT_READ_ONLY("Player sprint time remaining: ", fPlayerSprintRemaining) STOP_WIDGET_GROUP() ENDIF #ENDIF REGISTER_SCRIPT_WITH_AUDIO() IF IS_REPLAY_IN_PROGRESS() OR IS_REPEAT_PLAY_ACTIVE() CPRINTLN(DEBUG_MISSION, "Fanatic 1 *** Replay/repeat play IS in progress, doing INIT() now") RC_SET_ENTITY_PROOFS_FOR_CUTSCENE(sRCLauncherDataLocal, FALSE) IF IS_ENTITY_ALIVE(MARY_ANN) SET_ENTITY_PROOFS(MARY_ANN, FALSE, FALSE, FALSE, FALSE, FALSE) ENDIF START_REPLAY_SETUP(<<-1878.2344, -439.6985, 45.0299>>, 241.0468) INIT() IF NOT IS_REPEAT_PLAY_ACTIVE() // Play the intro if we do a repeat play SWITCH GET_REPLAY_MID_MISSION_STAGE() CASE CP_AFTER_MOCAP CPRINTLN(DEBUG_MISSION, "Fanatic 1 *** Replay/retry active, not a repeat play, skipping intro") JUMP_TO_STAGE(DEBUG_TO_START) BREAK ENDSWITCH ELSE IF IS_REPLAY_IN_PROGRESS() SWITCH GET_REPLAY_MID_MISSION_STAGE() CASE CP_AFTER_MOCAP CPRINTLN(DEBUG_MISSION, "Fanatic 1 *** Replay/retry active, is also a repeat play, skipping intro") JUMP_TO_STAGE(DEBUG_TO_START) BREAK ENDSWITCH ELSE CPRINTLN(DEBUG_MISSION, "Fanatic 1 *** Replay/retry NOT active, but is repeat play, playing intro") JUMP_TO_STAGE(DEBUG_TO_INTRO) ENDIF ENDIF ELSE CPRINTLN(DEBUG_MISSION, "Fanatic 1 *** Replay IS NOT in progress, proceeding normally") ENDIF // Loop within here until the mission passes or fails WHILE(TRUE) REPLAY_CHECK_FOR_EVENT_THIS_FRAME("SF_EDM") WAIT(0) UPDATE_MISSION_NAME_DISPLAYING(sRCLauncherDataLocal.sIntroCutscene, TRUE) CHECK_FAIL_POSSIBILITIES() DEAL_WITH_THE_RACE_TRACKING() HANDLE_GLOBAL_STAMINA_HELP() IF missionStage <> MS_LEADIN AND missionStage <> MS_CUTSCENE AND missionStage <> MS_FAIL_WAIT_FOR_FADE AND missionStage <> MS_LOST_RACE IF missionStage <> MS_END_CUTSCENE CHECK_PLAYER_COLLISIONS() ELSE // Stop the heartbeat audio from playing during the end cutscene if you ride away //STOP_SOUND(iHeartbeatAudioID) ENDIF DEAL_WITH_MARY_ANN() TRY_OVERTAKE_LINE() ELIF missionStage = MS_LEADIN // Disable controls and exit current vehicle RC_PLAYER_TRIGGER_SCENE_LOCK_IN() ELIF missionStage = MS_CUTSCENE IF IS_ENTITY_ALIVE(MARY_ANN) SET_PED_MAX_MOVE_BLEND_RATIO(MARY_ANN, 2.3) ENDIF ENDIF SWITCH missionStage CASE MS_LEADIN LEADIN() BREAK CASE MS_CUTSCENE INTRO_CUTSCENE() BREAK CASE MS_START_RUNNING START_RUNNING() BREAK CASE MS_ROAD_RUNNING_SECTION ROAD_RUNNING_SECTION() BREAK CASE MS_STEPS_DOWN STEPS_DOWN() BREAK CASE MS_SPRINT_TO_FINISH SPRINT_TO_FINISH() BREAK CASE MS_DEBUG_NEAR_FINISH_LINE DEBUG_NEAR_FINISH_LINE() BREAK CASE MS_PLAYER_IN_VEHICLE STAGE_PLAYER_IN_VEHICLE() BREAK CASE MS_END_CUTSCENE END_CUTSCENE() BREAK CASE MS_LOST_RACE LOST_RACE() BREAK CASE MS_FAIL_WAIT_FOR_FADE FAIL_WAIT_FOR_FADE() BREAK ENDSWITCH #IF IS_DEBUG_BUILD DEBUG_Check_Debug_Keys() #ENDIF ENDWHILE // Script should never reach here. Always terminate with cleanup function. ENDSCRIPT