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

320 lines
12 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.
USING "cutscene_public.sch"
USING "RC_launcher_public.sch"
USING "RC_Setup_public.sch"
USING "initial_scenes_Extreme.sch"
// *****************************************************************************************
// SCRIPT NAME : launcher_Extreme.sc
//
// AUTHOR : David Roberts / Andrew Minghella
//
// DESCRIPTION : Launcher script that determines which RC mission scene to setup.
// This launcher script should be attached to appropriate world point.
//
// If multiple missions share same coord or are within close proximity,
// we should just add one world point, and adjust the tolerance float.
// *****************************************************************************************
// ------------Constants----------------------
CONST_FLOAT WORLD_POINT_COORD_TOLERANCE 1.0
// ------------Variables----------------------
INT iCutsceneLoadRequestID = NULL_OFFMISSION_CUTSCENE_REQUEST // ID to register off-mission cutscene load request with cutscene_controller.
BOOL bDisplayedExtreme3HelpText = FALSE
INT iDomPants = GET_SOUND_ID()
SCENARIO_BLOCKING_INDEX mScenarioBlocker
BLIP_INDEX biLeadIn
// ----------Functions -------------------------
/// PURPOSE:
/// Does any necessary cleanup and terminates the launcher's thread.
/// PARAMS:
/// sData - launcher data struct
/// bCleanupEntities - do we want to cleanup the entities in the launcher struct
PROC Script_Cleanup(g_structRCScriptArgs& sData, BOOL bCleanupEntities = TRUE)
IF sData.eMissionID = RC_EXTREME_2 // B*1505969 - Unsure quad bikes are unlocked
IF IS_ENTITY_ALIVE(sData.vehID[0])
SET_VEHICLE_DOORS_LOCKED(sData.vehID[0], VEHICLELOCK_UNLOCKED)
ENDIF
IF IS_ENTITY_ALIVE(sData.vehID[1])
SET_VEHICLE_DOORS_LOCKED(sData.vehID[1], VEHICLELOCK_UNLOCKED)
ENDIF
ENDIF
IF bCleanupEntities
PRINT_LAUNCHER_DEBUG("SCRIPT TERMINATING: Cleaning up entities in Launcher")
RC_CleanupSceneEntities(sData, FALSE)
ENDIF
// Remove lead-in blip
IF DOES_BLIP_EXIST(biLeadIn)
REMOVE_BLIP(biLeadIn)
ENDIF
// Unload launcher animation dictionary
REMOVE_LAUNCHER_ANIM_DICT(sData.sAnims)
IF sData.eMissionID = RC_EXTREME_1
REMOVE_SCENARIO_BLOCKING_AREA(mScenarioBlocker)
SET_SCENARIO_TYPE_ENABLED("WORLD_VEHICLE_SALTON_DIRT_BIKE", TRUE)
ELIF sData.eMissionID = RC_EXTREME_2
REMOVE_SCENARIO_BLOCKING_AREA(mScenarioBlocker)
ELIF sData.eMissionID = RC_EXTREME_3
STOP_SOUND(iDomPants) // B*1508236 Ensure Dom stops panting
REMOVE_ANIM_DICT("rcmextreme3") // Dom's jumping off building anim is loaded by the initial scene, so he can jump if player threatens him
RELEASE_SCRIPT_AUDIO_BANK() // Unload Extreme3 Dom breathing banks
ENDIF
// Clear any cutscene requests with controller.
IF iCutsceneLoadRequestID != NULL_OFFMISSION_CUTSCENE_REQUEST
PRINT_LAUNCHER_DEBUG("SCRIPT TERMINATING: Ending off-mission cutscene request")
END_OFFMISSION_CUTSCENE_REQUEST(iCutsceneLoadRequestID)
ENDIF
//B*1574385 - Force update to blip in RandChar Controller if mission wasn't launched
IF bCleanupEntities
//Deactivated because of conflict with 1692449: Maze bank basejump blip permanently deactivated after completing the mission
//Should be safe since the area is far enough from the nearest hospital
// SET_RC_AWAITING_TRIGGER(sData.eMissionID)
ENDIF
RC_LAUNCHER_END()
// Kill the thread
PRINT_LAUNCHER_DEBUG(" SCRIPT TERMINATED")
TERMINATE_THIS_THREAD()
ENDPROC
/// PURPOSE:
/// Setup Dom for cutscene.
PROC SETUP_DOM_CUTSCENE_VARIATIONS(g_structRCScriptArgs& sData)
IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY()
#IF IS_DEBUG_BUILD CPRINTLN(DEBUG_MISSION, "EXTREME: CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY is TRUE") #ENDIF
IF IS_ENTITY_ALIVE(sData.pedID[0])
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Dom", sData.pedID[0])
#IF IS_DEBUG_BUILD CPRINTLN(DEBUG_MISSION, "EXTREME: Set cutscene variations for sData.pedID[0] in cutscene") #ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Make player car stop and player get out if near to Dom on the truck - see B*1529340
FUNC BOOL SPECIAL_EXT2_LAUNCH(g_structRCScriptArgs& sData)
IF sData.eMissionID = RC_EXTREME_2
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-954.535706,-2760.553223,11.916363>>, <<-947.684692,-2749.718994,15.631608>>, 26.000000)
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
PRINT_LAUNCHER_DEBUG("Special launching Extreme 2")
RETURN TRUE
ELSE
IF NOT IsPedPerformingTask(PLAYER_PED_ID(), SCRIPT_TASK_LEAVE_ANY_VEHICLE)
AND IS_ENTITY_ALIVE(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()))
AND BRING_VEHICLE_TO_HALT_AND_DISABLE_VEH_CONTROLS(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), 3)
TASK_LEAVE_ANY_VEHICLE(PLAYER_PED_ID())
ENDIF
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Creates the initial scene
FUNC BOOL LOAD_INITIAL_SCENE(g_structRCScriptArgs& sData)
// Setup the correct initial scene
SWITCH sData.eMissionID
CASE RC_EXTREME_1
IF NOT SetupScene_EXTREME_1(sData)
RETURN FALSE
ENDIF
BREAK
CASE RC_EXTREME_2
IF NOT SetupScene_EXTREME_2(sData)
RETURN FALSE
ENDIF
BREAK
CASE RC_EXTREME_3
IF NOT SetupScene_EXTREME_3(sData)
RETURN FALSE
ENDIF
BREAK
CASE RC_EXTREME_4
IF NOT SetupScene_EXTREME_4(sData)
RETURN FALSE
ENDIF
BREAK
ENDSWITCH
// Scene creation successful
PRINT_LAUNCHER_DEBUG("Created initial scene")
RETURN TRUE
ENDFUNC
/// PURPOSE:
/// Main script loops
/// PARAMS:
/// in_coords - world point co-ords
SCRIPT(coords_struct in_coords)
// Launcher priority for streaming requests
SET_THIS_IS_A_TRIGGER_SCRIPT(TRUE)
RC_LAUNCHER_START()
g_structRCScriptArgs sRCLauncherData // Scene information to pass to mission script
VECTOR vInCoords = <<0,0,0>> // Stores world point location
//Reset all basic values of the data, so each scene has to set them up correctly
RC_Reset_LauncherData(sRCLauncherData)
// Update world point
vInCoords = in_coords.vec_coord[0]
// Determine which RC mission we are attempting to launch (currently done on a launcher by launcher basis)
g_eRC_MissionIDs eRCMissions[4]
eRCMissions[0] = RC_EXTREME_1
eRCMissions[1] = RC_EXTREME_2
eRCMissions[2] = RC_EXTREME_3
eRCMissions[3] = RC_EXTREME_4
// Setup callback when player is killed, arrested or goes to multiplayer
IF (HAS_FORCE_CLEANUP_OCCURRED(DEFAULT_FORCE_CLEANUP_FLAGS|FORCE_CLEANUP_FLAG_DEBUG_MENU|FORCE_CLEANUP_FLAG_REPEAT_PLAY))
PRINT_LAUNCHER_DEBUG("Force cleanup [TERMINATING]")
// Ensure candidate id is released in the event that the player has died
// or been arrested prior to mission launch
IF sRCLauncherData.eMissionID <> NO_RC_MISSION
IF (g_RandomChars[sRCLauncherData.eMissionID].rcMissionCandidateID <> NO_CANDIDATE_ID)
PRINT_LAUNCHER_DEBUG("Relinquishing candidate id...")
Mission_Over(g_RandomChars[sRCLauncherData.eMissionID].rcMissionCandidateID)
ENDIF
ENDIF
// Standard cleanup
Script_Cleanup(sRCLauncherData)
ENDIF
//Pick which mission activated us
IF NOT (DETERMINE_RC_TO_LAUNCH(eRCMissions, sRCLauncherData, vInCoords, WORLD_POINT_COORD_TOLERANCE))
RC_LAUNCHER_END()
PRINT_LAUNCHER_DEBUG("SCRIPT TERMINATED")
TERMINATE_THIS_THREAD() // B* 1510945 - don't call cleanup if nothing has been setup yet
ENDIF
// Check with the Random Character Controller to see if this script is allowed to launch
IF NOT CAN_RC_LAUNCH(sRCLauncherData.eMissionID)
RC_LAUNCHER_END()
PRINT_LAUNCHER_DEBUG("SCRIPT TERMINATED")
TERMINATE_THIS_THREAD() // B* 1510945 - don't call cleanup if nothing has been setup yet
ENDIF
// Halt launcher as we are incorrect character
IF Random_Character_Blocked_Due_To_Character(sRCLauncherData.eMissionID)
RC_LAUNCHER_END()
PRINT_LAUNCHER_DEBUG("SCRIPT TERMINATED")
TERMINATE_THIS_THREAD() // B* 1510945 - don't call cleanup if nothing has been setup yet
ENDIF
// The script is allowed to launch so set up the initial scene
WHILE NOT LOAD_INITIAL_SCENE(sRCLauncherData)
WAIT(0)
IF NOT IS_WORLD_POINT_WITHIN_BRAIN_ACTIVATION_RANGE()
PRINT_LAUNCHER_DEBUG("Player out of range [TERMINATING]")
Script_Cleanup(sRCLauncherData)
ENDIF
ENDWHILE
// Setup scenario blocking areas
IF sRCLauncherData.eMissionID = RC_EXTREME_1
mScenarioBlocker = ADD_SCENARIO_BLOCKING_AREA(vInCoords-<<40, 40, 40>>, vInCoords+<<40, 40, 40>>)
SET_SCENARIO_TYPE_ENABLED("WORLD_VEHICLE_SALTON_DIRT_BIKE", FALSE)
ELIF sRCLauncherData.eMissionID = RC_EXTREME_2
mScenarioBlocker = ADD_SCENARIO_BLOCKING_AREA(<<-1040, -2870, 0>>, <<-910, -2740, 50>>, FALSE, FALSE)
ENDIF
// Clears area of non-mission entities and blood decals
CLEAR_AREA(vInCoords, sRCLauncherData.activationRange, TRUE)
// Loop to check conditions - should script terminate? or is player close enough to trigger mission?
WHILE (TRUE)
WAIT(0)
//Is the player still in activation range
IF NOT IS_RC_FINE_AND_IN_RANGE(sRCLauncherData)
Script_Cleanup(sRCLauncherData)
ENDIF
// Update launcher blip + preload intro
SET_RC_AWAITING_TRIGGER(sRCLauncherData.eMissionID)
MANAGE_PRELOADING_RC_CUTSCENE(iCutsceneLoadRequestID, sRCLauncherData.sIntroCutscene, vInCoords)
IF sRCLauncherData.eMissionID = RC_EXTREME_2
SETUP_DOM_CUTSCENE_VARIATIONS(sRCLauncherData)
PLAY_LAUNCHER_AMBIENT_DIALOGUE(sRCLauncherData, vInCoords, "EXT2AU", "EXT2_AMB", 3, "DOM")
ELIF sRCLauncherData.eMissionID = RC_EXTREME_3
SETUP_DOM_CUTSCENE_VARIATIONS(sRCLauncherData)
IF HAS_SOUND_FINISHED(iDomPants)
PLAY_LAUNCHER_AMBIENT_DIALOGUE(sRCLauncherData, vInCoords, "EXT3AUD", "EXT_AMB", 3, "DOM", 8000)
ENDIF
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
AND IS_ENTITY_ALIVE(sRCLauncherData.pedID[0])
AND NOT IS_ANY_SPEECH_PLAYING(sRCLauncherData.pedID[0])
AND HAS_SOUND_FINISHED(iDomPants)
AND REQUEST_SCRIPT_AUDIO_BANK("EXTREME_04_DOM_A")
AND REQUEST_SCRIPT_AUDIO_BANK("EXTREME_04_DOM_B")
AND REQUEST_SCRIPT_AUDIO_BANK("EXTREME_04_DOM_C")
PLAY_SOUND_FROM_ENTITY(iDomPants,"DOM_BREATHING",sRCLauncherData.pedID[0],"EXTREME_03_SOUNDSET")
ENDIF
IF bDisplayedExtreme3HelpText = FALSE
AND IS_ENTITY_ALIVE(PLAYER_PED_ID())
AND IS_ENTITY_AT_COORD(PLAYER_PED_ID(), vInCoords, <<sRCLauncherData.activationRange,sRCLauncherData.activationRange,sRCLauncherData.activationRange>>, FALSE, FALSE) // Player is within 2D range..
VECTOR v_player = GET_ENTITY_COORDS(PLAYER_PED_ID())
IF v_player.z < 100.0 // ..but not 3D range to trigger the mission..
bDisplayedExtreme3HelpText = TRUE
PRINT_HELP("TOPMAZE_HELP") // .. so display help text to tell him to get to the top of the Maze Tower, see B*1085511
PRINT_LAUNCHER_DEBUG("Player below mission start location so displaying help text TOPMAZE_HELP")
ENDIF
ENDIF
ENDIF
//Is the player close enough to start the mission off
IF ARE_RC_TRIGGER_CONDITIONS_MET(sRCLauncherData)
OR SPECIAL_EXT2_LAUNCH(sRCLauncherData)
// Create mission blip that persists for lead-in scene
// Original will be removed when RC controller shuts down
IF DOES_RC_MISSION_HAVE_LEAD_IN(sRCLauncherData.eMissionID)
CREATE_BLIP_FOR_LEAD_IN(sRCLauncherData.eMissionID, biLeadIn)
ENDIF
//Launch the mission script
IF NOT LAUNCH_RC_MISSION(sRCLauncherData)
Script_Cleanup(sRCLauncherData)
ELIF sRCLauncherData.eMissionID = RC_EXTREME_3
STOP_SOUND(iDomPants) // B*1508236 Ensure Dom stops panting when the mission launches
ENDIF
//Waits in a loop until we can terminate the launcher - flagged from mission at the moment
IF IS_RC_LAUNCHER_SAFE_TO_TERMINATE(sRCLauncherData.eMissionID)
Script_Cleanup(sRCLauncherData, FALSE) //No need to clean up entities, as we should have passed them over to the mission script
ENDIF
ENDIF
ENDWHILE
// Script should never reach here. Always terminate with cleanup function.
ENDSCRIPT