Files
gtav-src/script/dev_ng/singleplayer/scripts/RandomChar/Extreme/Extreme1.sc
T
2025-09-29 00:52:08 +02:00

4404 lines
189 KiB
Python
Executable File

//Compile out Title Update changes to header functions.
//Must be before includes.
//CONST_INT USE_TU_CHANGES 0 // Removed by Kenneth R.
// MISSION NAME : Extreme1.sc
// AUTHOR : Kev Edwards
// DESCRIPTION : Dog guides Franklin to Dom stuck in a tree, who invites Franklin to parachute jump out of a helicopter with him then race bikes down a mountain
USING "rage_builtins.sch"
USING "globals.sch"
USING "cutscene_public.sch"
USING "commands_cutscene.sch"
USING "commands_entity.sch"
USING "commands_script.sch"
USING "script_player.sch"
USING "randomChar_public.sch"
USING "cutscene_public.sch"
USING "commands_cutscene.sch"
USING "dialogue_public.sch"
USING "RC_Helper_Functions.sch"
USING "rc_launcher_public.sch"
USING "initial_scenes_Extreme.sch"
USING "script_ped.sch"
USING "CompletionPercentage_public.sch"
USING "script_races.sch"
USING "RC_Threat_public.sch"
USING "chase_hint_cam.sch" CHASE_HINT_CAM_STRUCT localChaseHintCamStruct
USING "commands_recording.sch"
#IF IS_DEBUG_BUILD
USING "select_mission_stage.sch"
#ENDIF
g_structRCScriptArgs sRCLauncherDataLocal
CONST_INT CP_FOLLOW_DOG 0 // Checkpoints
CONST_INT CP_MIDTRO 1
CONST_INT CP_GET_IN_HELICOPTER 2
CONST_INT CP_SKYDIVE 3
CONST_INT CP_BIKERACE_START 4
CONST_INT CP_BIKERACE_MIDDLE 5
CONST_INT CP_BIKERACE_NEAR_END 6
CONST_INT CP_OUTRO_CUTSCENE 7
BOOL bSetMidRaceCheckpoint[2] // Used to store whether we've set the mid-race checkpoints
BOOL bUpdatedMusicWhenNearingEndOfRace
CONST_INT Z_SKIP_INTRO 0 // Z Skips
CONST_INT Z_SKIP_FOLLOW_DOG 1
CONST_INT Z_SKIP_MIDTRO 2
CONST_INT Z_SKIP_GET_IN_HELICOPTER 3
CONST_INT Z_SKIP_JUMP_OUT_HELICOPTER 4
CONST_INT Z_SKIP_RACE_START 5
CONST_INT Z_SKIP_RACE_MIDDLE 6
CONST_INT Z_SKIP_RACE_NEAR_END 7
CONST_INT Z_SKIP_OUTRO_CUTSCENE_1 8
CONST_INT Z_SKIP_OUTRO_CUTSCENE_2 9
ENUM EXT1_MISSION_STATE
stateNULL,
stateIntro,
stateFollowDog,
stateMidtro,
stateGetInHelicopter,
stateHelicopterAscend,
stateJumpOutHelicopter,
stateSkyDive,
stateWaitForDom,
stateRaceDom,
stateRaceEndConversation,
stateMissionPassed,
stateFailed,
NUM_MISSION_STATES
ENDENUM
EXT1_MISSION_STATE missionState = stateIntro // Stores the current EXT1_MISSION_STATE
EXT1_MISSION_STATE missionStateSkip = stateNULL // Used if needing to change to a EXT1_MISSION_STATE out of sequence
ENUM EXT1_STATE_MACHINE
EXT1_STATE_MACHINE_SETUP,
EXT1_STATE_MACHINE_LOOP,
EXT1_STATE_MACHINE_CLEANUP
ENDENUM
EXT1_STATE_MACHINE missionStateMachine = EXT1_STATE_MACHINE_SETUP
ENUM FAILED_REASON
FAILED_DEFAULT = 0,
FAILED_DOG_DIED,
FAILED_DOM_DIED,
FAILED_OUTSIDE_ZONE,
FAILED_HELICOPTER_WRECKED,
FAILED_DIDNT_HELP_DOM,
FAILED_DIDNT_FOLLOW_DOG,
FAILED_DOM_INJURED,
FAILED_DOG_INJURED,
FAILED_PILOT_INJURED,
FAILED_DIDNT_ENTER_HELICOPTER,
FAILED_LEFT_MISSION_AREA,
FAILED_PILOT_SCARED,
FAILED_DOM_SCARED,
FAILED_DOG_SCARED,
FAILED_BIKE_WRECKED,
FAILED_FAILED_RACE,
FAILED_PLAYER_BIKE_LOST,
FAILED_FAILED_SKY_DIVE
ENDENUM
FAILED_REASON failReason
STRING failString
ENUM DOM_STATUS
DOM_IN_HELICOPTER,
DOM_GETTING_OUT_HELICOPTER,
DOM_DEPLOYING,
DOM_SKYDIVING,
DOM_PARACHUTING,
DOM_FINAL_TARGET,
DOM_LANDED,
DOM_GETTING_ON_BIKE,
DOM_SAT_ON_BIKE
ENDENUM
DOM_STATUS domStatus = DOM_IN_HELICOPTER
BOOL bZSkipping = FALSE // Changes to TRUE if z skipping to prevent subsequent mission state changes etc
BOOL bOpenedTimeWindowForSkydiveStat
BOOL bPlayerAttainedJumpStat
#IF IS_DEBUG_BUILD
CONST_INT MAX_SKIP_MENU_LENGTH 10
MissionStageMenuTextStruct mSkipMenu[MAX_SKIP_MENU_LENGTH]
WIDGET_GROUP_ID widgetGroup
BOOL bDebug_PrintToTTY = TRUE
BOOL bDebug_ShowRaceWarningDialogueTriggers = FALSE
INT iDebugSkipTime // Prevents skipping instantaneously
#ENDIF
INT iSkipToRaceCheckpoint = -1
VECTOR vPlayerCarRespot = <<-196.9491, 1301.1444, 303.2162>>
CONST_FLOAT fPlayerCarRespot 216.9263
RACER_INFO_STRUCT playerInfo
RACE_INFO_STRUCT raceInfo
CAMERA_INDEX camCutscene
INT iCutsceneStage = 0
BOOL bCutsceneSkipped
INT iOutroSynchedScene
BOOL bIsMidtroLoaded
INT iLeadInTimer
INT iEnterHeliSynchedScene
CAMERA_INDEX camEnterHeli
CONST_INT NUM_PED_MODELS 2
MODEL_NAMES modelPed[NUM_PED_MODELS]
CONST_INT EXT1_MODEL_PILOT 0
CONST_INT EXT1_MODEL_DOG 1
CONST_INT NUM_VEHICLE_MODELS 2
MODEL_NAMES modelVeh[NUM_VEHICLE_MODELS]
CONST_INT EXT1_MODEL_HELICOPTER 0
CONST_INT EXT1_MODEL_BIKE 1
PED_INDEX pedDog
PED_INDEX pedDom
VECTOR vDom = << 123.647, 1245.045, 252.8 >>
CONST_FLOAT fDom 30.0
SEQUENCE_INDEX fleeSequence // For if Dom or the dog need to flee Franklin
SEQUENCE_INDEX seqDomAnim
SEQUENCE_INDEX seqFranklinLeadIn
PED_INDEX pedPilot
VEHICLE_INDEX vehHelicopter
INT iHelicopterColour = 3
CONST_FLOAT fHelicopterSpeedFlat 25.0
CONST_FLOAT fHelicopterSpeedRise 100.0
BLIP_INDEX blipDog
BLIP_INDEX blipDom
BLIP_INDEX blipHelicopter
CONST_INT DOG_CONVERSATION_START_DIST 30 // Conversation with dog en-route to Dom only plays when Franklin is closer than this distance
structPedsForConversation sConversation
BOOL bStartedDogConversation
BOOL bStartedSeesDomConversation
BOOL bStartedAscendConversation
BOOL bStartedAscend2Conversation
BOOL bStartedAscend3Conversation
BOOL bStartedSummitConversation
BOOL bStartedJumpOutConversation
BOOL bStartedHurryUpConversation
BOOL bStartedPushOutConversation
BOOL bStartedJumpedOutConversation
BOOL bStartedDuringSkydiveConversation
BOOL bStoppedDuringSkydiveConversation
BOOL bRestartedDuringSkydiveConversation
BOOL bStartedDeployParachuteConversation
BOOL bStartedFairRaceConversation
BOOL bStartedRaceStartConversation
BOOL bStartedDomLandsConversation
BOOL bStartedThreatenDomConversation
BOOL bStartedDomCallPilotConversation
BOOL bStartedPilotGetInConversation
BOOL bStartedLeavingWithoutYouConversation
BOOL bStartedLeftWithoutYouConversation
BOOL bStartedWrongSideConversation
BOOL bStartedGetOnBikeReminderConversation
BOOL bPushedOutPlayer
BOOL bDomLookingAtHelicopter
BOOL bHelicopterLanded
INT iCurrentHelicopterMission
BOOL bPlayerLockedIntoEnteringHelicopter
BOOL bPlayerNowEnteringHelicopter
BOOL bGivenMissionAreaWarning
BOOL bLandedOutsideArea
BOOL bFranklinExitingHelicopter
VEHICLE_SEAT seatDom
CONST_INT NUM_DOG_WAYPOINTS 23
VECTOR vDogWaypoint[NUM_DOG_WAYPOINTS]
INT iNextDogWaypoint = 0
ENUM DOG_STATE
DOG_WAITING,
DOG_RUNNING,
DOG_ANIMATING,
DOG_FINISHED
ENDENUM
DOG_STATE stateDog
CONST_INT DOG_STOP_DIST 30
CONST_INT DOG_RUN_DIST 20
SEQUENCE_INDEX seqDog
VECTOR vHelicopterStart
CONST_FLOAT fHelicopterStart 278.0
VECTOR vHelicopterLand = << 153.457260,1272.411499,250 >>
VECTOR vHelicopterEnd = << 445, 4710, 2400 >>//<< 500, 5350, 2400 >>
CONST_FLOAT fHelicopterDesiredHeading 270.0 // Heading for the helicopter when hovering at the skydive so the player will be headed towards the checkpoint when he jumps out
BLIP_INDEX blipCheckpoint
VECTOR vLandingPos = << 497.01923, 5590.00000, 793.82373 >>
VECTOR vCheckpoint = << 493.43539, 5585.76221, 794.5 >>
VECTOR vMarkerRotation = << -90, 0, 0 >>
VECTOR vFranklinAfterIntro = << -189.9982, 1297.7646, 302.9516 >>
CONST_FLOAT fFranklinAfterIntro 231.5293
VECTOR vDomAfterMidtro = <<123.518105,1248.512451,253.766983>>
CONST_FLOAT fDomAfterMidtro -46.98
VECTOR vFranklinAfterMidtro = << 124.6139, 1248.0530, 253.7414 >>
CONST_FLOAT fFranklinAfterMidtro -53.85
VECTOR vDomBesideHelicopter = <<149.5508, 1266.9005, 249.5952>>
BOOL bDisplayedJumpOutHelpText
BOOL bDisplayedSkipJourneyHelpText
BOOL bSkippingJourney
OBJECT_INDEX oParachute
MODEL_NAMES modelParachute
VECTOR vParachute = << 122.3, 1244.7, 250.2 >>
CONST_FLOAT fParachute 0.0
REL_GROUP_HASH relGroupFriendly
CONST_INT NUM_BIKES 2
VEHICLE_INDEX vehBike[NUM_BIKES]
VECTOR vBike[NUM_BIKES]
FLOAT fBike[NUM_BIKES]
VECTOR vBikeOutro[NUM_BIKES]
BLIP_INDEX blipBike[NUM_BIKES]
CONST_INT BIKE_0 0
CONST_INT BIKE_1 1
INT iPlayersChosenBike
INT iDomsBike
BOOL bToldToGetBackOnBike
BOOL bAllowPlaySlowDialogue
BOOL bPlayerGotOnABike
BOOL bToldToWaitForDom
BOOL bStartedRace
BOOL bToldToGoToDom
INT iNumSlowConversationsPlayed
CONST_INT NUM_SLOW_DIALOGUE_LINES 4
INT iBikeRaceDialogueTimer
INT iBikeRaceConversationsDone
CONST_INT NUM_BIKE_RACE_DIALOGUE_LINES 4
STRING stringBikeRaceConversation[NUM_BIKE_RACE_DIALOGUE_LINES]
BOOL bDoneBikeRaceConversation[NUM_BIKE_RACE_DIALOGUE_LINES]
INT iDomNextCheckpoint
INT iRacePos
CONST_INT NUM_CHECKPOINTS 39
FLOAT fCheckpointFailDistance[NUM_CHECKPOINTS]
CONST_INT RACE_ABANDONED_DISTANCE 125 // Increased from 50 due to B*1034787 and B*1078601
BOOL bDoneRollingStart
INT iRollingStartTimer
BOOL bSlowestDomSpeed
BOOL bSetPlaybackToUseAI
BOOL bPlayerStartedRaceEarly
BOOL bPlayerGotFullyOnBike
CONST_INT NUM_WARNING_DIALOGUE 14
BOOL bDoneWarningDialogue[NUM_WARNING_DIALOGUE]
STRING stringWarningDialogue[NUM_WARNING_DIALOGUE]
VECTOR vWarningDialogue[NUM_WARNING_DIALOGUE]
VECTOR vDogSpawnPos = <<-194.23189, 1298.40088, 302.96289>>
CONST_FLOAT fDogSpawnPos -110.0
VECTOR vDogSpawnPosAlt = <<-188.33487, 1294.25964, 303>> // A few metres further ahead towards vDogWaypoint[0]
CONST_FLOAT fDogSpawnPosAlt -110.0
INT iDomGruntsDialogueTimer
INT iDogAnimsTimer
INT iEnterHelicopterTimer
INT iHelicopterPushOutTimer
INT iFailedLandingTimer
INT iDogHelpTextTimer
INT iCollisionDialogueTimer
INT iJumpStatTimer
INT iSkydiveDialogueTimer
INT iFranklinAheadConversationTimer
INT iPlayerEnterHelicopterTimer
INT iGetOnBikeReminderTimer
INT iDomFocusPushInTimer
INT iNumberSkydiveBanterDomDone
INT iNumberSkydiveBanterFranklinDone
VECTOR vLookCameraRot
CAMERA_INDEX camSkydive
CAMERA_INDEX camSkydiveInterp
VECTOR vSkydiveInterp = <<1.5,-0.2,2.0>>
FLOAT fSkydiveInterp = 30.0
VEHICLE_INDEX vehForReplay
SCENARIO_BLOCKING_INDEX blockScenarios
INT iWindSound = GET_SOUND_ID()
RC_CONV_RESTORE_STATE stateRestoreConversation
TEXT_LABEL_23 tSavedConversationLabel
INT iSceneId
SEQUENCE_INDEX jumpSequence
FLOAT fCameraRotationForSide
FLOAT fHelicopterHeading
VECTOR vFocalOffset
VECTOR vFocalPoint
VECTOR vCurrentFocalOffset
FLOAT fCameraXOffset
BOOL bDomCycledForward
BOOL bStartedDomFocusPushIn
STRING sSkydiveRoot
STRING sSkydiveLabel
BOOL bDone1stPersonCameraFlash = FALSE
BOOL bSetCameraToThirdPerson = FALSE
/// PURPOSE:
/// Used in every EXT1_STATE_MACHINE_SETUP. Advances state machine to EXT1_STATE_MACHINE_LOOP.
PROC EXT1_STATE_SETUP(#IF IS_DEBUG_BUILD STRING s_text #ENDIF)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Initialising ", s_text) ENDIF #ENDIF
bZSkipping = FALSE
#IF IS_DEBUG_BUILD iDebugSkipTime = GET_GAME_TIMER() #ENDIF
missionStateMachine = EXT1_STATE_MACHINE_LOOP
ENDPROC
/// PURPOSE:
/// Used in every EXT1_STATE_MACHINE_CLEANUP. Advances state machine to EXT1_STATE_MACHINE_SETUP.
PROC EXT1_STATE_CLEANUP(BOOL bCleanupPrints = TRUE)
IF bCleanupPrints = TRUE
CLEAR_PRINTS()
ENDIF
CLEAR_HELP(TRUE)
IF missionStateSkip = stateNULL
missionState = INT_TO_ENUM(EXT1_MISSION_STATE, ENUM_TO_INT(missionState) + 1)
ELSE
missionState = missionStateSkip
ENDIF
missionStateSkip = stateNULL
missionStateMachine = EXT1_STATE_MACHINE_SETUP
ENDPROC
/// PURPOSE:
/// Remove all blips associated with the checkpoint race.
PROC EXT1_REMOVE_RACE_BLIPS()
IF DOES_BLIP_EXIST(playerInfo.checkBlip)
SAFE_REMOVE_BLIP(playerInfo.checkBlip)
DELETE_CHECKPOINT(playerInfo.checkPoint)
ENDIF
SAFE_REMOVE_BLIP(playerInfo.nextCheckBlip)
ENDPROC
/// PURPOSE:
/// Safely remove all blips in this mission.
PROC EXT1_REMOVE_ALL_BLIPS()
SAFE_REMOVE_BLIP(blipDog)
SAFE_REMOVE_BLIP(blipDom)
SAFE_REMOVE_BLIP(blipHelicopter)
SAFE_REMOVE_BLIP(blipCheckpoint)
SAFE_REMOVE_BLIP(blipBike[BIKE_0])
SAFE_REMOVE_BLIP(blipBike[BIKE_1])
EXT1_REMOVE_RACE_BLIPS()
ENDPROC
/// PURPOSE:
/// Safely remove all vehicles in this mission.
PROC EXT1_REMOVE_ALL_VEHICLES(BOOL b_delete = FALSE)
IF b_delete = TRUE
SAFE_DELETE_VEHICLE(vehHelicopter)
SAFE_DELETE_VEHICLE(vehBike[BIKE_0])
SAFE_DELETE_VEHICLE(vehBike[BIKE_1])
SAFE_DELETE_VEHICLE(vehForReplay)
ELSE
IF IS_SCREEN_FADED_OUT()
SAFE_DELETE_VEHICLE(vehHelicopter)
ELSE
SAFE_RELEASE_VEHICLE(vehHelicopter)
ENDIF
SAFE_RELEASE_VEHICLE(vehBike[BIKE_0])
SAFE_RELEASE_VEHICLE(vehBike[BIKE_1])
SAFE_RELEASE_VEHICLE(vehForReplay)
ENDIF
ENDPROC
/// PURPOSE:
/// Sets ped to wander after mission.
PROC EXT1_MAKE_PED_WANDER(PED_INDEX ped_to_wander)
IF IS_ENTITY_ALIVE(ped_to_wander)
AND NOT IsPedPerformingTask(ped_to_wander, SCRIPT_TASK_VEHICLE_DRIVE_WANDER) // Don't overwrite Dom's task at the end of the mission
AND NOT IsPedPerformingTask(ped_to_wander, SCRIPT_TASK_WANDER_STANDARD)
AND NOT IsPedPerformingTask(ped_to_wander, SCRIPT_TASK_SMART_FLEE_PED)
AND NOT IsPedPerformingTask(ped_to_wander, SCRIPT_TASK_PERFORM_SEQUENCE)
SET_PED_KEEP_TASK(ped_to_wander, TRUE)
TASK_WANDER_STANDARD(ped_to_wander)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Set ped to wander") ENDIF #ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Mission is failing so set alive peds to flee from the player.
PROC EXT1_SET_PED_TO_FLEE(PED_INDEX ped_to_flee)
IF IS_ENTITY_ALIVE(ped_to_flee)
IF NOT IS_PED_IN_ANY_VEHICLE(ped_to_flee)
CLEAR_PED_TASKS(ped_to_flee)
ENDIF
SET_PED_KEEP_TASK(ped_to_flee, TRUE)
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
OPEN_SEQUENCE_TASK(fleeSequence)
IF IS_ENTITY_ALIVE(vehHelicopter)
AND IS_PED_IN_VEHICLE(ped_to_flee, vehHelicopter)
TASK_LEAVE_ANY_VEHICLE(NULL)
ENDIF
TASK_SMART_FLEE_PED(NULL, PLAYER_PED_ID(), 100, -1)
CLOSE_SEQUENCE_TASK(fleeSequence)
TASK_PERFORM_SEQUENCE(ped_to_flee, fleeSequence)
CLEAR_SEQUENCE_TASK(fleeSequence)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Set ped to flee") ENDIF #ENDIF
ELSE
TASK_WANDER_STANDARD(ped_to_flee)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Set ped to wander") ENDIF #ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Safely remove all peds in this mission.
PROC EXT1_REMOVE_ALL_PEDS(BOOL b_delete = FALSE)
IF IS_ENTITY_ALIVE(pedDom)
SET_ENTITY_LOAD_COLLISION_FLAG(pedDom, FALSE)
ENDIF
IF IS_ENTITY_ALIVE(pedDog)
SET_ENTITY_LOAD_COLLISION_FLAG(pedDog, FALSE)
ENDIF
IF b_delete = TRUE
SAFE_DELETE_PED(pedDom)
SAFE_DELETE_PED(pedPilot)
SAFE_DELETE_PED(pedDog)
ELSE
IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) // See B*902906 - dog & Dom should flee if Franklin has died, otherwise only be set to wander
EXT1_MAKE_PED_WANDER(pedDog)
EXT1_MAKE_PED_WANDER(pedDom)
ELSE
EXT1_SET_PED_TO_FLEE(pedDog)
EXT1_SET_PED_TO_FLEE(pedDom)
ENDIF
SAFE_RELEASE_PED(pedDom)
SAFE_RELEASE_PED(pedPilot)
SAFE_RELEASE_PED(pedDog)
ENDIF
ENDPROC
/// PURPOSE:
/// Models required for a mission state are all loaded when the mission state inits, but this is a safety check to ensure a model is loaded before subsequently creating an entity using it.
PROC EXT1_ENSURE_MODEL_IS_LOADED(MODEL_NAMES e_model)
REQUEST_MODEL(e_model)
IF NOT HAS_MODEL_LOADED(e_model)
WHILE NOT HAS_MODEL_LOADED(e_model)
WAIT(0)
ENDWHILE
ENDIF
ENDPROC
/// PURPOSE:
/// Safely creates a vehicle.
PROC EXT1_CREATE_VEHICLE(VEHICLE_INDEX &veh_to_create, MODEL_NAMES e_model, VECTOR v_pos, FLOAT f_heading = 0.0, INT i_colour = -1)
IF NOT DOES_ENTITY_EXIST(veh_to_create)
EXT1_ENSURE_MODEL_IS_LOADED(e_model)
veh_to_create = CREATE_VEHICLE(e_model, v_pos, f_heading)
IF i_colour >= 0
SET_VEHICLE_COLOUR_COMBINATION(veh_to_create, i_colour)
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Safely creates a ped.
PROC EXT1_CREATE_PED(PED_INDEX &ped_to_create, MODEL_NAMES e_model, VECTOR v_pos, FLOAT f_heading = 0.0)
IF NOT DOES_ENTITY_EXIST(ped_to_create)
EXT1_ENSURE_MODEL_IS_LOADED(e_model)
ped_to_create = CREATE_PED(PEDTYPE_MISSION, e_model, v_pos, f_heading)
SET_PED_DEFAULT_COMPONENT_VARIATION(ped_to_create)
REMOVE_ALL_PED_WEAPONS(ped_to_create)
ENDIF
ENDPROC
/// PURPOSE:
/// Safely creates a ped inside a vehicle.
PROC EXT1_CREATE_PED_IN_VEHICLE(VEHICLE_INDEX veh, PED_INDEX &ped_to_create, MODEL_NAMES e_model, VEHICLE_SEAT seat)
IF NOT DOES_ENTITY_EXIST(ped_to_create)
AND DOES_ENTITY_EXIST(veh)
EXT1_ENSURE_MODEL_IS_LOADED(e_model)
ped_to_create = CREATE_PED_INSIDE_VEHICLE(veh, PEDTYPE_MISSION, e_model, seat)
SET_PED_DEFAULT_COMPONENT_VARIATION(ped_to_create)
REMOVE_ALL_PED_WEAPONS(ped_to_create)
ENDIF
ENDPROC
/// PURPOSE:
/// Stop the hanging animation on Dom.
PROC EXT1_STOP_DOM_ANIMATIONS()
IF IS_ENTITY_ALIVE(pedDom)
IF IS_ENTITY_PLAYING_ANIM(pedDom, "rcm_extreme1", "es_1_rcm_dom_upside_down_base")
STOP_ANIM_TASK(pedDom, "rcm_extreme1", "es_1_rcm_dom_upside_down_base")
ENDIF
IF IS_ENTITY_PLAYING_ANIM(pedDom, "rcm_extreme1", "es_1_rcm_dom_upside_down_fidget_01")
STOP_ANIM_TASK(pedDom, "rcm_extreme1", "es_1_rcm_dom_upside_down_fidget_01")
ENDIF
IF IS_ENTITY_PLAYING_ANIM(pedDom, "rcm_extreme1", "es_1_rcm_dom_upside_down_fidget_02")
STOP_ANIM_TASK(pedDom, "rcm_extreme1", "es_1_rcm_dom_upside_down_fidget_02")
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Stop bike carrec and unload it.
PROC EXT1_STOP_AND_UNLOAD_BIKE_CARREC()
IF iDomsBike = 0
OR iDomsBike = 1
IF IS_ENTITY_ALIVE(vehBike[iDomsBike])
AND IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vehBike[iDomsBike])
STOP_PLAYBACK_RECORDED_VEHICLE(vehBike[iDomsBike])
ENDIF
ENDIF
REMOVE_VEHICLE_RECORDING(500, "Ext1_BikeRace")
ENDPROC
/// PURPOSE:
/// Stops loads of scenarios etc starting along the bike race route.
PROC EXT1_BLOCK_SPAWNERS_FOR_BIKE_RACE(BOOL b_block)
IF b_block = TRUE
SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(vCheckpoint-<<50,50,50>>, vCheckpoint+<<50,50,50>>, FALSE)
REMOVE_VEHICLES_FROM_GENERATORS_IN_AREA(vCheckpoint-<<50,50,50>>, vCheckpoint+<<50,50,50>>)
CLEAR_AREA(vCheckpoint, 50, TRUE)
ELSE
SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(vCheckpoint-<<50,50,50>>, vCheckpoint+<<50,50,50>>, TRUE)
ENDIF
ENDPROC
/// PURPOSE:
/// Start/stop an audio scene.
PROC EXT1_START_AUDIO_SCENE(STRING s_scene_name, BOOL b_start)
IF b_start = TRUE
IF NOT IS_AUDIO_SCENE_ACTIVE(s_scene_name)
START_AUDIO_SCENE(s_scene_name)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started audio scene ", s_scene_name) ENDIF #ENDIF
ENDIF
ELIF IS_AUDIO_SCENE_ACTIVE(s_scene_name)
STOP_AUDIO_SCENE(s_scene_name)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Stopped audio scene ", s_scene_name) ENDIF #ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Clean up everything conceivably setup in this mission.
/// PARAMS:
/// bTerminateMission - TRUE if cleaning up before terminating, FALSE if cleaning up before a debug skip.
PROC EXT1_MISSION_CLEANUP(BOOL b_remove_parachute_prop = TRUE, BOOL b_delete_entities = FALSE, BOOL b_terminate_mission = FALSE)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Cleaning up mission...") ENDIF #ENDIF
CLEAR_PRINTS()
CLEAR_HELP()
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
KILL_CHASE_HINT_CAM(localChaseHintCamStruct)
REMOVE_PED_FOR_DIALOGUE(sConversation, 1) // Franklin
REMOVE_PED_FOR_DIALOGUE(sConversation, 3) // Dom
REMOVE_PED_FOR_DIALOGUE(sConversation, 4) // Pilot
REMOVE_PED_FOR_DIALOGUE(sConversation, 5) // Dog
EXT1_STOP_DOM_ANIMATIONS()
EXT1_STOP_AND_UNLOAD_BIKE_CARREC()
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
SET_PED_CONFIG_FLAG(PLAYER_PED_ID(), PCF_ForceDirectEntry, FALSE)
SET_PED_HELMET(PLAYER_PED_ID(), TRUE) // B*1538808 Allow Franklin putting headset on, was set to false during mission
TASK_CLEAR_LOOK_AT(PLAYER_PED_ID())
ENDIF
EXT1_REMOVE_ALL_BLIPS()
EXT1_REMOVE_ALL_PEDS(b_delete_entities)
EXT1_REMOVE_ALL_VEHICLES(b_delete_entities)
IF b_remove_parachute_prop = TRUE
SAFE_RELEASE_OBJECT(oParachute)
ENDIF
REMOVE_VEHICLE_ASSET(modelVeh[EXT1_MODEL_HELICOPTER])
INT i = 0
REPEAT NUM_PED_MODELS i
SET_MODEL_AS_NO_LONGER_NEEDED(modelPed[i])
ENDREPEAT
i = 0
REPEAT NUM_VEHICLE_MODELS i
SET_MODEL_AS_NO_LONGER_NEEDED(modelVeh[i])
SET_VEHICLE_MODEL_IS_SUPPRESSED(modelVeh[i], FALSE)
ENDREPEAT
SET_MODEL_AS_NO_LONGER_NEEDED(modelParachute)
REMOVE_ANIM_DICT("rcm_extreme1")
REMOVE_ANIM_DICT("rcm_extreme1@heli")
REMOVE_ANIM_DICT("creatures@retriever@amb@world_dog_barking@enter")
REMOVE_ANIM_DICT("creatures@retriever@amb@world_dog_barking@exit")
REMOVE_ANIM_DICT("creatures@retriever@move")
DESTROY_ALL_CAMS()
IF IS_RADAR_HIDDEN()
DISPLAY_RADAR(TRUE)
ENDIF
IF IS_HUD_HIDDEN()
DISPLAY_HUD(TRUE)
ENDIF
REMOVE_PED_COMP_ITEM_SP(PLAYER_PED_ID(), COMP_TYPE_PROPS, PROPS_P1_HEADSET)
EXT1_BLOCK_SPAWNERS_FOR_BIKE_RACE(FALSE)
STOP_SOUND(iWindSound)
TRIGGER_MUSIC_EVENT("EXTREME1_STOP")
EXT1_START_AUDIO_SCENE("EXTREME_01_INTRO", FALSE)
EXT1_START_AUDIO_SCENE("EXTREME_01_JOURNEY", FALSE)
EXT1_START_AUDIO_SCENE("EXTREME_01_RACE", FALSE)
SET_WANTED_LEVEL_MULTIPLIER(1)
#IF IS_DEBUG_BUILD
SET_DEBUG_ACTIVE(FALSE)
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(FALSE)
#ENDIF
REMOVE_SCENARIO_BLOCKING_AREA(blockScenarios)
RC_CleanupSceneEntities(sRCLauncherDataLocal, FALSE)
SET_INSTANCE_PRIORITY_HINT(INSTANCE_HINT_NONE)
RENDER_SCRIPT_CAMS(FALSE, FALSE)
DESTROY_ALL_CAMS()
CLEAR_WEATHER_TYPE_PERSIST()
IF b_terminate_mission = TRUE
SET_SCENARIO_TYPE_ENABLED("WORLD_VEHICLE_SALTON_DIRT_BIKE", TRUE)
IF DOES_SCENARIO_GROUP_EXIST("Observatory_Bikers")
AND NOT IS_SCENARIO_GROUP_ENABLED("Observatory_Bikers")
SET_SCENARIO_GROUP_ENABLED("Observatory_Bikers", TRUE)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Enabled scenario group Observatory_Bikers") ENDIF #ENDIF
ENDIF
#IF IS_DEBUG_BUILD IF DOES_WIDGET_GROUP_EXIST(widgetGroup) DELETE_WIDGET_GROUP(widgetGroup) ENDIF #ENDIF
ENDIF
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Cleaned up mission") ENDIF #ENDIF
ENDPROC
/// PURPOSE:
/// Standard RC mission cleanup function.
PROC Script_Cleanup()
// Ensure launcher is cleaned up
RC_CLEANUP_LAUNCHER()
IF (Random_Character_Cleanup_If_Triggered())
EXT1_MISSION_CLEANUP(FALSE, FALSE, TRUE)
ENDIF
RC_CleanupSceneEntities(sRCLauncherDataLocal, FALSE)
TERMINATE_THIS_THREAD()
ENDPROC
/// PURPOSE:
/// Standard RC mission passed function.
PROC Script_Passed()
ADD_CONTACT_TO_PHONEBOOK(CHAR_DOM, FRANKLIN_BOOK)
Random_Character_Passed(CP_RAND_C_EXT1)
Script_Cleanup()
ENDPROC
/// PURPOSE:
/// Create Dom's parachute prop stuck in the tree.
PROC EXT1_CREATE_PARACHUTE_PROP()
EXT1_ENSURE_MODEL_IS_LOADED(modelParachute)
oParachute = CREATE_OBJECT(modelParachute, vParachute)
SET_MODEL_AS_NO_LONGER_NEEDED(modelParachute)
SET_ENTITY_COLLISION(oParachute, FALSE) // Allowing collision causes Dom to get moved out of the way, see B*1049852
FREEZE_ENTITY_POSITION(oParachute, TRUE)
SET_ENTITY_LOD_DIST(oParachute, 200)
SAFE_TELEPORT_ENTITY(oParachute, vParachute, fParachute)
ENDPROC
/// PURPOSE:
/// Loads the assets for the required mission stage.
PROC EXT1_LOAD_ASSETS_FOR_MISSION_STATE(EXT1_MISSION_STATE current_state, BOOL b_wait_for_assets_to_load = TRUE)
SWITCH current_state
CASE stateIntro
REQUEST_MODEL(modelPed[EXT1_MODEL_DOG])
REQUEST_ANIM_DICT("creatures@retriever@move")
BREAK
CASE stateFollowDog
REQUEST_ANIM_DICT("rcm_extreme1")
REQUEST_ANIM_DICT("creatures@retriever@amb@world_dog_barking@enter")
REQUEST_ANIM_DICT("creatures@retriever@amb@world_dog_barking@exit")
REQUEST_MODEL(modelParachute)
BREAK
CASE stateGetInHelicopter
REQUEST_MODEL(modelVeh[EXT1_MODEL_HELICOPTER])
REQUEST_MODEL(modelPed[EXT1_MODEL_PILOT])
REQUEST_MODEL(modelParachute)
REQUEST_VEHICLE_ASSET(modelVeh[EXT1_MODEL_HELICOPTER])
REQUEST_ANIM_DICT("rcm_extreme1@heli")
BREAK
CASE stateJumpOutHelicopter
REQUEST_MODEL(modelVeh[EXT1_MODEL_BIKE])
REQUEST_MODEL(modelPed[EXT1_MODEL_PILOT])
REQUEST_VEHICLE_ASSET(modelVeh[EXT1_MODEL_HELICOPTER])
REQUEST_ANIM_DICT("rcm_extreme1@heli")
BREAK
CASE stateRaceDom
REQUEST_MODEL(modelVeh[EXT1_MODEL_BIKE])
REQUEST_VEHICLE_RECORDING(500, "Ext1_BikeRace")
BREAK
CASE stateRaceEndConversation
REQUEST_ANIM_DICT("rcm_extreme1")
REQUEST_MODEL(modelVeh[EXT1_MODEL_BIKE])
BREAK
ENDSWITCH
IF b_wait_for_assets_to_load = TRUE
BOOL b_assets_loaded = FALSE
WHILE b_assets_loaded = FALSE
SWITCH current_state
CASE stateIntro
IF HAS_MODEL_LOADED(modelPed[EXT1_MODEL_DOG])
AND HAS_ANIM_DICT_LOADED("creatures@retriever@move")
b_assets_loaded = TRUE
ENDIF
BREAK
CASE stateFollowDog
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_MELEE_ATTACK_LIGHT) // Prevent Franklin swinging punches when using hint camera // See B*850461
IF HAS_ANIM_DICT_LOADED("rcm_extreme1")
AND HAS_ANIM_DICT_LOADED("creatures@retriever@amb@world_dog_barking@enter")
AND HAS_ANIM_DICT_LOADED("creatures@retriever@amb@world_dog_barking@exit")
AND HAS_MODEL_LOADED(modelParachute)
b_assets_loaded = TRUE
ENDIF
BREAK
CASE stateGetInHelicopter
IF HAS_MODEL_LOADED(modelVeh[EXT1_MODEL_HELICOPTER])
AND HAS_MODEL_LOADED(modelPed[EXT1_MODEL_PILOT])
AND HAS_MODEL_LOADED(modelParachute)
AND HAS_VEHICLE_ASSET_LOADED(modelVeh[EXT1_MODEL_HELICOPTER])
AND HAS_ANIM_DICT_LOADED("rcm_extreme1@heli")
SET_VEHICLE_MODEL_IS_SUPPRESSED(modelVeh[EXT1_MODEL_HELICOPTER], TRUE)
b_assets_loaded = TRUE
ENDIF
BREAK
CASE stateJumpOutHelicopter
IF HAS_MODEL_LOADED(modelVeh[EXT1_MODEL_BIKE])
AND HAS_MODEL_LOADED(modelPed[EXT1_MODEL_PILOT])
AND HAS_VEHICLE_ASSET_LOADED(modelVeh[EXT1_MODEL_HELICOPTER])
AND HAS_ANIM_DICT_LOADED("rcm_extreme1@heli")
SET_VEHICLE_MODEL_IS_SUPPRESSED(modelVeh[EXT1_MODEL_BIKE], TRUE)
b_assets_loaded = TRUE
ENDIF
BREAK
CASE stateRaceDom
IF HAS_MODEL_LOADED(modelVeh[EXT1_MODEL_BIKE])
AND HAS_VEHICLE_RECORDING_BEEN_LOADED(500, "Ext1_BikeRace")
SET_VEHICLE_MODEL_IS_SUPPRESSED(modelVeh[EXT1_MODEL_BIKE], TRUE)
b_assets_loaded = TRUE
ENDIF
BREAK
CASE stateRaceEndConversation
IF HAS_ANIM_DICT_LOADED("rcm_extreme1")
AND HAS_MODEL_LOADED(modelVeh[EXT1_MODEL_BIKE])
SET_VEHICLE_MODEL_IS_SUPPRESSED(modelVeh[EXT1_MODEL_BIKE], TRUE)
b_assets_loaded = TRUE
ENDIF
BREAK
ENDSWITCH
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Loading assets...") ENDIF #ENDIF
WAIT(0)
ENDWHILE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Assets loaded") ENDIF #ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Mission failed function.
PROC EXT1_MISSION_FAILED(FAILED_REASON reason = FAILED_DEFAULT)
IF bZSkipping = FALSE
failReason = reason
missionStateMachine = EXT1_STATE_MACHINE_CLEANUP
missionStateSkip = stateFailed
ENDIF
ENDPROC
/// PURPOSE:
/// Death checks for any mission critical entities.
PROC EXT1_DEATH_CHECKS()
IF ENUM_TO_INT(missionState) < (ENUM_TO_INT(NUM_MISSION_STATES)-1) // Don't check during stateFailed
IF DOES_ENTITY_EXIST(pedDog)
IF IS_ENTITY_DEAD(pedDog)
EXT1_MISSION_FAILED(FAILED_DOG_DIED)
ELSE
IF HAS_ENTITY_BEEN_DAMAGED_BY_ANY_VEHICLE(pedDog)
EXT1_MISSION_FAILED(FAILED_DOG_INJURED)
ENDIF
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(pedDog, PLAYER_PED_ID())
EXT1_MISSION_FAILED(FAILED_DOG_INJURED)
//ELIF IS_PLAYER_VISIBLY_TARGETTING_PED(pedDog) // B*1032303 - The dog won't know what a gun is so don't fail for just aiming at it
//EXT1_MISSION_FAILED(FAILED_DOG_SCARED)
ELSE
IF IS_PLAYER_SHOOTING_NEAR_PED(pedDog)
OR GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0
EXT1_MISSION_FAILED(FAILED_DOG_SCARED)
ENDIF
ENDIF
ENDIF
ENDIF
IF DOES_ENTITY_EXIST(pedDom)
IF IS_ENTITY_DEAD(pedDom)
EXT1_MISSION_FAILED(FAILED_DOM_DIED)
ELSE
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(pedDom, PLAYER_PED_ID())
EXT1_MISSION_FAILED(FAILED_DOM_INJURED)
ELIF HAS_PLAYER_THREATENED_PED(pedDom, TRUE, 70, 120)
EXT1_MISSION_FAILED(FAILED_DOM_SCARED)
ENDIF
ENDIF
ENDIF
IF DOES_ENTITY_EXIST(pedPilot)
IF IS_ENTITY_DEAD(pedPilot)
EXT1_MISSION_FAILED(FAILED_PILOT_INJURED)
ELIF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(pedPilot, PLAYER_PED_ID())
IF HAS_PED_BEEN_DAMAGED_BY_WEAPON(pedPilot, WEAPONTYPE_INVALID, GENERALWEAPON_TYPE_ANYWEAPON)
EXT1_MISSION_FAILED(FAILED_PILOT_INJURED)
ENDIF
ENDIF
ENDIF
IF DOES_ENTITY_EXIST(vehBike[BIKE_0])
AND NOT IS_VEHICLE_OK(vehBike[BIKE_0])
EXT1_MISSION_FAILED(FAILED_BIKE_WRECKED)
ENDIF
IF DOES_ENTITY_EXIST(vehBike[BIKE_1])
AND NOT IS_VEHICLE_OK(vehBike[BIKE_1])
EXT1_MISSION_FAILED(FAILED_BIKE_WRECKED)
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Set up mission prior to going into any mission states.
PROC EXT1_MISSION_SETUP()
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Starting mission setup...") ENDIF #ENDIF
failReason = FAILED_DEFAULT
REQUEST_ADDITIONAL_TEXT("EXT1", MISSION_TEXT_SLOT)
WHILE NOT HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT)
WAIT(0)
ENDWHILE
#IF IS_DEBUG_BUILD
mSkipMenu[Z_SKIP_INTRO].sTxtLabel = "Intro - es_1_rcm_p1"
mSkipMenu[Z_SKIP_FOLLOW_DOG].sTxtLabel = "Follow dog"
mSkipMenu[Z_SKIP_MIDTRO].sTxtLabel = "Midtro - es_1_rcm_concat"
mSkipMenu[Z_SKIP_GET_IN_HELICOPTER].sTxtLabel = "Get in helicopter"
mSkipMenu[Z_SKIP_JUMP_OUT_HELICOPTER].sTxtLabel = "Skydive"
mSkipMenu[Z_SKIP_RACE_START].sTxtLabel = "Bike race start"
mSkipMenu[Z_SKIP_RACE_MIDDLE].sTxtLabel = "Bike race middle"
mSkipMenu[Z_SKIP_RACE_NEAR_END].sTxtLabel = "Bike race near end"
mSkipMenu[Z_SKIP_OUTRO_CUTSCENE_1].sTxtLabel = "Outro - Franklin won race"
mSkipMenu[Z_SKIP_OUTRO_CUTSCENE_2].sTxtLabel = "Outro - Dom won race"
IF NOT DOES_WIDGET_GROUP_EXIST(widgetGroup)
widgetGroup = START_WIDGET_GROUP("Extreme 1 widgets")
ADD_WIDGET_BOOL("TTY Toggle - Print Mission Debug Info", bDebug_PrintToTTY)
ADD_WIDGET_BOOL("TTY Toggle - Show Race Warning Dialogue Triggers", bDebug_ShowRaceWarningDialogueTriggers)
ADD_WIDGET_VECTOR_SLIDER("Marker Pos", vCheckpoint, -7000, 7000, 1)
ADD_WIDGET_VECTOR_SLIDER("Marker Rot", vMarkerRotation, -360, 360, 1)
ADD_WIDGET_VECTOR_SLIDER("vSkydiveInterp", vSkydiveInterp, -5, 5, 0.1)
ADD_WIDGET_FLOAT_SLIDER("fSkydiveInterp", fSkydiveInterp, 0, 45, 1)
STOP_WIDGET_GROUP()
ENDIF
#ENDIF
modelVeh[EXT1_MODEL_HELICOPTER] = MAVERICK
modelVeh[EXT1_MODEL_BIKE] = SCORCHER
modelPed[EXT1_MODEL_PILOT] = S_M_Y_PILOT_01
modelPed[EXT1_MODEL_DOG] = A_C_RETRIEVER
modelParachute = P_PARACHUTE_FALLEN_S
vHelicopterStart = vHelicopterLand
vHelicopterStart.z += 65
vDogWaypoint[0] = << -177.9496, 1290.7903, 302.1454 >>
vDogWaypoint[1] = << -165.5742, 1291.4651, 301.7969 >>
vDogWaypoint[2] = << -149.0811, 1298.5104, 300.5185 >>
vDogWaypoint[3] = << -138.3162, 1304.6832, 299.2527 >>
vDogWaypoint[4] = << -127.9030, 1312.1460, 297.2072 >>
vDogWaypoint[5] = << -115.4994, 1316.7454, 294.7481 >>
vDogWaypoint[6] = << -105.6817, 1316.4902, 292.3575 >>
vDogWaypoint[7] = << -81.3657, 1312.5122, 286.1825 >>
vDogWaypoint[8] = << -67.1832, 1310.3461, 282.2675 >>
vDogWaypoint[9] = << -54.8578, 1314.4159, 279.2725 >>
vDogWaypoint[10] = << -40.8436, 1319.5903, 275.9793 >>
vDogWaypoint[11] = << -24.2113, 1323.7902, 272.6355 >>
vDogWaypoint[12] = << -14.2087, 1321.7465, 270.5240 >>
vDogWaypoint[13] = << -0.2958, 1312.8383, 267.7775 >>
vDogWaypoint[14] = << 19.9014, 1296.9558, 264.3661 >>
vDogWaypoint[15] = << 29.7225, 1291.1198, 262.8754 >>
vDogWaypoint[16] = << 40.4001, 1288.3376, 261.0924 >>
vDogWaypoint[17] = << 55.0540, 1289.5887, 258.9505 >>
vDogWaypoint[18] = << 69.2492, 1289.1915, 256.9763 >>
vDogWaypoint[19] = << 78.0711, 1286.0443, 255.7971 >>
vDogWaypoint[20] = << 85.8352, 1281.1764, 254.9151 >>
vDogWaypoint[21] = << 108.1321, 1261.0613, 252.7032 >>
vDogWaypoint[22] = << 111.7998, 1258.0898, 252.2282 >>
vBike[BIKE_0] = << 504.860535,5551.600586,780.087524 >>
vBike[BIKE_1] = << 504.235962,5554.369629,780.601807 >>
fBike[BIKE_0] = 139.360306
fBike[BIKE_1] = 144.644928
vBikeOutro[BIKE_0] = << -867.0817, 5258.5356, 85.0576 >>
vBikeOutro[BIKE_1] = << -867.3555, 5256.4604, 85.0412 >>
SET_WANTED_LEVEL_MULTIPLIER(0.1)
IF NOT Is_Replay_In_Progress()
g_replay.iReplayInt[0] = -1 // Reset this when on first attempt in order to set bike colour on retries (see B*1052281)
g_replay.iReplayInt[1] = 0
g_replay.iReplayInt[2] = 0
ENDIF
blockScenarios = ADD_SCENARIO_BLOCKING_AREA(<<-189.9982, 1297.7646, 302.9516>>-<<40, 40, 40>>, <<-189.9982, 1297.7646, 302.9516>>+<<40, 40, 40>>)
SET_SCENARIO_TYPE_ENABLED("WORLD_VEHICLE_SALTON_DIRT_BIKE", FALSE)
IF DOES_SCENARIO_GROUP_EXIST("Observatory_Bikers")
AND IS_SCENARIO_GROUP_ENABLED("Observatory_Bikers")
SET_SCENARIO_GROUP_ENABLED("Observatory_Bikers", FALSE)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Disabled scenario group Observatory_Bikers") ENDIF #ENDIF
ENDIF
EXT1_START_AUDIO_SCENE("EXTREME_01_INTRO", TRUE)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Finished mission setup") ENDIF #ENDIF
ENDPROC
/// PURPOSE:
/// Puts the desired ped into a group friendly to the player.
PROC EXT1_SET_PED_AS_PLAYER_FRIEND(PED_INDEX ped_to_set_as_friend)
IF IS_ENTITY_ALIVE(ped_to_set_as_friend)
relGroupFriendly = GET_PED_RELATIONSHIP_GROUP_HASH(PLAYER_PED_ID())
SET_PED_RELATIONSHIP_GROUP_HASH(ped_to_set_as_friend, relGroupFriendly)
SET_PED_CONFIG_FLAG(ped_to_set_as_friend, PCF_KeepRelationshipGroupAfterCleanUp, TRUE)
ENDIF
ENDPROC
/// PURPOSE:
/// Unloads midtro if it has been preloaded prior to reaching Dom.
PROC EXT1_REMOVE_PRELOADED_MIDTRO()
IF missionState = stateFollowDog // The midtro only gets preloaded during this state
AND HAS_CUTSCENE_LOADED()
REMOVE_CUTSCENE()
ENDIF
ENDPROC
/// PURPOSE:
/// Create the bikes for the race.
PROC EXT1_CREATE_BIKES(BOOL b_create_at_race_start)
INT i = 0
REPEAT NUM_BIKES i
IF b_create_at_race_start = TRUE
EXT1_CREATE_VEHICLE(vehBike[i], modelVeh[EXT1_MODEL_BIKE], vBike[i], fBike[i], i)
ELSE
EXT1_CREATE_VEHICLE(vehBike[i], modelVeh[EXT1_MODEL_BIKE], vBikeOutro[i], 270, i)
ENDIF
SET_VEHICLE_ON_GROUND_PROPERLY(vehBike[i])
SET_VEHICLE_HAS_STRONG_AXLES(vehBike[i], TRUE)
ENDREPEAT
SET_MODEL_AS_NO_LONGER_NEEDED(modelVeh[EXT1_MODEL_BIKE])
iPlayersChosenBike = -1 // If the player lands his parachute before Dom, he can choose either of the two bikes..
iDomsBike = -1 // ..Dom uses the other bike, but initially set the vars to -1
ENDPROC
/// PURPOSE:
/// Handles spawning and setting up Dom.
/// b_hung_up specifies whether to setup Dom as hung up in the parachute or not
PROC EXT1_SPAWN_DOM(VECTOR v_spawn, FLOAT f_heading, BOOL b_hung_up, BOOL b_has_parachute_backpack, BOOL b_has_headset)
IF NOT DOES_ENTITY_EXIST(pedDom)
WHILE NOT RC_CREATE_NPC_PED(pedDom, CHAR_DOM, v_spawn, f_heading, "DOM")
WAIT(0)
ENDWHILE
ENDIF
IF IS_ENTITY_ALIVE(pedDom)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(pedDom, TRUE)
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(pedDom, TRUE)
SET_ENTITY_LOD_DIST(pedDom, 500)
SET_ENTITY_LOAD_COLLISION_FLAG(pedDom, TRUE) // Load collision around Dom or else he'll stop updating if the player is far away when they're parachuting
SET_PED_HELMET(pedDom, FALSE)
SET_PED_PARACHUTE_TINT_INDEX(pedDom, 6) // Black
ADD_PED_FOR_DIALOGUE(sConversation, 3, pedDom, "DOM")
IF b_hung_up = TRUE
SET_PED_CAN_RAGDOLL_FROM_PLAYER_IMPACT(pedDom, FALSE)
SET_PED_CONFIG_FLAG(pedDom, PCF_RunFromFiresAndExplosions, FALSE)
SET_PED_CONFIG_FLAG(pedDom, PCF_DisableExplosionReactions, TRUE)
OPEN_SEQUENCE_TASK(seqDomAnim)
TASK_PLAY_ANIM(null, "rcm_extreme1", "es_1_rcm_dom_upside_down_base", INSTANT_BLEND_IN, INSTANT_BLEND_OUT, -1, AF_IGNORE_GRAVITY)
TASK_PLAY_ANIM(null, "rcm_extreme1", "es_1_rcm_dom_upside_down_fidget_01", INSTANT_BLEND_IN, INSTANT_BLEND_OUT, -1, AF_IGNORE_GRAVITY)
TASK_PLAY_ANIM(null, "rcm_extreme1", "es_1_rcm_dom_upside_down_base", INSTANT_BLEND_IN, INSTANT_BLEND_OUT, -1, AF_IGNORE_GRAVITY)
TASK_PLAY_ANIM(null, "rcm_extreme1", "es_1_rcm_dom_upside_down_fidget_02", INSTANT_BLEND_IN, INSTANT_BLEND_OUT, -1, AF_IGNORE_GRAVITY)
SET_SEQUENCE_TO_REPEAT(seqDomAnim, REPEAT_FOREVER)
CLOSE_SEQUENCE_TASK(seqDomAnim)
TASK_PERFORM_SEQUENCE(pedDom, seqDomAnim)
CLEAR_SEQUENCE_TASK(seqDomAnim)
EXT1_CREATE_PARACHUTE_PROP()
ELSE
EXT1_SET_PED_AS_PLAYER_FRIEND(pedDom) // When Dom is hung up, the player doesn't yet know him as a friend, so only do this if b_hung_up = FALSE
ENDIF
IF b_has_parachute_backpack = TRUE
SET_PED_COMPONENT_VARIATION(pedDom, INT_TO_ENUM(PED_COMPONENT,8), 1, 0, 0)
ELSE
SET_PED_COMPONENT_VARIATION(pedDom, INT_TO_ENUM(PED_COMPONENT,8), 2, 0, 0)
ENDIF
IF b_has_headset = TRUE
SET_PED_PROP_INDEX(pedDom, ANCHOR_EARS, 0, 0)
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Creates the pilot in the helicopter.
PROC EXT1_SPAWN_HELICOPTER_PILOT()
IF IS_ENTITY_ALIVE(vehHelicopter)
EXT1_CREATE_PED_IN_VEHICLE(vehHelicopter, pedPilot, modelPed[EXT1_MODEL_PILOT], VS_DRIVER)
SET_MODEL_AS_NO_LONGER_NEEDED(modelPed[EXT1_MODEL_PILOT])
EXT1_SET_PED_AS_PLAYER_FRIEND(pedPilot)
SET_PED_STAY_IN_VEHICLE_WHEN_JACKED(pedPilot, TRUE)
SET_PED_CONFIG_FLAG(pedPilot, PCF_PreventPedFromReactingToBeingJacked, TRUE)
ADD_PED_FOR_DIALOGUE(sConversation, 4, pedPilot, "EXT1HELIPILOT")
ENDIF
ENDPROC
/// PURPOSE:
/// Makes Franklin walk forward a few paces. See B*1041495.
PROC EXT1_MAKE_FRANKLIN_WALK_AFTER_INTRO()
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_WALK, FALSE, FAUS_CUTSCENE_EXIT)
SIMULATE_PLAYER_INPUT_GAIT(PLAYER_ID(), PEDMOVEBLENDRATIO_WALK, 3000)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Set Franklin to walk forwards a few paces") ENDIF #ENDIF
IF IS_ENTITY_ALIVE(pedDog)
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), pedDog, -1)
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Makes dog run towards first waypoint.
PROC EXT1_MAKE_DOG_RUN_AFTER_INTRO()
IF IS_ENTITY_ALIVE(pedDog)
IF NOT IsPedPerformingTask(pedDog, SCRIPT_TASK_FOLLOW_NAV_MESH_TO_COORD)
FORCE_PED_MOTION_STATE(pedDog, MS_ON_FOOT_SPRINT)
TASK_FOLLOW_NAV_MESH_TO_COORD(pedDog, vDogWaypoint[0], PEDMOVE_SPRINT)
FORCE_PED_AI_AND_ANIMATION_UPDATE(pedDog)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Set dog to sprint towards first waypoint after intro") ENDIF #ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Sets up the dog.
PROC EXT1_SETUP_DOG(VECTOR v_pos, FLOAT f_rot, BOOL b_make_dog_run)
IF IS_ENTITY_ALIVE(pedDog)
SAFE_TELEPORT_ENTITY(pedDog, v_pos, f_rot, TRUE)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Dog already existed so teleported it") ENDIF #ENDIF
ELSE
EXT1_LOAD_ASSETS_FOR_MISSION_STATE(stateIntro)
EXT1_CREATE_PED(pedDog, modelPed[EXT1_MODEL_DOG], v_pos, f_rot)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Dog didn't exist so created it") ENDIF #ENDIF
ENDIF
SET_MODEL_AS_NO_LONGER_NEEDED(modelPed[EXT1_MODEL_DOG])
IF IS_ENTITY_ALIVE(pedDog)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(pedDog, TRUE)
ADD_PED_FOR_DIALOGUE(sConversation, 5, pedDog, "COLLIE")
EXT1_SET_PED_AS_PLAYER_FRIEND(pedDog)
SET_PED_CAN_RAGDOLL_FROM_PLAYER_IMPACT(pedDog, FALSE) // Stops the player messing around running into the dog making it ragdoll
SET_ENTITY_LOAD_COLLISION_FLAG(pedDog, TRUE)
SET_PED_CAN_BE_TARGETTED(pedDog, FALSE)
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(pedDog, TRUE)
SET_PED_CONFIG_FLAG(pedDog, PCF_UseKinematicModeWhenStationary, TRUE) // Prevent the player pushing the dog around
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Setup dog") ENDIF #ENDIF
IF NOT DOES_BLIP_EXIST(blipDog)
blipDog = CREATE_PED_BLIP(pedDog, TRUE, TRUE)
ENDIF
IF b_make_dog_run = TRUE
EXT1_MAKE_DOG_RUN_AFTER_INTRO()
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Sets the new position of the skydive camera.
PROC EXT1_POSITION_SKYDIVE_CAMERA()
vCurrentFocalOffset = ROTATE_VECTOR_ABOUT_Z(vFocalOffset, vLookCameraRot.z)
SET_CAM_COORD(camSkydive, vFocalPoint + vCurrentFocalOffset)
SET_CAM_ROT(camSkydive, <<fCameraXOffset + vLookCameraRot.x, 0.0, fHelicopterHeading + vLookCameraRot.z + fCameraRotationForSide>>)
ENDPROC
/// PURPOSE:
/// Update the skydive camera.
PROC EXT1_UPDATE_SKYDIVE_CAMERA()
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
IF DOES_CAM_EXIST(camSkydive)
VECTOR vRightStick
FLOAT f_right_x, f_right_y
INT i_right_x, i_right_y
f_right_x = GET_CONTROL_NORMAL(FRONTEND_CONTROL, INPUT_SCRIPT_RIGHT_AXIS_X)
f_right_y = GET_CONTROL_NORMAL(FRONTEND_CONTROL, INPUT_SCRIPT_RIGHT_AXIS_Y)
i_right_x = ROUND(128 * f_right_x)
i_right_y = ROUND(128 * f_right_y)
vRightStick.x = TO_FLOAT(i_right_x) / 128.0
vRightStick.y = TO_FLOAT(i_right_y) / -128.0
IF vRightStick.x <> 0.0 OR vRightStick.y <> 0.0
IF IS_LOOK_INVERTED()
vRightStick.y *= -1.0
ENDIF
VECTOR v_camera_velocity = <<0,0,0>>
// Apply player input forces to the acceleration values.
v_camera_velocity.z -= vRightStick.x * GET_FRAME_TIME() * 1000.0
v_camera_velocity.x += vRightStick.y * GET_FRAME_TIME() * 1000.0
// Apply dampening to the acceleration values.
IF ABSF(v_camera_velocity.z) > 0.001
v_camera_velocity.z -= v_camera_velocity.z * GET_FRAME_TIME() * 4.0
ELSE
v_camera_velocity.z = 0.0
ENDIF
IF ABSF(v_camera_velocity.x) > 0.001
v_camera_velocity.x -= v_camera_velocity.x * GET_FRAME_TIME() * 5.0
ELSE
v_camera_velocity.x = 0.0
ENDIF
// Update the look offsets based on our velocity.
vLookCameraRot.x += v_camera_velocity.x * GET_FRAME_TIME()
vLookCameraRot.z += v_camera_velocity.z * GET_FRAME_TIME()
// Different rotate limits depending on the side
IF g_replay.iReplayInt[1] = 0 // Franklin in back left seat
IF vLookCameraRot.x > 1.2 * 21.6
vLookCameraRot.x = 1.2 * 21.6
v_camera_velocity.x = 0.0
ELIF vLookCameraRot.x < -0.2 * 21.6
vLookCameraRot.x = -0.2 * 21.6
v_camera_velocity.x = 0.0
ENDIF
IF vLookCameraRot.z > 0.05 * 43.7465 // Range when rotating to left
vLookCameraRot.z = 0.05 * 43.7465
v_camera_velocity.z = 0.0
ELIF vLookCameraRot.z < -0.15 * 43.7465 // Range when rotating to right
vLookCameraRot.z = -0.15 * 43.7465
v_camera_velocity.z = 0.0
ENDIF
ELSE
IF vLookCameraRot.x > 1.2 * 21.6
vLookCameraRot.x = 1.2 * 21.6
v_camera_velocity.x = 0.0
ELIF vLookCameraRot.x < -0.05 * 21.6
vLookCameraRot.x = -0.05 * 21.6
v_camera_velocity.x = 0.0
ENDIF
IF vLookCameraRot.z > 0.32 * 43.7465 // Range when rotating to left
vLookCameraRot.z = 0.32 * 43.7465
v_camera_velocity.z = 0.0
ELIF vLookCameraRot.z < 0.15 * 43.7465 // Range when rotating to right
vLookCameraRot.z = 0.15 * 43.7465
v_camera_velocity.z = 0.0
ENDIF
ENDIF
ENDIF
EXT1_POSITION_SKYDIVE_CAMERA()
ENDIF
ENDPROC
/// PURPOSE:
/// Setup the skydive camera.
PROC EXT1_SETUP_SKYDIVE_CAMERA()
IF IS_ENTITY_ALIVE(vehHelicopter)
AND NOT DOES_CAM_EXIST(camSkydive)
FREEZE_ENTITY_POSITION(vehHelicopter, TRUE)
IF g_replay.iReplayInt[1] = 0 // Franklin in back left seat
fCameraRotationForSide = 90
SET_ENTITY_ROTATION(vehHelicopter, <<0,0,fHelicopterDesiredHeading>>)
fHelicopterHeading = fHelicopterDesiredHeading
vFocalPoint = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(vehHelicopter, <<1.12046, -0.317773, 0.9385>>)
fCameraXOffset = -38.0000
vFocalOffset = 1.0 * <<SIN(-97.4239 + fHelicopterHeading), -COS(-97.4239 + fHelicopterHeading), 0.0>> // Don't know what this does
vLookCameraRot = <<20,0,-5>> // Start facing 5 degrees left of center, 20 above center
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Setup skydive camera for back left") ENDIF #ENDIF
ELSE
fCameraRotationForSide = -90
SET_ENTITY_ROTATION(vehHelicopter, <<0,0,fHelicopterDesiredHeading - 180>>)
fHelicopterHeading = fHelicopterDesiredHeading - 180
vFocalPoint = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(vehHelicopter, <<-1.12046, -0.317773, 0.9385>>)
fCameraXOffset = -38.0000
vFocalOffset = -1.0 * <<SIN(-97.4239 + fHelicopterHeading), -COS(-97.4239 + fHelicopterHeading), 0.0>> // Don't know what this does
vLookCameraRot = <<20,0,12>> // Start facing 12 degrees right of center, 20 above center
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Setup skydive camera for back right") ENDIF #ENDIF
ENDIF
camSkydive = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA")
SET_CAM_FOV(camSkydive, 26.0)
SET_CAM_NEAR_CLIP(camSkydive, 0.840)
EXT1_POSITION_SKYDIVE_CAMERA()
camSkydiveInterp = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA")
VECTOR v_camera
IF g_replay.iReplayInt[1] = 0 // Franklin in back left seat
v_camera = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(vehHelicopter, <<-vSkydiveInterp.x,vSkydiveInterp.y,vSkydiveInterp.z>>)
ELSE
v_camera = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(vehHelicopter, vSkydiveInterp)
ENDIF
SET_CAM_COORD(camSkydiveInterp, v_camera)
VECTOR v_cam_rot = GET_CAM_ROT(camSkydive)
v_cam_rot.x -= fSkydiveInterp
SET_CAM_ROT(camSkydiveInterp, v_cam_rot)
SET_CAM_ACTIVE(camSkydive, TRUE)
SHAKE_CAM(camSkydive, "SKY_DIVING_SHAKE", 0.15)
RENDER_SCRIPT_CAMS(TRUE, FALSE)
PLAY_SOUND_FROM_COORD(iWindSound, "WIND", vHelicopterEnd, "EXTREME_01_SOUNDSET")
ENDIF
EXT1_UPDATE_SKYDIVE_CAMERA()
ENDPROC
/// PURPOSE:
/// Play synched scenes on the player for jumping out of the helicopter.
PROC EXT1_PLAY_SYNCHED_SCENE(BOOL b_play_jump_out)
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
AND IS_ENTITY_ALIVE(vehHelicopter)
IF b_play_jump_out = FALSE
IF NOT IS_SYNCHRONIZED_SCENE_RUNNING(iSceneId)
iSceneId = CREATE_SYNCHRONIZED_SCENE (<<0,0,0>>, <<0,0,0>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iSceneId, vehHelicopter, GET_ENTITY_BONE_INDEX_BY_NAME(vehHelicopter, "Chassis"))
CLEAR_PED_TASKS_IMMEDIATELY(PLAYER_PED_ID())
IF g_replay.iReplayInt[1] = 0
TASK_SYNCHRONIZED_SCENE(PLAYER_PED_ID(), iSceneId, "rcm_extreme1@heli", "Heli_door_loop_l", INSTANT_BLEND_IN, NORMAL_BLEND_OUT, SYNCED_SCENE_DONT_INTERRUPT|SYNCED_SCENE_LOOP_WITHIN_SCENE|SYNCED_SCENE_USE_PHYSICS)
ELSE
TASK_SYNCHRONIZED_SCENE(PLAYER_PED_ID(), iSceneId, "rcm_extreme1@heli", "Heli_door_loop", INSTANT_BLEND_IN, NORMAL_BLEND_OUT, SYNCED_SCENE_DONT_INTERRUPT|SYNCED_SCENE_LOOP_WITHIN_SCENE|SYNCED_SCENE_USE_PHYSICS)
ENDIF
SET_SYNCHRONIZED_SCENE_LOOPED(iSceneId, TRUE)
FORCE_PED_AI_AND_ANIMATION_UPDATE(PLAYER_PED_ID())
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started synched scene Heli_door_loop") ENDIF #ENDIF
ENDIF
ELSE
iSceneId = CREATE_SYNCHRONIZED_SCENE (<<0,0,0>>, <<0,0,0>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iSceneId, vehHelicopter, GET_ENTITY_BONE_INDEX_BY_NAME(vehHelicopter, "Chassis"))
IF g_replay.iReplayInt[1] = 0
TASK_SYNCHRONIZED_SCENE(PLAYER_PED_ID(), iSceneId, "rcm_extreme1@heli", "Heli_jump_l", SLOW_BLEND_IN, SLOW_BLEND_OUT, SYNCED_SCENE_DONT_INTERRUPT|SYNCED_SCENE_USE_PHYSICS|SYNCED_SCENE_TAG_SYNC_OUT)
ELSE
TASK_SYNCHRONIZED_SCENE(PLAYER_PED_ID(), iSceneId, "rcm_extreme1@heli", "Heli_jump", SLOW_BLEND_IN, SLOW_BLEND_OUT, SYNCED_SCENE_DONT_INTERRUPT|SYNCED_SCENE_USE_PHYSICS|SYNCED_SCENE_TAG_SYNC_OUT)
ENDIF
FORCE_PED_AI_AND_ANIMATION_UPDATE(PLAYER_PED_ID())
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started synched scene Heli_jump") ENDIF #ENDIF
ENDIF
ENDIF
ENDPROC
FUNC BOOL EXT1_HAS_PLAYER_FINISHED_JUMPING_OUT()
IF bFranklinExitingHelicopter = TRUE
AND IS_SYNCHRONIZED_SCENE_RUNNING(iSceneId)
IF bDone1stPersonCameraFlash = FALSE
AND GET_FOLLOW_PED_CAM_VIEW_MODE() = CAM_VIEW_MODE_FIRST_PERSON
AND GET_SYNCHRONIZED_SCENE_PHASE(iSceneId) > 0.7
ANIMPOSTFX_PLAY("CamPushInNeutral", 0, FALSE)
PLAY_SOUND_FRONTEND(-1, "1st_Person_Transition", "PLAYER_SWITCH_CUSTOM_SOUNDSET")
bDone1stPersonCameraFlash = TRUE
#IF IS_DEBUG_BUILD CPRINTLN(DEBUG_MISSION, "EXTREME1: Doing 1st person camera flash") #ENDIF
ENDIF
IF GET_SYNCHRONIZED_SCENE_PHASE(iSceneId) > 0.92
OPEN_SEQUENCE_TASK(jumpSequence)
TASK_FORCE_MOTION_STATE(NULL, ENUM_TO_INT(MS_PARACHUTING))
TASK_PARACHUTE(NULL, TRUE)
CLOSE_SEQUENCE_TASK(jumpSequence)
TASK_PERFORM_SEQUENCE(PLAYER_PED_ID(), jumpSequence)
CLEAR_SEQUENCE_TASK(jumpSequence)
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
PROC EXT1_SET_FRANKLIN_INTO_PARACHUTE_OUTFIT()
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
INT i_franklin_parachute_tint
GET_PED_PARACHUTE_TINT_INDEX(PLAYER_PED_ID(), i_franklin_parachute_tint)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: i_franklin_parachute_tint = ", i_franklin_parachute_tint) ENDIF #ENDIF
SET_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_SPECIAL, SPECIAL_P1_PARACHUTE, FALSE) // B*1406827
SET_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_PROPS, PROPS_P1_HEADSET, FALSE)
SET_PED_PARACHUTE_TINT_INDEX(PLAYER_PED_ID(), 1)
ENDIF
ENDPROC
/// PURPOSE:
/// Handles debug skipping.
/// PARAMS:
/// i_new_state - The state to debug skip to.
PROC EXT1_DEBUG_SKIP_STATE(INT i_new_state)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Starting debug skip to ", i_new_state, "...") ENDIF #ENDIF
RC_START_Z_SKIP()
bZSkipping = TRUE
EXT1_REMOVE_PRELOADED_MIDTRO()
IF NOT IS_REPLAY_BEING_SET_UP()
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), GET_ENTITY_COORDS(PLAYER_PED_ID()))
ENDIF
SET_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_SPECIAL, SPECIAL_P1_DUMMY, FALSE) // B*1601720 - Only remove the parachute and headset
SET_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_PROPS, PROPS_EARS_NONE, FALSE)
SWITCH i_new_state
CASE Z_SKIP_INTRO
EXT1_MISSION_CLEANUP(TRUE, TRUE)
IF NOT IS_REPLAY_BEING_SET_UP()
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), vFranklinAfterIntro, fFranklinAfterIntro, TRUE) // Required in case the player is in helicopter when z skipping, see B*1029801
ENDIF
CLEAR_AREA(GET_ENTITY_COORDS(PLAYER_PED_ID()), 1000, TRUE)
missionStateSkip = stateIntro
BREAK
CASE Z_SKIP_FOLLOW_DOG
EXT1_MISSION_CLEANUP(TRUE, TRUE)
IF NOT IS_REPLAY_BEING_SET_UP()
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), vFranklinAfterIntro, fFranklinAfterIntro, TRUE)
ENDIF
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
CLEAR_AREA(<< -188.8000, 1296.1221, 302.9238 >>, 1000, TRUE)
CREATE_VEHICLE_FOR_REPLAY(vehForReplay, vPlayerCarRespot, fPlayerCarRespot, FALSE, FALSE, FALSE, FALSE, FALSE)
missionStateSkip = stateFollowDog
BREAK
CASE Z_SKIP_MIDTRO
EXT1_MISSION_CLEANUP(TRUE, TRUE)
IF NOT IS_REPLAY_BEING_SET_UP()
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), vFranklinAfterMidtro, fFranklinAfterMidtro) // Required in case the player is in helicopter when z skipping, see B*1029801
ENDIF
EXT1_LOAD_ASSETS_FOR_MISSION_STATE(stateFollowDog)
EXT1_SPAWN_DOM(vDom, fDom, TRUE, TRUE, FALSE)
missionStateSkip = stateMidtro
BREAK
CASE Z_SKIP_GET_IN_HELICOPTER
EXT1_MISSION_CLEANUP(TRUE, TRUE)
IF NOT IS_REPLAY_BEING_SET_UP()
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), vFranklinAfterMidtro, fFranklinAfterMidtro) // Required in case the player is currently parachuting
ENDIF
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
EXT1_SPAWN_DOM(<<122.37, 1248.63, 253.77>>, fDomAfterMidtro, FALSE, TRUE, TRUE)
EXT1_LOAD_ASSETS_FOR_MISSION_STATE(stateGetInHelicopter)
EXT1_CREATE_PARACHUTE_PROP()
missionStateSkip = stateGetInHelicopter
BREAK
CASE Z_SKIP_JUMP_OUT_HELICOPTER
EXT1_MISSION_CLEANUP(TRUE, TRUE)
SET_WEATHER_TYPE_NOW_PERSIST("CLEAR")
IF NOT IS_REPLAY_BEING_SET_UP()
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), vBike[BIKE_0]) // Required in case the player is currently parachuting
ENDIF
EXT1_LOAD_ASSETS_FOR_MISSION_STATE(stateJumpOutHelicopter)
REMOVE_WEAPON_FROM_PED(PLAYER_PED_ID(), GADGETTYPE_PARACHUTE)
ADD_PED_FOR_DIALOGUE(sConversation, 1, PLAYER_PED_ID(), "FRANKLIN")
IF g_replay.iReplayInt[1] = 0 // Set helicopter direction depending on whether the player was in the left or right seat before retrying
EXT1_CREATE_VEHICLE(vehHelicopter, modelVeh[EXT1_MODEL_HELICOPTER], vHelicopterEnd, fHelicopterDesiredHeading, iHelicopterColour)
ELIF g_replay.iReplayInt[1] = 1
EXT1_CREATE_VEHICLE(vehHelicopter, modelVeh[EXT1_MODEL_HELICOPTER], vHelicopterEnd, fHelicopterDesiredHeading-180, iHelicopterColour)
ELSE
SCRIPT_ASSERT("Extreme1: Player seat isn't set")
ENDIF
SET_MODEL_AS_NO_LONGER_NEEDED(modelVeh[EXT1_MODEL_HELICOPTER])
IF IS_ENTITY_ALIVE(vehHelicopter)
SET_HELI_BLADES_FULL_SPEED(vehHelicopter)
EXT1_SPAWN_HELICOPTER_PILOT()
ENDIF
EXT1_SPAWN_DOM(vLandingPos, 0, FALSE, TRUE, TRUE)
IF IS_ENTITY_ALIVE(pedDom)
AND IS_ENTITY_ALIVE(vehHelicopter)
IF g_replay.iReplayInt[1] = 0
SET_PED_INTO_VEHICLE(pedDom, vehHelicopter, VS_BACK_RIGHT)
ELSE
SET_PED_INTO_VEHICLE(pedDom, vehHelicopter, VS_BACK_LEFT)
ENDIF
ENDIF
SET_PLAYER_WANTED_LEVEL(PLAYER_ID(),0)
SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID())
SET_EVERYONE_IGNORE_PLAYER(PLAYER_ID(), TRUE)
DISPLAY_RADAR(FALSE)
DISPLAY_HUD(FALSE)
CLEAR_AREA(GET_ENTITY_COORDS(PLAYER_PED_ID()), 100, TRUE)
EXT1_SETUP_SKYDIVE_CAMERA()
missionStateSkip = stateJumpOutHelicopter
BREAK
CASE Z_SKIP_RACE_START
CASE Z_SKIP_RACE_MIDDLE
CASE Z_SKIP_RACE_NEAR_END
EXT1_MISSION_CLEANUP(TRUE, TRUE)
IF NOT IS_REPLAY_BEING_SET_UP()
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), << 501.5130, 5535.7295, 777.2975 >>, 126.8669) // Required in case the player is currently parachuting
ENDIF
EXT1_BLOCK_SPAWNERS_FOR_BIKE_RACE(TRUE)
EXT1_LOAD_ASSETS_FOR_MISSION_STATE(stateRaceDom)
EXT1_CREATE_BIKES(TRUE)
IF g_replay.iReplayInt[0] = 0
iPlayersChosenBike = BIKE_0
iDomsBike = BIKE_1
ELSE
iPlayersChosenBike = BIKE_1
iDomsBike = BIKE_0
ENDIF
bToldToGetBackOnBike = FALSE
bPlayerStartedRaceEarly = FALSE
IF NOT IS_REPLAY_BEING_SET_UP()
AND IS_ENTITY_ALIVE(vehBike[iPlayersChosenBike])
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), vehBike[iPlayersChosenBike])
ENDIF
EXT1_SPAWN_DOM(vLandingPos, 0, FALSE, FALSE, TRUE)
IF IS_ENTITY_ALIVE(vehBike[iDomsBike])
AND IS_ENTITY_ALIVE(pedDom)
domStatus = DOM_SAT_ON_BIKE
SET_PED_INTO_VEHICLE(pedDom, vehBike[iDomsBike])
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(vehBike[iDomsBike], FALSE)
EXT1_START_AUDIO_SCENE("EXTREME_01_RACE", TRUE)
ADD_ENTITY_TO_AUDIO_MIX_GROUP(vehBike[iDomsBike], "EXTREME_01_BIKE_RACE_DOM_GROUP")
ENDIF
ADD_PED_FOR_DIALOGUE(sConversation, 1, PLAYER_PED_ID(), "FRANKLIN")
SET_EVERYONE_IGNORE_PLAYER(PLAYER_ID(), FALSE)
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
WAIT(0)
CLEAR_AREA(vBike[0], 100, TRUE)
missionStateSkip = stateRaceDom
BREAK
CASE Z_SKIP_OUTRO_CUTSCENE_1
CASE Z_SKIP_OUTRO_CUTSCENE_2
EXT1_MISSION_CLEANUP(TRUE, TRUE)
EXT1_LOAD_ASSETS_FOR_MISSION_STATE(stateRaceEndConversation)
EXT1_CREATE_BIKES(FALSE)
EXT1_SPAWN_DOM(<<-867.3832, 5254.3071, 85.0097>>, 0, FALSE, FALSE, TRUE)
IF g_replay.iReplayInt[0] = 0
iPlayersChosenBike = BIKE_0
iDomsBike = BIKE_1
ELSE
iPlayersChosenBike = BIKE_1
iDomsBike = BIKE_0
ENDIF
IF i_new_state = Z_SKIP_OUTRO_CUTSCENE_1
iRacePos = 1
ELSE
iRacePos = 2
ENDIF
missionStateSkip = stateRaceEndConversation
BREAK
ENDSWITCH
IF i_new_state = Z_SKIP_RACE_START
OR i_new_state = Z_SKIP_RACE_MIDDLE
OR i_new_state = Z_SKIP_RACE_NEAR_END
IF IS_ENTITY_ALIVE(vehBike[iPlayersChosenBike])
END_REPLAY_SETUP(vehBike[iPlayersChosenBike])
ENDIF
TRIGGER_MUSIC_EVENT("EXTREME1_BIKE")
ELIF i_new_state = Z_SKIP_JUMP_OUT_HELICOPTER
IF IS_ENTITY_ALIVE(vehHelicopter)
END_REPLAY_SETUP(vehHelicopter, VS_FRONT_RIGHT)
ENDIF
EXT1_SET_FRANKLIN_INTO_PARACHUTE_OUTFIT() // B*1406827
ELSE
END_REPLAY_SETUP()
ENDIF
// The below ensures if skipping to one of the race checkpoints, both Franklin and Dom are on their carrecs in suitable places before fading up
FLOAT f_time_skip_player
FLOAT f_time_skip_dom
IF i_new_state = Z_SKIP_RACE_MIDDLE
OR i_new_state = Z_SKIP_RACE_NEAR_END
IF i_new_state = Z_SKIP_RACE_MIDDLE
f_time_skip_player = 74000
f_time_skip_dom = f_time_skip_player + 300
iSkipToRaceCheckpoint = CP_BIKERACE_MIDDLE
ELSE
f_time_skip_player = 143500
f_time_skip_dom = f_time_skip_player + 1500
iSkipToRaceCheckpoint = CP_BIKERACE_NEAR_END
ENDIF
IF IS_ENTITY_ALIVE(vehBike[iDomsBike])
START_PLAYBACK_RECORDED_VEHICLE(vehBike[iDomsBike], 500, "Ext1_BikeRace")
PAUSE_PLAYBACK_RECORDED_VEHICLE(vehBike[iDomsBike])
SKIP_TIME_IN_PLAYBACK_RECORDED_VEHICLE(vehBike[iDomsBike], f_time_skip_dom)
ENDIF
IF IS_ENTITY_ALIVE(vehBike[iPlayersChosenBike])
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vehBike[iPlayersChosenBike])
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), vehBike[iPlayersChosenBike])
ENDIF
START_PLAYBACK_RECORDED_VEHICLE(vehBike[iPlayersChosenBike], 500, "Ext1_BikeRace")
PAUSE_PLAYBACK_RECORDED_VEHICLE(vehBike[iPlayersChosenBike])
SKIP_TIME_IN_PLAYBACK_RECORDED_VEHICLE(vehBike[iPlayersChosenBike], f_time_skip_player)
ENDIF
IF NOT IS_REPLAY_BEING_SET_UP()
WAIT(100)
WAIT_FOR_WORLD_TO_LOAD(GET_ENTITY_COORDS(PLAYER_PED_ID()))
WAIT(100)
ENDIF
IF IS_ENTITY_ALIVE(vehBike[iDomsBike])
UNPAUSE_PLAYBACK_RECORDED_VEHICLE(vehBike[iDomsBike])
ENDIF
IF IS_ENTITY_ALIVE(vehBike[iPlayersChosenBike])
UNPAUSE_PLAYBACK_RECORDED_VEHICLE(vehBike[iPlayersChosenBike])
ENDIF
ELIF i_new_state = Z_SKIP_JUMP_OUT_HELICOPTER
IF g_replay.iReplayInt[1] = 0
EXT1_PLAY_SYNCHED_SCENE(FALSE) // VS_BACK_LEFT
ELSE
EXT1_PLAY_SYNCHED_SCENE(FALSE) // VS_BACK_RIGHT
ENDIF
IF NOT IS_REPLAY_BEING_SET_UP()
WAIT_FOR_WORLD_TO_LOAD(GET_ENTITY_COORDS(PLAYER_PED_ID()), 1000) // See B*1012766 - Ensure ground way below helicopter has been loaded
ENDIF
iSkipToRaceCheckpoint = -1
ELSE
IF NOT IS_REPLAY_BEING_SET_UP()
WAIT_FOR_WORLD_TO_LOAD(GET_ENTITY_COORDS(PLAYER_PED_ID()), 100)
ENDIF
iSkipToRaceCheckpoint = -1
ENDIF
IF i_new_state = Z_SKIP_FOLLOW_DOG
EXT1_SETUP_DOG(vDogSpawnPosAlt, fDogSpawnPosAlt, TRUE)
EXT1_MAKE_FRANKLIN_WALK_AFTER_INTRO()
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
ENDIF
IF i_new_state = Z_SKIP_INTRO
OR i_new_state = Z_SKIP_MIDTRO
OR i_new_state = Z_SKIP_OUTRO_CUTSCENE_1
OR i_new_state = Z_SKIP_OUTRO_CUTSCENE_2
RC_END_Z_SKIP(TRUE, FALSE)
ELIF i_new_state = Z_SKIP_JUMP_OUT_HELICOPTER
RC_END_Z_SKIP(FALSE, TRUE, FALSE) // Fixed helicopter vantage cam has been setup so don't reset camera
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE, SPC_LEAVE_CAMERA_CONTROL_ON)
ELSE
RC_END_Z_SKIP()
ENDIF
missionStateMachine = EXT1_STATE_MACHINE_CLEANUP
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Finished debug skip to ", i_new_state) ENDIF #ENDIF
ENDPROC
/// PURPOSE:
/// Returns TRUE if a conversation can be played.
FUNC BOOL EXT1_ALLOW_CONVERSATION_TO_PLAY(BOOL b_check_for_interrupted_conversations = TRUE, BOOL b_check_for_god_text = TRUE)
IF bZSkipping = TRUE
RETURN FALSE
ENDIF
IF b_check_for_god_text = TRUE // If FALSE the conversation is set to not display subtitles ever, so play conversation regardless of whether there is god text onscreen or not
AND IS_MESSAGE_BEING_DISPLAYED()
AND GET_PROFILE_SETTING(PROFILE_DISPLAY_SUBTITLES) > 0 // B*665755 Support playing conversations over god text when subtitles are turned off
RETURN FALSE
ENDIF
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
RETURN FALSE
ENDIF
IF b_check_for_interrupted_conversations = TRUE
AND IS_FACE_TO_FACE_CONVERSATION_PAUSED() // A conversation has been interrupted and still needs to be restored
RETURN FALSE
ENDIF
RETURN TRUE
ENDFUNC
/// PURPOSE:
/// If Franklin is lagging behind the dog waits for him to catch up and plays idle animations every so often.
PROC EXT1_MANAGE_DOG_IDLE_ANIMATIONS(BOOL b_face_player)
OPEN_SEQUENCE_TASK(seqDog)
IF b_face_player = TRUE
TASK_TURN_PED_TO_FACE_ENTITY(NULL, PLAYER_PED_ID())
ELSE
IF NOT IS_ENTITY_IN_RANGE_COORDS(pedDog, vDogWaypoint[NUM_DOG_WAYPOINTS-1], 5)
TASK_GO_STRAIGHT_TO_COORD(NULL, vDogWaypoint[NUM_DOG_WAYPOINTS-1], PEDMOVE_RUN)
ENDIF
TASK_TURN_PED_TO_FACE_COORD(NULL, vDom)
ENDIF
TASK_PLAY_ANIM(NULL, "creatures@retriever@amb@world_dog_barking@enter", "enter", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_DEFAULT)
IF GET_RANDOM_INT_IN_RANGE(0, 3) = 0
TASK_PLAY_ANIM(NULL, "rcm_extreme1", "idle_c", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_DEFAULT)
ELSE
TASK_PLAY_ANIM(NULL, "rcm_extreme1", "idle_a", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_DEFAULT)
ENDIF
TASK_PLAY_ANIM(NULL, "creatures@retriever@amb@world_dog_barking@exit", "exit", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_DEFAULT)
CLOSE_SEQUENCE_TASK(seqDog)
TASK_PERFORM_SEQUENCE(pedDog, seqDog)
SET_PED_KEEP_TASK(pedDog, TRUE)
CLEAR_SEQUENCE_TASK(seqDog)
IF b_face_player = TRUE
AND EXT1_ALLOW_CONVERSATION_TO_PLAY()
AND GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), pedDog) < 50 // Don't play these random lines if the player is far away from the dog
AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_ONELIN", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_ONELIN conversation") ENDIF #ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Returns TRUE if Franklin is closer to Dom than the dog is.
FUNC BOOL EXT1_IS_PLAYER_CLOSER_TO_DOM_THAN_DOG()
IF IS_ENTITY_ALIVE(pedDog)
FLOAT fPlayerDist = GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), vDom, FALSE)
FLOAT fDogDist = GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(pedDog), vDom, FALSE)
IF fPlayerDist < fDogDist
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Handles moving the dog along the waypointed path.
PROC EXT1_MANAGE_DOG_MOVEMENT()
IF IS_ENTITY_ALIVE(pedDog)
SWITCH stateDog
CASE DOG_WAITING // Dog is waiting for the player to get closer
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), pedDog) < DOG_RUN_DIST // Player is close to dog so start running again
stateDog = DOG_RUNNING
ELIF (GET_GAME_TIMER() - iDogAnimsTimer) > 7500 // Timer expired so play anim
EXT1_MANAGE_DOG_IDLE_ANIMATIONS(TRUE)
stateDog = DOG_ANIMATING
ELIF GET_SCRIPT_TASK_STATUS(pedDog, SCRIPT_TASK_TURN_PED_TO_FACE_ENTITY) = FINISHED_TASK // Player isn't close enough and not yet time to play an anim, so ensure dog faces player
IF NOT IS_PED_FACING_PED(pedDog, PLAYER_PED_ID(), 25)
TASK_TURN_PED_TO_FACE_ENTITY(pedDog, PLAYER_PED_ID())
TASK_LOOK_AT_ENTITY(pedDog, PLAYER_PED_ID(), -1)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Turning dog to face Franklin") ENDIF #ENDIF
ENDIF
ENDIF
BREAK
CASE DOG_RUNNING // Dog is actively running along its path
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), pedDog) > DOG_STOP_DIST
AND NOT EXT1_IS_PLAYER_CLOSER_TO_DOM_THAN_DOG() // Dog should only stop running if it's closer to Dom, and more than DOG_STOP_DIST from Franklin
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Dog is too far ahead so needs to stop") ENDIF #ENDIF
iDogAnimsTimer = GET_GAME_TIMER()
stateDog = DOG_WAITING
ELSE
IF iNextDogWaypoint < NUM_DOG_WAYPOINTS
AND NOT IsPedPerformingTask(pedDog, SCRIPT_TASK_FOLLOW_NAV_MESH_TO_COORD)
TASK_FOLLOW_NAV_MESH_TO_COORD(pedDog, vDogWaypoint[iNextDogWaypoint], PEDMOVE_SPRINT)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Dog wasn't on TASK_FOLLOW_NAV_MESH_TO_COORD so re-applied it") ENDIF #ENDIF
ENDIF
IF IS_ENTITY_IN_RANGE_COORDS(pedDog, vDogWaypoint[iNextDogWaypoint], LOCATE_SIZE_ON_FOOT_ONLY) // Dog has reached next waypoint
iNextDogWaypoint++
IF iNextDogWaypoint = NUM_DOG_WAYPOINTS
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Dog reached end of its path") ENDIF #ENDIF
stateDog = DOG_FINISHED
ELSE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Dog reached next waypoint") ENDIF #ENDIF
TASK_FOLLOW_NAV_MESH_TO_COORD(pedDog, vDogWaypoint[iNextDogWaypoint], PEDMOVE_SPRINT)
ENDIF
ENDIF
ENDIF
BREAK
CASE DOG_ANIMATING
IF NOT IsPedPerformingTask(pedDog, SCRIPT_TASK_PERFORM_SEQUENCE)
iDogAnimsTimer = GET_GAME_TIMER()
stateDog = DOG_WAITING
ENDIF
BREAK
CASE DOG_FINISHED // Dog has finished its path to Dom
BREAK
ENDSWITCH
ENDIF
ENDPROC
/// PURPOSE:
/// Setup Dom for cutscene.
PROC SETUP_DOM_CUTSCENE_VARIATIONS()
IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY()
#IF IS_DEBUG_BUILD CPRINTLN(DEBUG_MISSION, "EXTREME1: CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY is TRUE") #ENDIF
IF IS_ENTITY_ALIVE(pedDom)
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Dom", pedDom)
#IF IS_DEBUG_BUILD CPRINTLN(DEBUG_MISSION, "EXTREME1: Set cutscene variations for pedDom in cutscene") #ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Load/unload midtro cutscene depending on distance.
PROC EXT1_MANAGE_MIDTRO_CUTSCENE_LOADING()
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
IF bIsMidtroLoaded = FALSE
IF IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), vDom, DEFAULT_CUTSCENE_LOAD_DIST)
REQUEST_CUTSCENE("ES_1_RCM_CONCAT")
bIsMidtroLoaded = TRUE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Loaded ES_1_RCM_CONCAT into memory") ENDIF #ENDIF
ENDIF
ELSE
IF NOT IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), vDom, DEFAULT_CUTSCENE_UNLOAD_DIST)
AND HAS_CUTSCENE_LOADED()
REMOVE_CUTSCENE()
bIsMidtroLoaded = FALSE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Unloaded ES_1_RCM_CONCAT from memory") ENDIF #ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Handles playing the dog conversation.
PROC EXT1_MANAGE_DOG_CONVERSATION()
IF bStartedDogConversation = FALSE
IF EXT1_ALLOW_CONVERSATION_TO_PLAY()
AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_DOG", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_DOG conversation") ENDIF #ENDIF
bStartedDogConversation = TRUE
ENDIF
ELIF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
TEXT_LABEL_23 t_current_conversation_root = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT()
IF ARE_STRINGS_EQUAL(t_current_conversation_root, "EXT1_DOG") // B*1169057 Only stop and restore the main dog conversation
AND IS_ENTITY_ALIVE(pedDog)
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), pedDog) < DOG_CONVERSATION_START_DIST
IF IS_FACE_TO_FACE_CONVERSATION_PAUSED()
PAUSE_FACE_TO_FACE_CONVERSATION(FALSE)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Resuming EXT1_DOG conversation") ENDIF #ENDIF
ENDIF
ELSE
IF NOT IS_FACE_TO_FACE_CONVERSATION_PAUSED()
PAUSE_FACE_TO_FACE_CONVERSATION(TRUE)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Pausing EXT1_DOG conversation") ENDIF #ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Checks the player doesn't abandon the dog, and fails the mission if necessary.
PROC EXT1_CHECK_PLAYER_ISNT_ABANDONING_DOG()
IF IS_ENTITY_ALIVE(pedDog)
AND GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), pedDog) > 100
AND NOT EXT1_IS_PLAYER_CLOSER_TO_DOM_THAN_DOG() // Don't allow fail if player is closer to Dom than the dog is (maybe the dog is lagging behind)
EXT1_MISSION_FAILED(FAILED_DIDNT_FOLLOW_DOG)
ENDIF
ENDPROC
/// PURPOSE:
/// Handles displaying the hint camera and text for the dog.
PROC EXT1_MANAGE_DOG_FOCUS_CAMERA()
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_MELEE_ATTACK_LIGHT) // Prevent Franklin swinging punches when using hint camera
IF IS_ENTITY_ALIVE(pedDog)
AND (GET_GAME_TIMER() - iDogHelpTextTimer) > 2000
weapon_type wep_current
GET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), wep_current)
IF wep_current = WEAPONTYPE_UNARMED // B*1500542 Prevent conflict with reloading
CONTROL_ENTITY_CHASE_HINT_CAM_ANY_MEANS(localChaseHintCamStruct, pedDog, "EXT1_08") // Press ~INPUT_VEH_CIN_CAM~ to toggle focus on the dog.
ELSE
KILL_CHASE_HINT_CAM(localChaseHintCamStruct)
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Handles playing Dom's grunts and groans when hung up in the parachute while following the dog.
PROC EXT1_MANAGE_DOM_CONVERSATION()
IF (GET_GAME_TIMER() - iDomGruntsDialogueTimer) > 4000
AND EXT1_ALLOW_CONVERSATION_TO_PLAY()
AND IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), vDom, 40)
IF GET_RANDOM_INT_IN_RANGE(0, 4) = 0
IF CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_HEY", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_HEY conversation") ENDIF #ENDIF
iDomGruntsDialogueTimer = GET_GAME_TIMER()
ENDIF
ELIF CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_HUNG", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_HUNG conversation") ENDIF #ENDIF
iDomGruntsDialogueTimer = GET_GAME_TIMER()
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Handles playing the conversation in which Franklin spots Dom.
PROC EXT1_MANAGE_FRANKLIN_SEES_DOM_CONVERSATION()
IF bStartedSeesDomConversation = FALSE
AND EXT1_ALLOW_CONVERSATION_TO_PLAY()
AND IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), vDom, 50)
AND IS_SPHERE_VISIBLE(vDom, 1)
AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_SEE", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_SEE conversation") ENDIF #ENDIF
bStartedSeesDomConversation = TRUE
ENDIF
ENDPROC
/// PURPOSE:
/// Checks the player doesn't abandon Dom, and fails the mission if necessary.
PROC EXT1_CHECK_PLAYER_ISNT_ABANDONING_DOM()
IF IS_ENTITY_ALIVE(pedDom)
AND NOT IS_ENTITY_IN_RANGE_ENTITY(PLAYER_PED_ID(), pedDom, 100)
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
EXT1_MISSION_FAILED(FAILED_DIDNT_HELP_DOM)
ENDIF
ENDPROC
/// PURPOSE:
/// Handles displaying the hint camera and text for Dom.
PROC EXT1_MANAGE_DOM_FOCUS_CAMERA()
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_MELEE_ATTACK_LIGHT) // Prevent Franklin swinging punches when using hint camera
IF IS_ENTITY_ALIVE(pedDom)
IF missionState = stateFollowDog
CONTROL_ENTITY_CHASE_HINT_CAM_IN_VEHICLE(localChaseHintCamStruct, pedDom, "EXT1_13") // Press ~INPUT_VEH_CIN_CAM~ to toggle focus on the man.
ELSE
CONTROL_ENTITY_CHASE_HINT_CAM_IN_VEHICLE(localChaseHintCamStruct, pedDom, "EXT1_20") // Press ~INPUT_VEH_CIN_CAM~ to toggle focus on Dom.
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Handles the player getting into the helicopter.
PROC EXT1_PLAYER_IS_ENTERING_HELICOPTER()
IF IS_ENTITY_ALIVE(vehHelicopter)
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE, SPC_LEAVE_CAMERA_CONTROL_ON)
SET_PED_HELMET(PLAYER_PED_ID(), FALSE) // B*1538808 Prevent Franklin putting headset on
VECTOR v_synch_scene_rot = <<0,0,0>>
IF g_replay.iReplayInt[1] = 1
v_synch_scene_rot.z += 180.0
TASK_ENTER_VEHICLE(PLAYER_PED_ID(), vehHelicopter, DEFAULT_TIME_BEFORE_WARP, VS_BACK_RIGHT, PEDMOVEBLENDRATIO_WALK, ECF_WARP_ENTRY_POINT)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Player seat = back right") ENDIF #ENDIF
ELSE
TASK_ENTER_VEHICLE(PLAYER_PED_ID(), vehHelicopter, DEFAULT_TIME_BEFORE_WARP, VS_BACK_LEFT, PEDMOVEBLENDRATIO_WALK, ECF_WARP_ENTRY_POINT)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Player seat = back left") ENDIF #ENDIF
ENDIF
FORCE_PED_AI_AND_ANIMATION_UPDATE(PLAYER_PED_ID())
iEnterHeliSynchedScene = CREATE_SYNCHRONIZED_SCENE(<<0,0,0>>, v_synch_scene_rot)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iEnterHeliSynchedScene, vehHelicopter, GET_ENTITY_BONE_INDEX_BY_NAME(vehHelicopter, "chassis")) // B*1936072 ensure the camera moves with the helicopter
camEnterHeli = CREATE_CAM("DEFAULT_ANIMATED_CAMERA", TRUE)
PLAY_SYNCHRONIZED_CAM_ANIM(camEnterHeli, iEnterHeliSynchedScene, "get_in_cam", "rcm_extreme1@heli")
SET_CAM_ACTIVE(camEnterHeli, TRUE)
RENDER_SCRIPT_CAMS(TRUE, FALSE)
SET_SCRIPTS_SAFE_FOR_CUTSCENE(TRUE)
SET_PLAYER_WANTED_LEVEL(PLAYER_ID(),0)
SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID())
SET_EVERYONE_IGNORE_PLAYER(PLAYER_ID(), TRUE)
DISPLAY_RADAR(FALSE)
DISPLAY_HUD(FALSE)
TRIGGER_MUSIC_EVENT("EXTREME1_START")
bPlayerNowEnteringHelicopter = TRUE
IF g_replay.iReplayInt[1] = 1
AND bStartedPilotGetInConversation = TRUE // See B*588731 - don't play criticising dialogue until player has been told which side to get into
AND bStartedWrongSideConversation = FALSE
AND EXT1_ALLOW_CONVERSATION_TO_PLAY()
AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_SIDE", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_SIDE conversation") ENDIF #ENDIF
bStartedWrongSideConversation = TRUE
ENDIF
IF GET_FOLLOW_PED_CAM_VIEW_MODE() = CAM_VIEW_MODE_FIRST_PERSON
SET_FOLLOW_PED_CAM_VIEW_MODE(CAM_VIEW_MODE_THIRD_PERSON_FAR)
bSetCameraToThirdPerson = true
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Reset ped camera to 3rd person") ENDIF #ENDIF
ENDIF
IF GET_FOLLOW_VEHICLE_CAM_VIEW_MODE() = CAM_VIEW_MODE_FIRST_PERSON
SET_FOLLOW_VEHICLE_CAM_VIEW_MODE(CAM_VIEW_MODE_THIRD_PERSON_FAR)
bSetCameraToThirdPerson = true
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Reset vehicle camera to 3rd person") ENDIF #ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Returns true if the player is within a certain range of the helicopter's back door.
FUNC BOOL EXT1_IS_PLAYER_IN_HELICOPTER_DOOR_OFFSET_RANGE(VECTOR v_offset, FLOAT f_range)
IF IS_ENTITY_ALIVE(vehHelicopter)
AND IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(vehHelicopter, v_offset), f_range)
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Handles the player getting into the helicopter.
PROC EXT1_MANAGE_PLAYER_ENTERING_HELICOPTER()
IF bPlayerLockedIntoEnteringHelicopter = FALSE // Don't allow multiple triggers
IF bStartedLeftWithoutYouConversation = FALSE // Don't allow player to enter helicopter when it starts taking off
AND bHelicopterLanded = TRUE // Wait until the helicopter is low enough to be considered as having landed
AND IS_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_ENTER)
AND IS_ENTITY_ALIVE(vehHelicopter)
AND IS_ENTITY_ALIVE(pedDom)
AND NOT IsPedPerformingTask(pedDom, SCRIPT_TASK_SHUFFLE_TO_NEXT_VEHICLE_SEAT) // B*1415068 Don't allow player to get in while Dom is shuffling seats
IF EXT1_IS_PLAYER_IN_HELICOPTER_DOOR_OFFSET_RANGE(<<-2.5,1,0>>, 3.5)
IF IS_VEHICLE_SEAT_FREE(vehHelicopter, VS_BACK_LEFT)
IF seatDom = VS_BACK_RIGHT // Dom has been told to get into VS_BACK_RIGHT
OR NOT IsPedPerformingTask(pedDom, SCRIPT_TASK_ENTER_VEHICLE) // Dom is currently getting into the VS_BACK_LEFT so don't allow the player to get in just yet
g_replay.iReplayInt[1] = 0
iPlayerEnterHelicopterTimer = GET_GAME_TIMER()
bPlayerLockedIntoEnteringHelicopter = TRUE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Allowing player to get into VS_BACK_LEFT") ENDIF #ENDIF
ENDIF
ENDIF
ELIF EXT1_IS_PLAYER_IN_HELICOPTER_DOOR_OFFSET_RANGE(<<2.5,1,0>>, 3.5)
IF IS_VEHICLE_SEAT_FREE(vehHelicopter, VS_BACK_RIGHT)
IF seatDom = VS_BACK_LEFT // Dom has been told to get into VS_BACK_LEFT
OR NOT IsPedPerformingTask(pedDom, SCRIPT_TASK_ENTER_VEHICLE) // Dom is currently getting into the VS_BACK_LEFT so don't allow the player to get in just yet
g_replay.iReplayInt[1] = 1
iPlayerEnterHelicopterTimer = GET_GAME_TIMER()
bPlayerLockedIntoEnteringHelicopter = TRUE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Allowing player to get into VS_BACK_RIGHT") ENDIF #ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ELIF bPlayerNowEnteringHelicopter = FALSE // Don't allow multiple triggers
IF (GET_GAME_TIMER() - iPlayerEnterHelicopterTimer) > 250
EXT1_PLAYER_IS_ENTERING_HELICOPTER()
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Handles the helicopter landing after the midtro has finished.
PROC EXT1_MANAGE_HELICOPTER_LANDING()
IF IS_ENTITY_ALIVE(vehHelicopter)
AND IS_ENTITY_ALIVE(pedDom)
IF bHelicopterLanded = FALSE
FLOAT z_height = GET_ENTITY_HEIGHT_ABOVE_GROUND(vehHelicopter)
IF z_height < 1.5 // B*1741671 Slightly relax height requirement for the heli having landed (can't increase too much or Dom warps into it due to heli being too much off the ground)
bHelicopterLanded = TRUE
ELIF z_height < 50.0
IF bDomLookingAtHelicopter = FALSE
TASK_LOOK_AT_ENTITY(pedDom, vehHelicopter, -1)
bDomLookingAtHelicopter = TRUE
ENDIF
ENDIF
ELSE // Helicopter has landed so get Dom into it
IF IS_PED_SITTING_IN_VEHICLE(pedDom, vehHelicopter) // Dom now sat in helicopter (which has its own blip) so remove Dom's blip
SAFE_REMOVE_BLIP(blipDom)
IF bPlayerLockedIntoEnteringHelicopter = FALSE
AND IS_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_ENTER)
AND NOT IsPedPerformingTask(pedDom, SCRIPT_TASK_SHUFFLE_TO_NEXT_VEHICLE_SEAT)
IF GET_PED_IN_VEHICLE_SEAT(vehHelicopter, VS_BACK_RIGHT) = pedDom
IF EXT1_IS_PLAYER_IN_HELICOPTER_DOOR_OFFSET_RANGE(<<2.5,1,0>>, 3)
TASK_SHUFFLE_TO_NEXT_VEHICLE_SEAT(pedDom, vehHelicopter)
seatDom = VS_BACK_LEFT
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Dom is sat in back right seat but player wants to get in so shuffle Dom across seats") ENDIF #ENDIF
ENDIF
ELIF GET_PED_IN_VEHICLE_SEAT(vehHelicopter, VS_BACK_LEFT) = pedDom
IF EXT1_IS_PLAYER_IN_HELICOPTER_DOOR_OFFSET_RANGE(<<-2.5,1,0>>, 3)
TASK_SHUFFLE_TO_NEXT_VEHICLE_SEAT(pedDom, vehHelicopter)
seatDom = VS_BACK_RIGHT
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Dom is sat in back left seat but player wants to get in so shuffle Dom across seats") ENDIF #ENDIF
ENDIF
ENDIF
ENDIF
ELIF NOT IS_PED_IN_VEHICLE(pedDom, vehHelicopter, TRUE)
IF NOT IsPedPerformingTask(pedDom, SCRIPT_TASK_ENTER_VEHICLE)
IF NOT EXT1_IS_PLAYER_IN_HELICOPTER_DOOR_OFFSET_RANGE(<<2.5,1,0>>, 3)
TASK_CLEAR_LOOK_AT(pedDom)
TASK_ENTER_VEHICLE(pedDom, vehHelicopter, 10000, VS_BACK_RIGHT, PEDMOVEBLENDRATIO_RUN)
seatDom = VS_BACK_RIGHT
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Dom entering back right seat") ENDIF #ENDIF
ELIF NOT EXT1_IS_PLAYER_IN_HELICOPTER_DOOR_OFFSET_RANGE(<<-2.5,1,0>>, 3)
TASK_CLEAR_LOOK_AT(pedDom)
TASK_ENTER_VEHICLE(pedDom, vehHelicopter, 10000, VS_BACK_LEFT, PEDMOVEBLENDRATIO_RUN)
seatDom = VS_BACK_LEFT
bStartedPilotGetInConversation = TRUE // Player is near VS_BACK_RIGHT so Dom gets into VS_BACK_LEFT straight away so don't allow this conversation to play
bStartedWrongSideConversation = TRUE // Player is near VS_BACK_RIGHT so Dom gets into VS_BACK_LEFT straight away so don't allow this conversation to play
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Dom entering back left seat") ENDIF #ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Handles playing the conversation in which Dom calls the helicopter pilot.
PROC EXT1_MANAGE_DOM_CALL_PILOT_CONVERSATION()
IF bStartedDomCallPilotConversation = FALSE
IF (GET_GAME_TIMER() - iEnterHelicopterTimer) > 9000
AND EXT1_ALLOW_CONVERSATION_TO_PLAY()
AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_MEETLZ", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_MEETLZ conversation") ENDIF #ENDIF
bStartedDomCallPilotConversation = TRUE
ENDIF
ELIF bPlayerLockedIntoEnteringHelicopter = FALSE // B*699928 Don't create blip or start conversation if player has already initiated getting into the left hand side of the helicopter
IF bHelicopterLanded = TRUE
IF NOT DOES_BLIP_EXIST(blipHelicopter)
blipHelicopter = CREATE_VEHICLE_BLIP(vehHelicopter)
PRINT_NOW("EXT1_05", 5000, 1) // Get in the ~b~helicopter.
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), vehHelicopter, -1)
ENDIF
IF bStartedPilotGetInConversation = FALSE
AND EXT1_ALLOW_CONVERSATION_TO_PLAY()
AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_GETIN", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_GETIN conversation") ENDIF #ENDIF
bStartedPilotGetInConversation = TRUE
ENDIF
ENDIF
ENDIF
IF bStartedDomCallPilotConversation = TRUE
AND bStartedPilotGetInConversation = FALSE
AND IS_ENTITY_ALIVE(pedDom)
AND IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
AND NOT IS_ENTITY_IN_RANGE_ENTITY(PLAYER_PED_ID(), pedDom, 20)
TEXT_LABEL_23 t_current_dialogue = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT()
IF ARE_STRINGS_EQUAL(t_current_dialogue, "EXT1_MEETLZ")
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Player moved away from Dom so killed EXT1_MEETLZ conversation") ENDIF #ENDIF
KILL_ANY_CONVERSATION() // See B*588812 - kill the conversation if the player moves too far away from Dom
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Checks the player doesn't abandon the helicopter or take too long getting in, and fails the mission if necessary.
PROC EXT1_MANAGE_PLAYER_NOT_ENTERING_HELICOPTER()
IF bZSkipping = FALSE
AND bPlayerLockedIntoEnteringHelicopter = FALSE // Prevent mission fail if player presses triangle to initiate getting into the helicopter
IF (GET_GAME_TIMER() - iEnterHelicopterTimer) > 60000
IF bStartedLeftWithoutYouConversation = FALSE
IF IS_ENTITY_ALIVE(vehHelicopter)
AND NOT IS_ENTITY_IN_RANGE_ENTITY(PLAYER_PED_ID(), pedDom, 20)
AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_NOTIN", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_NOTIN conversation") ENDIF #ENDIF
bStartedLeftWithoutYouConversation = TRUE
TASK_HELI_MISSION(pedPilot,vehHelicopter,NULL,NULL,vHelicopterStart,MISSION_GOTO,10,5,-1,100,30)
ENDIF
ELIF (GET_GAME_TIMER() - iEnterHelicopterTimer) > 62000
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() // Wait until the EXT1_NOTIN conversation has finished before failing
EXT1_MISSION_FAILED(FAILED_DIDNT_ENTER_HELICOPTER)
ENDIF
ENDIF
ELIF (GET_GAME_TIMER() - iEnterHelicopterTimer) > 40000
IF bStartedLeavingWithoutYouConversation = FALSE
AND EXT1_ALLOW_CONVERSATION_TO_PLAY()
AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_HURRY", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_HURRY conversation") ENDIF #ENDIF
bStartedLeavingWithoutYouConversation = TRUE
ENDIF
ENDIF
IF IS_ENTITY_ALIVE(pedDom)
AND NOT IS_ENTITY_IN_RANGE_ENTITY(PLAYER_PED_ID(), pedDom, 75)
EXT1_MISSION_FAILED(FAILED_DIDNT_ENTER_HELICOPTER)
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Custom fade out function that prevents the 1st person vehicle cam updating
PROC EXT1_SAFE_FADE_SCREEN_OUT_TO_BLACK(INT iTime = 500, BOOL bWaitForFade = TRUE)
IF IS_SCREEN_FADED_IN()
IF NOT IS_SCREEN_FADING_OUT()
DO_SCREEN_FADE_OUT(iTime)
IF bWaitForFade
WHILE NOT IS_SCREEN_FADED_OUT()
DISABLE_CINEMATIC_BONNET_CAMERA_THIS_UPDATE()
WAIT(0)
ENDWHILE
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Handles skipping the helicopter journey by pressing X.
PROC EXT1_MANAGE_SKIP_JOURNEY()
IF bSkippingJourney = FALSE
IF bDisplayedSkipJourneyHelpText = FALSE
IF iCurrentHelicopterMission > 0
AND IS_ENTITY_ALIVE(vehHelicopter)
AND IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vehHelicopter)
CLEAR_HELP()
PRINT_HELP_FOREVER("EXT1_17") // Press ~INPUT_SKIP_CUTSCENE~ to skip the journey.
bDisplayedSkipJourneyHelpText = TRUE
ENDIF
ELSE
IF bZSkipping = FALSE
AND IS_CUTSCENE_SKIP_BUTTON_JUST_PRESSED()
CLEAR_HELP()
KILL_FACE_TO_FACE_CONVERSATION() // Stop conversation but don't kill it dead
bSkippingJourney = TRUE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Skipping helicopter journey") ENDIF #ENDIF
ENDIF
ENDIF
ELSE
EXT1_SAFE_FADE_SCREEN_OUT_TO_BLACK(1000, TRUE)
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() // Kill the conversation now it's faded to black
EXT1_DEBUG_SKIP_STATE(Z_SKIP_JUMP_OUT_HELICOPTER)
SAFE_FADE_SCREEN_IN_FROM_BLACK(1000, TRUE)
missionStateMachine = EXT1_STATE_MACHINE_CLEANUP
ENDIF
ENDPROC
/// PURPOSE:
/// Handles giving the helicopter intermediate helicopter missions to ascend to the mountain summit. Can't give one mission cos the helicopter goes straight there (through trees etc).
PROC EXT1_MANAGE_HELICOPTER_MISSIONS()
IF IS_ENTITY_ALIVE(vehHelicopter)
SWITCH iCurrentHelicopterMission
CASE 0
IF bStartedAscendConversation = TRUE
TASK_HELI_MISSION(pedPilot,vehHelicopter,NULL,NULL,vHelicopterStart,MISSION_GOTO,fHelicopterSpeedFlat,5,354.7650,100,30)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: iCurrentHelicopterMission = taking off") ENDIF #ENDIF
iCurrentHelicopterMission++
ENDIF
BREAK
CASE 1
IF IS_ENTITY_IN_RANGE_COORDS(vehHelicopter, vHelicopterStart, 30)
TASK_HELI_MISSION(pedPilot,vehHelicopter,NULL,NULL,<<vHelicopterEnd.x,vHelicopterEnd.y,800>>,MISSION_GOTO,fHelicopterSpeedFlat,5,354.7650,100,30) // -1000 for the z in order to go flatter along the ground towards the summit
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: iCurrentHelicopterMission = flying flat to mountain") ENDIF #ENDIF
iCurrentHelicopterMission++
ENDIF
BREAK
CASE 2
IF IS_ENTITY_IN_RANGE_COORDS(vehHelicopter, <<vHelicopterEnd.x,vHelicopterEnd.y,800>>, 500)
TASK_HELI_MISSION(pedPilot,vehHelicopter,NULL,NULL,vHelicopterEnd,MISSION_GOTO,fHelicopterSpeedRise,5,GET_ENTITY_HEADING(vehHelicopter),100,30)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: iCurrentHelicopterMission = flying up to basejump pos") ENDIF #ENDIF
SET_WEATHER_TYPE_OVERTIME_PERSIST("CLEAR", 30)
iCurrentHelicopterMission++
ENDIF
BREAK
CASE 3
IF IS_ENTITY_IN_RANGE_COORDS(vehHelicopter, vHelicopterEnd, 50)
IF PLAYER_PED_ID() = GET_PED_IN_VEHICLE_SEAT(vehHelicopter, VS_BACK_LEFT)
TASK_HELI_MISSION(pedPilot,vehHelicopter,NULL,NULL,vHelicopterEnd,MISSION_GOTO,fHelicopterSpeedRise,5,fHelicopterDesiredHeading,100,30)
ELSE
TASK_HELI_MISSION(pedPilot,vehHelicopter,NULL,NULL,vHelicopterEnd,MISSION_GOTO,fHelicopterSpeedRise,5,fHelicopterDesiredHeading-180,100,30)
ENDIF
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: iCurrentHelicopterMission = almost reached basejump pos so re-orientating") ENDIF #ENDIF
iCurrentHelicopterMission++
ENDIF
BREAK
CASE 4
IF IS_ENTITY_IN_RANGE_COORDS(vehHelicopter, vHelicopterEnd, 10)
AND bStartedSummitConversation = TRUE
AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() // Wait until EXT1_SUMMIT has finished
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: iCurrentHelicopterMission = now reached basejump pos") ENDIF #ENDIF
missionStateMachine = EXT1_STATE_MACHINE_CLEANUP
iCurrentHelicopterMission++
ENDIF
BREAK
DEFAULT
BREAK
ENDSWITCH
ENDIF
ENDPROC
/// PURPOSE:
/// Handles motion blur on the gameplay camera during the heli ride to the summit.
PROC EXT1_MANAGE_GAMEPLAY_CAM_MOTION_BLUR()
SET_GAMEPLAY_CAM_MAX_MOTION_BLUR_STRENGTH_THIS_UPDATE(0.15)
ENDPROC
/// PURPOSE:
/// Handles playing the conversation during the helicopter ascent.
PROC EXT1_MANAGE_HELICOPTER_ASCEND_CONVERSATION()
IF bStartedAscend3Conversation = FALSE
IF EXT1_ALLOW_CONVERSATION_TO_PLAY()
AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_ASCEND3", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_ASCEND3 conversation") ENDIF #ENDIF
bStartedAscend3Conversation = TRUE
EXT1_SET_FRANKLIN_INTO_PARACHUTE_OUTFIT()
ENDIF
ELIF bStartedAscendConversation = FALSE
IF EXT1_ALLOW_CONVERSATION_TO_PLAY()
AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_ASCEND", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_ASCEND conversation") ENDIF #ENDIF
bStartedAscendConversation = TRUE
ENDIF
ELIF bStartedAscend2Conversation = FALSE
IF EXT1_ALLOW_CONVERSATION_TO_PLAY()
AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_ASCEND2", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_ASCEND2 conversation") ENDIF #ENDIF
bStartedAscend2Conversation = TRUE
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Handles playing the conversation when the helicopter reaches the summit at which the skydive occurs.
PROC EXT1_MANAGE_HELICOPTER_SUMMIT_CONVERSATION()
IF bStartedSummitConversation = FALSE
AND EXT1_ALLOW_CONVERSATION_TO_PLAY()
AND IS_ENTITY_ALIVE(vehHelicopter)
AND IS_ENTITY_IN_RANGE_COORDS(vehHelicopter, vHelicopterEnd, 200) // Wait until we've actually reached the summit
AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_SUMMIT", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_SUMMIT conversation") ENDIF #ENDIF
bStartedSummitConversation = TRUE
ENDIF
ENDPROC
/// PURPOSE:
/// Handles playing the conversation during the skydive.
PROC EXT1_MANAGE_DURING_SKYDIVE_CONVERSATIONS()
IF bStartedJumpedOutConversation = FALSE
IF EXT1_ALLOW_CONVERSATION_TO_PLAY(TRUE, FALSE)
AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_FIST", CONV_PRIORITY_HIGH, DO_NOT_DISPLAY_SUBTITLES) // Don't display subtitles because it'll be printing the "Skydive to the ~y~landing zone." objective
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_FIST conversation") ENDIF #ENDIF
bStartedJumpedOutConversation = TRUE
ENDIF
ELIF bStartedDuringSkydiveConversation = FALSE
IF EXT1_ALLOW_CONVERSATION_TO_PLAY(TRUE, FALSE)
AND CREATE_CONVERSATION(sConversation, "EXT1AU", sSkydiveRoot, CONV_PRIORITY_HIGH, DO_NOT_DISPLAY_SUBTITLES)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started sSkydiveRoot conversation") ENDIF #ENDIF
bStartedDuringSkydiveConversation = TRUE
ENDIF
ELIF bStoppedDuringSkydiveConversation = FALSE
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
tSavedConversationLabel = GET_STANDARD_CONVERSATION_LABEL_FOR_FUTURE_RESUMPTION()
IF ARE_STRINGS_EQUAL(tSavedConversationLabel, sSkydiveLabel)
KILL_FACE_TO_FACE_CONVERSATION()
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Stopped sSkydiveRoot conversation") ENDIF #ENDIF
bStoppedDuringSkydiveConversation = TRUE
ENDIF
ENDIF
ELIF bRestartedDuringSkydiveConversation = FALSE
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
AND CREATE_CONVERSATION_FROM_SPECIFIC_LINE(sConversation, "EXT1AU", sSkydiveRoot, tSavedConversationLabel, CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Restarted sSkydiveRoot conversation") ENDIF #ENDIF
bRestartedDuringSkydiveConversation = TRUE
ENDIF
ELIF bStartedDeployParachuteConversation = FALSE
IF EXT1_ALLOW_CONVERSATION_TO_PLAY()
AND IS_ENTITY_ALIVE(PLAYER_PED_ID())
VECTOR v_player_pos = GET_ENTITY_COORDS(PLAYER_PED_ID())
IF v_player_pos.z < 1000
AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_LATE", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_LATE conversation") ENDIF #ENDIF
bStartedDeployParachuteConversation = TRUE
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Handles releasing the parachute object see B*1327983
PROC EXT1_MANAGE_RELEASING_PARACHUTE_OBJECT()
IF DOES_ENTITY_EXIST(oParachute)
AND IS_ENTITY_ALIVE(vehHelicopter)
AND GET_DISTANCE_BETWEEN_ENTITIES(oParachute, vehHelicopter) > 200
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Released parachute object") ENDIF #ENDIF
SAFE_RELEASE_OBJECT(oParachute)
ENDIF
ENDPROC
/// PURPOSE:
/// Handles playing the dialogue when Dom lands.
PROC EXT1_MANAGE_DOM_LANDS_DIALOGUE()
IF bStartedDomLandsConversation = FALSE
AND GET_PED_PARACHUTE_STATE(PLAYER_PED_ID()) = PPS_INVALID // B*1149077 Don't allow this dialogue to trigger if player is still skydiving
KILL_FACE_TO_FACE_CONVERSATION() // Stop EXT1_SKYDIVE if it's ongoing
STOP_CHECKING_CONVERSATION_AND_OBJECTIVE_TEXT_CONFLICT(stateRestoreConversation) // No need to keep checking for EXT1_SKYDIVE because we're now stopping it anyway
IF EXT1_ALLOW_CONVERSATION_TO_PLAY()
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
IF CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_WAIT", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_WAIT conversation") ENDIF #ENDIF
bStartedDomLandsConversation = TRUE
ENDIF
ELIF CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_GETBIKE", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_GETBIKE conversation") ENDIF #ENDIF
bStartedDomLandsConversation = TRUE
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Returns true if the player has started to cycle off on the race before Dom is on his bike.
PROC EXT1_CHECK_FOR_WARP_DOM_ONTO_BIKE()
IF missionState = stateWaitForDom
AND iPlayersChosenBike > -1 // Wait until player has got on his bike
AND IS_ENTITY_ALIVE(vehBike[iPlayersChosenBike])
AND IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vehBike[iPlayersChosenBike], TRUE)
AND NOT IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), vBike[0], 60)
AND IS_ENTITY_ALIVE(pedDom)
AND IS_ENTITY_ALIVE(vehBike[iDomsBike])
AND NOT IS_POINT_VISIBLE(GET_ENTITY_COORDS(pedDom), 10) // Ensure Dom isn't visible before allowing the warp
AND NOT IS_POINT_VISIBLE(GET_ENTITY_COORDS(vehBike[iDomsBike]), 5) // Ensure Dom's bike isn't visible before allowing the warp
SET_PED_INTO_VEHICLE(pedDom, vehBike[iDomsBike])
bPlayerStartedRaceEarly = TRUE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Player trying to cheat so warped Dom onto his bike") ENDIF #ENDIF
domStatus = DOM_SAT_ON_BIKE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: domStatus = DOM_SAT_ON_BIKE") ENDIF #ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Handles Dom skydiving out of the helicopter.
PROC EXT1_MANAGE_DOM_SKYDIVE()
VECTOR v_dom
IF IS_ENTITY_ALIVE(pedDom)
SWITCH domStatus
CASE DOM_IN_HELICOPTER
IF IS_PED_IN_ANY_VEHICLE(pedDom)
TASK_LEAVE_ANY_VEHICLE(pedDom, 0, ECF_DONT_CLOSE_DOOR)
domStatus = DOM_GETTING_OUT_HELICOPTER
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: domStatus = DOM_GETTING_OUT_HELICOPTER") ENDIF #ENDIF
ENDIF
BREAK
CASE DOM_GETTING_OUT_HELICOPTER
IF IS_ENTITY_ALIVE(vehHelicopter)
AND NOT IS_PED_IN_VEHICLE(pedDom, vehHelicopter)
v_dom = GET_ENTITY_COORDS(pedDom)
IF v_dom.z < 1200 // Wait until Dom has cleared the helicopter before deploying parachute
TASK_PARACHUTE_TO_TARGET(pedDom, vLandingPos)
domStatus = DOM_DEPLOYING
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: domStatus = DOM_DEPLOYING") ENDIF #ENDIF
ENDIF
ENDIF
BREAK
CASE DOM_DEPLOYING
IF GET_PED_PARACHUTE_STATE(pedDom) = PPS_INVALID
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: GET_PED_PARACHUTE_STATE is PPS_INVALID") ENDIF #ENDIF
ELSE // Usually takes a few frames before the parachuting sorts itself out and changes from PPS_INVALID
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: GET_PED_PARACHUTE_STATE is not PPS_INVALID") ENDIF #ENDIF
SET_PARACHUTE_TASK_TARGET(pedDom, vLandingPos)
SAFE_RELEASE_PED(pedPilot)
SAFE_RELEASE_VEHICLE(vehHelicopter)
domStatus = DOM_SKYDIVING
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: domStatus = DOM_SKYDIVING") ENDIF #ENDIF
ENDIF
BREAK
CASE DOM_SKYDIVING
IF GET_PED_PARACHUTE_STATE(pedDom) = PPS_DEPLOYING
domStatus = DOM_PARACHUTING
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: domStatus = DOM_PARACHUTING") ENDIF #ENDIF
ENDIF
BREAK
CASE DOM_PARACHUTING
IF GET_PED_PARACHUTE_STATE(pedDom) = PPS_LANDING
OR GET_PED_PARACHUTE_STATE(pedDom) = PPS_INVALID
IF IS_ENTITY_ALIVE(pedDom)
SET_PED_COMPONENT_VARIATION(pedDom, INT_TO_ENUM(PED_COMPONENT,8), 2, 0, 0)
TASK_LOOK_AT_ENTITY(pedDom, PLAYER_PED_ID(), -1)
ENDIF
domStatus = DOM_LANDED
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: domStatus = DOM_LANDED") ENDIF #ENDIF
ELSE // Dom is still skydiving, so check for the player cheating by hurrying down to his bike and riding off
EXT1_CHECK_FOR_WARP_DOM_ONTO_BIKE()
ENDIF
BREAK
CASE DOM_LANDED
EXT1_MANAGE_DOM_LANDS_DIALOGUE()
IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(pedDom, vBike[1]) < 5
IF iDomsBike = -1 // The player hasn't yet got on a bike, so set these vars now
iPlayersChosenBike = BIKE_0
iDomsBike = BIKE_1
ENDIF
IF IS_ENTITY_ALIVE(vehBike[iDomsBike])
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(vehBike[iDomsBike], FALSE)
SET_VEHICLE_DOORS_LOCKED(vehBike[iDomsBike], VEHICLELOCK_LOCKOUT_PLAYER_ONLY) // B*1915104 Lock the bike to the player to prevent him getting on it after the bike is allocated to Dom
SAFE_REMOVE_BLIP(blipBike[iDomsBike])
domStatus = DOM_GETTING_ON_BIKE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: domStatus = DOM_GETTING_ON_BIKE") ENDIF #ENDIF
ENDIF
ELIF NOT IsPedPerformingTask(pedDom, SCRIPT_TASK_FOLLOW_NAV_MESH_TO_COORD)
TASK_FOLLOW_NAV_MESH_TO_COORD(pedDom, vBike[1], PEDMOVE_RUN)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: pedDom given TASK_FOLLOW_NAV_MESH_TO_COORD") ENDIF #ENDIF
ENDIF
BREAK
CASE DOM_GETTING_ON_BIKE
EXT1_MANAGE_DOM_LANDS_DIALOGUE()
IF IS_ENTITY_ALIVE(vehBike[iDomsBike])
IF IS_PED_IN_VEHICLE(pedDom, vehBike[iDomsBike])
domStatus = DOM_SAT_ON_BIKE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: domStatus = DOM_SAT_ON_BIKE") ENDIF #ENDIF
iGetOnBikeReminderTimer = GET_GAME_TIMER()
ELSE // Dom is still getting on his bike, so check for the player cheating by riding off
IF NOT IsPedPerformingTask(pedDom, SCRIPT_TASK_ENTER_VEHICLE)
TASK_ENTER_VEHICLE(pedDom, vehBike[iDomsBike])
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: pedDom given TASK_ENTER_VEHICLE") ENDIF #ENDIF
ENDIF
EXT1_CHECK_FOR_WARP_DOM_ONTO_BIKE()
ENDIF
ENDIF
BREAK
CASE DOM_SAT_ON_BIKE // Dom now waiting for the bike race to start
EXT1_MANAGE_DOM_LANDS_DIALOGUE()
IF bStartedGetOnBikeReminderConversation = FALSE
AND bStartedDomLandsConversation = TRUE // Only allow playing after first telling the player to get on the bike
AND (GET_GAME_TIMER() - iGetOnBikeReminderTimer) > 10000
AND EXT1_ALLOW_CONVERSATION_TO_PLAY()
AND IS_ENTITY_ALIVE(PLAYER_PED_ID())
AND GET_PED_PARACHUTE_STATE(PLAYER_PED_ID()) = PPS_INVALID // Player has finished parachuting..
AND IS_ENTITY_ALIVE(vehBike[iPlayersChosenBike])
AND NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vehBike[iPlayersChosenBike], TRUE) // .. but not yet got onto his bike
AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_GET2", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_GET2 conversation") ENDIF #ENDIF
bStartedGetOnBikeReminderConversation = TRUE
ENDIF
BREAK
ENDSWITCH
ENDIF
ENDPROC
/// PURPOSE:
/// Commands to execute when the player presses Y to leave the helicopter or is pushed out due to taking too long.
PROC EXT1_PLAYER_IS_LEAVING_HELICOPTER()
bFranklinExitingHelicopter = TRUE
REPLAY_RECORD_BACK_FOR_TIME(3.0)
IF IS_HELP_MESSAGE_BEING_DISPLAYED() // Use ~PAD_RSTICK_ALL~ to look and press ~PAD_Y~ to jump.
CLEAR_HELP()
ENDIF
IF DOES_CAM_EXIST(camSkydive)
AND DOES_CAM_EXIST(camSkydiveInterp)
SET_CAM_FOV(camSkydiveInterp, 26.0)
SET_CAM_NEAR_CLIP(camSkydiveInterp, 0.840)
SHAKE_CAM(camSkydiveInterp, "SKY_DIVING_SHAKE", 0.15)
SET_CAM_ACTIVE_WITH_INTERP(camSkydiveInterp, camSkydive, 1500, GRAPH_TYPE_ACCEL)
ENDIF
EXT1_PLAY_SYNCHED_SCENE(TRUE)
KILL_FACE_TO_FACE_CONVERSATION()
STOP_SOUND(iWindSound)
ENDPROC
/// PURPOSE:
/// Handles the player taking too long to get out of the helicopter.
PROC EXT1_MANAGE_HURRY_UP_CONVERSATIONS()
IF EXT1_ALLOW_CONVERSATION_TO_PLAY()
IF bStartedJumpOutConversation = FALSE
IF CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_JUMP", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_JUMP conversation") ENDIF #ENDIF
bStartedJumpOutConversation = TRUE
ENDIF
ELIF bStartedHurryUpConversation = FALSE
IF (GET_GAME_TIMER() - iHelicopterPushOutTimer) > 15000
AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_WAIT1", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_WAIT1 conversation") ENDIF #ENDIF
bStartedHurryUpConversation = TRUE
ENDIF
ELIF bStartedPushOutConversation = FALSE
IF (GET_GAME_TIMER() - iHelicopterPushOutTimer) > 40000 // The player has had 40 seconds to jump out, we can't wait all day so imply the pilot pushes him out
AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_WAIT2", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_WAIT2 conversation") ENDIF #ENDIF
bStartedPushOutConversation = TRUE
ENDIF
ELIF bPushedOutPlayer = FALSE
bPushedOutPlayer = TRUE
EXT1_PLAYER_IS_LEAVING_HELICOPTER()
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Handles displaying the objective and help text for jumping out of the helicopter.
PROC EXT1_MANAGE_DISPLAY_JUMP_OUT_TEXT()
IF bDisplayedJumpOutHelpText = FALSE
IF (GET_GAME_TIMER() - iHelicopterPushOutTimer) > 2000
PRINT_HELP_FOREVER("EXT1_10") // Use ~INPUTGROUP_LOOK~ to look and press ~INPUT_SCRIPT_RLEFT~ to jump.
bDisplayedJumpOutHelpText = TRUE
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Check if the player landed within the landing zone.
FUNC BOOL EXT1_DID_PLAYER_LAND_IN_TARGET_ZONE()
FLOAT f_dist = GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), vCheckpoint)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Distance away from target=", ROUND(f_dist)) ENDIF #ENDIF
IF f_dist < 50.0
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
ENDFUNC
/// PURPOSE:
/// Returns TRUE when the player has landed on the ground.
FUNC BOOL EXT1_HAS_PLAYER_LANDED()
IF GET_PED_PARACHUTE_STATE(PLAYER_PED_ID()) = PPS_LANDING
OR GET_PED_PARACHUTE_STATE(PLAYER_PED_ID()) = PPS_INVALID // B*1029431 If the player crashed into the side of something the status goes from PPS_PARACHUTING to PPS_INVALID, bypassing PPS_LANDING
IF GET_ENTITY_HEIGHT_ABOVE_GROUND(PLAYER_PED_ID()) < 50.0
RETURN TRUE
ELSE // Player has manually removed his parachute by pressing Y when high above the ground, so fail the mission
IF NOT GET_PLAYER_HAS_RESERVE_PARACHUTE(PLAYER_ID()) // B*1933916 Don't fail if the player has a reserve parachute
EXT1_MISSION_FAILED(FAILED_FAILED_SKY_DIVE)
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Checks the player doesn't leave the mission area.
PROC EXT1_MANAGE_PLAYER_LEAVING_MISSION_AREA()
IF NOT IS_ENTITY_AT_COORD(PLAYER_PED_ID(), vCheckpoint, <<1300,1300,1300>>, FALSE, FALSE)
EXT1_MISSION_FAILED(FAILED_LEFT_MISSION_AREA)
ELIF bGivenMissionAreaWarning = FALSE
IF NOT IS_ENTITY_AT_COORD(PLAYER_PED_ID(), vCheckpoint, <<1000,1000,1000>>, FALSE, FALSE)
bGivenMissionAreaWarning = TRUE
PRINT_NOW("EXT1_09", DEFAULT_GOD_TEXT_TIME, 1) // You are leaving the mission area. Skydive to the ~y~landing zone.
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Handles displaying the hint camera and text for the landing zone.
PROC EXT1_MANAGE_LANDING_ZONE_FOCUS_CAMERA()
IF GET_PED_PARACHUTE_STATE(PLAYER_PED_ID()) = PPS_DEPLOYING
IF bOpenedTimeWindowForSkydiveStat = TRUE
INFORM_MISSION_STATS_SYSTEM_OF_TIME_WINDOW_CLOSED()
bOpenedTimeWindowForSkydiveStat = FALSE
ENDIF
IF IS_HELP_MESSAGE_BEING_DISPLAYED()
CLEAR_HELP()
ENDIF
bStartedDeployParachuteConversation = TRUE // Prevent the conversation for deploying the parachute triggering, since the player has just deploted
ELIF GET_PED_PARACHUTE_STATE(PLAYER_PED_ID()) = PPS_PARACHUTING
CONTROL_COORD_CHASE_HINT_CAM_ON_FOOT(localChaseHintCamStruct, vCheckpoint) // Press ~INPUT_VEH_CIN_CAM~ to toggle focus on the landing zone.
IF IS_USING_KEYBOARD_AND_MOUSE(PLAYER_CONTROL)
IF NOT IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("EXT1_06_KM")
PRINT_HELP_FOREVER("EXT1_06_KM") // Parachute help text
ENDIF
ELSE
IF NOT IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("EXT1_06")
PRINT_HELP_FOREVER("EXT1_06") // Parachute help text
ENDIF
ENDIF
ENDIF
IF bRestartedDuringSkydiveConversation = TRUE
AND iSkydiveDialogueTimer > -1
AND (GET_GAME_TIMER() - iSkydiveDialogueTimer) > 8000
AND EXT1_ALLOW_CONVERSATION_TO_PLAY()
IF GET_RANDOM_INT_IN_RANGE(0, 2) = 0
IF iNumberSkydiveBanterFranklinDone < 5
AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_GENF", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_GENF conversation") ENDIF #ENDIF
iSkydiveDialogueTimer = GET_GAME_TIMER()
iNumberSkydiveBanterFranklinDone++
ENDIF
ELSE
IF iNumberSkydiveBanterDomDone < 5
AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_GEND", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_GEND conversation") ENDIF #ENDIF
iSkydiveDialogueTimer = GET_GAME_TIMER()
iNumberSkydiveBanterDomDone++
ENDIF
ENDIF
IF iNumberSkydiveBanterFranklinDone = 5
AND iNumberSkydiveBanterDomDone = 5
iSkydiveDialogueTimer = -1
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: All EXT1_GENF and EXT1_GEND dialogue now done") ENDIF #ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Draws the checkpoint ring. Must be called every frame.
PROC EXT1_DRAW_TARGET_MARKER()
DRAW_MARKER(MARKER_RING, vCheckpoint, <<0,0,0>>, vMarkerRotation, <<4, 4, 4>>, 255, 120, 0, 100, FALSE, FALSE)
DRAW_MARKER(MARKER_RING, vCheckpoint, <<0,0,0>>, vMarkerRotation, <<9, 9, 9>>, 255, 120, 0, 100, FALSE, FALSE)
DRAW_MARKER(MARKER_RING, vCheckpoint, <<0,0,0>>, vMarkerRotation, <<14, 14, 14>>, 255, 120, 0, 100, FALSE, FALSE)
ENDPROC
/// PURPOSE:
/// Creates a blip on the specified bike.
PROC EXT1_CREATE_BLIP_FOR_BIKE(INT i)
IF IS_ENTITY_ALIVE(vehBike[i])
AND NOT DOES_BLIP_EXIST(blipBike[i])
blipBike[i] = CREATE_VEHICLE_BLIP(vehBike[i])
ENDIF
ENDPROC
/// PURPOSE:
/// Creates a blip on the player's bike and if necessary tells him to get on it.
PROC EXT1_TELL_PLAYER_TO_GET_ON_HIS_BIKE()
EXT1_CREATE_BLIP_FOR_BIKE(iPlayersChosenBike)
IF bToldToGetBackOnBike = FALSE
PRINT_NOW("EXT1_16", DEFAULT_GOD_TEXT_TIME, 1) // Get back on your ~b~bike.
bToldToGetBackOnBike = TRUE
ENDIF
ENDPROC
/// PURPOSE:
/// Handles playing the dialogue if the player drives off on his bike before Dom has landed.
PROC EXT1_MANAGE_FAIR_RACE_DIALOGUE()
IF bStartedFairRaceConversation = FALSE
AND EXT1_ALLOW_CONVERSATION_TO_PLAY(TRUE, FALSE)
AND IS_ENTITY_ALIVE(vehBike[iDomsBike])
AND IS_ENTITY_ALIVE(pedDom)
AND GET_DISTANCE_BETWEEN_ENTITIES(vehBike[iDomsBike], pedDom) > 5 // B*1359416 Don't play this dialogue if Dom is about to get on his own bike
AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_FAIR", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_FAIR conversation") ENDIF #ENDIF
bStartedFairRaceConversation = TRUE
ENDIF
ENDPROC
/// PURPOSE:
/// Creates a slidey blip for Dom. See B*1089563.
PROC CREATE_DOM_SLIDEY_BLIP(BOOL b_ped_scale)
IF NOT DOES_BLIP_EXIST(blipDom)
AND IS_ENTITY_ALIVE(pedDom)
blipDom = CREATE_COORD_BLIP(GET_ENTITY_COORDS(pedDom), BLIPPRIORITY_HIGH, FALSE)
SET_BLIP_NAME_FROM_TEXT_FILE(blipDom, "BLIP_FRIEND")
SET_BLIP_COLOUR(blipDom, BLIP_COLOUR_BLUE)
IF b_ped_scale = TRUE
SET_BLIP_SCALE(blipDom, BLIP_SIZE_PED)
ELSE
SET_BLIP_SCALE(blipDom, BLIP_SIZE_VEHICLE)
ENDIF
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Created slidey blip for Dom") ENDIF #ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Returns TRUE when both the player and Dom are sat on their bikes. Also handles creating/deleting blips etc.
FUNC BOOL EXT1_ARE_BOTH_ON_BIKES()
IF iPlayersChosenBike = -1
IF IS_ENTITY_ALIVE(vehBike[BIKE_0])
AND IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vehBike[BIKE_0], TRUE)
iPlayersChosenBike = BIKE_0
iDomsBike = BIKE_1
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Player has chosen bike 0") ENDIF #ENDIF
SAFE_REMOVE_BLIP(blipBike[BIKE_0])
SAFE_REMOVE_BLIP(blipBike[BIKE_1])
IF IS_ENTITY_ALIVE(vehBike[iDomsBike])
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(vehBike[iDomsBike], FALSE)
SET_VEHICLE_DOORS_LOCKED(vehBike[iDomsBike], VEHICLELOCK_LOCKOUT_PLAYER_ONLY) // B*1915104 Lock the bike to the player to prevent him getting on it after the bike is allocated to Dom
ENDIF
ENDIF
IF IS_ENTITY_ALIVE(vehBike[BIKE_1])
AND IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vehBike[BIKE_1], TRUE)
iPlayersChosenBike = BIKE_1
iDomsBike = BIKE_0
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Player has chosen bike 1") ENDIF #ENDIF
SAFE_REMOVE_BLIP(blipBike[BIKE_0])
SAFE_REMOVE_BLIP(blipBike[BIKE_1])
IF IS_ENTITY_ALIVE(vehBike[iDomsBike])
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(vehBike[iDomsBike], FALSE)
SET_VEHICLE_DOORS_LOCKED(vehBike[iDomsBike], VEHICLELOCK_LOCKOUT_PLAYER_ONLY) // B*1915104 Lock the bike to the player to prevent him getting on it after the bike is allocated to Dom
ENDIF
ENDIF
ELSE
EXT1_START_AUDIO_SCENE("EXTREME_01_JOURNEY", FALSE)
EXT1_START_AUDIO_SCENE("EXTREME_01_RACE", TRUE)
IF IS_ENTITY_ALIVE(vehBike[iDomsBike])
ADD_ENTITY_TO_AUDIO_MIX_GROUP(vehBike[iDomsBike], "EXTREME_01_BIKE_RACE_DOM_GROUP")
ENDIF
IF IS_ENTITY_ALIVE(vehBike[iPlayersChosenBike])
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vehBike[iPlayersChosenBike], TRUE)
bPlayerGotOnABike = TRUE
SAFE_REMOVE_BLIP(blipBike[iPlayersChosenBike])
IF IS_THIS_PRINT_BEING_DISPLAYED("EXT1_14") // Get on the ~b~bike.
OR IS_THIS_PRINT_BEING_DISPLAYED("EXT1_16") // Get back on your ~b~bike.
OR IS_THIS_PRINT_BEING_DISPLAYED("EXT1_21") // Get on a ~b~bike.
CLEAR_PRINTS()
ENDIF
TRIGGER_MUSIC_EVENT("EXTREME1_BIKE")
IF domStatus = DOM_SAT_ON_BIKE
RETURN TRUE // Both Franklin and Dom are now sat on their bikes
ELSE
EXT1_MANAGE_FAIR_RACE_DIALOGUE()
CREATE_DOM_SLIDEY_BLIP(TRUE)
IF bToldToWaitForDom = FALSE
AND NOT IS_ENTITY_IN_RANGE_COORDS(vehBike[iPlayersChosenBike], vBike[iDomsBike], 5)
PRINT_NOW("EXT1_12", DEFAULT_GOD_TEXT_TIME, 1) // Wait for ~b~Dom.
bToldToWaitForDom = TRUE
ENDIF
MANAGE_SLIDY_BLIP_FOR_ENTITY(blipDom, pedDom, TRUE, 10.0, FALSE)
ENDIF
ELIF bPlayerGotOnABike = TRUE // B*1143587 - Don't tell player to get back on his bike until he's been on it
SAFE_REMOVE_BLIP(blipDom) // B*1393204 - Ensure Dom's blip is removed
IF NOT DOES_BLIP_EXIST(blipBike[iPlayersChosenBike])
EXT1_TELL_PLAYER_TO_GET_ON_HIS_BIKE()
ENDIF
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Handles the text and blip for getting on the bike.
PROC EXT1_MANAGE_GET_ON_BIKE_TEXT()
IF IS_ENTITY_ALIVE(vehBike[iPlayersChosenBike])
IF bPlayerGotFullyOnBike = FALSE // Required for B*1342962 - Start race when player starts getting on bike, but only check for changing the blips/text from when the player has fully got on the bike
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vehBike[iPlayersChosenBike])
bPlayerGotFullyOnBike = TRUE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Player fully got on bike at start of race") ENDIF #ENDIF
ENDIF
ELSE
IF DOES_BLIP_EXIST(blipBike[iPlayersChosenBike])
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vehBike[iPlayersChosenBike])
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Player got on bike") ENDIF #ENDIF
SAFE_REMOVE_BLIP(blipBike[iPlayersChosenBike])
CREATE_DOM_SLIDEY_BLIP(FALSE)
CLEAR_PRINTS()
ENDIF
ELIF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vehBike[iPlayersChosenBike])
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Player got off bike") ENDIF #ENDIF
SAFE_REMOVE_BLIP(blipDom)
EXT1_TELL_PLAYER_TO_GET_ON_HIS_BIKE()
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Works out if the player is behind Dom or ahead in the race.
PROC EXT1_MANAGE_RACE_POSITIONS()
FLOAT f_dist_player, f_dist_dom
IF IS_ENTITY_ALIVE(pedDom)
IF IS_ENTITY_IN_RANGE_COORDS(pedDom, raceInfo.checkPos[iDomNextCheckpoint], checkSize)
iDomNextCheckpoint++
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Next Dom checkpoint = ", iDomNextCheckpoint) ENDIF #ENDIF
ENDIF
IF iDomNextCheckpoint >= raceInfo.totalChecks // Dom has finished so stop any further checking
iRacePos = 2
ELSE
IF iDomNextCheckpoint > playerInfo.currentCheck // Dom is ahead in checkpoints so don't do any distance checking
iRacePos = 2
ELIF iDomNextCheckpoint < playerInfo.currentCheck // Dom is behind in checkpoints so don't do any distance checking
iRacePos = 1
ELSE // Dom and Franklin are both going to the same checkpoint, so work out the distance they both are away from the next checkpoint
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
f_dist_player = GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), raceInfo.checkPos[playerInfo.currentCheck])
ENDIF
f_dist_dom = GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(pedDom), raceInfo.checkPos[playerInfo.currentCheck])
IF f_dist_player > f_dist_dom
iRacePos = 2
ELSE
iRacePos = 1
ENDIF
ENDIF
ENDIF
ENDIF
IF iRacePos = 1
AND (GET_GAME_TIMER() - iFranklinAheadConversationTimer) > 5000
AND EXT1_ALLOW_CONVERSATION_TO_PLAY()
AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_OVERT", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_OVERT conversation") ENDIF #ENDIF
iFranklinAheadConversationTimer = GET_GAME_TIMER()
ENDIF
ENDPROC
/// PURPOSE:
/// Sets the checkpoint when the player reaches certain parts of the race.
PROC EXT1_MANAGE_PLAYER_REACHING_CHECKPOINTS()
IF bSetMidRaceCheckpoint[0] = FALSE
AND playerInfo.currentCheck = 20
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_BIKERACE_MIDDLE, "Bike race middle")
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Set checkpoint to CP_BIKERACE_MIDDLE") ENDIF #ENDIF
bSetMidRaceCheckpoint[0] = TRUE
ENDIF
IF bSetMidRaceCheckpoint[1] = FALSE
AND playerInfo.currentCheck = raceInfo.totalChecks-2
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_BIKERACE_NEAR_END, "Bike race near end")
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Set checkpoint to CP_BIKERACE_NEAR_END") ENDIF #ENDIF
bSetMidRaceCheckpoint[1] = TRUE
ENDIF
IF bUpdatedMusicWhenNearingEndOfRace = FALSE
AND playerInfo.currentCheck = raceInfo.totalChecks-10
bUpdatedMusicWhenNearingEndOfRace = TRUE
TRIGGER_MUSIC_EVENT("EXTREME1_CYCLE")
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Triggered EXTREME1_CYCLE") ENDIF #ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Handle starting the vehicle recording when there is a driver, and subsequently stopping the vehicle recording if the driver leaves.
PROC EXT1_MANAGE_DOM_BIKE_VEHICLE_RECORDING()
IF IS_ENTITY_ALIVE(vehBike[iDomsBike])
IF bStartedRace = FALSE
IF IS_ENTITY_ALIVE(vehBike[iPlayersChosenBike])
IF IS_ENTITY_IN_RANGE_COORDS(vehBike[iPlayersChosenBike], vBike[iDomsBike], 100)
PRINT_NOW("EXT1_19", DEFAULT_GOD_TEXT_TIME, 1) // Race ~b~Dom.
IF IS_ENTITY_ALIVE(vehBike[iDomsBike])
START_PLAYBACK_RECORDED_VEHICLE_USING_AI(vehBike[iDomsBike], 500, "Ext1_BikeRace", 30, DRIVINGMODE_AVOIDCARS)
SET_PLAYBACK_TO_USE_AI_TRY_TO_REVERT_BACK_LATER(vehBike[iDomsBike], 4000)
ENDIF
bStartedRace = TRUE
ELIF bToldToGoToDom = FALSE
PRINT_NOW("EXT1_22", DEFAULT_GOD_TEXT_TIME, 1) // Go to ~b~Dom.
bToldToGoToDom = TRUE
ENDIF
ENDIF
ELIF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vehBike[iDomsBike])
//#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Dom playback position = ", GET_POSITION_IN_RECORDING(vehBike[iDomsBike])) ENDIF #ENDIF
IF IS_VEHICLE_SEAT_FREE(vehBike[iDomsBike])
STOP_PLAYBACK_RECORDED_VEHICLE(vehBike[iDomsBike])
ELSE
IF bSetPlaybackToUseAI = FALSE // See B*835002
AND GET_TIME_POSITION_IN_RECORDING(vehBike[iDomsBike]) > (GET_TOTAL_DURATION_OF_VEHICLE_RECORDING_ID(GET_CURRENT_PLAYBACK_FOR_VEHICLE(vehBike[iDomsBike])) - 7000)
SET_PLAYBACK_TO_USE_AI(vehBike[iDomsBike], DRIVINGMODE_AVOIDCARS_RECKLESS)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Set playback to use AI right at the end of race to prevent any snapping and to avoid Franklin") ENDIF #ENDIF
bSetPlaybackToUseAI = TRUE
ENDIF
IF bSlowestDomSpeed = TRUE // If starting from the near end checkpoint
SET_PLAYBACK_SPEED(vehBike[iDomsBike], 0.65)
ELIF GET_POSITION_IN_RECORDING(vehBike[iDomsBike]) > 2100 // B*510629 - slow Dom near finish line so player can overtake
SET_PLAYBACK_SPEED(vehBike[iDomsBike], 0.8)
ELSE
IF iRacePos = 1 // Player is 1st so increase Dom's speed
SET_PLAYBACK_SPEED(vehBike[iDomsBike], 1.3)
ELSE // Dom is 1st to change his playback speed depending on distance to Franklin's bike
FLOAT fDist = GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), vehBike[iDomsBike])
IF fDist > 50
SET_PLAYBACK_SPEED(vehBike[iDomsBike], 0.5)
bAllowPlaySlowDialogue = TRUE
ELIF fDist > 25
SET_PLAYBACK_SPEED(vehBike[iDomsBike], 0.8)
ELIF fDist < 5
SET_PLAYBACK_SPEED(vehBike[iDomsBike], 1.1)
ELSE
SET_PLAYBACK_SPEED(vehBike[iDomsBike], 1.05)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Handles playing the dialogue at the start of the bike race.
PROC EXT1_MANAGE_BIKE_START_DIALOGUE()
IF EXT1_ALLOW_CONVERSATION_TO_PLAY(TRUE, FALSE)
AND bStartedRaceStartConversation = FALSE
IF bPlayerStartedRaceEarly = FALSE
IF CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_LETSRAC", CONV_PRIORITY_HIGH, DO_NOT_DISPLAY_SUBTITLES)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_LETSRAC conversation") ENDIF #ENDIF
bStartedRaceStartConversation = TRUE
ENDIF
ELIF CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_CHEAT", CONV_PRIORITY_HIGH, DO_NOT_DISPLAY_SUBTITLES)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_CHEAT conversation") ENDIF #ENDIF
bStartedRaceStartConversation = TRUE
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Returns distance between Franklin and Dom during the bike race.
FUNC BOOL EXT1_IS_DISTANCE_BETWEEN_RACERS_GREATER_THAN(FLOAT distance)
IF IS_ENTITY_ALIVE(pedDom)
AND GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), pedDom) > distance
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Managing playing the banter between Dom/Franklin during the bike race.
PROC EXT1_MANAGE_BIKE_RACE_CONVERSATION()
IF iBikeRaceConversationsDone < NUM_BIKE_RACE_DIALOGUE_LINES
AND playerInfo.currentCheck < raceInfo.totalChecks-3 // B*700181 Prevent conversations triggering near the finish line
AND bAllowPlaySlowDialogue = FALSE // Only play this banter if we're not trying to play a EXT1_SLOW line
AND (GET_GAME_TIMER() - iBikeRaceDialogueTimer) > 45000 // B*1415986 Less banter
AND EXT1_ALLOW_CONVERSATION_TO_PLAY()
AND IS_ENTITY_ALIVE(vehBike[iPlayersChosenBike])
AND IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vehBike[iPlayersChosenBike])
AND NOT EXT1_IS_DISTANCE_BETWEEN_RACERS_GREATER_THAN(30)
INT i_random = GET_RANDOM_INT_IN_RANGE(0, NUM_BIKE_RACE_DIALOGUE_LINES)
IF bDoneBikeRaceConversation[i_random] = FALSE
AND CREATE_CONVERSATION(sConversation, "EXT1AU", stringBikeRaceConversation[i_random], CONV_PRIORITY_HIGH)
bDoneBikeRaceConversation[i_random] = TRUE
iBikeRaceConversationsDone++
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_RACE conversation ", i_random, " iBikeRaceConversationsDone = ", iBikeRaceConversationsDone) ENDIF #ENDIF
iBikeRaceDialogueTimer = GET_GAME_TIMER()
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Managing playing the banter from Dom if the player keeps lagging behind.
PROC EXT1_MANAGE_SLOW_CONVERSATION()
IF EXT1_ALLOW_CONVERSATION_TO_PLAY()
AND playerInfo.currentCheck < raceInfo.totalChecks-1 // B*700181 Prevent conversations triggering near the finish line
AND bAllowPlaySlowDialogue = TRUE
AND iNumSlowConversationsPlayed < NUM_SLOW_DIALOGUE_LINES
AND NOT EXT1_IS_DISTANCE_BETWEEN_RACERS_GREATER_THAN(25)
AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_SLOW", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_SLOW dialogue line. iNumSlowConversationsPlayed = ", iNumSlowConversationsPlayed) ENDIF #ENDIF
iNumSlowConversationsPlayed++
bAllowPlaySlowDialogue = FALSE
ENDIF
ENDPROC
/// PURPOSE:
/// If the race is failed in EXT1_MANAGE_PLAYER_LEAVING_BIKE_RACE we need to check which fail reason to use.
PROC EXT1_CHECK_IF_RACE_ABANDONED_OR_BIKE_LOST()
IF bZSkipping = FALSE
AND IS_ENTITY_ALIVE(vehBike[iPlayersChosenBike])
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vehBike[iPlayersChosenBike], TRUE)
EXT1_MISSION_FAILED(FAILED_FAILED_RACE)
ELSE
IF IS_SPHERE_VISIBLE(GET_ENTITY_COORDS(vehBike[iPlayersChosenBike]), 5)
OR IS_ENTITY_IN_RANGE_ENTITY(PLAYER_PED_ID(), vehBike[iPlayersChosenBike], 5)
EXT1_MISSION_FAILED(FAILED_FAILED_RACE)
ELSE
EXT1_MISSION_FAILED(FAILED_PLAYER_BIKE_LOST)
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Checks for the player leaving the bike race area.
/// EXT1_CALC_CHECKPOINT_DISTANCES calculates the distance in-between each checkpoint. If the player's distance from the next checkpoint is more than the calculated distance plus RACE_ABANDONED_DISTANCE then the mission fails.
/// Also fails mission if player's bike is 5 metres below the next checkpoint vector, because he's probably gone off a cliff.
PROC EXT1_MANAGE_PLAYER_LEAVING_BIKE_RACE()
IF bZSkipping = FALSE
AND iSkipToRaceCheckpoint = -1
AND IS_ENTITY_ALIVE(vehBike[iPlayersChosenBike])
IF NOT IS_ENTITY_IN_RANGE_COORDS(vehBike[iPlayersChosenBike], raceInfo.checkPos[playerInfo.currentCheck], fCheckpointFailDistance[playerInfo.currentCheck]+RACE_ABANDONED_DISTANCE)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Failing race - bike distance far away from next checkpoint") ENDIF #ENDIF
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Fail distance = ", fCheckpointFailDistance[playerInfo.currentCheck]+RACE_ABANDONED_DISTANCE) ENDIF #ENDIF
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Actual distance = ", GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(vehBike[iPlayersChosenBike], raceInfo.checkPos[playerInfo.currentCheck])) ENDIF #ENDIF
EXT1_CHECK_IF_RACE_ABANDONED_OR_BIKE_LOST()
ELSE
VECTOR v_player_bike = GET_ENTITY_COORDS(vehBike[iPlayersChosenBike])
VECTOR v_checkpoint = raceInfo.checkPos[playerInfo.currentCheck]
IF v_player_bike.z < (v_checkpoint.z-15)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Failing race - player z much lower than next checkpoint") ENDIF #ENDIF
EXT1_CHECK_IF_RACE_ABANDONED_OR_BIKE_LOST()
ELIF NOT IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), raceInfo.checkPos[playerInfo.currentCheck], fCheckpointFailDistance[playerInfo.currentCheck]+RACE_ABANDONED_DISTANCE) // See B*902696
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Failing race - player distance far away from next checkpoint") ENDIF #ENDIF
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Fail distance = ", fCheckpointFailDistance[playerInfo.currentCheck]+RACE_ABANDONED_DISTANCE) ENDIF #ENDIF
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Actual distance = ", GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), raceInfo.checkPos[playerInfo.currentCheck])) ENDIF #ENDIF
EXT1_MISSION_FAILED(FAILED_LEFT_MISSION_AREA)
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Sets up the vars for all the bike race dialogue.
PROC EXT1_SETUP_BIKE_RACE_CONVERSATIONS()
bAllowPlaySlowDialogue = FALSE
stringBikeRaceConversation[0] = "EXT1_RACE2"
stringBikeRaceConversation[1] = "EXT1_RACE3"
stringBikeRaceConversation[2] = "EXT1_RACE4"
stringBikeRaceConversation[3] = "EXT1_RACE5"
INT i = 0
REPEAT NUM_BIKE_RACE_DIALOGUE_LINES i
bDoneBikeRaceConversation[i] = FALSE
ENDREPEAT
i = 0
REPEAT NUM_WARNING_DIALOGUE i
bDoneWarningDialogue[i] = FALSE
ENDREPEAT
stringWarningDialogue[0] = "EXT1_WARN1"
stringWarningDialogue[1] = "EXT1_WARN2"
stringWarningDialogue[2] = "EXT1_WARN3"
stringWarningDialogue[3] = "EXT1_WARN4"
stringWarningDialogue[4] = "EXT1_WARN5"
stringWarningDialogue[5] = "EXT1_WARN6"
stringWarningDialogue[6] = "EXT1_WARN7"
stringWarningDialogue[7] = "EXT1_WARN8"
stringWarningDialogue[8] = "EXT1_WARN9"
stringWarningDialogue[9] = "EXT1_WARN10"
stringWarningDialogue[10] = "EXT1_WARN11"
stringWarningDialogue[11] = "EXT1_WARN12"
stringWarningDialogue[12] = "EXT1_WARN13"
stringWarningDialogue[13] = "EXT1_WARN14"
vWarningDialogue[0] = <<408,5504,733>>
vWarningDialogue[1] = <<362,5466,692>>
vWarningDialogue[2] = <<228,5268,612>>
vWarningDialogue[3] = <<135,5218,546>>
vWarningDialogue[4] = <<119,5201,536>>
vWarningDialogue[5] = <<95,5083,501>>
vWarningDialogue[6] = <<7,5010,447>>
vWarningDialogue[7] = <<-119,4924,365>>
vWarningDialogue[8] = <<-297,4940,272>>
vWarningDialogue[9] = <<-326,4992,230>>
vWarningDialogue[10] = <<-399,4893,192>>
vWarningDialogue[11] = <<-523,4879,171>>
vWarningDialogue[12] = <<-579,4945,164>>
vWarningDialogue[13] = <<-792,5263,90>>
ENDPROC
/// PURPOSE:
/// Calculates the distances in-between each of the race checkpoints. Used to determine if the player is driving towards the next checkpoint or away from it.
PROC EXT1_CALC_CHECKPOINT_DISTANCES()
INT i_current_parse_check = 0
INT i_previous_parse_check = i_current_parse_check-1
INT i = 0
REPEAT NUM_CHECKPOINTS i
IF i = 0
fCheckpointFailDistance[i_current_parse_check] = GET_DISTANCE_BETWEEN_COORDS(raceInfo.checkPos[i_current_parse_check], vBike[iPlayersChosenBike])
ELSE
fCheckpointFailDistance[i_current_parse_check] = GET_DISTANCE_BETWEEN_COORDS(raceInfo.checkPos[i_current_parse_check], raceInfo.checkPos[i_previous_parse_check])
ENDIF
i_current_parse_check++
i_previous_parse_check++
ENDREPEAT
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Calcs done for checkpoint fail distances") ENDIF #ENDIF
ENDPROC
/// PURPOSE:
/// Handles performing a rolling start on the player's vehicle when retrying the bike race from a mid-race checkpoint.
PROC EXT1_MANAGE_ROLLING_START()
IF bDoneRollingStart = FALSE
IF IS_VEHICLE_OK(vehBike[iPlayersChosenBike])
IF bSlowestDomSpeed = TRUE // B*1052506 - Slow player's bike if retrying from final checkpoint
AND IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vehBike[iPlayersChosenBike])
SET_PLAYBACK_SPEED(vehBike[iPlayersChosenBike], 0.7)
ENDIF
IF NOT IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vehBike[iPlayersChosenBike])
OR IS_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_VEH_ACCELERATE)
OR IS_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_VEH_BRAKE)
OR IS_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_VEH_MOVE_LEFT)
OR IS_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_VEH_MOVE_RIGHT)
OR IS_VEHICLE_SEAT_FREE(vehBike[iPlayersChosenBike])
OR (GET_GAME_TIMER() - iRollingStartTimer > 5000)
IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vehBike[iPlayersChosenBike])
STOP_PLAYBACK_RECORDED_VEHICLE(vehBike[iPlayersChosenBike])
ENDIF
bDoneRollingStart = TRUE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Rolling start finished") ENDIF #ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Handles playing the dialogue in which Dom warns the player of upcoming hazards.
PROC EXT1_MANAGE_RACE_WARNING_DIALOGUE()
IF EXT1_ALLOW_CONVERSATION_TO_PLAY()
AND IS_ENTITY_ALIVE(vehBike[iPlayersChosenBike])
AND IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vehBike[iPlayersChosenBike]) // Check player is on his bike
AND NOT EXT1_IS_DISTANCE_BETWEEN_RACERS_GREATER_THAN(50) // Check player is near to Dom so that he could hear Dom's warning
INT i = 0
REPEAT NUM_WARNING_DIALOGUE i
IF bDoneWarningDialogue[i] = FALSE
AND IS_ENTITY_IN_RANGE_COORDS(vehBike[iPlayersChosenBike], vWarningDialogue[i], 10)
AND CREATE_CONVERSATION(sConversation, "EXT1AU", stringWarningDialogue[i], CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_WARN conversation ", i) ENDIF #ENDIF
bDoneWarningDialogue[i] = TRUE
IF i = 6 // "Whoa, massive air alert!"
OR i = 7 // "Get ready for more air!"
OR i = 8 // "Monster jump coming atcha!"
OR i = 11 // "Ski jump! Hit the sky, bro!"
OR i = 12 // "Oh shit! Double jump!"
REPLAY_RECORD_BACK_FOR_TIME(3.0, 6.0)
ENDIF
ENDIF
ENDREPEAT
ENDIF
#IF IS_DEBUG_BUILD IF bDebug_ShowRaceWarningDialogueTriggers = TRUE
INT i_debug = 0
REPEAT NUM_WARNING_DIALOGUE i_debug
DRAW_DEBUG_SPHERE(vWarningDialogue[i_debug], 0.1, 255, 0, 0)
ENDREPEAT
ENDIF #ENDIF
ENDPROC
/// PURPOSE:
/// Handles playing the dialogue in which Dom warns the player if they're going to collide.
PROC EXT1_MANAGE_RACE_COLLISION_DIALOGUE()
IF (GET_GAME_TIMER() - iCollisionDialogueTimer) > 10000 // B*1415986 Less banter
AND EXT1_ALLOW_CONVERSATION_TO_PLAY()
AND IS_ENTITY_ALIVE(vehBike[iDomsBike])
AND IS_ENTITY_ALIVE(vehBike[iPlayersChosenBike])
IF GET_ENTITY_SPEED(vehBike[iDomsBike]) > GET_ENTITY_SPEED(PLAYER_PED_ID()) // Dom must be going faster than Franklin
VECTOR v_offset = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(vehBike[iDomsBike], <<0,4,0>>)
IF IS_ANY_VEHICLE_NEAR_POINT(v_offset, 3)
AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_INWAY", CONV_PRIORITY_HIGH, DISPLAY_SUBTITLES)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_INWAY conversation") ENDIF #ENDIF
iCollisionDialogueTimer = GET_GAME_TIMER()
ENDIF
ELIF IS_ENTITY_TOUCHING_ENTITY(vehBike[iDomsBike], vehBike[iPlayersChosenBike])
IF CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_CRASH", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_CRASH conversation") ENDIF #ENDIF
iCollisionDialogueTimer = GET_GAME_TIMER()
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Handles playing the dialogue if the player threatens Dom and fails the mission.
PROC EXT1_MANAGE_THREATEN_DOM_DIALOGUE()
IF bStartedThreatenDomConversation = FALSE
AND IS_ENTITY_ALIVE(pedDom)
IF failReason = FAILED_DOM_SCARED
OR failReason = FAILED_DOM_INJURED
IF bStartedRace = TRUE
IF CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_THREAT", CONV_PRIORITY_HIGH, DO_NOT_DISPLAY_SUBTITLES)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_THREAT conversation") ENDIF #ENDIF
bStartedThreatenDomConversation = TRUE
ENDIF
ELSE
MAKE_PED_SCREAM(pedDom) // B*1202563 Dom's dialogue isn't suitable prior to getting in the helicopter because it's over headset, which Dom isn't wearing at that point
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Made Dom scream") ENDIF #ENDIF
bStartedThreatenDomConversation = TRUE
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Checks for the player attaining the jump height stat requirements.
PROC EXT1_CHECK_FOR_JUMP_HEIGHT_STAT()
IF bPlayerAttainedJumpStat = FALSE
VECTOR v_player_coords = GET_ENTITY_COORDS(PLAYER_PED_ID())
FLOAT f_ground_z
IF GET_GROUND_Z_FOR_3D_COORD(v_player_coords, f_ground_z)
FLOAT f_distance_from_ground = (v_player_coords.z - f_ground_z)
IF f_distance_from_ground > 1.0
IF iJumpStatTimer = -1 // Player's bike is more than 1 metre off the ground so start counting for 'air time'
iJumpStatTimer = GET_GAME_TIMER()
ELIF (GET_GAME_TIMER() - iJumpStatTimer) > 2000 // Player's bike has been off the ground for an 'air time' of 2 seconds so he's attained the stat
INFORM_STAT_SYSTEM_OF_BOOL_STAT_HAPPENED(EXT1_BIG_AIR)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Achieved stat: EX1_BIG_AIR") ENDIF #ENDIF
bPlayerAttainedJumpStat = TRUE
ENDIF
ELIF iJumpStatTimer > -1 // If the player's bike is not more than 1 metre off the ground but the 'air time' jump timer is in progress, reset the timer
//#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Big air jump failed at this ms:", GET_GAME_TIMER() - iJumpStatTimer) ENDIF #ENDIF
iJumpStatTimer = -1
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Main state for handling the intro cutscene.
PROC MS_INTRO()
SET_SCENARIO_PED_DENSITY_MULTIPLIER_THIS_FRAME(0.0, 0.0) // B*1288575 Stop creating these dirt bikers
IF IS_ENTITY_ALIVE(pedDog)
AND IsPedPerformingTask(pedDog, SCRIPT_TASK_FOLLOW_NAV_MESH_TO_COORD)
SET_PED_MOVE_RATE_OVERRIDE(pedDog, 1.15)
SET_PED_MIN_MOVE_BLEND_RATIO(pedDog, 3)
ENDIF
SWITCH missionStateMachine
CASE EXT1_STATE_MACHINE_SETUP
EXT1_STATE_SETUP(#IF IS_DEBUG_BUILD "MS_INTRO" #ENDIF)
RC_REQUEST_CUTSCENE("es_1_rcm_p1")
iCutsceneStage = 0
bCutsceneSkipped = FALSE
IF IS_SCREEN_FADED_IN() // Don't do gameplay hint if skipping to intro
AND NOT IS_REPLAY_IN_PROGRESS() // Or if replaying mission
AND IS_ENTITY_ALIVE(sRCLauncherDataLocal.pedID[0])
AND GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), sRCLauncherDataLocal.pedID[0]) > 4.0
SET_GAMEPLAY_ENTITY_HINT(sRCLauncherDataLocal.pedID[0], (<<0, 0, 0>>), TRUE, -1, 3000)
SET_GAMEPLAY_HINT_FOLLOW_DISTANCE_SCALAR(0.45)
SET_GAMEPLAY_HINT_CAMERA_RELATIVE_SIDE_OFFSET(-0.9)
SET_GAMEPLAY_HINT_FOV(30.00)
SET_GAMEPLAY_HINT_CAMERA_BLEND_TO_FOLLOW_PED_MEDIUM_VIEW_MODE(TRUE)
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), sRCLauncherDataLocal.pedID[0], -1) // Ensure Franklin is headtracking the dog during the focus push-in
OPEN_SEQUENCE_TASK(seqFranklinLeadIn)
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
TASK_LEAVE_ANY_VEHICLE(NULL)
ENDIF
TASK_GO_TO_ENTITY(NULL, sRCLauncherDataLocal.pedID[0], DEFAULT_TIME_BEFORE_WARP, DEFAULT_SEEK_RADIUS, PEDMOVEBLENDRATIO_WALK)
TASK_TURN_PED_TO_FACE_ENTITY(NULL, sRCLauncherDataLocal.pedID[0])
CLOSE_SEQUENCE_TASK(seqFranklinLeadIn)
TASK_PERFORM_SEQUENCE(PLAYER_PED_ID(), seqFranklinLeadIn)
CLEAR_SEQUENCE_TASK(seqFranklinLeadIn)
CLEAR_PED_TASKS(sRCLauncherDataLocal.pedID[0])
TASK_GO_TO_ENTITY(sRCLauncherDataLocal.pedID[0], PLAYER_PED_ID(), DEFAULT_TIME_BEFORE_WARP, DEFAULT_SEEK_RADIUS, PEDMOVEBLENDRATIO_WALK)
iLeadInTimer = GET_GAME_TIMER()
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Doing leadin focus camera") ENDIF #ENDIF
ELSE
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
AND IS_ENTITY_ALIVE(sRCLauncherDataLocal.pedID[0])
TASK_TURN_PED_TO_FACE_ENTITY(PLAYER_PED_ID(), sRCLauncherDataLocal.pedID[0])
ENDIF
iLeadInTimer = -1
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Not doing leadin focus camera") ENDIF #ENDIF
ENDIF
IF IS_ENTITY_ALIVE(sRCLauncherDataLocal.pedID[0])
pedDog = sRCLauncherDataLocal.pedID[0]
SET_ENTITY_AS_MISSION_ENTITY(pedDog, TRUE, TRUE)
ENDIF
BREAK
CASE EXT1_STATE_MACHINE_LOOP
SWITCH iCutsceneStage
CASE 0
IF RC_IS_CUTSCENE_OK_TO_START()
IF iLeadInTimer = -1
OR (GET_GAME_TIMER() - iLeadInTimer) > 3000
IF IS_ENTITY_ALIVE(pedDog)
REGISTER_ENTITY_FOR_CUTSCENE(pedDog, "Hudson", CU_ANIMATE_EXISTING_SCRIPT_ENTITY, modelPed[EXT1_MODEL_DOG])
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: CU_ANIMATE_EXISTING_SCRIPT_ENTITY Hudson") ENDIF #ENDIF
ELSE
REGISTER_ENTITY_FOR_CUTSCENE(pedDog, "Hudson", CU_CREATE_AND_ANIMATE_NEW_SCRIPT_ENTITY, modelPed[EXT1_MODEL_DOG])
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: CU_CREATE_AND_ANIMATE_NEW_SCRIPT_ENTITY pedDog") ENDIF #ENDIF
ENDIF
RC_CLEANUP_LAUNCHER()
START_CUTSCENE()
REPLAY_START_EVENT(REPLAY_IMPORTANCE_LOW)
iCutsceneStage++
ENDIF
ENDIF
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
AND IsPedPerformingTask(PLAYER_PED_ID(), SCRIPT_TASK_PERFORM_SEQUENCE)
AND IS_ENTITY_ALIVE(pedDog)
AND GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), pedDog) < 3
CLEAR_PED_TASKS(PLAYER_PED_ID())
TASK_TURN_PED_TO_FACE_ENTITY(PLAYER_PED_ID(), pedDog)
CLEAR_PED_TASKS(pedDog)
TASK_TURN_PED_TO_FACE_ENTITY(pedDog, PLAYER_PED_ID())
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Franklin and pedDog closer than 5m so halting them") ENDIF #ENDIF
ENDIF
BREAK
CASE 1
IF IS_CUTSCENE_PLAYING()
IF IS_GAMEPLAY_HINT_ACTIVE()
STOP_GAMEPLAY_HINT()
ENDIF
VEHICLE_INDEX player_last_veh
player_last_veh = GET_PLAYERS_LAST_VEHICLE()
IF DOES_ENTITY_EXIST(player_last_veh)
AND IS_VEHICLE_DRIVEABLE(player_last_veh)
IF NOT IS_ENTITY_A_MISSION_ENTITY(player_last_veh)
SET_ENTITY_AS_MISSION_ENTITY(player_last_veh)
ENDIF
TRACK_VEHICLE_FOR_IMPOUND(player_last_veh)
SET_VEHICLE_AS_NO_LONGER_NEEDED(player_last_veh)
IF VDIST2(GET_VEHICLE_GEN_COORDS(VEHGEN_MISSION_VEH), vPlayerCarRespot) < 4
DELETE_VEHICLE_GEN_VEHICLE(VEHGEN_MISSION_VEH)
ENDIF
ENDIF
IF IS_REPLAY_START_VEHICLE_UNDER_SIZE_LIMIT(GET_DEFAULT_ALLOWABLE_VEHICLE_SIZE_VECTOR(), TRUE)
RESOLVE_VEHICLES_INSIDE_ANGLED_AREA(<<-197.892563,1305.306641,302.424713>>, <<-182.360489,1291.453613,305.628052>>, 7.000000, vPlayerCarRespot, fPlayerCarRespot)
SET_MISSION_START_VEHICLE_AS_VEHICLE_GEN(vPlayerCarRespot, fPlayerCarRespot)
ELSE
RESOLVE_VEHICLES_INSIDE_ANGLED_AREA(<<-197.892563,1305.306641,302.424713>>, <<-182.360489,1291.453613,305.628052>>, 7.000000, <<-198.46, 1313.53, 304.50>>, 129.93) // B*1346580 Respot helis on road
SET_MISSION_START_VEHICLE_AS_VEHICLE_GEN(<<-198.46, 1313.53, 304.50>>, 129.93)
ENDIF
RC_START_CUTSCENE_MODE(<<-188.22, 1296.10, 302.86>>)
SAFE_FADE_SCREEN_IN_FROM_BLACK(500, FALSE) // Just in case screen is faded out
EXT1_LOAD_ASSETS_FOR_MISSION_STATE(stateIntro, FALSE)
iCutsceneStage++
ENDIF
BREAK
CASE 2
IF IS_CUTSCENE_PLAYING()
IF NOT DOES_ENTITY_EXIST(pedDog)
AND DOES_ENTITY_EXIST(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY("Hudson"))
pedDog = GET_PED_INDEX_FROM_ENTITY_INDEX(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY("Hudson"))
SET_ENTITY_AS_MISSION_ENTITY(pedDog, TRUE, TRUE)
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), pedDog, -1) // Ensure Franklin is headtracking the dog during the transition to gameplay
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Grabbed pedDog from Hudson") ENDIF #ENDIF
ENDIF
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Hudson", modelPed[EXT1_MODEL_DOG])
EXT1_SETUP_DOG(vDogSpawnPos, fDogSpawnPos, WAS_CUTSCENE_SKIPPED())
ENDIF
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Franklin", GET_PLAYER_PED_MODEL(CHAR_FRANKLIN))
EXT1_MAKE_FRANKLIN_WALK_AFTER_INTRO()
ENDIF
IF WAS_CUTSCENE_SKIPPED()
bCutsceneSkipped = TRUE
ELIF GET_CUTSCENE_TIME() > 22500
EXT1_MAKE_DOG_RUN_AFTER_INTRO()
ENDIF
ELSE
IF bCutsceneSkipped = TRUE
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
ENDIF
RC_END_CUTSCENE_MODE()
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: IS_CUTSCENE_PLAYING returned false") ENDIF #ENDIF
missionStateMachine = EXT1_STATE_MACHINE_CLEANUP
ENDIF
BREAK
ENDSWITCH
BREAK
CASE EXT1_STATE_MACHINE_CLEANUP
REPLAY_STOP_EVENT()
REPLAY_RECORD_BACK_FOR_TIME(0.0, 10.0, REPLAY_IMPORTANCE_LOWEST)
EXT1_STATE_CLEANUP()
RC_SET_ENTITY_PROOFS_FOR_CUTSCENE(sRCLauncherDataLocal, FALSE)
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Main state for handling following the dog.
PROC MS_FOLLOW_DOG()
SETUP_DOM_CUTSCENE_VARIATIONS()
IF IS_ENTITY_ALIVE(pedDog)
AND IsPedPerformingTask(pedDog, SCRIPT_TASK_FOLLOW_NAV_MESH_TO_COORD)
SET_PED_MOVE_RATE_OVERRIDE(pedDog, 1.15)
SET_PED_MIN_MOVE_BLEND_RATIO(pedDog, 3)
ENDIF
SWITCH missionStateMachine
CASE EXT1_STATE_MACHINE_SETUP
EXT1_STATE_SETUP(#IF IS_DEBUG_BUILD "MS_FOLLOW_DOG" #ENDIF)
ADD_PED_FOR_DIALOGUE(sConversation, 1, PLAYER_PED_ID(), "FRANKLIN")
PRINT_NOW("EXT1_01", DEFAULT_GOD_TEXT_TIME, 1) // Follow the ~b~dog.
EXT1_LOAD_ASSETS_FOR_MISSION_STATE(stateFollowDog)
EXT1_SPAWN_DOM(vDom, fDom, TRUE, TRUE, FALSE)
iNextDogWaypoint = 0
bStartedDogConversation = FALSE
bStartedSeesDomConversation = FALSE
bStartedDomFocusPushIn = FALSE
bIsMidtroLoaded = FALSE
stateDog = DOG_RUNNING
iDogHelpTextTimer = GET_GAME_TIMER()
iDomGruntsDialogueTimer = GET_GAME_TIMER()
BREAK
CASE EXT1_STATE_MACHINE_LOOP
IF IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), vDom, 15)
SAFE_REMOVE_BLIP(blipDog)
SAFE_REMOVE_BLIP(blipDom)
IF IS_ENTITY_ALIVE(pedDom)
IF bStartedDomFocusPushIn = FALSE
KILL_ANY_CONVERSATION()
SET_GAMEPLAY_ENTITY_HINT(pedDom, (<<0, 0, 0>>), TRUE, -1, 3000)
SET_GAMEPLAY_HINT_FOLLOW_DISTANCE_SCALAR(0.45)
SET_GAMEPLAY_HINT_CAMERA_RELATIVE_SIDE_OFFSET(-0.01)
SET_GAMEPLAY_HINT_FOV(35.00)
SET_GAMEPLAY_HINT_CAMERA_BLEND_TO_FOLLOW_PED_MEDIUM_VIEW_MODE(TRUE)
iDomFocusPushInTimer = GET_GAME_TIMER()
bStartedDomFocusPushIn = TRUE
ELSE
RC_PLAYER_TRIGGER_SCENE_LOCK_IN()
IF (GET_GAME_TIMER() - iDomFocusPushInTimer) > 4000
missionStateMachine = EXT1_STATE_MACHINE_CLEANUP
ENDIF
ENDIF
ENDIF
ELIF stateDog = DOG_FINISHED
SAFE_REMOVE_BLIP(blipDog)
IF IS_ENTITY_ALIVE(pedDom)
AND NOT DOES_BLIP_EXIST(blipDom)
blipDom = CREATE_PED_BLIP(pedDom, TRUE, TRUE)
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), pedDom, -1)
ENDIF
EXT1_CHECK_PLAYER_ISNT_ABANDONING_DOM()
EXT1_MANAGE_DOM_FOCUS_CAMERA()
EXT1_MANAGE_DOM_CONVERSATION()
EXT1_MANAGE_FRANKLIN_SEES_DOM_CONVERSATION()
EXT1_MANAGE_MIDTRO_CUTSCENE_LOADING()
IF (GET_GAME_TIMER() - iDogAnimsTimer) > 12500
AND NOT IsPedPerformingTask(pedDog, SCRIPT_TASK_PERFORM_SEQUENCE)
EXT1_MANAGE_DOG_IDLE_ANIMATIONS(FALSE) // See B*588668
iDogAnimsTimer = GET_GAME_TIMER()
ENDIF
ELSE
EXT1_MANAGE_DOG_CONVERSATION()
EXT1_MANAGE_DOM_CONVERSATION()
EXT1_MANAGE_DOG_MOVEMENT()
EXT1_MANAGE_FRANKLIN_SEES_DOM_CONVERSATION()
EXT1_CHECK_PLAYER_ISNT_ABANDONING_DOG()
EXT1_MANAGE_DOG_FOCUS_CAMERA()
EXT1_MANAGE_MIDTRO_CUTSCENE_LOADING()
ENDIF
BREAK
CASE EXT1_STATE_MACHINE_CLEANUP
EXT1_STATE_CLEANUP()
SAFE_REMOVE_BLIP(blipDog)
SAFE_REMOVE_BLIP(blipDom)
KILL_CHASE_HINT_CAM(localChaseHintCamStruct)
EXT1_START_AUDIO_SCENE("EXTREME_01_INTRO", FALSE)
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
TASK_CLEAR_LOOK_AT(PLAYER_PED_ID())
ENDIF
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Main state for handling the midtro cutscene.
PROC MS_MIDTRO()
SETUP_DOM_CUTSCENE_VARIATIONS()
SWITCH missionStateMachine
CASE EXT1_STATE_MACHINE_SETUP
EXT1_STATE_SETUP(#IF IS_DEBUG_BUILD "MS_MIDTRO" #ENDIF)
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_MIDTRO, "Midtro")
RC_REQUEST_MID_MISSION_CUTSCENE("ES_1_RCM_CONCAT")
EXT1_START_AUDIO_SCENE("EXTREME_01_JOURNEY", TRUE)
iCutsceneStage = 0
bCutsceneSkipped = FALSE
BREAK
CASE EXT1_STATE_MACHINE_LOOP
SWITCH iCutsceneStage
CASE 0
IF RC_IS_CUTSCENE_OK_TO_START(TRUE, 10, TRUE)
IF IS_ENTITY_ALIVE(pedDom)
REGISTER_ENTITY_FOR_CUTSCENE(pedDom, "Dom", CU_ANIMATE_EXISTING_SCRIPT_ENTITY, GET_NPC_PED_MODEL(CHAR_DOM))
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: CU_ANIMATE_EXISTING_SCRIPT_ENTITY Dom") ENDIF #ENDIF
ENDIF
REPLAY_RECORD_BACK_FOR_TIME(5.0, 0.0, REPLAY_IMPORTANCE_LOWEST)
REPLAY_START_EVENT(REPLAY_IMPORTANCE_LOW)
START_CUTSCENE()
SET_CUTSCENE_FADE_VALUES(FALSE, FALSE, FALSE, FALSE)
iCutsceneStage++
ENDIF
BREAK
CASE 1
IF IS_CUTSCENE_PLAYING()
IF DOES_ENTITY_EXIST(oParachute)
SET_ENTITY_VISIBLE(oParachute, FALSE)
ENDIF
RESOLVE_VEHICLES_INSIDE_ANGLED_AREA(<<119.485062,1254.300049,251.637146>>, <<124.809174,1243.714966,257.318542>>, 7.000000, <<111.8733, 1267.6517, 253.3308>>, 249.7582)
RC_START_CUTSCENE_MODE(vDom)
SAFE_FADE_SCREEN_IN_FROM_BLACK(500, FALSE) // Just in case screen is faded out
SAFE_DELETE_PED(pedDog)
EXT1_LOAD_ASSETS_FOR_MISSION_STATE(stateGetInHelicopter) // B*1036096 - Ensure assets are loaded so we can create the helicopter straight away
iCutsceneStage++
ENDIF
BREAK
CASE 2
IF IS_CUTSCENE_PLAYING()
IF IS_ENTITY_ALIVE(pedDom)
AND CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Dom")
SAFE_TELEPORT_ENTITY(pedDom, vDomAfterMidtro, fDomAfterMidtro)
TASK_GO_STRAIGHT_TO_COORD(pedDom, vDomBesideHelicopter, PEDMOVE_WALK, 40000)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Teleported Dom at end of midtro") ENDIF #ENDIF
ENDIF
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Franklin", GET_PLAYER_PED_MODEL(CHAR_FRANKLIN))
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), pedDom, -1)
ENDIF
IF WAS_CUTSCENE_SKIPPED()
bCutsceneSkipped = TRUE
ENDIF
ELSE
IF bCutsceneSkipped = TRUE
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
ENDIF
IF DOES_ENTITY_EXIST(oParachute)
SET_ENTITY_VISIBLE(oParachute, TRUE)
ENDIF
IF IS_ENTITY_ALIVE(pedDom)
SET_PED_CONFIG_FLAG(pedDom, PCF_RunFromFiresAndExplosions, TRUE)
SET_PED_CONFIG_FLAG(pedDom, PCF_DisableExplosionReactions, FALSE)
EXT1_SET_PED_AS_PLAYER_FRIEND(pedDom)
ENDIF
RC_END_CUTSCENE_MODE()
SET_MULTIHEAD_SAFE(FALSE) //B* 2229065 - manually remove blinders
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: IS_CUTSCENE_PLAYING returned false") ENDIF #ENDIF
missionStateMachine = EXT1_STATE_MACHINE_CLEANUP
ENDIF
BREAK
ENDSWITCH
BREAK
CASE EXT1_STATE_MACHINE_CLEANUP
REPLAY_STOP_EVENT()
REPLAY_RECORD_BACK_FOR_TIME(0.0, 13.0)
EXT1_STATE_CLEANUP()
SAFE_FADE_SCREEN_IN_FROM_BLACK()
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Main state for handling getting into the helicopter.
PROC MS_GET_IN_HELICOPTER()
SWITCH missionStateMachine
CASE EXT1_STATE_MACHINE_SETUP
EXT1_STATE_SETUP(#IF IS_DEBUG_BUILD "MS_GET_IN_HELICOPTER" #ENDIF)
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_GET_IN_HELICOPTER, "Get in helicopter")
ADD_PED_FOR_DIALOGUE(sConversation, 1, PLAYER_PED_ID(), "FRANKLIN")
EXT1_LOAD_ASSETS_FOR_MISSION_STATE(stateGetInHelicopter)
EXT1_CREATE_VEHICLE(vehHelicopter, modelVeh[EXT1_MODEL_HELICOPTER], vHelicopterStart, fHelicopterStart, iHelicopterColour)
SET_MODEL_AS_NO_LONGER_NEEDED(modelVeh[EXT1_MODEL_HELICOPTER])
IF IS_ENTITY_ALIVE(vehHelicopter)
ADD_ENTITY_TO_AUDIO_MIX_GROUP(vehHelicopter, "EXTREME_01_CHOPPER_GROUP")
SET_HELI_BLADES_FULL_SPEED(vehHelicopter)
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(vehHelicopter, FALSE)
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(vehHelicopter, TRUE)
SET_HELI_TURBULENCE_SCALAR(vehHelicopter, 0.4) // B*1416032
EXT1_SPAWN_HELICOPTER_PILOT()
IF IS_ENTITY_ALIVE(pedPilot)
TASK_HELI_MISSION(pedPilot,vehHelicopter,NULL,NULL,vHelicopterLand,MISSION_LAND_AND_WAIT,20,1,fHelicopterStart,0,0)
ENDIF
ENDIF
IF IS_ENTITY_ALIVE(pedDom)
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), pedDom, -1)
SET_PED_PROP_INDEX(pedDom, ANCHOR_EARS, 0, 0)
SET_PED_CAN_RAGDOLL_FROM_PLAYER_IMPACT(pedDom, FALSE)
IF NOT IsPedPerformingTask(pedDom, SCRIPT_TASK_GO_STRAIGHT_TO_COORD)
TASK_GO_STRAIGHT_TO_COORD(pedDom, vDomBesideHelicopter, PEDMOVE_WALK, 40000)
ENDIF
IF NOT DOES_BLIP_EXIST(blipDom)
blipDom = CREATE_PED_BLIP(pedDom, TRUE, TRUE) // B*763958
ENDIF
SET_PED_CONFIG_FLAG(pedDom, PCF_ForceDirectEntry, TRUE)
PRINT_NOW("EXT1_02", DEFAULT_GOD_TEXT_TIME, 1) // Follow ~b~Dom.
ENDIF
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
SET_PED_CONFIG_FLAG(PLAYER_PED_ID(), PCF_ForceDirectEntry, TRUE)
ENDIF
bDomLookingAtHelicopter = FALSE
bHelicopterLanded = FALSE
bStartedPilotGetInConversation = FALSE
bStartedDomCallPilotConversation = FALSE
bPlayerLockedIntoEnteringHelicopter = FALSE
bPlayerNowEnteringHelicopter = FALSE
iPlayerEnterHelicopterTimer = -1
bStartedLeavingWithoutYouConversation = FALSE
bStartedLeftWithoutYouConversation = FALSE
bStartedWrongSideConversation = FALSE
seatDom = VS_ANY_PASSENGER
iEnterHelicopterTimer = GET_GAME_TIMER()
BREAK
CASE EXT1_STATE_MACHINE_LOOP
IF IS_ENTITY_ALIVE(pedDom)
IF IS_ENTITY_ALIVE(vehHelicopter)
IF HAS_VEHICLE_GOT_PROJECTILE_ATTACHED(PLAYER_PED_ID(), vehHelicopter, WEAPONTYPE_STICKYBOMB)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Stickybomb on helicopter") ENDIF #ENDIF
EXT1_MISSION_FAILED(FAILED_PILOT_SCARED)
ELIF HAS_ENTITY_BEEN_DAMAGED_BY_ANY_VEHICLE(vehHelicopter) // B*732754 Fail if player rams helicopter in a vehicle
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Helicopter damaged by a vehicle") ENDIF #ENDIF
EXT1_MISSION_FAILED(FAILED_PILOT_SCARED)
ELSE
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vehHelicopter)
AND IS_PED_IN_VEHICLE(pedDom, vehHelicopter)
missionStateMachine = EXT1_STATE_MACHINE_CLEANUP
ELSE
EXT1_MANAGE_HELICOPTER_LANDING()
EXT1_MANAGE_PLAYER_ENTERING_HELICOPTER()
EXT1_MANAGE_PLAYER_NOT_ENTERING_HELICOPTER()
EXT1_MANAGE_DOM_CALL_PILOT_CONVERSATION()
ENDIF
ENDIF
ELSE
EXT1_MISSION_FAILED(FAILED_HELICOPTER_WRECKED)
ENDIF
ENDIF
BREAK
CASE EXT1_STATE_MACHINE_CLEANUP
REPLAY_RECORD_BACK_FOR_TIME(5.0, 10.0)
EXT1_STATE_CLEANUP(FALSE)
SAFE_REMOVE_BLIP(blipHelicopter)
SAFE_REMOVE_BLIP(blipDom)
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Main state for handling the helicopter ascending the skydiving height.
PROC MS_HELICOPTER_ASCEND()
DISABLE_ON_FOOT_FIRST_PERSON_VIEW_THIS_UPDATE()
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_NEXT_CAMERA)
DISABLE_CINEMATIC_BONNET_CAMERA_THIS_UPDATE()
SWITCH missionStateMachine
CASE EXT1_STATE_MACHINE_SETUP
EXT1_STATE_SETUP(#IF IS_DEBUG_BUILD "MS_HELICOPTER_ASCEND" #ENDIF)
IF DOES_CAM_EXIST(camEnterHeli)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
RENDER_SCRIPT_CAMS(FALSE, FALSE)
DESTROY_CAM(camEnterHeli)
ENDIF
bStartedAscendConversation = FALSE
bStartedAscend2Conversation = FALSE
bStartedAscend3Conversation = FALSE
bStartedSummitConversation = FALSE
iCurrentHelicopterMission = 0
bDisplayedSkipJourneyHelpText = FALSE
bSkippingJourney = FALSE
BREAK
CASE EXT1_STATE_MACHINE_LOOP
EXT1_MANAGE_SKIP_JOURNEY()
IF bSkippingJourney = FALSE
EXT1_MANAGE_HELICOPTER_MISSIONS()
EXT1_MANAGE_HELICOPTER_ASCEND_CONVERSATION()
EXT1_MANAGE_HELICOPTER_SUMMIT_CONVERSATION()
EXT1_MANAGE_RELEASING_PARACHUTE_OBJECT()
EXT1_MANAGE_GAMEPLAY_CAM_MOTION_BLUR()
ENDIF
BREAK
CASE EXT1_STATE_MACHINE_CLEANUP
EXT1_STATE_CLEANUP()
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
SAFE_RELEASE_OBJECT(oParachute)
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Main state for handling jumping out of the helicopter.
PROC MS_JUMP_OUT_HELICOPTER()
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_NEXT_CAMERA)
SWITCH missionStateMachine
CASE EXT1_STATE_MACHINE_SETUP
EXT1_STATE_SETUP(#IF IS_DEBUG_BUILD "MS_JUMP_OUT_HELICOPTER" #ENDIF)
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_SKYDIVE, "Skydive")
EXT1_SET_FRANKLIN_INTO_PARACHUTE_OUTFIT()
EXT1_LOAD_ASSETS_FOR_MISSION_STATE(stateJumpOutHelicopter)
EXT1_SETUP_SKYDIVE_CAMERA()
EXT1_PLAY_SYNCHED_SCENE(FALSE)
EXT1_CREATE_BIKES(TRUE)
SET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_UNARMED, TRUE)
IF NOT HAS_PED_GOT_WEAPON(PLAYER_PED_ID(), GADGETTYPE_PARACHUTE)
GIVE_WEAPON_TO_PED(PLAYER_PED_ID(), GADGETTYPE_PARACHUTE, 1, FALSE, FALSE)
ENDIF
IF IS_ENTITY_ALIVE(pedDom)
IF NOT HAS_PED_GOT_WEAPON(pedDom, GADGETTYPE_PARACHUTE)
GIVE_WEAPON_TO_PED(pedDom, GADGETTYPE_PARACHUTE, 1, FALSE, FALSE)
ENDIF
SET_ENTITY_LOD_DIST(pedDom, 500)
SET_ENTITY_LOAD_COLLISION_FLAG(pedDom, TRUE)
ENDIF
bDisplayedJumpOutHelpText = FALSE
bStartedJumpOutConversation = FALSE
bStartedHurryUpConversation = FALSE
bStartedPushOutConversation = FALSE
bStartedJumpedOutConversation = FALSE
bPushedOutPlayer = FALSE
bFranklinExitingHelicopter = FALSE
domStatus = DOM_IN_HELICOPTER
iHelicopterPushOutTimer = GET_GAME_TIMER()
bOpenedTimeWindowForSkydiveStat = FALSE
bDone1stPersonCameraFlash = FALSE
EXT1_BLOCK_SPAWNERS_FOR_BIKE_RACE(TRUE)
IF NOT Is_Replay_In_Progress()
TRIGGER_MUSIC_EVENT("EXTREME1_JUMP")
ELSE
TRIGGER_MUSIC_EVENT("EXTREME1_RESTART1")
ENDIF
IF bSetCameraToThirdPerson = true
SET_FOLLOW_PED_CAM_VIEW_MODE(CAM_VIEW_MODE_FIRST_PERSON)
SET_FOLLOW_VEHICLE_CAM_VIEW_MODE(CAM_VIEW_MODE_FIRST_PERSON)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Reset cameras back to 1st person") ENDIF #ENDIF
ENDIF
BREAK
CASE EXT1_STATE_MACHINE_LOOP
ALLOW_ALTERNATIVE_SCRIPT_CONTROLS_LAYOUT(FRONTEND_CONTROL)
IF EXT1_HAS_PLAYER_FINISHED_JUMPING_OUT()
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Player skydiving") ENDIF #ENDIF
IF IS_ENTITY_ALIVE(vehHelicopter)
FREEZE_ENTITY_POSITION(vehHelicopter, FALSE)
ENDIF
INFORM_MISSION_STATS_SYSTEM_OF_TIME_WINDOW_OPEN(EXT1_FALL_TIME)
bOpenedTimeWindowForSkydiveStat = TRUE
REMOVE_ANIM_DICT("rcm_extreme1@heli")
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
IF GET_FOLLOW_PED_CAM_VIEW_MODE() = CAM_VIEW_MODE_FIRST_PERSON
RENDER_SCRIPT_CAMS(FALSE, FALSE, 0)
ELSE
RENDER_SCRIPT_CAMS(FALSE, TRUE, 1000, FALSE)
ENDIF
DESTROY_ALL_CAMS()
REPLAY_RECORD_BACK_FOR_TIME(10.0, 10.0)
missionStateMachine = EXT1_STATE_MACHINE_CLEANUP
ELIF bFranklinExitingHelicopter = FALSE
IF IS_CONTROL_PRESSED(FRONTEND_CONTROL, INPUT_SCRIPT_RLEFT)
AND (GET_GAME_TIMER() - iHelicopterPushOutTimer) > 2000 // B*763981 - Prevent jumping out on frame 1 if player is holding triangle
EXT1_PLAYER_IS_LEAVING_HELICOPTER()
ELSE
EXT1_MANAGE_HURRY_UP_CONVERSATIONS()
EXT1_MANAGE_DISPLAY_JUMP_OUT_TEXT()
EXT1_UPDATE_SKYDIVE_CAMERA()
ENDIF
ELSE
IF bStartedJumpedOutConversation = FALSE
AND EXT1_ALLOW_CONVERSATION_TO_PLAY()
AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_FIST", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_FIST conversation") ENDIF #ENDIF
bStartedJumpedOutConversation = TRUE
ENDIF
ENDIF
BREAK
CASE EXT1_STATE_MACHINE_CLEANUP
EXT1_STATE_CLEANUP()
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Main state for handling the skydive.
PROC MS_SKYDIVE()
SWITCH missionStateMachine
CASE EXT1_STATE_MACHINE_SETUP
EXT1_STATE_SETUP(#IF IS_DEBUG_BUILD "MS_SKYDIVE" #ENDIF)
blipCheckpoint = CREATE_COORD_BLIP(vCheckpoint, BLIPPRIORITY_MED, FALSE)
IF IS_RADAR_HIDDEN()
DISPLAY_RADAR(TRUE)
ENDIF
IF IS_HUD_HIDDEN()
DISPLAY_HUD(TRUE)
ENDIF
SET_SCRIPTS_SAFE_FOR_CUTSCENE(FALSE)
SET_EVERYONE_IGNORE_PLAYER(PLAYER_ID(), FALSE)
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
PRINT_NOW("EXT1_03", 5000, 1) // Skydive to the landing zone.
PRINT_HELP_FOREVER("EXT1_04") // Press ~PAD_A~ to open your parachute.
bGivenMissionAreaWarning = FALSE
bLandedOutsideArea = FALSE
bStartedDomLandsConversation = FALSE
bStartedDuringSkydiveConversation = FALSE
bStoppedDuringSkydiveConversation = FALSE
bRestartedDuringSkydiveConversation = FALSE
bStartedDeployParachuteConversation = FALSE
bStartedGetOnBikeReminderConversation = FALSE
iNumberSkydiveBanterDomDone = 0
iNumberSkydiveBanterFranklinDone = 0
IF g_replay.iReplayInt[2] = 0 // B*1415985 - Skydive dialogue alternates with each retry
sSkydiveRoot = "EXT1_SKYDIVE"
sSkydiveLabel = "EXT1_SKYDIVE_4"
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: sSkydiveRoot set to EXT1_SKYDIVE") ENDIF #ENDIF
g_replay.iReplayInt[2] = 1
ELSE
sSkydiveRoot = "EXT1_SKYDIV2"
sSkydiveLabel = "EXT1_SKYDIV2_4"
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: sSkydiveRoot set to EXT1_SKYDIV2") ENDIF #ENDIF
g_replay.iReplayInt[2] = 0
ENDIF
iSkydiveDialogueTimer = GET_GAME_TIMER()
BREAK
CASE EXT1_STATE_MACHINE_LOOP
IF bLandedOutsideArea = FALSE
EXT1_MANAGE_DOM_SKYDIVE()
EXT1_MANAGE_PLAYER_LEAVING_MISSION_AREA()
EXT1_DRAW_TARGET_MARKER()
EXT1_MANAGE_LANDING_ZONE_FOCUS_CAMERA()
EXT1_MANAGE_DURING_SKYDIVE_CONVERSATIONS()
IF EXT1_HAS_PLAYER_LANDED()
IF IS_HELP_MESSAGE_BEING_DISPLAYED()
CLEAR_HELP()
ENDIF
IF EXT1_DID_PLAYER_LAND_IN_TARGET_ZONE()
REPLAY_RECORD_BACK_FOR_TIME(10.0, 6.0)
TRIGGER_MUSIC_EVENT("EXTREME1_LAND")
iGetOnBikeReminderTimer = GET_GAME_TIMER() // Reset this timer if player has landed after Dom, so that EXT1_GET2 doesn't instantly play, see B*1149087
missionStateMachine = EXT1_STATE_MACHINE_CLEANUP
ELSE
bLandedOutsideArea = TRUE
iFailedLandingTimer = GET_GAME_TIMER()
SAFE_REMOVE_BLIP(blipCheckpoint)
ENDIF
ENDIF
ELIF (GET_GAME_TIMER() - iFailedLandingTimer) > 3000
EXT1_MISSION_FAILED(FAILED_OUTSIDE_ZONE)
ENDIF
BREAK
CASE EXT1_STATE_MACHINE_CLEANUP
REPLAY_RECORD_BACK_FOR_TIME(10.0, 10.0)
EXT1_STATE_CLEANUP()
SAFE_REMOVE_BLIP(blipCheckpoint)
KILL_CHASE_HINT_CAM(localChaseHintCamStruct)
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Main state for handling getting on a bike and waiting for Dom to land and get on his.
PROC MS_WAIT_FOR_DOM()
SWITCH missionStateMachine
CASE EXT1_STATE_MACHINE_SETUP
EXT1_STATE_SETUP(#IF IS_DEBUG_BUILD "MS_WAIT_FOR_DOM" #ENDIF)
IF iPlayersChosenBike = -1
EXT1_CREATE_BLIP_FOR_BIKE(BIKE_0)
EXT1_CREATE_BLIP_FOR_BIKE(BIKE_1)
PRINT_NOW("EXT1_21", 4000, 1) // Get on a ~b~bike.
ELSE
EXT1_CREATE_BLIP_FOR_BIKE(iPlayersChosenBike)
PRINT_NOW("EXT1_14", 4000, 1) // Get on the ~b~bike.
ENDIF
bToldToGetBackOnBike = FALSE
bToldToWaitForDom = FALSE
bPlayerGotOnABike = FALSE
bPlayerStartedRaceEarly = FALSE
BREAK
CASE EXT1_STATE_MACHINE_LOOP
IF EXT1_ARE_BOTH_ON_BIKES()
missionStateMachine = EXT1_STATE_MACHINE_CLEANUP
ELSE
EXT1_MANAGE_DOM_FOCUS_CAMERA()
EXT1_MANAGE_DOM_SKYDIVE()
ENDIF
BREAK
CASE EXT1_STATE_MACHINE_CLEANUP
EXT1_STATE_CLEANUP()
KILL_CHASE_HINT_CAM(localChaseHintCamStruct)
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Main state for handling the bike race.
PROC MS_RACE_DOM()
SWITCH missionStateMachine
CASE EXT1_STATE_MACHINE_SETUP
EXT1_STATE_SETUP(#IF IS_DEBUG_BUILD "MS_RACE_DOM" #ENDIF)
SET_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_PROPS, PROPS_P1_HEADSET, FALSE)
EXT1_LOAD_ASSETS_FOR_MISSION_STATE(stateRaceDom)
iRacePos = 2
bGivenMissionAreaWarning = FALSE
raceInfo.chosenCourse = RACE_COURSE_RC_EXTREME1
GENERATE_RACE_INFO(raceInfo)
playerInfo.raceVehicle = vehBike[iPlayersChosenBike]
playerInfo.racer = PLAYER_PED_ID()
bSetMidRaceCheckpoint[0] = FALSE
bSetMidRaceCheckpoint[1] = FALSE
bSetPlaybackToUseAI = FALSE
EXT1_CALC_CHECKPOINT_DISTANCES()
iRollingStartTimer = GET_GAME_TIMER()
IF iSkipToRaceCheckpoint = CP_BIKERACE_MIDDLE // We're retrying the race from the middle checkpoint
bStartedRace = TRUE
playerInfo.currentCheck = 20
playerInfo.nextCheck = 21
iDomNextCheckpoint = 20
iNumSlowConversationsPlayed = 2
iBikeRaceConversationsDone = 0
iSkipToRaceCheckpoint = -1
bToldToGoToDom = TRUE
bStartedFairRaceConversation = TRUE
bStartedRaceStartConversation = TRUE
bDoneRollingStart = FALSE
bSlowestDomSpeed = FALSE
bUpdatedMusicWhenNearingEndOfRace = FALSE
bPlayerGotFullyOnBike = TRUE
PRINT_NOW("EXT1_19", DEFAULT_GOD_TEXT_TIME, 1) // Race ~b~Dom.
ELIF iSkipToRaceCheckpoint = CP_BIKERACE_NEAR_END // We're retrying the race from the end checkpoint
bStartedRace = TRUE
playerInfo.currentCheck = raceInfo.totalChecks-2
playerInfo.nextCheck = raceInfo.totalChecks-1
iDomNextCheckpoint = raceInfo.totalChecks-2
iNumSlowConversationsPlayed = NUM_SLOW_DIALOGUE_LINES
iBikeRaceConversationsDone = NUM_BIKE_RACE_DIALOGUE_LINES
iSkipToRaceCheckpoint = -1
bToldToGoToDom = TRUE
bStartedFairRaceConversation = TRUE
bStartedRaceStartConversation = TRUE
bDoneRollingStart = FALSE
bSlowestDomSpeed = TRUE
bUpdatedMusicWhenNearingEndOfRace = TRUE
bPlayerGotFullyOnBike = TRUE
PRINT_NOW("EXT1_19", DEFAULT_GOD_TEXT_TIME, 1) // Race ~b~Dom.
ELSE // We're just starting the race from the beginning
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_BIKERACE_START, "Bike race start")
bStartedRace = FALSE
IF bPlayerStartedRaceEarly = TRUE
OR GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), raceInfo.checkPos[2]) < fCheckpointFailDistance[2] // B*866613 - work out if the player has passed some checkpoints but not enough to cause bPlayerStartedRaceEarly = TRUE
playerInfo.currentCheck = 2
playerInfo.nextCheck = 3
ELIF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), raceInfo.checkPos[1]) < fCheckpointFailDistance[1]
playerInfo.currentCheck = 1
playerInfo.nextCheck = 2
ELSE
playerInfo.currentCheck = 0
playerInfo.nextCheck = 1
ENDIF
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: playerInfo.currentCheck = ", playerInfo.currentCheck, " playerInfo.nextCheck = ", playerInfo.nextCheck) ENDIF #ENDIF
iDomNextCheckpoint = 0
iNumSlowConversationsPlayed = 0
iBikeRaceConversationsDone = 0
bToldToGoToDom = FALSE
bStartedFairRaceConversation = FALSE
bStartedRaceStartConversation = FALSE
bDoneRollingStart = TRUE
bSlowestDomSpeed = FALSE
iJumpStatTimer = -1
bPlayerAttainedJumpStat = FALSE
bUpdatedMusicWhenNearingEndOfRace = FALSE
bPlayerGotFullyOnBike = FALSE
ENDIF
EXT1_SETUP_BIKE_RACE_CONVERSATIONS()
g_replay.iReplayInt[0] = iPlayersChosenBike // B*1052281 - Set player's chosen bike for future retries
iBikeRaceDialogueTimer = GET_GAME_TIMER()
iCollisionDialogueTimer = GET_GAME_TIMER()
iFranklinAheadConversationTimer = GET_GAME_TIMER()
IF IS_ENTITY_ALIVE(pedDom)
TASK_LOOK_AT_ENTITY(pedDom, PLAYER_PED_ID(), -1)
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), pedDom, -1)
SET_PED_CAN_BE_KNOCKED_OFF_VEHICLE(pedDom, KNOCKOFFVEHICLE_NEVER)
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
IF DOES_BLIP_EXIST(blipDom)
SET_BLIP_SCALE(blipDom, BLIP_SIZE_VEHICLE)
ELSE
CREATE_DOM_SLIDEY_BLIP(FALSE)
ENDIF
ENDIF
ENDIF
REPLAY_RECORD_BACK_FOR_TIME(10.0, 10.0)
SET_INSTANCE_PRIORITY_HINT(INSTANCE_HINT_DRIVING)
#IF IS_DEBUG_BUILD IF bDebug_ShowRaceWarningDialogueTriggers = TRUE
SET_DEBUG_ACTIVE(TRUE)
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE)
ENDIF #ENDIF
BREAK
CASE EXT1_STATE_MACHINE_LOOP
IF IS_ENTITY_ALIVE(vehBike[iPlayersChosenBike])
AND IS_ENTITY_ALIVE(pedDom)
IF playerInfo.racerStatus = RACER_STATUS_FINISHED
TRIGGER_MUSIC_EVENT("EXTREME1_STOP")
IF iRacePos = 1
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Player won race") ENDIF #ENDIF
INFORM_STAT_SYSTEM_OF_BOOL_STAT_HAPPENED(EXT1_RACE_WON)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Achieved stat: EX1_RACE_WON") ENDIF #ENDIF
ELSE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Dom won race") ENDIF #ENDIF
ENDIF
missionStateMachine = EXT1_STATE_MACHINE_CLEANUP
ELSE
IF bStartedRace = TRUE
RUN_PLAYER_CHECKPOINTS_AND_BLIPS(playerInfo, raceInfo)
EXT1_MANAGE_RACE_POSITIONS()
EXT1_MANAGE_SLOW_CONVERSATION()
EXT1_MANAGE_BIKE_RACE_CONVERSATION()
EXT1_MANAGE_RACE_WARNING_DIALOGUE()
EXT1_MANAGE_ROLLING_START()
EXT1_MANAGE_PLAYER_REACHING_CHECKPOINTS()
EXT1_MANAGE_RACE_COLLISION_DIALOGUE()
EXT1_CHECK_FOR_JUMP_HEIGHT_STAT()
ENDIF
EXT1_MANAGE_GET_ON_BIKE_TEXT()
EXT1_MANAGE_DOM_BIKE_VEHICLE_RECORDING()
EXT1_MANAGE_BIKE_START_DIALOGUE()
EXT1_MANAGE_PLAYER_LEAVING_BIKE_RACE()
EXT1_MANAGE_DOM_FOCUS_CAMERA()
MANAGE_SLIDY_BLIP_FOR_ENTITY(blipDom, pedDom, TRUE, 10.0, FALSE)
ENDIF
ENDIF
BREAK
CASE EXT1_STATE_MACHINE_CLEANUP
REPLAY_RECORD_BACK_FOR_TIME(8.0, 2.0)
EXT1_STATE_CLEANUP()
SAFE_REMOVE_BLIP(blipBike[BIKE_0])
SAFE_REMOVE_BLIP(blipBike[BIKE_1])
SAFE_REMOVE_BLIP(blipCheckpoint)
#IF IS_DEBUG_BUILD IF bDebug_ShowRaceWarningDialogueTriggers = TRUE
SET_DEBUG_ACTIVE(FALSE)
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(FALSE)
ENDIF #ENDIF
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Main state for handling the end of race conversation.
PROC MS_RACE_END_CUTSCENE()
SWITCH missionStateMachine
CASE EXT1_STATE_MACHINE_SETUP
EXT1_STATE_SETUP(#IF IS_DEBUG_BUILD "MS_RACE_END_CUTSCENE" #ENDIF)
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_OUTRO_CUTSCENE, "Outro - Dom won race", TRUE)
bDomCycledForward = FALSE
bDone1stPersonCameraFlash = FALSE
iCutsceneStage = 0
BREAK
CASE EXT1_STATE_MACHINE_LOOP
SWITCH iCutsceneStage
CASE 0
IF IS_ENTITY_ALIVE(vehBike[iDomsBike])
AND IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vehBike[iDomsBike])
AND IS_ENTITY_ALIVE(vehBike[iPlayersChosenBike])
AND GET_DISTANCE_BETWEEN_ENTITIES(vehBike[iDomsBike], vehBike[iPlayersChosenBike]) < 10
STOP_PLAYBACK_RECORDED_VEHICLE(vehBike[iDomsBike])
BRING_VEHICLE_TO_HALT(vehBike[iDomsBike], 5, 1) // B*1570966 Ensure Dom doesn't cycle beyond Franklin if the player finishes ahead of Dom
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Stopped Dom's car recording") ENDIF #ENDIF
ENDIF
REQUEST_ANIM_DICT("rcm_extreme1")
IF IS_ENTITY_ALIVE(vehBike[iPlayersChosenBike])
AND BRING_VEHICLE_TO_HALT_AND_DISABLE_VEH_CONTROLS(vehBike[iPlayersChosenBike])
AND EXT1_ALLOW_CONVERSATION_TO_PLAY()
AND HAS_ANIM_DICT_LOADED("rcm_extreme1")
AND IS_ENTITY_ALIVE(PLAYER_PED_ID())
AND IS_ENTITY_ALIVE(pedDom)
AND IS_ENTITY_ALIVE(vehBike[iDomsBike])
IF (iRacePos = 1 AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_BIKEF1", CONV_PRIORITY_HIGH))
OR (iRacePos = 2 AND CREATE_CONVERSATION(sConversation, "EXT1AU", "EXT1_BIKED1", CONV_PRIORITY_HIGH))
IF iRacePos = 1
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_BIKEF1 conversation") ENDIF #ENDIF
ELSE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Started EXT1_BIKED1 conversation") ENDIF #ENDIF
ENDIF
iOutroSynchedScene = CREATE_SYNCHRONIZED_SCENE(<<-846.460, 5265.205, 85.835>>, <<0, 0, 96.000>>)
camCutscene = CREATE_CAM("DEFAULT_ANIMATED_CAMERA", TRUE)
IF iRacePos = 1
PLAY_SYNCHRONIZED_CAM_ANIM(camCutscene, iOutroSynchedScene, "banter_after_win_cam", "rcm_extreme1")
ELSE
PLAY_SYNCHRONIZED_CAM_ANIM(camCutscene, iOutroSynchedScene, "banter_after_loss_cam", "rcm_extreme1")
ENDIF
RC_START_CUTSCENE_MODE(<<0.0,0.0,0.0>>)
RENDER_SCRIPT_CAMS(TRUE, FALSE)
REPLAY_START_EVENT(REPLAY_IMPORTANCE_LOW)
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vehBike[iPlayersChosenBike])
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), vehBike[iPlayersChosenBike])
ENDIF
IF iRacePos = 1
PLAY_SYNCHRONIZED_ENTITY_ANIM(vehBike[iPlayersChosenBike], iOutroSynchedScene, "banter_after_win_bike_p", "rcm_extreme1", INSTANT_BLEND_IN, INSTANT_BLEND_OUT, ENUM_TO_INT(SYNCED_SCENE_USE_PHYSICS|SYNCED_SCENE_DONT_INTERRUPT))
TASK_SYNCHRONIZED_SCENE(PLAYER_PED_ID(), iOutroSynchedScene, "rcm_extreme1", "banter_after_win_player", INSTANT_BLEND_IN, INSTANT_BLEND_OUT, SYNCED_SCENE_USE_PHYSICS|SYNCED_SCENE_DONT_INTERRUPT)
ELSE
PLAY_SYNCHRONIZED_ENTITY_ANIM(vehBike[iPlayersChosenBike], iOutroSynchedScene, "banter_after_loss_bike_p", "rcm_extreme1", INSTANT_BLEND_IN, INSTANT_BLEND_OUT, ENUM_TO_INT(SYNCED_SCENE_USE_PHYSICS|SYNCED_SCENE_DONT_INTERRUPT))
TASK_SYNCHRONIZED_SCENE(PLAYER_PED_ID(), iOutroSynchedScene, "rcm_extreme1", "banter_after_loss_player", INSTANT_BLEND_IN, INSTANT_BLEND_OUT, SYNCED_SCENE_USE_PHYSICS|SYNCED_SCENE_DONT_INTERRUPT)
ENDIF
FORCE_ENTITY_AI_AND_ANIMATION_UPDATE(vehBike[iPlayersChosenBike])
FORCE_PED_AI_AND_ANIMATION_UPDATE(PLAYER_PED_ID())
IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vehBike[iDomsBike])
STOP_PLAYBACK_RECORDED_VEHICLE(vehBike[iDomsBike])
ENDIF
IF NOT IS_PED_IN_VEHICLE(pedDom, vehBike[iDomsBike])
SET_PED_INTO_VEHICLE(pedDom, vehBike[iDomsBike])
ENDIF
IF iRacePos = 1
PLAY_SYNCHRONIZED_ENTITY_ANIM(vehBike[iDomsBike], iOutroSynchedScene, "banter_after_win_bike_d", "rcm_extreme1", INSTANT_BLEND_IN, INSTANT_BLEND_OUT, ENUM_TO_INT(SYNCED_SCENE_USE_PHYSICS|SYNCED_SCENE_DONT_INTERRUPT))
TASK_SYNCHRONIZED_SCENE(pedDom, iOutroSynchedScene, "rcm_extreme1", "banter_after_win_dom", INSTANT_BLEND_IN, INSTANT_BLEND_OUT, SYNCED_SCENE_USE_PHYSICS|SYNCED_SCENE_DONT_INTERRUPT)
ELSE
PLAY_SYNCHRONIZED_ENTITY_ANIM(vehBike[iDomsBike], iOutroSynchedScene, "banter_after_loss_bike_d", "rcm_extreme1", INSTANT_BLEND_IN, INSTANT_BLEND_OUT, ENUM_TO_INT(SYNCED_SCENE_USE_PHYSICS|SYNCED_SCENE_DONT_INTERRUPT))
TASK_SYNCHRONIZED_SCENE(pedDom, iOutroSynchedScene, "rcm_extreme1", "banter_after_loss_dom", INSTANT_BLEND_IN, INSTANT_BLEND_OUT, SYNCED_SCENE_USE_PHYSICS|SYNCED_SCENE_DONT_INTERRUPT)
ENDIF
FORCE_ENTITY_AI_AND_ANIMATION_UPDATE(vehBike[iDomsBike])
FORCE_PED_AI_AND_ANIMATION_UPDATE(pedDom)
SAFE_FADE_SCREEN_IN_FROM_BLACK(500, FALSE) // Just in case screen is faded out
iCutsceneStage++
ENDIF
ENDIF
BREAK
CASE 1 // Conversation ongoing
IF IS_CUTSCENE_SKIP_BUTTON_JUST_PRESSED_WITH_DELAY()
SAFE_FADE_SCREEN_OUT_TO_BLACK()
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Player skipped outro cutscene") ENDIF #ENDIF
iCutsceneStage++
ELIF IS_SYNCHRONIZED_SCENE_RUNNING(iOutroSynchedScene)
IF bDone1stPersonCameraFlash = FALSE
AND GET_FOLLOW_PED_CAM_VIEW_MODE() = CAM_VIEW_MODE_FIRST_PERSON
AND GET_SYNCHRONIZED_SCENE_PHASE(iOutroSynchedScene) >= 0.99
ANIMPOSTFX_PLAY("CamPushInNeutral", 0, FALSE)
PLAY_SOUND_FRONTEND(-1, "1st_Person_Transition", "PLAYER_SWITCH_CUSTOM_SOUNDSET")
bDone1stPersonCameraFlash = TRUE
#IF IS_DEBUG_BUILD CPRINTLN(DEBUG_MISSION, "EXTREME1: Doing 1st person camera flash") #ENDIF
ENDIF
IF GET_SYNCHRONIZED_SCENE_PHASE(iOutroSynchedScene) = 1
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Synched scene finished so ending outro cutscene") ENDIF #ENDIF
iCutsceneStage++
ELIF bDomCycledForward = FALSE
IF IS_ENTITY_ALIVE(pedDom)
AND IS_ENTITY_ALIVE(vehBike[iDomsBike])
IF (iRacePos = 1 AND GET_SYNCHRONIZED_SCENE_PHASE(iOutroSynchedScene) >= 0.732) // Make Dom ride off when the camera cuts
OR (iRacePos = 2 AND GET_SYNCHRONIZED_SCENE_PHASE(iOutroSynchedScene) >= 0.710)// Make Dom ride off when he's out of shot
STOP_SYNCHRONIZED_ENTITY_ANIM(vehBike[iDomsBike], INSTANT_BLEND_OUT, TRUE)
STOP_SYNCHRONIZED_ENTITY_ANIM(pedDom, INSTANT_BLEND_OUT, TRUE)
IF NOT IS_PED_IN_VEHICLE(pedDom, vehBike[iDomsBike])
SET_PED_INTO_VEHICLE(pedDom, vehBike[iDomsBike])
ENDIF
TASK_VEHICLE_TEMP_ACTION(pedDom, vehBike[iDomsBike], TEMPACT_GOFORWARD, 5000)
FORCE_ENTITY_AI_AND_ANIMATION_UPDATE(vehBike[iDomsBike])
FORCE_PED_AI_AND_ANIMATION_UPDATE(pedDom)
bDomCycledForward = TRUE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Doing temp action forward on Dom") ENDIF #ENDIF
ENDIF
ENDIF
ENDIF
ELIF bDomCycledForward = TRUE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: IS_SYNCHRONIZED_SCENE_RUNNING is false and bDomCycledForward is true so end cutscene using failsafe") ENDIF #ENDIF
ENDIF
BREAK
CASE 2 // Ending cutscene and deleting Dom - see B*1416059
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
SAFE_DELETE_PED(pedDom)
SAFE_DELETE_VEHICLE(vehBike[iDomsBike])
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
AND IS_ENTITY_ALIVE(vehBike[iPlayersChosenBike])
STOP_SYNCHRONIZED_ENTITY_ANIM(vehBike[iPlayersChosenBike], INSTANT_BLEND_OUT, TRUE)
STOP_SYNCHRONIZED_ENTITY_ANIM(PLAYER_PED_ID(), INSTANT_BLEND_OUT, TRUE)
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vehBike[iPlayersChosenBike])
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), vehBike[iPlayersChosenBike])
ENDIF
SET_VEHICLE_ON_GROUND_PROPERLY(vehBike[iPlayersChosenBike])
FORCE_ENTITY_AI_AND_ANIMATION_UPDATE(vehBike[iPlayersChosenBike])
FORCE_PED_AI_AND_ANIMATION_UPDATE(PLAYER_PED_ID())
ENDIF
REPLAY_STOP_EVENT()
RENDER_SCRIPT_CAMS(FALSE, FALSE)
DESTROY_ALL_CAMS()
SAFE_FADE_SCREEN_IN_FROM_BLACK()
RC_END_CUTSCENE_MODE()
missionStateMachine = EXT1_STATE_MACHINE_CLEANUP
BREAK
ENDSWITCH
BREAK
CASE EXT1_STATE_MACHINE_CLEANUP
EXT1_STATE_CLEANUP()
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Sets the fail reason + prints the fail reason to the TTY
PROC SET_FAIL_REASON()
SWITCH failReason
CASE FAILED_DEFAULT
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: MISSION_FAILED reason=FAILED_DEFAULT") ENDIF #ENDIF
BREAK
CASE FAILED_DOG_DIED
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: MISSION_FAILED reason=FAILED_DOG_DIED") ENDIF #ENDIF
failString = "EXT1_F1" // ~r~The dog died.
BREAK
CASE FAILED_DOM_DIED
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: MISSION_FAILED reason=FAILED_DOM_DIED") ENDIF #ENDIF
failString = "EXT1_F2" // ~r~Dom died.
BREAK
CASE FAILED_OUTSIDE_ZONE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: MISSION_FAILED reason=FAILED_OUTSIDE_ZONE") ENDIF #ENDIF
failString = "EXT1_F3" // ~r~You landed too far outside the target zone.
BREAK
CASE FAILED_HELICOPTER_WRECKED
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: MISSION_FAILED reason=FAILED_HELICOPTER_WRECKED") ENDIF #ENDIF
failString = "EXT1_F4" // ~r~The helicopter was wrecked.
BREAK
CASE FAILED_DIDNT_HELP_DOM
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: MISSION_FAILED reason=FAILED_DIDNT_HELP_DOM") ENDIF #ENDIF
failString = "EXT1_F5" // ~r~You didn't help Dom.
BREAK
CASE FAILED_DIDNT_FOLLOW_DOG
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: MISSION_FAILED reason=FAILED_DIDNT_FOLLOW_DOG") ENDIF #ENDIF
failString = "EXT1_F6" // ~r~You didn't follow the dog.
BREAK
CASE FAILED_DOM_INJURED
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: MISSION_FAILED reason=FAILED_DOM_INJURED") ENDIF #ENDIF
failString = "EXT1_F7" // ~r~Dom was injured.
BREAK
CASE FAILED_DOG_INJURED
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: MISSION_FAILED reason=FAILED_DOG_INJURED") ENDIF #ENDIF
failString = "EXT1_F8" // ~r~The dog was injured.
BREAK
CASE FAILED_PILOT_INJURED
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: MISSION_FAILED reason=FAILED_PILOT_INJURED") ENDIF #ENDIF
failString = "EXT1_F9" // ~r~The pilot was injured.
BREAK
CASE FAILED_DIDNT_ENTER_HELICOPTER
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: MISSION_FAILED reason=FAILED_DIDNT_ENTER_HELICOPTER") ENDIF #ENDIF
failString = "EXT1_F10" // ~r~You didn't get into the helicopter.
BREAK
CASE FAILED_LEFT_MISSION_AREA
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: MISSION_FAILED reason=FAILED_LEFT_MISSION_AREA") ENDIF #ENDIF
failString = "EXT1_F11" // ~r~You left the mission area.
BREAK
CASE FAILED_PILOT_SCARED
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: MISSION_FAILED reason=FAILED_PILOT_SCARED") ENDIF #ENDIF
failString = "EXT1_F12" // ~r~The pilot was scared away.
BREAK
CASE FAILED_DOM_SCARED
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: MISSION_FAILED reason=FAILED_DOM_SCARED") ENDIF #ENDIF
failString = "EXT1_F13" // ~r~Dom was scared away.
BREAK
CASE FAILED_DOG_SCARED
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: MISSION_FAILED reason=FAILED_DOG_SCARED") ENDIF #ENDIF
failString = "EXT1_F14" // ~r~The dog was scared away.
BREAK
CASE FAILED_BIKE_WRECKED
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: MISSION_FAILED reason=FAILED_BIKE_WRECKED") ENDIF #ENDIF
failString = "EXT1_F15" // ~r~One of the bikes was wrecked.
BREAK
CASE FAILED_FAILED_RACE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: MISSION_FAILED reason=FAILED_FAILED_RACE") ENDIF #ENDIF
failString = "EXT1_F17" // ~r~You failed the race.
BREAK
CASE FAILED_PLAYER_BIKE_LOST
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: MISSION_FAILED reason=FAILED_PLAYER_BIKE_LOST") ENDIF #ENDIF
failString = "EXT1_F18" // ~r~You lost your bike.
BREAK
CASE FAILED_FAILED_SKY_DIVE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: MISSION_FAILED reason=FAILED_FAILED_SKY_DIVE") ENDIF #ENDIF
failString = "EXT1_F19" // ~r~You failed the sky dive.
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Starts the mission failed sequence.
PROC MS_FAILED()
SWITCH missionStateMachine
CASE EXT1_STATE_MACHINE_SETUP
EXT1_STATE_SETUP(#IF IS_DEBUG_BUILD "MS_FAILED" #ENDIF)
CLEAR_PRINTS()
CLEAR_HELP()
EXT1_REMOVE_ALL_BLIPS()
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
TRIGGER_MUSIC_EVENT("EXTREME1_FAIL")
EXT1_SET_PED_TO_FLEE(pedDog)
IF IS_ENTITY_ALIVE(pedDom)
IF IS_ENTITY_PLAYING_ANIM(pedDom, "rcm_extreme1", "es_1_rcm_dom_upside_down_base")
OR IS_ENTITY_PLAYING_ANIM(pedDom, "rcm_extreme1", "es_1_rcm_dom_upside_down_fidget_01")
OR IS_ENTITY_PLAYING_ANIM(pedDom, "rcm_extreme1", "es_1_rcm_dom_upside_down_fidget_02")
OR GET_PED_PARACHUTE_STATE(pedDom) = PPS_SKYDIVING // See B*547967 - don't make Dom flee if he's parachuting
OR GET_PED_PARACHUTE_STATE(pedDom) = PPS_DEPLOYING
OR GET_PED_PARACHUTE_STATE(pedDom) = PPS_PARACHUTING
ADD_PED_FOR_DIALOGUE(sConversation, 3, pedDom, "DOM")
ELSE
EXT1_SET_PED_TO_FLEE(pedDom)
ENDIF
ENDIF
bStartedThreatenDomConversation = FALSE
SET_FAIL_REASON() // set the fail string
IF failReason = FAILED_DEFAULT // No fail reason
Random_Character_Failed()
ELSE
Random_Character_Failed_With_Reason(failString)
ENDIF
BREAK
CASE EXT1_STATE_MACHINE_LOOP
IF GET_MISSION_FLOW_SAFE_TO_CLEANUP()
EXT1_STATE_CLEANUP()
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
SET_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_SPECIAL, SPECIAL_P1_DUMMY, FALSE) // B*1601720 - Only remove the parachute and headset
SET_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_PROPS, PROPS_EARS_NONE, FALSE)
IF (IS_ENTITY_ALIVE(vehHelicopter) AND IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vehHelicopter))
OR (IS_ENTITY_ALIVE(PLAYER_PED_ID()) AND GET_ENTITY_HEIGHT_ABOVE_GROUND(PLAYER_PED_ID()) > 5.0) // B*1045200 - Set respawn warp if player is in mid-air
MISSION_FLOW_SET_FAIL_WARP_LOCATION(<< -188.8000, 1296.1221, 302.9238 >>, 213.9571)
SET_REPLAY_DECLINED_VEHICLE_WARP_LOCATION(<<-190.889603,1305.530151,304.068054>>, 45.933205)
ENDIF
ENDIF
EXT1_REMOVE_ALL_PEDS(TRUE)
SAFE_DELETE_OBJECT(oParachute)
SAFE_DELETE_VEHICLE(vehHelicopter)
SAFE_DELETE_VEHICLE(vehBike[0])
SAFE_DELETE_VEHICLE(vehBike[1])
REMOVE_CUTSCENE() // In case midtro mocap has been preloaded
Script_Cleanup()
ELSE
// not finished fading out: handle dialogue etc here
EXT1_MANAGE_THREATEN_DOM_DIALOGUE()
ENDIF
BREAK
ENDSWITCH
ENDPROC
#IF IS_DEBUG_BUILD
/// PURPOSE:
/// Checks for debug keys being pressed.
PROC DEBUG_Check_Debug_Keys()
IF bZSkipping = FALSE
AND (GET_GAME_TIMER() - iDebugSkipTime) > 1000
AND ENUM_TO_INT(missionState) < (ENUM_TO_INT(NUM_MISSION_STATES)-1) // Don't check during stateFailed
IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_S))
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: S key pressed so passing mission") ENDIF #ENDIF
EXT1_REMOVE_PRELOADED_MIDTRO()
IF missionState = stateIntro
OR missionState = stateMidtro
WAIT_FOR_CUTSCENE_TO_STOP()
ENDIF
Script_Passed()
ENDIF
IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_F))
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: F key pressed so failing mission") ENDIF #ENDIF
EXT1_REMOVE_PRELOADED_MIDTRO()
IF missionState = stateIntro
OR missionState = stateMidtro
WAIT_FOR_CUTSCENE_TO_STOP()
ENDIF
EXT1_MISSION_FAILED()
ENDIF
IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_J))
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: J key pressed so doing z skip forwards") ENDIF #ENDIF
SWITCH missionState
CASE stateIntro
IF IS_CUTSCENE_ACTIVE()
STOP_CUTSCENE()
ENDIF
BREAK
CASE stateFollowDog
EXT1_REMOVE_PRELOADED_MIDTRO()
EXT1_DEBUG_SKIP_STATE(Z_SKIP_MIDTRO)
BREAK
CASE stateMidtro
IF IS_CUTSCENE_ACTIVE()
STOP_CUTSCENE()
ENDIF
BREAK
CASE stateGetInHelicopter
CASE stateHelicopterAscend
EXT1_DEBUG_SKIP_STATE(Z_SKIP_JUMP_OUT_HELICOPTER)
BREAK
CASE stateJumpOutHelicopter
CASE stateSkyDive
CASE stateWaitForDom
EXT1_DEBUG_SKIP_STATE(Z_SKIP_RACE_START)
BREAK
CASE stateRaceDom
EXT1_DEBUG_SKIP_STATE(Z_SKIP_OUTRO_CUTSCENE_2)
BREAK
ENDSWITCH
ENDIF
IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_P))
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: P key pressed so doing z skip backwards") ENDIF #ENDIF
SWITCH missionState
CASE stateFollowDog
EXT1_REMOVE_PRELOADED_MIDTRO()
EXT1_DEBUG_SKIP_STATE(Z_SKIP_INTRO)
BREAK
CASE stateGetInHelicopter
EXT1_DEBUG_SKIP_STATE(Z_SKIP_FOLLOW_DOG)
BREAK
CASE stateHelicopterAscend
CASE stateJumpOutHelicopter
CASE stateSkyDive
CASE stateWaitForDom
EXT1_DEBUG_SKIP_STATE(Z_SKIP_GET_IN_HELICOPTER)
BREAK
CASE stateRaceDom
EXT1_DEBUG_SKIP_STATE(Z_SKIP_JUMP_OUT_HELICOPTER)
BREAK
CASE stateRaceEndConversation
EXT1_DEBUG_SKIP_STATE(Z_SKIP_RACE_START)
BREAK
ENDSWITCH
ENDIF
INT i_new_state
IF LAUNCH_MISSION_STAGE_MENU(mSkipMenu, i_new_state)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME1: Z skip menu used so doing z skip") ENDIF #ENDIF
EXT1_DEBUG_SKIP_STATE(i_new_state)
ENDIF
ENDIF
ENDPROC
#ENDIF
SCRIPT(g_structRCScriptArgs sRCLauncherDataIn)
sRCLauncherDataLocal = sRCLauncherDataIn
RC_TakeEntityOwnership(sRCLauncherDataLocal)
SET_MISSION_FLAG(TRUE)
IF (HAS_FORCE_CLEANUP_OCCURRED(DEFAULT_FORCE_CLEANUP_FLAGS|FORCE_CLEANUP_FLAG_DEBUG_MENU))
PRINT_LAUNCHER_DEBUG("Force cleanup [TERMINATING]")
Random_Character_Failed()
Script_Cleanup()
ENDIF
EXT1_MISSION_SETUP()
IF IS_REPLAY_IN_PROGRESS()
RC_CleanupSceneEntities(sRCLauncherDataLocal, TRUE, TRUE)
INT istage = GET_REPLAY_MID_MISSION_STAGE()
IF g_bShitskipAccepted = TRUE
istage++
ENDIF
SWITCH istage
CASE CP_FOLLOW_DOG
START_REPLAY_SETUP(vFranklinAfterIntro, fFranklinAfterIntro)
EXT1_DEBUG_SKIP_STATE(Z_SKIP_FOLLOW_DOG)
BREAK
CASE CP_MIDTRO
START_REPLAY_SETUP(vFranklinAfterIntro, fFranklinAfterIntro, FALSE)
EXT1_DEBUG_SKIP_STATE(Z_SKIP_MIDTRO)
BREAK
CASE CP_GET_IN_HELICOPTER
START_REPLAY_SETUP(vFranklinAfterMidtro, fFranklinAfterMidtro, FALSE)
EXT1_DEBUG_SKIP_STATE(Z_SKIP_GET_IN_HELICOPTER)
BREAK
CASE CP_SKYDIVE
START_REPLAY_SETUP(<<502.9590, 5550.9399, 779.2255>>, 160.8655, FALSE)
EXT1_DEBUG_SKIP_STATE(Z_SKIP_JUMP_OUT_HELICOPTER)
BREAK
CASE CP_BIKERACE_START
START_REPLAY_SETUP(<<502.9590, 5550.9399, 779.2255>>, 160.8655, FALSE)
EXT1_DEBUG_SKIP_STATE(Z_SKIP_RACE_START)
BREAK
CASE CP_BIKERACE_MIDDLE
START_REPLAY_SETUP(<<-66.1980, 4956.3643, 393.0010>>, 146.0558, FALSE)
EXT1_DEBUG_SKIP_STATE(Z_SKIP_RACE_MIDDLE)
BREAK
CASE CP_BIKERACE_NEAR_END
START_REPLAY_SETUP(<<-765.4150, 5208.9624, 108.2433>>, 355.2759, FALSE)
EXT1_DEBUG_SKIP_STATE(Z_SKIP_RACE_NEAR_END)
BREAK
CASE CP_OUTRO_CUTSCENE
START_REPLAY_SETUP(<<-854.5977, 5256.7173, 85.4694>>, 270, FALSE)
EXT1_DEBUG_SKIP_STATE(Z_SKIP_OUTRO_CUTSCENE_2)
BREAK
ENDSWITCH
ENDIF
WHILE(TRUE)
WAIT(0)
REPLAY_CHECK_FOR_EVENT_THIS_FRAME("SF_RA")
UPDATE_MISSION_NAME_DISPLAYING(sRCLauncherDataLocal.sIntroCutscene)
EXT1_DEATH_CHECKS()
SWITCH missionState
CASE stateIntro
MS_INTRO()
BREAK
CASE stateFollowDog
MS_FOLLOW_DOG()
BREAK
CASE stateMidtro
MS_MIDTRO()
BREAK
CASE stateGetInHelicopter
MS_GET_IN_HELICOPTER()
BREAK
CASE stateHelicopterAscend
MS_HELICOPTER_ASCEND()
BREAK
CASE stateJumpOutHelicopter
MS_JUMP_OUT_HELICOPTER()
BREAK
CASE stateSkyDive
MS_SKYDIVE()
BREAK
CASE stateWaitForDom
MS_WAIT_FOR_DOM()
BREAK
CASE stateRaceDom
MS_RACE_DOM()
BREAK
CASE stateRaceEndConversation
MS_RACE_END_CUTSCENE()
BREAK
CASE stateMissionPassed
Script_Passed()
BREAK
CASE stateFailed
MS_FAILED()
BREAK
ENDSWITCH
#IF IS_DEBUG_BUILD
DEBUG_Check_Debug_Keys()
#ENDIF
ENDWHILE
ENDSCRIPT