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

1727 lines
74 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 : Extreme3.sc
// AUTHOR : Kev Edwards
// DESCRIPTION : Franklin and Dom do a parachute jump off a skyscraper
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 "dialogue_public.sch"
USING "RC_Helper_Functions.sch"
USING "rc_launcher_public.sch"
USING "initial_scenes_Extreme.sch"
USING "CompletionPercentage_public.sch"
USING "traffic_default_values.sch"
USING "traffic.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_INTRO 0
CONST_INT CP_BASE_JUMP 1
CONST_INT CP_OUTRO 2 // Only used for shitskips
CONST_INT Z_SKIP_INTRO 0 // Z Skips
CONST_INT Z_SKIP_JUMP 1
CONST_INT Z_SKIP_OUTRO_1 2
CONST_INT Z_SKIP_OUTRO_2 3
ENUM EXT3_MISSION_STATE
stateNULL,
stateIntro,
stateJump,
stateParachute,
stateOutro,
stateFailed,
NUM_MISSION_STATES
ENDENUM
EXT3_MISSION_STATE missionState = stateIntro // Stores the current EXT3_MISSION_STATE
EXT3_MISSION_STATE missionStateSkip = stateNULL // Used if needing to change to a EXT3_MISSION_STATE out of sequence
ENUM EXT3_STATE_MACHINE
EXT3_STATE_MACHINE_SETUP,
EXT3_STATE_MACHINE_LOOP,
EXT3_STATE_MACHINE_CLEANUP
ENDENUM
EXT3_STATE_MACHINE missionStateMachine = EXT3_STATE_MACHINE_SETUP
ENUM FAILED_REASON
FAIL_DEFAULT,
FAIL_DOM_DEAD,
FAIL_DIDNT_LAND_ON_TRUCK,
FAIL_TRUCK_WRECKED,
FAIL_DIDNT_ATTEMPT_JUMP,
FAIL_DOM_SPOOKED,
FAIL_JUMPED_OFF_BEFORE_INTRO
ENDENUM
FAILED_REASON failReason
STRING failString
ENUM DOM_STATE
DS_FREE_FALL,
DS_PARACHUTING,
DS_ATTACHED,
DS_MISSED_TRUCK
ENDENUM
BOOL bZSkipping = FALSE // Changes to TRUE if z skipping to prevent subsequent mission state changes etc
BOOL bHasChanged // variable for storing the state of "player has changed outfit"
#IF IS_DEBUG_BUILD
CONST_INT MAX_SKIP_MENU_LENGTH 4
MissionStageMenuTextStruct mSkipMenu[MAX_SKIP_MENU_LENGTH]
WIDGET_GROUP_ID widgetGroup
BOOL bDebug_PrintToTTY = TRUE
INT iDebugSkipTime // Prevents skipping instantaneously
#ENDIF
VECTOR vPlayerCarRespot = <<-75.08253, -818.78278, 325.36554>>
CONST_FLOAT fPlayerCarRespot 0.0
structPedsForConversation sSpeech
BOOL bStartedPreJumpSpeech
BOOL bStartedDuringSkydiveSpeech
BOOL bStoppedDuringSkydiveSpeech
BOOL bRestartedDuringSkydiveSpeech
BOOL bStartedFranklinLandsSpeech
BOOL bStartedDomLandsSpeech
BOOL bStartedDriverSpeech
BOOL bStartedCollisionSpeech
TEXT_LABEL_23 tStoredTricksConversationLabel
INT iCutsceneStage
CAMERA_INDEX camCutscene, camInterp
BOOL bHasSetExitStateFromOutroMocapForGameplayCam
PED_INDEX pedDom
DOM_STATE eDomState
SEQUENCE_INDEX seqDomJump
SEQUENCE_INDEX seqFranklinJump
SEQUENCE_INDEX seqDomDriveAway
VECTOR vDomJumpPos = << -65.416122,-809.763916,321.3 >>
CONST_FLOAT fDomJumpHeading -75.630417
VECTOR vPlayerJumpPos = << -65.175079,-810.619995,321.3 >>
CONST_FLOAT fPlayerJumpHeading -50.0
VECTOR vPlayerOutroPos = <<126.8733, -569.9907, 42.5572>>
CONST_FLOAT fPlayerOutroHeading 115.2982
VECTOR vDomOutroPos = <<96.8964, -650.2531, 43.2203>>
CONST_FLOAT fDomOutroHeading 347.5251
CONST_FLOAT TRUCK_CHECK_LENGTH 5.0
MODEL_NAMES modelTruck
MODEL_NAMES modelDriver
VEHICLE_INDEX vehTruck
BLIP_INDEX blipTruck
PED_INDEX pedDriver
FLOAT fPlaybackSpeed
INT iTruckColourCombo = 0
CONST_FLOAT PLAYBACK_SPEED_FASTEST 1.0
CONST_FLOAT PLAYBACK_SPEED_NORMAL 0.35 // Ideal landing speed
CONST_FLOAT PLAYBACK_SPEED_SLOWEST 0.15
MODEL_NAMES modelSportsCar
VEHICLE_INDEX vehSportsCar
VECTOR vSportsCar = <<521.823181,-177.840149,53.947510>>
CONST_FLOAT fSportsCar 14.914182
VECTOR vDomAfterOutro = <<519.884338,-176.249329,55>>
CONST_FLOAT fDomAfterOutro -172.460220
BOOL bDisplayedDeployParachuteHelpText
BOOL bPlayerPressedSquare
BOOL bPlayerStartedJump
PED_PARACHUTE_LANDING_TYPE typePlayerLanding
BOOL bOpenedTimeWindowForSkydiveStat
BOOL bGivenMissionAreaWarning
INT iDisplayParachuteHelpTimer
INT iPlayerLandedTimer
INT iDomUpdateTargetTimer // Dom doesn't update his parachute target every frame
INT iPlayerDelayJumpTimer
BOOL bChangedFranklinIntoOutfit
CONST_FLOAT OUTRO_TRUCK_PLAYBACK_SKIP_TIME 6000.0
BOOL bPreloadingOutroMocap
INT iCutsceneFailsafeTimer
VECTOR vFranklinAttachedToTruckPos = <<-0.379716, -2.29171, 1.42498>>
VECTOR vFranklinAttachedToTruckRot = <<0, 0, -20>>
VECTOR vDomAttachedToTruckPos = <<0, -1, 1.42498>>
VECTOR vDomAttachedToTruckRot = <<0, 0, 160>>
STREAMVOL_ID streamVolumeExtreme3
/// PURPOSE:
/// Used in every EXT3_STATE_MACHINE_SETUP. Advances state machine to EXT3_STATE_MACHINE_LOOP.
PROC EXT3_STATE_SETUP(#IF IS_DEBUG_BUILD STRING s_text #ENDIF)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Initialising ", s_text) ENDIF #ENDIF
bZSkipping = FALSE
#IF IS_DEBUG_BUILD iDebugSkipTime = GET_GAME_TIMER() #ENDIF
missionStateMachine = EXT3_STATE_MACHINE_LOOP
ENDPROC
/// PURPOSE:
/// Used in every EXT3_STATE_MACHINE_CLEANUP. Advances state machine to EXT3_STATE_MACHINE_SETUP.
PROC EXT3_STATE_CLEANUP(#IF IS_DEBUG_BUILD STRING s_text #ENDIF)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Cleaning up ", s_text) ENDIF #ENDIF
IF NOT IS_THIS_PRINT_BEING_DISPLAYED("EXT3_01") // This print needs to span across stateJump to stateParachute
CLEAR_PRINTS()
ENDIF
CLEAR_HELP(TRUE)
IF missionStateSkip = stateNULL
missionState = INT_TO_ENUM(EXT3_MISSION_STATE, ENUM_TO_INT(missionState) + 1)
ELSE
missionState = missionStateSkip
ENDIF
missionStateSkip = stateNULL
missionStateMachine = EXT3_STATE_MACHINE_SETUP
ENDPROC
/// PURPOSE:
/// Safely remove all blips in this mission.
PROC EXT3_REMOVE_ALL_BLIPS()
SAFE_REMOVE_BLIP(blipTruck)
ENDPROC
/// PURPOSE:
/// Stop any active anims on the player.
PROC EXT3_STOP_PLAYER_ANIMATIONS()
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
IF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "rcmextreme3", "idle_frantic")
STOP_ANIM_TASK(PLAYER_PED_ID(), "rcmextreme3", "idle_frantic")
CLEAR_PED_TASKS_IMMEDIATELY(PLAYER_PED_ID())
ENDIF
IF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "rcmextreme3", "jump_fall")
STOP_ANIM_TASK(PLAYER_PED_ID(), "rcmextreme3", "jump_fall")
CLEAR_PED_TASKS_IMMEDIATELY(PLAYER_PED_ID())
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Sets up Franklin in his skydiving outfit or back to his normal clothes.
PROC EXT3_SET_FRANKLIN_INTO_SKYDIVING_OUTFIT(BOOL b_set_into_outfit)
IF b_set_into_outfit = 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 bChangedFranklinIntoOutfit = FALSE
STORE_PLAYER_PED_VARIATIONS(PLAYER_PED_ID()) // B*1206376 - Store current clothes before setting into parachuting outfit
SET_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_OUTFIT, OUTFIT_P1_SKYDIVING, FALSE)
SET_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_SPECIAL, SPECIAL_P1_PARACHUTE, FALSE)
SET_PED_PARACHUTE_TINT_INDEX(PLAYER_PED_ID(), 1)
SET_PLAYER_HAS_CHANGE_CLOTHES_ON_MISSION(CHAR_FRANKLIN) // Set that the player has changed clothes on mission
SET_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_PROPS, PROPS_P1_HEADSET)
bChangedFranklinIntoOutfit = TRUE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Set Franklin into his parachuting outfit") ENDIF #ENDIF
ENDIF
ELSE
REMOVE_PED_COMP_ITEM_SP(PLAYER_PED_ID(), COMP_TYPE_PROPS, PROPS_P1_HEADSET)
IF IS_SCREEN_FADED_OUT() // These commands completely change the player's entire outfit so only do this if the screen is faded out
RESTORE_PLAYER_PED_VARIATIONS(PLAYER_PED_ID())
RESET_PLAYER_HAS_CHANGE_CLOTHES_ON_MISSION(CHAR_FRANKLIN, bHasChanged) // Reset that the player has changed outfit on mission to how it was at the start of the mission
bChangedFranklinIntoOutfit = FALSE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Restored Franklin's outfit") ENDIF #ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Unloads all models, anims etc.
PROC EXT3_MISSION_CLEANUP(BOOL b_delete_entities = FALSE, BOOL b_terminate_mission = FALSE)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Cleaning up mission...") ENDIF #ENDIF
CLEAR_PRINTS()
CLEAR_HELP()
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
KILL_CHASE_HINT_CAM(localChaseHintCamStruct)
RENDER_SCRIPT_CAMS(FALSE, FALSE)
DESTROY_ALL_CAMS()
EXT3_STOP_PLAYER_ANIMATIONS()
REMOVE_PED_FOR_DIALOGUE(sSpeech, 0)
REMOVE_PED_FOR_DIALOGUE(sSpeech, 1)
REMOVE_PED_FOR_DIALOGUE(sSpeech, 3)
EXT3_REMOVE_ALL_BLIPS()
IF IS_ENTITY_ALIVE(pedDom)
SET_ENTITY_LOAD_COLLISION_FLAG(pedDom, FALSE)
SET_ENTITY_INVINCIBLE(pedDom, FALSE)
SET_ENTITY_PROOFS(pedDom, FALSE, FALSE, FALSE, FALSE, FALSE)
ENDIF
IF IS_ENTITY_ALIVE(vehTruck)
SET_ENTITY_LOAD_COLLISION_FLAG(vehTruck, FALSE)
ENDIF
IF b_delete_entities = TRUE
SAFE_DELETE_PED(pedDom)
SAFE_DELETE_PED(pedDriver)
SAFE_DELETE_VEHICLE(vehTruck)
SAFE_DELETE_VEHICLE(vehSportsCar)
ELSE
SAFE_RELEASE_PED(pedDom)
SAFE_RELEASE_PED(pedDriver)
SAFE_RELEASE_VEHICLE(vehTruck)
SAFE_RELEASE_VEHICLE(vehSportsCar)
ENDIF
SET_MODEL_AS_NO_LONGER_NEEDED(GET_NPC_PED_MODEL(CHAR_DOM))
SET_MODEL_AS_NO_LONGER_NEEDED(modelTruck)
SET_VEHICLE_MODEL_IS_SUPPRESSED(modelTruck, FALSE)
SET_MODEL_AS_NO_LONGER_NEEDED(modelDriver)
SET_MODEL_AS_NO_LONGER_NEEDED(modelSportsCar)
REMOVE_ANIM_DICT("rcmextreme3")
REMOVE_VEHICLE_RECORDING(500, "Ext3_Truck")
REMOVE_VEHICLE_RECORDING(501, "Ext3_Truck")
TRIGGER_MUSIC_EVENT("EXTREME3_STOP")
RC_CleanupSceneEntities(sRCLauncherDataLocal, FALSE)
IF STREAMVOL_IS_VALID(streamVolumeExtreme3)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME2: Deleting streamVolumeExtreme3") ENDIF #ENDIF
STREAMVOL_DELETE(streamVolumeExtreme3)
ENDIF
IF b_terminate_mission = TRUE
DISABLE_CELLPHONE(FALSE)
SET_FRONTEND_RADIO_ACTIVE(TRUE)
#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, "EXTREME3: 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())
EXT3_MISSION_CLEANUP(FALSE, TRUE)
ENDIF
RC_CleanupSceneEntities(sRCLauncherDataLocal, FALSE) // Cleanup the scene created by the launcher
TERMINATE_THIS_THREAD()
ENDPROC
/// PURPOSE:
/// Standard RC mission passed function.
PROC Script_Passed()
Random_Character_Passed(CP_RAND_C_EXT3)
SET_STATIC_BLIP_ACTIVE_STATE(STATIC_BLIP_AMBIENT_BASEJUMP_MAZE_BANK, TRUE)
Script_Cleanup()
ENDPROC
/// PURPOSE:
/// Checks if the ped is within the landing area on the truck.
FUNC BOOL EXT3_IS_PED_WITHIN_TRUCK_AREA(PED_INDEX ped_to_check)
IF IS_ENTITY_ALIVE(ped_to_check)
AND IS_ENTITY_ALIVE(vehTruck)
VECTOR v_offset_from_truck = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(vehTruck, GET_ENTITY_COORDS(ped_to_check))
IF v_offset_from_truck.y < 1 // Dummy ref
ENDIF
//IF v_offset_from_truck.y < 1 // B*1363969 - Don't check for the ped landing on the flat part of the truck, but rather the entire truck
IF IS_PED_ON_VEHICLE(ped_to_check)
IF ped_to_check = PLAYER_PED_ID()
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Player is on truck: ", v_offset_from_truck) ENDIF #ENDIF
ELSE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Dom is on truck: ", v_offset_from_truck) ENDIF #ENDIF
ENDIF
RETURN TRUE
ENDIF
IF ped_to_check = PLAYER_PED_ID()
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Player is NOT on truck: ", v_offset_from_truck) ENDIF #ENDIF
ELSE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Dom is NOT on truck: ", v_offset_from_truck) ENDIF #ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Checks if a ped is on the ground.
FUNC BOOL EXT3_IS_PED_ON_GROUND(PED_INDEX ped_to_check)
IF IS_ENTITY_ALIVE(ped_to_check)
IF (NOT IS_PED_RAGDOLL(ped_to_check) AND NOT IS_PED_GETTING_UP(ped_to_check)) // B*1226094 Wait until the ped has stopped ragdolling // B*1553334 and until finished getting up
OR (GET_ENTITY_HEIGHT_ABOVE_GROUND(ped_to_check) > 10 AND NOT GET_PLAYER_HAS_RESERVE_PARACHUTE(PLAYER_ID())) // In case the player manually bails out above the ground - B*1942700 added condition to check the player having a backup parachute
IF GET_PED_PARACHUTE_STATE(ped_to_check) = PPS_LANDING
OR (ped_to_check = PLAYER_PED_ID() AND GET_PED_PARACHUTE_STATE(ped_to_check) = PPS_INVALID) // Safety in case the player somehow lands without going through PPS_LANDING
IF typePlayerLanding = PPLT_INVALID
AND ped_to_check = PLAYER_PED_ID()
typePlayerLanding = GET_PED_PARACHUTE_LANDING_TYPE(ped_to_check)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: typePlayerLanding: ", typePlayerLanding) ENDIF #ENDIF
ENDIF
RETURN TRUE
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Attaches the ped to the truck and gets them to play the getting up animation.
PROC EXT3_ATTACH_PED_TO_TRUCK(PED_INDEX ped_to_attach)
IF IS_ENTITY_ALIVE(ped_to_attach)
AND IS_ENTITY_ALIVE(vehTruck)
AND NOT IS_ENTITY_ATTACHED_TO_ENTITY(ped_to_attach, vehTruck)
VECTOR v_attach_offset = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(vehTruck, GET_ENTITY_COORDS(ped_to_attach))
VECTOR v_attach_rotation = GET_ENTITY_ROTATION(ped_to_attach)
ATTACH_ENTITY_TO_ENTITY(ped_to_attach, vehTruck, 0, v_attach_offset, v_attach_rotation)
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 EXT3_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:
/// Creates the truck.
PROC EXT3_CREATE_TRUCK(BOOL b_create_for_outro)
IF NOT IS_ENTITY_ALIVE(vehTruck)
EXT3_ENSURE_MODEL_IS_LOADED(modelTruck)
IF b_create_for_outro = TRUE
VECTOR v_truck_pos = GET_ROTATION_OF_VEHICLE_RECORDING_ID_AT_TIME(GET_VEHICLE_RECORDING_ID(501, "Ext3_Truck"), OUTRO_TRUCK_PLAYBACK_SKIP_TIME)
VECTOR v_truck_rot = GET_ROTATION_OF_VEHICLE_RECORDING_ID_AT_TIME(GET_VEHICLE_RECORDING_ID(501, "Ext3_Truck"), OUTRO_TRUCK_PLAYBACK_SKIP_TIME)
vehTruck = CREATE_VEHICLE(modelTruck, v_truck_pos, v_truck_rot.z)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Created vehTruck for outro") ENDIF #ENDIF
ELSE
CLEAR_AREA_OF_VEHICLES(<< 30.3356, -795.6482, 44.2600 >>, 20) // B*1428993
vehTruck = CREATE_VEHICLE(modelTruck, << 30.3356, -795.6482, 44.2600 >>, -20.623877)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Created vehTruck for jump") ENDIF #ENDIF
ENDIF
SET_VEHICLE_COLOUR_COMBINATION(vehTruck, iTruckColourCombo)
SET_ENTITY_LOAD_COLLISION_FLAG(vehTruck, TRUE)
IF NOT IS_ENTITY_ALIVE(pedDriver)
pedDriver = CREATE_PED_INSIDE_VEHICLE(vehTruck, PEDTYPE_MISSION, modelDriver, VS_DRIVER)
SET_MODEL_AS_NO_LONGER_NEEDED(modelDriver)
ENDIF
ADD_PED_FOR_DIALOGUE(sSpeech, 4, pedDriver, "EXT1HELIPILOT")
IF b_create_for_outro = TRUE
WHILE NOT RC_CREATE_NPC_PED(pedDom, CHAR_DOM, vDomOutroPos, fDomOutroHeading, "EXTREME LAUNCHER RC")
WAIT(0)
ENDWHILE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Created pedDom for outro") ENDIF #ENDIF
ENDIF
ENDIF
IF IS_ENTITY_ALIVE(vehTruck)
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(vehTruck, TRUE) // B*1582473
IF b_create_for_outro = TRUE
AND IS_ENTITY_ALIVE(pedDom)
SET_PED_COMPONENT_VARIATION(pedDom, INT_TO_ENUM(PED_COMPONENT,8), 2, 0, 0)
SET_ENTITY_INVINCIBLE(pedDom, TRUE) // Ensure Dom can't die
IF eDomState = DS_ATTACHED
ATTACH_ENTITY_TO_ENTITY(pedDom, vehTruck, 0, vDomAttachedToTruckPos, vDomAttachedToTruckRot)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Attached pedDom to vehTruck") ENDIF #ENDIF
ELSE
TASK_GO_TO_ENTITY(pedDom, vehTruck)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Tasked pedDom to go to vehTruck") ENDIF #ENDIF
ENDIF
ENDIF
START_PLAYBACK_RECORDED_VEHICLE(vehTruck, 500, "Ext3_Truck")//, ENUM_TO_INT(SWITCH_ON_ANY_VEHICLE_IMPACT), 0, DRIVINGMODE_PLOUGHTHROUGH) // This caused 1036534
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Started Ext3_Truck500 on vehTruck") ENDIF #ENDIF
IF b_create_for_outro = TRUE
SKIP_TIME_IN_PLAYBACK_RECORDED_VEHICLE(vehTruck, 20000)
ELSE
SKIP_TIME_IN_PLAYBACK_RECORDED_VEHICLE(vehTruck, 6000) // B*1164184 Ensure truck is well out of sight so Dom won't land potentially a little bit in view if the player doesn't jump
PAUSE_PLAYBACK_RECORDED_VEHICLE(vehTruck)
ENDIF
fPlaybackSpeed = 0.4
ENDIF
ENDPROC
/// PURPOSE:
/// Loads the assets for the required mission stage.
PROC EXT3_LOAD_ASSETS_FOR_MISSION_STATE(EXT3_MISSION_STATE current_stage, BOOL b_wait_until_loaded = TRUE)
SWITCH current_stage
CASE stateIntro
REQUEST_ANIM_DICT("rcmextreme3")
BREAK
CASE stateJump
REQUEST_MODEL(modelTruck)
REQUEST_MODEL(modelDriver)
REQUEST_VEHICLE_RECORDING(500, "Ext3_Truck")
BREAK
CASE stateOutro
REQUEST_MODEL(modelTruck)
REQUEST_MODEL(modelDriver)
REQUEST_MODEL(modelSportsCar)
REQUEST_VEHICLE_RECORDING(500, "Ext3_Truck")
REQUEST_VEHICLE_RECORDING(501, "Ext3_Truck")
REQUEST_ANIM_DICT("rcmextreme3")
BREAK
ENDSWITCH
IF b_wait_until_loaded = TRUE
BOOL b_assets_loaded = FALSE
WHILE b_assets_loaded = FALSE
SWITCH current_stage
CASE stateIntro
IF HAS_ANIM_DICT_LOADED("rcmextreme3")
b_assets_loaded = TRUE
ENDIF
BREAK
CASE stateJump
IF HAS_MODEL_LOADED(modelTruck)
AND HAS_MODEL_LOADED(modelDriver)
AND HAS_VEHICLE_RECORDING_BEEN_LOADED(500, "Ext3_Truck")
SET_VEHICLE_MODEL_IS_SUPPRESSED(modelTruck, TRUE)
b_assets_loaded = TRUE
ENDIF
BREAK
CASE stateOutro
IF HAS_MODEL_LOADED(modelTruck)
AND HAS_MODEL_LOADED(modelDriver)
AND HAS_MODEL_LOADED(modelSportsCar)
AND HAS_VEHICLE_RECORDING_BEEN_LOADED(500, "Ext3_Truck")
AND HAS_VEHICLE_RECORDING_BEEN_LOADED(501, "Ext3_Truck")
AND HAS_ANIM_DICT_LOADED("rcmextreme3")
b_assets_loaded = TRUE
ENDIF
BREAK
ENDSWITCH
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Loading assets...") ENDIF #ENDIF
WAIT(0)
ENDWHILE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Assets loaded") ENDIF #ENDIF
ELSE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Assets requested for preload") ENDIF #ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Mission failed function.
PROC EXT3_MISSION_FAILED(FAILED_REASON reason)
IF bZSkipping = FALSE
failReason = reason
missionStateMachine = EXT3_STATE_MACHINE_CLEANUP
missionStateSkip = stateFailed
ENDIF
ENDPROC
PROC EXT3_UPDATE_PLAYBACK_SPEED(FLOAT f_desired_playback_speed, FLOAT f_step = 0.01)
IF f_desired_playback_speed > fPlaybackSpeed
fPlaybackSpeed += f_step
ELIF f_desired_playback_speed < fPlaybackSpeed
fPlaybackSpeed -= f_step
ENDIF
//#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: f_desired_playback_speed = ", f_desired_playback_speed, " fPlaybackSpeed = ", fPlaybackSpeed) ENDIF #ENDIF
ENDPROC
/// PURPOSE:
/// Ensures any cars in truck of the truck drive away.
PROC EXT3_MOVE_VEHICLES_AHEAD_OF_TRUCK()
IF IS_ENTITY_ALIVE(vehTruck)
AND IS_ENTITY_ALIVE(pedDriver)
VEHICLE_INDEX veh_random = GET_RANDOM_VEHICLE_IN_SPHERE(GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(vehTruck,<<0,10,0>>), 5.0, DUMMY_MODEL_FOR_SCRIPT, VEHICLE_SEARCH_FLAG_RETURN_RANDOM_VEHICLES)
IF IS_VEHICLE_OK(veh_random)
AND veh_random != vehTruck
PED_INDEX ped_random = GET_PED_IN_VEHICLE_SEAT(veh_random)
IF IS_ENTITY_ALIVE(ped_random)
AND NOT IsPedPerformingTask(ped_random, SCRIPT_TASK_SMART_FLEE_PED)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ped_random, TRUE)
SET_PED_FLEE_ATTRIBUTES(ped_random, FA_USE_VEHICLE, TRUE)
TASK_SMART_FLEE_PED(ped_random, pedDriver, 300, -1)
SET_PED_KEEP_TASK(ped_random, TRUE)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Set an ambient car to flee") ENDIF #ENDIF
ENDIF
SAFE_RELEASE_PED(ped_random)
ENDIF
SAFE_RELEASE_VEHICLE(veh_random)
ENDIF
ENDPROC
/// PURPOSE:
/// Fails mission if the truck is destroyed. Sets trucks to wander once finished playing vehicle recording.
PROC EXT3_MANAGE_TRUCK()
IF IS_ENTITY_ALIVE(vehTruck)
// Only for debug purposes to check for offsets
//VECTOR v_offset_from_truck = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(vehTruck, GET_ENTITY_COORDS(PLAYER_PED_ID()))
//#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Player offset = ", v_offset_from_truck) ENDIF #ENDIF
IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vehTruck)
IF GET_PED_PARACHUTE_STATE(PLAYER_PED_ID()) = PPS_SKYDIVING
OR GET_PED_PARACHUTE_STATE(PLAYER_PED_ID()) = PPS_DEPLOYING
OR GET_PED_PARACHUTE_STATE(PLAYER_PED_ID()) = PPS_PARACHUTING
// Calculate truck speed depending on player distance away from it
VECTOR v_offset_from_truck = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(vehTruck, GET_ENTITY_COORDS(PLAYER_PED_ID()))
FLOAT f_current_dist = GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), vehTruck)
FLOAT f_playback_initial_calc
FLOAT f_playback_pre_limits
FLOAT f_playback_final
IF v_offset_from_truck.z > 150
f_playback_final = PLAYBACK_SPEED_NORMAL
//#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: offset = ", v_offset_from_truck, " z is greater than 150 so f_playback_final = ", f_playback_final) ENDIF #ENDIF
ELSE
f_playback_initial_calc = ABSF(f_current_dist/100)
IF v_offset_from_truck.y > 0 // Player ahead of truck
f_playback_pre_limits = PLAYBACK_SPEED_NORMAL + f_playback_initial_calc + 0.2 // extra speed boost when ahead
ELSE
f_playback_pre_limits = PLAYBACK_SPEED_NORMAL - f_playback_initial_calc
ENDIF
IF f_playback_pre_limits < PLAYBACK_SPEED_SLOWEST
f_playback_final = PLAYBACK_SPEED_SLOWEST
ELIF f_playback_pre_limits > PLAYBACK_SPEED_FASTEST
f_playback_final = PLAYBACK_SPEED_FASTEST
ELSE
f_playback_final = f_playback_pre_limits
ENDIF
//#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: offset = ", v_offset_from_truck, " initial_calc = ", f_playback_initial_calc, " pre_limits = ", f_playback_pre_limits, " f_playback_final = ", f_playback_final) ENDIF #ENDIF
ENDIF
EXT3_UPDATE_PLAYBACK_SPEED(f_playback_final)
//ELSE
//EXT3_UPDATE_PLAYBACK_SPEED(PLAYBACK_SPEED_SLOWEST, 0.03) // Player has landed so ensure truck slows down // B*1553923 Don't alter speed when player has landed on it before being attached
ENDIF
SET_PLAYBACK_SPEED(vehTruck, fPlaybackSpeed)
ELSE
IF IS_ENTITY_ALIVE(pedDriver)
AND NOT IsPedPerformingTask(pedDriver, SCRIPT_TASK_VEHICLE_DRIVE_WANDER)
TASK_VEHICLE_DRIVE_WANDER(pedDriver, vehTruck, 30.0, DRIVINGMODE_AVOIDCARS)
ENDIF
ENDIF
ELSE
EXT3_MISSION_FAILED(FAIL_TRUCK_WRECKED)
ENDIF
ENDPROC
/// PURPOSE:
/// Create conversation if the parachutes collide.
PROC EXT3_MANAGE_COLLISION_CONVERSATION()
IF bZSkipping = FALSE
AND bStartedCollisionSpeech = FALSE
AND IS_ENTITY_ALIVE(PLAYER_PED_ID())
AND IS_ENTITY_ALIVE(pedDom)
AND GET_PED_PARACHUTE_STATE(PLAYER_PED_ID()) = PPS_SKYDIVING
AND GET_PED_PARACHUTE_STATE(pedDom) = PPS_SKYDIVING
AND GET_DISTANCE_BETWEEN_ENTITIES(pedDom, PLAYER_PED_ID()) < 3
AND CREATE_CONVERSATION(sSpeech, "EXT3AUD", "EXT_MESS", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Started EXT_MESS conversation") ENDIF #ENDIF
bStartedCollisionSpeech = TRUE
ENDIF
ENDPROC
/// PURPOSE:
/// Handles Dom's parachute jump.
PROC EXT3_MANAGE_DOM_PARACHUTE_JUMP()
IF IS_ENTITY_ALIVE(pedDom)
SWITCH eDomState
CASE DS_FREE_FALL
IF GET_PED_PARACHUTE_STATE(pedDom) = PPS_DEPLOYING
eDomState = DS_PARACHUTING
ENDIF
BREAK
CASE DS_PARACHUTING
IF EXT3_IS_PED_ON_GROUND(pedDom)
IF EXT3_IS_PED_WITHIN_TRUCK_AREA(pedDom)
EXT3_ATTACH_PED_TO_TRUCK(pedDom)
eDomState = DS_ATTACHED
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: eDomState = DS_ATTACHED") ENDIF #ENDIF
ELSE
eDomState = DS_MISSED_TRUCK
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: eDomState = DS_MISSED_TRUCK") ENDIF #ENDIF
CLEAR_PED_TASKS(pedDom)
IF IS_ENTITY_ALIVE(vehTruck)
TASK_GO_TO_ENTITY(pedDom, vehTruck)
ENDIF
ENDIF
ELSE // The truck is moving so we need to keep updating Dom's parachuting target, but only once per second
IF (GET_GAME_TIMER() - iDomUpdateTargetTimer) > 250
AND GET_PED_PARACHUTE_STATE(pedDom) = PPS_PARACHUTING
AND IS_ENTITY_ALIVE(vehTruck)
SET_PARACHUTE_TASK_TARGET(pedDom, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(vehTruck, <<0,5,1>>))
iDomUpdateTargetTimer = GET_GAME_TIMER()
ENDIF
EXT3_MANAGE_COLLISION_CONVERSATION()
ENDIF
BREAK
CASE DS_ATTACHED
BREAK
CASE DS_MISSED_TRUCK
BREAK
ENDSWITCH
IF IS_BULLET_IN_AREA(GET_ENTITY_COORDS(pedDom), 30, TRUE) // B*1469810 Fail mission if shooting at Dom while parachuting
EXT3_MISSION_FAILED(FAIL_DOM_SPOOKED)
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Handles displaying the hint camera and text for the truck.
PROC EXT3_MANAGE_TRUCK_FOCUS_CAMERA()
IF IS_ENTITY_ALIVE(vehTruck)
AND bDisplayedDeployParachuteHelpText = FALSE
IF GET_PED_PARACHUTE_STATE(PLAYER_PED_ID()) = PPS_DEPLOYING
bDisplayedDeployParachuteHelpText = TRUE
ENDIF
IF (GET_GAME_TIMER() - iDisplayParachuteHelpTimer) > 3000 // B*711660
PRINT_HELP_FOREVER("EXT3_03") // Press ~PAD_A~ to open your parachute.
bDisplayedDeployParachuteHelpText = TRUE
ENDIF
ELSE
IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("EXT3_03")
AND IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SPRINT)
CLEAR_HELP()
ENDIF
CONTROL_ENTITY_CHASE_HINT_CAM_ON_FOOT_WITH_OFFSET(localChaseHintCamStruct, vehTruck, <<0.0, 15.0, 0.0>>, "EXT3_04")
ENDIF
ENDPROC
/// PURPOSE:
/// Set up mission prior to going into any mission states.
PROC EXT3_MISSION_SETUP()
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Starting mission setup...") ENDIF #ENDIF
failReason = FAIL_DEFAULT
REQUEST_ADDITIONAL_TEXT("EXT3", MISSION_TEXT_SLOT)
WHILE NOT HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT)
WAIT(0)
ENDWHILE
modelTruck = FLATBED
modelDriver = S_M_Y_PILOT_01
modelSportsCar = BUFFALO
#IF IS_DEBUG_BUILD
mSkipMenu[Z_SKIP_INTRO].sTxtLabel = "Intro - es_3_rcm"
mSkipMenu[Z_SKIP_JUMP].sTxtLabel = "Base jump"
mSkipMenu[Z_SKIP_OUTRO_1].sTxtLabel = "Outro (Dom landed ok) - es_3_mcs_1"
mSkipMenu[Z_SKIP_OUTRO_2].sTxtLabel = "Outro (Dom didn't land ok) - es_3_mcs_2"
IF NOT DOES_WIDGET_GROUP_EXIST(widgetGroup)
widgetGroup = START_WIDGET_GROUP("Extreme 3 widgets")
ADD_WIDGET_BOOL("TTY Toggle - Print Mission Debug Info", bDebug_PrintToTTY)
STOP_WIDGET_GROUP()
ENDIF
#ENDIF
bHasChanged = GET_PLAYER_HAS_CHANGE_CLOTHES_ON_MISSION(CHAR_FRANKLIN) //ensure bChange is set to the state of "player has changed outfit" at the start of the mission
bChangedFranklinIntoOutfit = FALSE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Finished mission setup") ENDIF #ENDIF
ENDPROC
/// PURPOSE:
/// Ensure assets required for immediately after the intro mocap are preloaded for instant usage.
PROC EXT3_PRELOAD_ASSETS_FOR_AFTER_INTRO()
SET_PED_PRELOAD_VARIATION_DATA(PLAYER_PED_ID(), PED_COMP_SPECIAL, GET_PED_DRAWABLE_VARIATION(PLAYER_PED_ID(), PED_COMP_SPECIAL), GET_PED_TEXTURE_VARIATION(PLAYER_PED_ID(), PED_COMP_SPECIAL))
REQUEST_ANIM_DICT("rcmextreme3")
REQUEST_MODEL(GET_NPC_PED_MODEL(CHAR_DOM))
ENDPROC
/// PURPOSE:
/// Returns true if Dom landed ok on the truck.
FUNC BOOL IS_DOM_ON_TRUCK()
IF eDomState = DS_ATTACHED
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: IF IS_DOM_ON_TRUCK eDomState = DS_ATTACHED") ENDIF #ENDIF
RETURN TRUE
ENDIF
IF IS_ENTITY_ALIVE(pedDom)
IF EXT3_IS_PED_WITHIN_TRUCK_AREA(pedDom) // B*951196 - Do one last check in case Dom finished landing on truck during the fade to black
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: IF EXT3_IS_PED_WITHIN_TRUCK_AREA(pedDom) returned TRUE") ENDIF #ENDIF
RETURN TRUE
ENDIF
VECTOR v_offset_from_truck = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(vehTruck, GET_ENTITY_COORDS(pedDom))
IF v_offset_from_truck.y < 5 // Front bumper
AND v_offset_from_truck.y > -8 // Rear bumper
AND v_offset_from_truck.x < 1.7
AND v_offset_from_truck.x > -1.7
AND v_offset_from_truck.z < 4
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Dom within acceptable offsets above truck") ENDIF #ENDIF
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Create conversation after intro mocap has finished.
PROC EXT3_MANAGE_PRE_JUMP_CONVERSATION()
IF bZSkipping = FALSE
AND bStartedPreJumpSpeech = FALSE
AND CREATE_CONVERSATION(sSpeech, "EXT3AUD", "EXT_GEEUP", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Started EXT_GEEUP conversation") ENDIF #ENDIF
bStartedPreJumpSpeech = TRUE
ENDIF
ENDPROC
/// PURPOSE:
/// Create conversation during the skydive.
PROC EXT3_MANAGE_DURING_SKYDIVE_CONVERSATION()
IF bZSkipping = FALSE
AND bPlayerStartedJump = TRUE
IF bStartedDuringSkydiveSpeech = FALSE
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
AND CREATE_CONVERSATION(sSpeech, "EXT3AUD", "EXT_SKYDIVE", CONV_PRIORITY_HIGH, DO_NOT_DISPLAY_SUBTITLES)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Started EXT_SKYDIVE conversation") ENDIF #ENDIF
PRINT_NOW("EXT3_01", DEFAULT_GOD_TEXT_TIME, 1) // Parachute onto the ~b~truck.
IF IS_ENTITY_ALIVE(vehTruck)
blipTruck = CREATE_VEHICLE_BLIP(vehTruck)
ENDIF
bStartedDuringSkydiveSpeech = TRUE
ENDIF
ELIF bStoppedDuringSkydiveSpeech = FALSE
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
tStoredTricksConversationLabel = GET_STANDARD_CONVERSATION_LABEL_FOR_FUTURE_RESUMPTION()
IF ARE_STRINGS_EQUAL(tStoredTricksConversationLabel, "EXT_SKYDIVE_3")
KILL_FACE_TO_FACE_CONVERSATION()
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Stopped EXT_SKYDIVE conversation") ENDIF #ENDIF
bStoppedDuringSkydiveSpeech = TRUE
ENDIF
ENDIF
ELIF bRestartedDuringSkydiveSpeech = FALSE
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
AND CREATE_CONVERSATION_FROM_SPECIFIC_LINE(sSpeech, "EXT3AUD", "EXT_SKYDIVE", tStoredTricksConversationLabel, CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Restarted EXT_SKYDIVE conversation with subtitles") ENDIF #ENDIF
bRestartedDuringSkydiveSpeech = TRUE
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Create Franklin lands on truck conversation.
PROC EXT3_MANAGE_FRANKLIN_LANDS_CONVERSATION()
IF bZSkipping = FALSE
AND bStartedFranklinLandsSpeech = FALSE
AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
AND CREATE_CONVERSATION(sSpeech, "EXT3AUD", "EXT_COMM", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Started EXT_COMM conversation") ENDIF #ENDIF
bStartedFranklinLandsSpeech = TRUE
ENDIF
ENDPROC
/// PURPOSE:
/// Create conversation when Franklin and Dom are on the truck in the scripted cutscene.
PROC EXT3_MANAGE_ON_TRUCK_CONVERSATION()
IF bZSkipping = FALSE
IF bStartedDomLandsSpeech = FALSE
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
AND IS_ENTITY_ALIVE(pedDom)
AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
ADD_PED_FOR_DIALOGUE(sSpeech, 1, PLAYER_PED_ID(), "FRANKLIN")
ADD_PED_FOR_DIALOGUE(sSpeech, 3, pedDom, "DOM")
IF GET_PED_PARACHUTE_STATE(pedDom) = PPS_INVALID // Dom has finished parachuting...
AND NOT IS_DOM_ON_TRUCK() // ...and isn't on the truck
IF CREATE_CONVERSATION(sSpeech, "EXT3AUD", "EXT_NTRUCK", CONV_PRIORITY_HIGH) // "Looks like you're walking, man."
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Started EXT_NTRUCK conversation") ENDIF #ENDIF
bStartedDomLandsSpeech = TRUE
ENDIF
ELSE
IF CREATE_CONVERSATION(sSpeech, "EXT3AUD", "EXT_YTRUCK", CONV_PRIORITY_HIGH) // "Whoa! Captain Conservative actually jumped! Figured you'd take the elevator!"
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Started EXT_YTRUCK conversation") ENDIF #ENDIF
bStartedDomLandsSpeech = TRUE
ENDIF
ENDIF
ENDIF
ELIF bStartedDriverSpeech = FALSE
IF IS_ENTITY_ALIVE(pedDom)
AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF GET_PED_PARACHUTE_STATE(pedDom) = PPS_INVALID // Dom has finished parachuting...
AND IS_DOM_ON_TRUCK() // ...and is on the truck
IF CREATE_CONVERSATION(sSpeech, "EXT3AUD", "EXT_LAND", CONV_PRIORITY_HIGH) // "Dudes, that was insane! Hey Franklin, it's me, Jeff! I'm gonna drop you at that garage on Elgin, okay, Dom?"
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Started EXT_LAND conversation") ENDIF #ENDIF
bStartedDriverSpeech = TRUE
ENDIF
ELSE
IF CREATE_CONVERSATION(sSpeech, "EXT3AUD", "EXT_LAND2", CONV_PRIORITY_HIGH) // "Dude! It's me, Jeff! No way, the Dominator didn't make it!? I'm gonna drop you at the rendezvous spot, okay?"
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Started EXT_LAND2 conversation") ENDIF #ENDIF
bStartedDriverSpeech = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Checks the player doesn't leave the mission area.
PROC EXT3_MANAGE_PLAYER_LEAVING_MISSION_AREA()
IF IS_ENTITY_ALIVE(vehTruck)
IF NOT IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), vehTruck, <<350,350,350>>, FALSE, FALSE)
EXT3_MISSION_FAILED(FAIL_DIDNT_LAND_ON_TRUCK)
ELIF bGivenMissionAreaWarning = FALSE
IF NOT IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), vehTruck, <<200,200,200>>, FALSE, FALSE)
bGivenMissionAreaWarning = TRUE
PRINT_NOW("EXT3_02", DEFAULT_GOD_TEXT_TIME, 1) // You are leaving the mission area. Parachute onto the ~b~truck.
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Starts Dom jumping off the building.
PROC EXT3_START_DOM_JUMP()
IF IS_ENTITY_ALIVE(pedDom)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Starting Dom's jump") ENDIF #ENDIF
OPEN_SEQUENCE_TASK(seqDomJump)
TASK_PLAY_ANIM(NULL, "rcmextreme3", "jump_fall", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_NOT_INTERRUPTABLE)
TASK_PARACHUTE_TO_TARGET(NULL, << 30.3356, -795.6482, 44.2600 >>) // Truck's spawn vec
CLOSE_SEQUENCE_TASK(seqDomJump)
TASK_PERFORM_SEQUENCE(pedDom, seqDomJump)
CLEAR_SEQUENCE_TASK(seqDomJump)
REPLAY_RECORD_BACK_FOR_TIME(3.0, 5.0, REPLAY_IMPORTANCE_LOW)
ENDIF
ENDPROC
/// PURPOSE:
/// Sets up Dom ready to jump off the building.
PROC EXT3_SETUP_DOM_FOR_JUMP()
IF NOT IS_ENTITY_ALIVE(pedDom)
WHILE NOT RC_CREATE_NPC_PED(pedDom, CHAR_DOM, vDomJumpPos, fDomJumpHeading, "EXTREME LAUNCHER RC")
WAIT(0)
ENDWHILE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Dom didn't exist so created him") ENDIF #ENDIF
ENDIF
IF IS_ENTITY_ALIVE(pedDom)
SAFE_TELEPORT_ENTITY(pedDom, vDomJumpPos, fDomJumpHeading)
REQUEST_ANIM_DICT("rcmextreme3") // Has been preloaded
IF HAS_ANIM_DICT_LOADED("rcmextreme3")
TASK_PLAY_ANIM(pedDom, "rcmextreme3", "idle_frantic", INSTANT_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_LOOPING|AF_NOT_INTERRUPTABLE)
ENDIF
FORCE_PED_AI_AND_ANIMATION_UPDATE(pedDom)
ADD_PED_FOR_DIALOGUE(sSpeech, 3, pedDom, "DOM")
SET_PED_CAN_RAGDOLL_FROM_PLAYER_IMPACT(pedDom, FALSE)
SET_ENTITY_LOAD_COLLISION_FLAG(pedDom, TRUE)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(pedDom, TRUE)
GIVE_WEAPON_TO_PED(pedDom, GADGETTYPE_PARACHUTE, 1, FALSE, FALSE)
SET_PED_PARACHUTE_TINT_INDEX(pedDom, 6) // Black
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(pedDom, TRUE)
SET_ENTITY_PROOFS(pedDom, FALSE, FALSE, FALSE, TRUE, FALSE)
SET_PED_COMPONENT_VARIATION(pedDom, INT_TO_ENUM(PED_COMPONENT,8), 1, 0, 0)
eDomState = DS_FREE_FALL
ENDIF
ENDPROC
/// PURPOSE:
/// Sets up Franklin ready to jump off the building.
PROC EXT3_SETUP_FRANKLIN_FOR_JUMP()
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), vPlayerJumpPos, fPlayerJumpHeading)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
REQUEST_ANIM_DICT("rcmextreme3") // Has been preloaded
IF HAS_ANIM_DICT_LOADED("rcmextreme3")
TASK_PLAY_ANIM(PLAYER_PED_ID(), "rcmextreme3", "idle_frantic", INSTANT_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_LOOPING|AF_NOT_INTERRUPTABLE)
ENDIF
FORCE_PED_AI_AND_ANIMATION_UPDATE(PLAYER_PED_ID())
ADD_PED_FOR_DIALOGUE(sSpeech, 1, PLAYER_PED_ID(), "FRANKLIN")
DISABLE_CELLPHONE(TRUE)
SET_FRONTEND_RADIO_ACTIVE(FALSE)
ENDPROC
/// PURPOSE:
/// Handles debug skipping.
/// PARAMS:
/// i_new_state - The state to debug skip to.
PROC EXT3_DEBUG_SKIP_STATE(INT i_new_state)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Starting debug skip to ", i_new_state, "...") ENDIF #ENDIF
RC_START_Z_SKIP()
bZSkipping = TRUE
EXT3_SET_FRANKLIN_INTO_SKYDIVING_OUTFIT(FALSE)
EXT3_MISSION_CLEANUP(TRUE)
SWITCH i_new_state
CASE Z_SKIP_INTRO
missionStateSkip = stateIntro
BREAK
CASE Z_SKIP_JUMP
EXT3_PRELOAD_ASSETS_FOR_AFTER_INTRO()
EXT3_LOAD_ASSETS_FOR_MISSION_STATE(stateIntro)
EXT3_SET_FRANKLIN_INTO_SKYDIVING_OUTFIT(TRUE)
EXT3_SETUP_FRANKLIN_FOR_JUMP()
EXT3_SETUP_DOM_FOR_JUMP()
missionStateSkip = stateJump
IF NOT IS_REPLAY_BEING_SET_UP()
WAIT_FOR_WORLD_TO_LOAD(GET_ENTITY_COORDS(PLAYER_PED_ID()))
ENDIF
TRIGGER_MUSIC_EVENT("EXTREME3_RESTART1")
BREAK
CASE Z_SKIP_OUTRO_1
EXT3_LOAD_ASSETS_FOR_MISSION_STATE(stateOutro)
eDomState = DS_ATTACHED
EXT3_CREATE_TRUCK(TRUE)
missionStateSkip = stateOutro
BREAK
CASE Z_SKIP_OUTRO_2
EXT3_LOAD_ASSETS_FOR_MISSION_STATE(stateOutro)
eDomState = DS_MISSED_TRUCK
EXT3_CREATE_TRUCK(TRUE)
missionStateSkip = stateOutro
BREAK
ENDSWITCH
IF NOT IS_REPLAY_BEING_SET_UP()
WAIT_FOR_WORLD_TO_LOAD(GET_ENTITY_COORDS(PLAYER_PED_ID()), 100)
ENDIF
END_REPLAY_SETUP()
IF i_new_state = Z_SKIP_OUTRO_1
OR i_new_state = Z_SKIP_OUTRO_2
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
CLEAR_AREA(GET_ENTITY_COORDS(PLAYER_PED_ID()), 100, TRUE)
IF IS_ENTITY_ALIVE(vehTruck)
ATTACH_ENTITY_TO_ENTITY(PLAYER_PED_ID(), vehTruck, 0, vFranklinAttachedToTruckPos, vFranklinAttachedToTruckRot)
ENDIF
ENDIF
ENDIF
IF i_new_state = Z_SKIP_JUMP
EXT3_SETUP_FRANKLIN_FOR_JUMP() // Need to do this after the replay stuff has finished warping the player
ENDIF
RC_END_Z_SKIP(TRUE, FALSE)
missionStateMachine = EXT3_STATE_MACHINE_CLEANUP
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Finished debug skip to ", i_new_state) ENDIF #ENDIF
ENDPROC
/// PURPOSE:
/// Fails mission if the player jumps off prior to the intro. See B*1532863.
FUNC BOOL EXT3_HAS_PLAYER_JUMPED_OFF()
IF iCutsceneStage < 3 // Only check before the cutscene has started
AND IS_ENTITY_ALIVE(PLAYER_PED_ID())
VECTOR v_player_coords = GET_ENTITY_COORDS(PLAYER_PED_ID())
IF v_player_coords.z < 320.0
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Setup Dom for cutscene.
PROC EXT3_SETUP_DOM_CUTSCENE_VARIATIONS()
IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY()
#IF IS_DEBUG_BUILD CPRINTLN(DEBUG_MISSION, "EXTREME3: CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY is TRUE") #ENDIF
IF IS_ENTITY_ALIVE(sRCLauncherDataLocal.pedID[0])
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Dom", sRCLauncherDataLocal.pedID[0])
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Set cutscene variations for sRCLauncherDataLocal.pedID[0] in cutscene") ENDIF #ENDIF
ELIF IS_ENTITY_ALIVE(pedDom)
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Dom", pedDom)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Set cutscene variations for pedDom in cutscene") ENDIF #ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Plays the intro of the player meeting Dom.
PROC MS_INTRO()
EXT3_SETUP_DOM_CUTSCENE_VARIATIONS()
SWITCH missionStateMachine
CASE EXT3_STATE_MACHINE_SETUP
EXT3_STATE_SETUP(#IF IS_DEBUG_BUILD "MS_INTRO" #ENDIF)
RC_REQUEST_CUTSCENE("es_3_rcm", TRUE)
iCutsceneStage = 0
BREAK
CASE EXT3_STATE_MACHINE_LOOP
IF EXT3_HAS_PLAYER_JUMPED_OFF()
EXT3_MISSION_FAILED(FAIL_JUMPED_OFF_BEFORE_INTRO)
ELSE
SWITCH iCutsceneStage
CASE 0
RC_PLAYER_TRIGGER_SCENE_LOCK_IN()
IF IS_ENTITY_ALIVE(sRCLauncherDataLocal.pedID[0])
REQUEST_ANIM_DICT("rcmextreme3")
IF HAS_ANIM_DICT_LOADED("rcmextreme3")
ADD_PED_FOR_DIALOGUE(sSpeech, 0, sRCLauncherDataLocal.pedID[0], "DOM")
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
AND CREATE_CONVERSATION(sSpeech, "EXT3AUD", "EXT3_RCM_LI2", CONV_PRIORITY_HIGH)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Started EXT3_RCM_LI2 conversation") ENDIF #ENDIF
TASK_PLAY_ANIM(sRCLauncherDataLocal.pedID[0], "rcmextreme3", "fidget_02", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_LOOPING) // Not using 'leadin' anim from this dict cos it doesn't match 'idle_calm' used by the launcher
iCutsceneStage++
ENDIF
ENDIF
ELSE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Launcher ped Dom doesn't exist so not doing leadin") ENDIF #ENDIF
iCutsceneStage = 2
ENDIF
BREAK
CASE 1
RC_PLAYER_TRIGGER_SCENE_LOCK_IN()
IF NOT IS_ENTITY_ALIVE(sRCLauncherDataLocal.pedID[0])
OR NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
OR GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), sRCLauncherDataLocal.pedID[0]) < 1.5
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() // B*1284039 - Kill the leadin conversation if player got very near to Dom
REMOVE_PED_FOR_DIALOGUE(sSpeech, 0)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Done leadin") ENDIF #ENDIF
iCutsceneStage++
ENDIF
BREAK
CASE 2
RC_PLAYER_TRIGGER_SCENE_LOCK_IN()
IF RC_IS_CUTSCENE_OK_TO_START()
IF IS_ENTITY_ALIVE(sRCLauncherDataLocal.pedID[0])
pedDom = sRCLauncherDataLocal.pedID[0]
SET_ENTITY_AS_MISSION_ENTITY(pedDom, TRUE, TRUE)
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, "EXTREME3: CU_ANIMATE_EXISTING_SCRIPT_ENTITY Dom") ENDIF #ENDIF
ELSE
REGISTER_ENTITY_FOR_CUTSCENE(pedDom, "Dom", CU_CREATE_AND_ANIMATE_NEW_SCRIPT_ENTITY, GET_NPC_PED_MODEL(CHAR_DOM))
ENDIF
RC_CLEANUP_LAUNCHER() // Cleanup launcher to remove lead-in blip
START_CUTSCENE()
REPLAY_START_EVENT(REPLAY_IMPORTANCE_LOW)
SET_CUTSCENE_FADE_VALUES(FALSE, FALSE, FALSE, FALSE)
iCutsceneStage++
ENDIF
BREAK
CASE 3
IF IS_CUTSCENE_PLAYING()
RESOLVE_VEHICLES_INSIDE_ANGLED_AREA(<<-63.858517,-811.770081,320.242645>>, <<-66.118721,-809.212463,324.242676>>, 5.000000, vPlayerCarRespot, fPlayerCarRespot)
SET_MISSION_START_VEHICLE_AS_VEHICLE_GEN(vPlayerCarRespot, fPlayerCarRespot)
RC_START_CUTSCENE_MODE(<<-68.69, -810.56, 325.35>>)
SAFE_FADE_SCREEN_IN_FROM_BLACK(500, FALSE) // Just in case screen is faded out
EXT3_PRELOAD_ASSETS_FOR_AFTER_INTRO()
iCutsceneStage++
ENDIF
BREAK
CASE 4
IF IS_CUTSCENE_PLAYING()
IF bChangedFranklinIntoOutfit = FALSE
AND GET_CUTSCENE_TIME() > 5500 // B*1308289 - Set Franklin into his skydiving outfit when offscreen
EXT3_SET_FRANKLIN_INTO_SKYDIVING_OUTFIT(TRUE)
ENDIF
IF NOT DOES_ENTITY_EXIST(pedDom)
AND DOES_ENTITY_EXIST(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY("Dom"))
pedDom = GET_PED_INDEX_FROM_ENTITY_INDEX(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY("Dom"))
SET_ENTITY_AS_MISSION_ENTITY(pedDom, TRUE, TRUE)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Grabbed pedDom from Dom") ENDIF #ENDIF
ENDIF
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
AND CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Franklin")
EXT3_SETUP_FRANKLIN_FOR_JUMP()
ENDIF
IF IS_ENTITY_ALIVE(pedDom)
AND CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Dom")
EXT3_SETUP_DOM_FOR_JUMP()
ENDIF
ELSE
EXT3_SET_FRANKLIN_INTO_SKYDIVING_OUTFIT(TRUE) // Call again here in case player skipped cutscene
RC_END_CUTSCENE_MODE()
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: IS_CUTSCENE_PLAYING returned false") ENDIF #ENDIF
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_BASE_JUMP, "Base jump")
missionStateMachine = EXT3_STATE_MACHINE_CLEANUP
ENDIF
BREAK
ENDSWITCH
ENDIF
BREAK
CASE EXT3_STATE_MACHINE_CLEANUP
REPLAY_STOP_EVENT()
EXT3_STATE_CLEANUP(#IF IS_DEBUG_BUILD "MS_INTRO" #ENDIF)
RC_SET_ENTITY_PROOFS_FOR_CUTSCENE(sRCLauncherDataLocal, FALSE)
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Waits for the player to jump.
PROC MS_JUMP()
SWITCH missionStateMachine
CASE EXT3_STATE_MACHINE_SETUP
EXT3_STATE_SETUP(#IF IS_DEBUG_BUILD "MS_JUMP" #ENDIF)
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE, SPC_LEAVE_CAMERA_CONTROL_ON)
IF GET_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_SPECIAL) != SPECIAL_P1_PARACHUTE
SET_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_SPECIAL, SPECIAL_P1_PARACHUTE, FALSE)
SET_PED_PARACHUTE_TINT_INDEX(PLAYER_PED_ID(), 1)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Player didn't have parachute backpack visible so set this onto him again") ENDIF #ENDIF
ENDIF
EXT3_LOAD_ASSETS_FOR_MISSION_STATE(stateJump)
EXT3_START_DOM_JUMP()
EXT3_CREATE_TRUCK(FALSE)
bStartedPreJumpSpeech = FALSE
bStartedDuringSkydiveSpeech = FALSE
bStoppedDuringSkydiveSpeech = FALSE
bRestartedDuringSkydiveSpeech = FALSE
iDomUpdateTargetTimer = GET_GAME_TIMER()
iPlayerDelayJumpTimer = GET_GAME_TIMER()
bPlayerPressedSquare = FALSE
bPlayerStartedJump = FALSE
typePlayerLanding = PPLT_INVALID
SAFE_FADE_SCREEN_IN_FROM_BLACK(500, FALSE) // Just in case screen is faded out
BREAK
CASE EXT3_STATE_MACHINE_LOOP
EXT3_MANAGE_DOM_PARACHUTE_JUMP()
EXT3_MANAGE_PRE_JUMP_CONVERSATION()
EXT3_MANAGE_DURING_SKYDIVE_CONVERSATION()
IF GET_PED_PARACHUTE_STATE(PLAYER_PED_ID()) = PPS_SKYDIVING
missionStateMachine = EXT3_STATE_MACHINE_CLEANUP
ELIF bPlayerStartedJump = FALSE
IF (GET_GAME_TIMER() - iPlayerDelayJumpTimer) > 60000
EXT3_MISSION_FAILED(FAIL_DIDNT_ATTEMPT_JUMP)
ELSE
IF NOT IS_HELP_MESSAGE_BEING_DISPLAYED()
AND IS_SCREEN_FADED_IN()
PRINT_HELP_FOREVER("EXT3_05") // Use ~INPUTGROUP_LOOK~ to look and press ~INPUT_JUMP~ to jump.
ENDIF
IF bPlayerPressedSquare = FALSE // Franklin has a 1 second jump delay after the mocap ends, but this allows us to store if the player has pressed square during this period
AND IS_CONTROL_PRESSED(FRONTEND_CONTROL, INPUT_JUMP)
bPlayerPressedSquare = TRUE
KILL_FACE_TO_FACE_CONVERSATION()
ENDIF
IF bPlayerPressedSquare = TRUE
AND (GET_GAME_TIMER() - iPlayerDelayJumpTimer) > 1000
REPLAY_RECORD_BACK_FOR_TIME(3.0)
IF NOT Is_Replay_In_Progress()
TRIGGER_MUSIC_EVENT("EXTREME3_START")
ENDIF
OPEN_SEQUENCE_TASK(seqFranklinJump)
TASK_PLAY_ANIM(NULL, "rcmextreme3", "jump_fall", SLOW_BLEND_IN, WALK_BLEND_OUT, -1, AF_NOT_INTERRUPTABLE)
TASK_FORCE_MOTION_STATE(NULL, ENUM_TO_INT(MS_PARACHUTING))
TASK_PARACHUTE(NULL, FALSE)
CLOSE_SEQUENCE_TASK(seqFranklinJump)
TASK_PERFORM_SEQUENCE(PLAYER_PED_ID(), seqFranklinJump)
CLEAR_SEQUENCE_TASK(seqFranklinJump)
IF IS_ENTITY_ALIVE(vehTruck)
SKIP_TIME_IN_PLAYBACK_RECORDED_VEHICLE(vehTruck, 3000)
UNPAUSE_PLAYBACK_RECORDED_VEHICLE(vehTruck)
ENDIF
CLEAR_HELP()
INFORM_MISSION_STATS_SYSTEM_OF_TIME_WINDOW_OPEN(EXT3_DARE_DEVIL,TRUE)
bPlayerStartedJump = TRUE
ENDIF
ENDIF
ENDIF
BREAK
CASE EXT3_STATE_MACHINE_CLEANUP
REPLAY_RECORD_BACK_FOR_TIME(4.0, 20.0, REPLAY_IMPORTANCE_LOW)
EXT3_STATE_CLEANUP(#IF IS_DEBUG_BUILD "MS_JUMP" #ENDIF)
REMOVE_ANIM_DICT("rcmextreme3")
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// The player has jumped and is attempting to land near the meeting point.
PROC MS_PARACHUTE()
SWITCH missionStateMachine
CASE EXT3_STATE_MACHINE_SETUP
EXT3_STATE_SETUP(#IF IS_DEBUG_BUILD "MS_PARACHUTE" #ENDIF)
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
bDisplayedDeployParachuteHelpText = FALSE
bGivenMissionAreaWarning = FALSE
iDisplayParachuteHelpTimer = GET_GAME_TIMER()
iPlayerLandedTimer = -1
bOpenedTimeWindowForSkydiveStat = TRUE
bStartedFranklinLandsSpeech = FALSE
bStartedDomLandsSpeech = FALSE
bStartedDriverSpeech = FALSE
bStartedCollisionSpeech = FALSE
BREAK
CASE EXT3_STATE_MACHINE_LOOP
EXT3_MANAGE_DOM_PARACHUTE_JUMP()
EXT3_MANAGE_TRUCK()
EXT3_MOVE_VEHICLES_AHEAD_OF_TRUCK()
EXT3_MANAGE_TRUCK_FOCUS_CAMERA()
IF iPlayerLandedTimer = -1 // Player hasn't yet landed on something (the truck, the ground, whatever..)
IF EXT3_IS_PED_ON_GROUND(PLAYER_PED_ID())
iPlayerLandedTimer = GET_GAME_TIMER()
KILL_FACE_TO_FACE_CONVERSATION()
IF typePlayerLanding = PPLT_SLOW
OR typePlayerLanding = PPLT_REGULAR
INFORM_STAT_SYSTEM_OF_BOOL_STAT_HAPPENED(EXT3_PERFECT_LANDING)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Achieved stat: EXT3_PERFECT_LANDING") ENDIF #ENDIF
ENDIF
ELSE
EXT3_MANAGE_PLAYER_LEAVING_MISSION_AREA()
EXT3_MANAGE_DURING_SKYDIVE_CONVERSATION()
IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("EXT3_03")
AND GET_PED_PARACHUTE_STATE(PLAYER_PED_ID()) = PPS_DEPLOYING
CLEAR_HELP()
ENDIF
IF bOpenedTimeWindowForSkydiveStat = TRUE
AND GET_PED_PARACHUTE_STATE(PLAYER_PED_ID()) = PPS_DEPLOYING
INFORM_MISSION_STATS_SYSTEM_OF_TIME_WINDOW_CLOSED()
bOpenedTimeWindowForSkydiveStat = FALSE
ENDIF
ENDIF
ELSE
IF bStartedFranklinLandsSpeech = FALSE
IF EXT3_IS_PED_WITHIN_TRUCK_AREA(PLAYER_PED_ID())
IF IS_PLAYER_SCRIPT_CONTROL_ON(PLAYER_ID())
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Player is within truck area - removing player control and attaching") ENDIF #ENDIF
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE, SPC_LEAVE_CAMERA_CONTROL_ON)
EXT3_ATTACH_PED_TO_TRUCK(PLAYER_PED_ID())
REPLAY_RECORD_BACK_FOR_TIME(5.0)
EXT3_LOAD_ASSETS_FOR_MISSION_STATE(stateOutro, FALSE)
ENDIF
EXT3_MANAGE_FRANKLIN_LANDS_CONVERSATION()
IF IS_ENTITY_ALIVE(pedDom)
SET_ENTITY_INVINCIBLE(pedDom, TRUE) // B*1571664 Ensure Dom can't die when landing
ENDIF
ELIF (GET_GAME_TIMER() - iPlayerLandedTimer) > 1000
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: More than 1000ms have elapsed since player landed and EXT3_IS_PED_WITHIN_TRUCK_AREA is returning false") ENDIF #ENDIF
EXT3_MISSION_FAILED(FAIL_DIDNT_LAND_ON_TRUCK)
ENDIF
ELIF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
TRIGGER_MUSIC_EVENT("EXTREME3_STOP")
missionStateMachine = EXT3_STATE_MACHINE_CLEANUP
ENDIF
ENDIF
BREAK
CASE EXT3_STATE_MACHINE_CLEANUP
REPLAY_RECORD_BACK_FOR_TIME(15.0, 3.5, REPLAY_IMPORTANCE_LOW)
EXT3_STATE_CLEANUP(#IF IS_DEBUG_BUILD "MS_PARACHUTE" #ENDIF)
SAFE_REMOVE_BLIP(blipTruck)
KILL_CHASE_HINT_CAM(localChaseHintCamStruct)
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Plays outro cutscene.
PROC MS_OUTRO()
IF IS_ENTITY_ALIVE(vehSportsCar)
REQUEST_VEHICLE_HIGH_DETAIL_MODEL(vehSportsCar) // B*1552422 Ensure car doesn't change to its low LOD model
IF IS_VEHICLE_HIGH_DETAIL(vehSportsCar)
SET_FORCE_HD_VEHICLE(vehSportsCar, TRUE)
ENDIF
ENDIF
// Ease load on the streaming
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.25)
SET_RANDOM_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.25)
SET_PARKED_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.25)
SET_PED_DENSITY_MULTIPLIER_THIS_FRAME(0.25)
SET_SCENARIO_PED_DENSITY_MULTIPLIER_THIS_FRAME(0.25, 0.25)
SWITCH missionStateMachine
CASE EXT3_STATE_MACHINE_SETUP
EXT3_STATE_SETUP(#IF IS_DEBUG_BUILD "MS_OUTRO" #ENDIF)
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_OUTRO, "Outro", TRUE)
iCutsceneStage = 0
bHasSetExitStateFromOutroMocapForGameplayCam = FALSE
EXT3_LOAD_ASSETS_FOR_MISSION_STATE(stateOutro)
IF HAS_PED_GOT_WEAPON(PLAYER_PED_ID(), GADGETTYPE_PARACHUTE)
REMOVE_WEAPON_FROM_PED(PLAYER_PED_ID(), GADGETTYPE_PARACHUTE)
ENDIF
bPreloadingOutroMocap = FALSE
iCutsceneFailsafeTimer = GET_GAME_TIMER()
BREAK
CASE EXT3_STATE_MACHINE_LOOP
OVERRIDE_LODSCALE_THIS_FRAME(1.0)
SWITCH iCutsceneStage
CASE 0
EXT3_MOVE_VEHICLES_AHEAD_OF_TRUCK()
EXT3_MANAGE_ON_TRUCK_CONVERSATION()
EXT3_MANAGE_DOM_PARACHUTE_JUMP()
IF IS_ENTITY_ALIVE(vehTruck)
IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vehTruck)
SET_PLAYBACK_SPEED(vehTruck, PLAYBACK_SPEED_NORMAL) // Maintain last playback speed during the scripted cutscene on the truck
ENDIF
IF NOT DOES_CAM_EXIST(camCutscene)
camCutscene = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", TRUE)
ATTACH_CAM_TO_ENTITY(camCutscene, vehTruck, <<-4.7308, 20.6208, 6.3419>>)
POINT_CAM_AT_ENTITY(camCutscene, vehTruck, <<-4.0898, 17.7773, 5.6320>>)
SET_CAM_FOV(camCutscene, 33.4911)
SHAKE_CAM(camCutscene, "HAND_SHAKE", 0.5)
RC_START_CUTSCENE_MODE(<<0.0,0.0,0.0>>)
REPLAY_START_EVENT(REPLAY_IMPORTANCE_LOW)
RENDER_SCRIPT_CAMS(TRUE, FALSE)
IF NOT DOES_CAM_EXIST(camInterp)
camInterp = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE)
ATTACH_CAM_TO_ENTITY(camInterp, vehTruck, <<-12.5501, -4.3722, 5.6236>>)
POINT_CAM_AT_ENTITY(camInterp, vehTruck, <<-9.8242, -3.8605, 4.4802>>)
SET_CAM_ACTIVE_WITH_INTERP(camInterp, camCutscene, 15000)
ENDIF
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Created camCutscene for scripted shot 1") ENDIF #ENDIF
CLEAR_AREA_OF_VEHICLES(GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(vehTruck, <<0, 50, 0>>), 50) // B*1921258 - Clear area ahead of the truck
// Reattach Franklin and Dom at nice positions near the middle of the truck in case they landed at the edges or facing odd directions
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
IF IS_ENTITY_ATTACHED_TO_ENTITY(PLAYER_PED_ID(), vehTruck)
DETACH_ENTITY(PLAYER_PED_ID(), FALSE, FALSE)
ENDIF
ATTACH_ENTITY_TO_ENTITY(PLAYER_PED_ID(), vehTruck, 0, vFranklinAttachedToTruckPos, vFranklinAttachedToTruckRot)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Reattached Franklin") ENDIF #ENDIF
ENDIF
IF IS_ENTITY_ALIVE(pedDom)
AND IS_ENTITY_ATTACHED_TO_ENTITY(pedDom, vehTruck)
DETACH_ENTITY(pedDom, FALSE, FALSE)
ATTACH_ENTITY_TO_ENTITY(pedDom, vehTruck, 0, vDomAttachedToTruckPos, vDomAttachedToTruckRot)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Reattached Dom") ENDIF #ENDIF
ENDIF
IF NOT STREAMVOL_IS_VALID(streamVolumeExtreme3)
streamVolumeExtreme3 = STREAMVOL_CREATE_SPHERE(<< 516.2540, -163.8118, 57.1199 >>, 50.0, FLAG_MAPDATA)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Created streaming volume") ENDIF #ENDIF
ENDIF
ENDIF
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
AND NOT IsPedPerformingTask(PLAYER_PED_ID(), SCRIPT_TASK_PLAY_ANIM)
TASK_PLAY_ANIM(PLAYER_PED_ID(), "rcmextreme3", "idle", INSTANT_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_NOT_INTERRUPTABLE|AF_LOOPING)
//SET_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_SPECIAL, SPECIAL_P1_PARACHUTE, FALSE) // B*1854764 Prevent dupe parachutes
FORCE_PED_AI_AND_ANIMATION_UPDATE(PLAYER_PED_ID())
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Playing crouched anim on Franklin") ENDIF #ENDIF
ENDIF
IF IS_ENTITY_ALIVE(pedDom)
AND NOT IsPedPerformingTask(pedDom, SCRIPT_TASK_PLAY_ANIM)
AND IS_ENTITY_ATTACHED_TO_ENTITY(pedDom, vehTruck)
TASK_PLAY_ANIM(pedDom, "rcmextreme3", "idle", INSTANT_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_NOT_INTERRUPTABLE|AF_LOOPING, 0.5)
FORCE_PED_AI_AND_ANIMATION_UPDATE(pedDom)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Playing crouched anim on Dom") ENDIF #ENDIF
ENDIF
SAFE_FADE_SCREEN_IN_FROM_BLACK(500, FALSE) // Just in case screen is faded out
//IF IS_CUTSCENE_SKIP_BUTTON_JUST_PRESSED_WITH_DELAY() // B*1590205 Prevent player skipping initial scripted shot while dialogue is ongoing
IF (bStartedDriverSpeech = TRUE AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED())
OR (GET_GAME_TIMER() - iCutsceneFailsafeTimer) > 15000
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: EXT_LAND conversation finished") ENDIF #ENDIF
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
IF eDomState != DS_ATTACHED
AND IS_DOM_ON_TRUCK() // B*951196 - Do one last check in case Dom finished landing on truck
eDomState = DS_ATTACHED
ENDIF
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Created camCutscene for scripted shot 2") ENDIF #ENDIF
IF IS_ENTITY_ALIVE(vehTruck)
IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vehTruck)
STOP_PLAYBACK_RECORDED_VEHICLE(vehTruck)
ENDIF
START_PLAYBACK_RECORDED_VEHICLE(vehTruck, 501, "Ext3_Truck")
SKIP_TIME_IN_PLAYBACK_RECORDED_VEHICLE(vehTruck, OUTRO_TRUCK_PLAYBACK_SKIP_TIME)
FORCE_ENTITY_AI_AND_ANIMATION_UPDATE(vehTruck)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Started Ext3_Truck501 on vehTruck") ENDIF #ENDIF
ENDIF
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
FORCE_PED_AI_AND_ANIMATION_UPDATE(PLAYER_PED_ID())
ENDIF
IF DOES_CAM_EXIST(camCutscene)
DESTROY_CAM(camCutscene)
ENDIF
IF DOES_CAM_EXIST(camInterp)
DESTROY_CAM(camInterp)
ENDIF
camCutscene = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", TRUE)
SET_CAM_PARAMS(camCutscene, <<516.2540, -163.8118, 57.1199>>, <<1.5934, -0.0000, -123.5450>>, 41.3162, 0, GRAPH_TYPE_LINEAR, GRAPH_TYPE_LINEAR)
SET_CAM_PARAMS(camCutscene, <<515.1053, -167.2159, 57.1385>>, <<0.5677, -0.0000, -116.9788>>, 41.3162, 7000, GRAPH_TYPE_LINEAR, GRAPH_TYPE_LINEAR)
SHAKE_CAM(camCutscene, "HAND_SHAKE", 0.5)
EXT3_SET_FRANKLIN_INTO_SKYDIVING_OUTFIT(FALSE)
IF IS_ENTITY_ALIVE(pedDom)
IF eDomState = DS_ATTACHED
AND IS_ENTITY_ALIVE(vehTruck)
//AND NOT IS_ENTITY_ATTACHED_TO_ENTITY(pedDom, vehTruck) // B*1958304 Commented out to ensure Dom is attached if he should be attached
CLEAR_PED_TASKS_IMMEDIATELY(pedDom)
ATTACH_ENTITY_TO_ENTITY(pedDom, vehTruck, 0, vDomAttachedToTruckPos, vDomAttachedToTruckRot)
TASK_PLAY_ANIM(pedDom, "rcmextreme3", "idle", INSTANT_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_NOT_INTERRUPTABLE|AF_LOOPING, 0.5)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Shot2: Attached Dom and played anim on him") ENDIF #ENDIF
ELSE
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Shot2: Didn't have to attach Dom") ENDIF #ENDIF
ENDIF
FORCE_PED_AI_AND_ANIMATION_UPDATE(pedDom)
ENDIF
iCutsceneStage++
ENDIF
ENDIF
BREAK
CASE 1
IF bPreloadingOutroMocap = FALSE
bPreloadingOutroMocap = TRUE
IF eDomState = DS_ATTACHED
REQUEST_CUTSCENE("ES_3_MCS_1")
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Dom landed on truck - requested ES_3_MCS_1") ENDIF #ENDIF
ELSE
REQUEST_CUTSCENE("ES_3_MCS_2")
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Dom didn't land on truck - requested ES_3_MCS_2") ENDIF #ENDIF
ENDIF
ELIF IS_ENTITY_ALIVE(vehTruck)
IF (IS_CUTSCENE_SKIP_BUTTON_JUST_PRESSED_WITH_DELAY() AND HAS_CUTSCENE_LOADED_WITH_FAILSAFE())
OR NOT IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vehTruck)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Truck finished car recording playback driving into the garage or cutscene skipped") ENDIF #ENDIF
iCutsceneStage++
ELSE
SET_PLAYBACK_SPEED(vehTruck, 1)
ENDIF
ENDIF
BREAK
CASE 2
IF RC_IS_CUTSCENE_OK_TO_START()
IF STREAMVOL_IS_VALID(streamVolumeExtreme3)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME2: Deleting streamVolumeExtreme3") ENDIF #ENDIF
STREAMVOL_DELETE(streamVolumeExtreme3)
ENDIF
IF IS_ENTITY_ALIVE(vehTruck)
IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vehTruck)
STOP_PLAYBACK_RECORDED_VEHICLE(vehTruck)
ENDIF
REGISTER_ENTITY_FOR_CUTSCENE(vehTruck, "DOM_Flatbed_truck", CU_ANIMATE_EXISTING_SCRIPT_ENTITY, modelTruck)
SET_VEHICLE_ENGINE_ON(vehTruck, FALSE, TRUE) // B*1513356
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: CU_ANIMATE_EXISTING_SCRIPT_ENTITY vehTruck") ENDIF #ENDIF
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
AND IS_ENTITY_ATTACHED_TO_ENTITY(PLAYER_PED_ID(), vehTruck)
DETACH_ENTITY(PLAYER_PED_ID(), FALSE, FALSE)
ENDIF
IF IS_ENTITY_ALIVE(pedDom)
IF IS_ENTITY_ATTACHED_TO_ENTITY(pedDom, vehTruck)
DETACH_ENTITY(pedDom, FALSE, FALSE)
ENDIF
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, "EXTREME3: CU_ANIMATE_EXISTING_SCRIPT_ENTITY pedDom") ENDIF #ENDIF
ENDIF
ENDIF
START_CUTSCENE()
SET_CUTSCENE_FADE_VALUES(FALSE, FALSE, FALSE, FALSE)
iCutsceneStage++
ENDIF
BREAK
CASE 3
IF IS_CUTSCENE_PLAYING()
IF NOT IS_ENTITY_ALIVE(vehSportsCar)
vehSportsCar = CREATE_VEHICLE(modelSportsCar, vSportsCar, fSportsCar)
SET_VEHICLE_ON_GROUND_PROPERLY(vehSportsCar)
SET_MODEL_AS_NO_LONGER_NEEDED(modelSportsCar)
ENDIF
SAFE_DELETE_PED(pedDriver)
IF DOES_CAM_EXIST(camCutscene)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Mocap is now playing so destroying script cam") ENDIF #ENDIF
RENDER_SCRIPT_CAMS(FALSE, FALSE)
DESTROY_ALL_CAMS()
ENDIF
IF NOT DOES_ENTITY_EXIST(pedDom)
AND DOES_ENTITY_EXIST(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY("Dom"))
pedDom = GET_PED_INDEX_FROM_ENTITY_INDEX(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY("Dom"))
SET_ENTITY_AS_MISSION_ENTITY(pedDom, TRUE, TRUE)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Grabbed pedDom from Dom") ENDIF #ENDIF
ENDIF
IF NOT DOES_ENTITY_EXIST(vehTruck)
AND DOES_ENTITY_EXIST(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY("DOM_Flatbed_truck"))
vehTruck = GET_VEHICLE_INDEX_FROM_ENTITY_INDEX(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY("DOM_Flatbed_truck"))
SET_ENTITY_AS_MISSION_ENTITY(vehTruck, TRUE, TRUE)
SET_VEHICLE_COLOUR_COMBINATION(vehTruck, iTruckColourCombo)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Grabbed vehTruck from DOM_Flatbed_truck") ENDIF #ENDIF
ENDIF
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
AND CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Franklin")
bHasSetExitStateFromOutroMocapForGameplayCam = TRUE
IF WAS_CUTSCENE_SKIPPED()
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Player skipped cutscene") ENDIF #ENDIF
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), <<525.9053, -173.6703, 53.9032>>, 143.0017)
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
ENDIF
ENDIF
IF bHasSetExitStateFromOutroMocapForGameplayCam = FALSE // Unfortunately the only way to ensure the mocap camera blends out to gameplay cam at a sensible position is to spam this until the player's character exit state has fired
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
ENDIF
IF IS_ENTITY_ALIVE(pedDom)
AND CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Dom")
SAFE_TELEPORT_ENTITY(pedDom, vDomAfterOutro, fDomAfterOutro, TRUE)
SET_PED_COMPONENT_VARIATION(pedDom, INT_TO_ENUM(PED_COMPONENT,8), 2, 0, 0)
IF IS_ENTITY_ALIVE(vehSportsCar)
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(vehSportsCar, FALSE)
SET_PED_KEEP_TASK(pedDom, TRUE)
OPEN_SEQUENCE_TASK(seqDomDriveAway)
TASK_ENTER_VEHICLE(NULL, vehSportsCar, DEFAULT_TIME_BEFORE_WARP, VS_DRIVER, PEDMOVEBLENDRATIO_WALK)
TASK_VEHICLE_DRIVE_WANDER(NULL, vehSportsCar, 30, DRIVINGMODE_AVOIDCARS)
CLOSE_SEQUENCE_TASK(seqDomDriveAway)
TASK_PERFORM_SEQUENCE(pedDom, seqDomDriveAway)
CLEAR_SEQUENCE_TASK(seqDomDriveAway)
SET_ENTITY_INVINCIBLE(pedDom, FALSE)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: pedDom tasked to drive away") ENDIF #ENDIF
ELSE
TASK_WANDER_STANDARD(pedDom)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: pedDom tasked to wander away") ENDIF #ENDIF
ENDIF
ENDIF
ELSE
RC_END_CUTSCENE_MODE()
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: IS_CUTSCENE_PLAYING returned false") ENDIF #ENDIF
missionStateMachine = EXT3_STATE_MACHINE_CLEANUP
ENDIF
BREAK
ENDSWITCH
BREAK
CASE EXT3_STATE_MACHINE_CLEANUP
REPLAY_STOP_EVENT()
EXT3_STATE_CLEANUP(#IF IS_DEBUG_BUILD "MS_OUTRO" #ENDIF)
SAFE_FADE_SCREEN_IN_FROM_BLACK()
SAFE_RELEASE_VEHICLE(vehTruck)
SAFE_RELEASE_VEHICLE(vehSportsCar)
SAFE_RELEASE_PED(pedDom)
Script_Passed()
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Starts the mission failed sequence.
PROC MS_FAILED()
SWITCH missionStateMachine
CASE EXT3_STATE_MACHINE_SETUP
EXT3_STATE_SETUP(#IF IS_DEBUG_BUILD "MS_FAILED" #ENDIF)
CLEAR_PRINTS()
CLEAR_HELP()
EXT3_REMOVE_ALL_BLIPS()
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
TRIGGER_MUSIC_EVENT("EXTREME3_FAIL")
SWITCH failReason
CASE FAIL_DEFAULT
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: MISSION_FAILED reason=FAIL_DEFAULT") ENDIF #ENDIF
BREAK
CASE FAIL_DOM_DEAD
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: MISSION_FAILED reason=FAIL_DOM_DEAD") ENDIF #ENDIF
failString = "EXT3_F1" // ~s~Dom died.
BREAK
CASE FAIL_DIDNT_LAND_ON_TRUCK
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: MISSION_FAILED reason=FAIL_DIDNT_LAND_ON_TRUCK") ENDIF #ENDIF
failString = "EXT3_F2" // ~s~Franklin didn't land on the truck.
BREAK
CASE FAIL_TRUCK_WRECKED
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: MISSION_FAILED reason=FAIL_TRUCK_WRECKED") ENDIF #ENDIF
failString = "EXT3_F3" // ~s~The truck was destroyed.
BREAK
CASE FAIL_DIDNT_ATTEMPT_JUMP
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: MISSION_FAILED reason=FAIL_DIDNT_ATTEMPT_JUMP") ENDIF #ENDIF
failString = "EXT3_F4" // ~s~Franklin didn't attempt the jump.
BREAK
CASE FAIL_DOM_SPOOKED
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: MISSION_FAILED reason=FAIL_DOM_SPOOKED") ENDIF #ENDIF
failString = "EXT3_F5" // ~s~Dom was spooked.
BREAK
CASE FAIL_JUMPED_OFF_BEFORE_INTRO
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: MISSION_FAILED reason=FAIL_JUMPED_OFF_BEFORE_INTRO") ENDIF #ENDIF
failString = "EXT3_F6" // ~s~Franklin jumped off the building without a parachute.
BREAK
ENDSWITCH
IF failReason = FAIL_DEFAULT
Random_Character_Failed()
ELSE
Random_Character_Failed_With_Reason(failString)
ENDIF
BREAK
CASE EXT3_STATE_MACHINE_LOOP
IF GET_MISSION_FLOW_SAFE_TO_CLEANUP()
EXT3_STATE_CLEANUP(#IF IS_DEBUG_BUILD "MS_FAILED" #ENDIF)
EXT3_SET_FRANKLIN_INTO_SKYDIVING_OUTFIT(FALSE)
SAFE_DELETE_PED(pedDom)
SAFE_DELETE_PED(pedDriver)
SAFE_DELETE_VEHICLE(vehTruck)
Script_Cleanup()
ELSE
// not finished fading out: handle dialogue etc here
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, "EXTREME3: S key pressed so passing mission") ENDIF #ENDIF
IF missionState = stateIntro
OR missionState = stateOutro
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, "EXTREME3: F key pressed so failing mission") ENDIF #ENDIF
IF missionState = stateIntro
OR missionState = stateOutro
WAIT_FOR_CUTSCENE_TO_STOP()
ENDIF
EXT3_MISSION_FAILED(FAIL_DEFAULT)
ENDIF
IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_J))
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: J key pressed so doing z skip forwards") ENDIF #ENDIF
SWITCH missionState
CASE stateIntro
CASE stateOutro
IF IS_CUTSCENE_ACTIVE()
STOP_CUTSCENE()
ENDIF
BREAK
CASE stateJump
CASE stateParachute
EXT3_DEBUG_SKIP_STATE(Z_SKIP_OUTRO_1)
BREAK
ENDSWITCH
ENDIF
IF ENUM_TO_INT(missionState) < (ENUM_TO_INT(stateOutro))
INT i_new_state
IF LAUNCH_MISSION_STAGE_MENU(mSkipMenu, i_new_state)
#IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EXTREME3: Z skip menu used so doing z skip") ENDIF #ENDIF
EXT3_DEBUG_SKIP_STATE(i_new_state)
ENDIF
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
ADD_CONTACT_TO_PHONEBOOK(CHAR_DOM, FRANKLIN_BOOK, FALSE)
EXT3_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_INTRO
START_REPLAY_SETUP(vPlayerJumpPos, fPlayerJumpHeading)
EXT3_DEBUG_SKIP_STATE(Z_SKIP_INTRO)
BREAK
CASE CP_BASE_JUMP
START_REPLAY_SETUP(vPlayerJumpPos, fPlayerJumpHeading)
EXT3_DEBUG_SKIP_STATE(Z_SKIP_JUMP)
BREAK
CASE CP_OUTRO
START_REPLAY_SETUP(vPlayerOutroPos, fPlayerOutroHeading)
EXT3_DEBUG_SKIP_STATE(Z_SKIP_OUTRO_1)
BREAK
ENDSWITCH
ENDIF
WHILE(TRUE)
WAIT(0)
REPLAY_CHECK_FOR_EVENT_THIS_FRAME("SF_TR")
UPDATE_MISSION_NAME_DISPLAYING(sRCLauncherDataLocal.sIntroCutscene)
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
SET_PED_RESET_FLAG(PLAYER_PED_ID(), PRF_KeepParachutePackOnAfterTeleport, TRUE)
SET_PED_RESET_FLAG(PLAYER_PED_ID(), PRF_DisableTakeOffParachutePack, TRUE)
ENDIF
SWITCH missionState
CASE stateIntro
MS_INTRO()
BREAK
CASE stateJump
MS_JUMP()
BREAK
CASE stateParachute
MS_PARACHUTE()
BREAK
CASE stateOutro
MS_OUTRO()
BREAK
CASE stateFailed
MS_FAILED()
BREAK
ENDSWITCH
#IF IS_DEBUG_BUILD
DEBUG_Check_Debug_Keys()
#ENDIF
ENDWHILE
ENDSCRIPT