Files
2025-09-29 00:52:08 +02:00

405 lines
13 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_Omega.sch"
// *****************************************************************************************
// SCRIPT NAME : launcher_Omega.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.
// *****************************************************************************************
// ------------Variables----------------------
CONST_FLOAT WORLD_POINT_COORD_TOLERANCE 1.0
INT iCutsceneLoadRequestID = NULL_OFFMISSION_CUTSCENE_REQUEST // ID to register off-mission cutscene load request with cutscene_controller.
ENUM convPauseState
CONVPS_READY,
CONVPS_PAUSED,
CONVPS_PLAYING,
CONVPS_COMPLETE
ENDENUM
convPauseState omega1ConvPState = CONVPS_READY
convPauseState omega2ConvPState = CONVPS_READY
// Omega 1 detector things
SCALEFORM_INDEX si_DetectorScaleform
INT rt_ID
INT iPhaseTimer
INT iDetectorSndID
// ----------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_OMEGA_2
SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<<2314.5459, 2576.3296, 44.7>>, <<2326.4463, 2579.6082, 47.6645>>, TRUE)
ENDIF
IF bCleanupEntities
PRINT_LAUNCHER_DEBUG("SCRIPT TERMINATING: Cleaning up entities in Launcher")
// Prevent Omega's walkie-talkie falling off - standard safe release detaches objects
IF sData.eMissionID = RC_OMEGA_1
AND DOES_ENTITY_EXIST(sData.objID[1])
SET_OBJECT_AS_NO_LONGER_NEEDED(sData.objID[1])
ENDIF
RC_CleanupSceneEntities(sData, FALSE)
ENDIF
// Unload launcher animation dictionary
REMOVE_LAUNCHER_ANIM_DICT(sData.sAnims)
// 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
// Stop launcher conversation
STRING sConversationRoot
SWITCH sData.eMissionID
CASE RC_OMEGA_1
sConversationRoot = "SCRAP_1_AMB"
BREAK
CASE RC_OMEGA_2
sConversationRoot = "SCRAP_2_AMB"
BREAK
ENDSWITCH
RC_STOP_LAUNCHER_DIALOGUE(sConversationRoot)
//B*1574385 - Force update to blip in RandChar Controller if mission wasn't launched
IF bCleanupEntities
SET_RC_AWAITING_TRIGGER(sData.eMissionID)
ENDIF
RC_LAUNCHER_END()
// Kill the thread
PRINT_LAUNCHER_DEBUG("SCRIPT TERMINATED")
TERMINATE_THIS_THREAD()
ENDPROC
PROC SET_UP_DETECTOR_SCREEN()
si_DetectorScaleform = REQUEST_SCALEFORM_MOVIE("digiscanner")
WHILE NOT HAS_SCALEFORM_MOVIE_LOADED(si_DetectorScaleform)
WAIT(0)
ENDWHILE
IF NOT IS_NAMED_RENDERTARGET_REGISTERED("digiscanner")
REGISTER_NAMED_RENDERTARGET("digiscanner")
ENDIF
LINK_NAMED_RENDERTARGET(GET_WEAPONTYPE_MODEL(WEAPONTYPE_DIGISCANNER))
IF IS_NAMED_RENDERTARGET_REGISTERED("digiscanner")
rt_ID = GET_NAMED_RENDERTARGET_RENDER_ID("digiscanner")
ENDIF
iDetectorSndID = GET_SOUND_ID()
iPhaseTimer = GET_GAME_TIMER()
ENDPROC
PROC FORCE_NOT_FOUND_SCREEN_ON_DETECTOR()
BEGIN_SCALEFORM_MOVIE_METHOD(si_DetectorScaleform, "SET_COLOUR")
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(255) //BarsR
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(10) //BarsG
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(10) //BarsB
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(255) //LightsR
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(10) //LightsG
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(10) //LightsB
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(255) //WrongWayR
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(10) //WrongWayG
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(10) //WrongWayB
END_SCALEFORM_MOVIE_METHOD()
BEGIN_SCALEFORM_MOVIE_METHOD(si_DetectorScaleform, "SET_DISTANCE")
SCALEFORM_MOVIE_METHOD_ADD_PARAM_FLOAT(10.0)
END_SCALEFORM_MOVIE_METHOD()
SET_TEXT_RENDER_ID(rt_ID)
FLOAT centreX = 0.100
FLOAT centreY = 0.240
FLOAT width = 0.210
FLOAT height = 0.510
IF IS_PLAYSTATION_PLATFORM()
centreX = 0.050
centreY = 0.120
width = 0.105
height = 0.255
ENDIF
DRAW_SCALEFORM_MOVIE(si_DetectorScaleform, centreX, centreY, width, height, 100,100,100,255)
IF (GET_GAME_TIMER() - iPhaseTimer) > 1250
PLAY_SOUND_FROM_COORD(iDetectorSndID, "IDLE_BEEP", <<2468.51, 3437.39, 49.90>>, "EPSILONISM_04_SOUNDSET")
iPhaseTimer = GET_GAME_TIMER()
ENDIF
ENDPROC
/// PURPOSE:
/// Creates the initial scene
FUNC BOOL LOAD_INITIAL_SCENE(g_structRCScriptArgs& sData)
// Create Omega
SWITCH sData.eMissionID
CASE RC_OMEGA_1
IF NOT SetupScene_OMEGA_1(sData)
RETURN FALSE
ENDIF
BREAK
CASE RC_OMEGA_2
IF NOT SetupScene_OMEGA_2(sData)
RETURN FALSE
ENDIF
BREAK
ENDSWITCH
// Scene creation successful
PRINT_LAUNCHER_DEBUG("Created initial scene")
RETURN TRUE
ENDFUNC
/// PURPOSE: Play a conversation in full, looped, from the RC ped once only
/// v_ped_pos = Pass in the vInCoords from your launcher file
/// s_dialogue_slot = Dialogue file to load eg EXT3AUD
/// s_dialogue_to_play = Root to play eg EXT_AMB
/// ped_dialogue_number = index of the ped in the Dialogue Star file
/// ped_dialogue_name = string name of the ped in the Dialogue Star file
/// convPS = the conv pause state of the mission
FUNC BOOL PLAY_LAUNCHER_FULL_CONVERSATION_ONCE(g_structRCScriptArgs& sData, VECTOR v_ped_pos, STRING s_dialogue_slot, STRING s_dialogue_to_play, INT ped_dialogue_number, STRING ped_dialogue_name, convPauseState& convPS)
IF NOT (convPS = CONVPS_COMPLETE)
IF IS_IT_SAFE_TO_TRIGGER_SCRIPT_TYPE(ST_RANDOM_CHARACTER)
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
AND IS_ENTITY_ALIVE(sData.pedID[0])
AND GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), v_ped_pos) < 20.0
PRINT_LAUNCHER_DEBUG("start conversation")
structPedsForConversation s_conversation
IF (convPS = CONVPS_READY)
ADD_PED_FOR_DIALOGUE(s_conversation, ped_dialogue_number, sData.pedID[0], ped_dialogue_name)
ADD_NON_CRITICAL_STANDARD_CONVERSATION_TO_BUFFER(s_conversation, s_dialogue_slot, s_dialogue_to_play, CONV_PRIORITY_MEDIUM)
convPS = CONVPS_PLAYING
ELIF (convPS = CONVPS_PLAYING)
PRINT_LAUNCHER_DEBUG("conversation ended")
convPS = CONVPS_COMPLETE
RETURN TRUE
ENDIF
ENDIF
ELSE
IF RC_IS_THIS_CONVERSATION_ROOT_PLAYING(s_dialogue_to_play)
IF NOT (convPS = CONVPS_PAUSED)
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), v_ped_pos) >= 20.0
PRINT_LAUNCHER_DEBUG("pause conversation")
PAUSE_FACE_TO_FACE_CONVERSATION(TRUE)
convPS = CONVPS_PAUSED
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
IF (GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), v_ped_pos) < 20.0)
AND (convPS = CONVPS_PAUSED)
PRINT_LAUNCHER_DEBUG("unpause conversation")
PAUSE_FACE_TO_FACE_CONVERSATION(FALSE)
convPS = CONVPS_PLAYING
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
PROC SETUP_OMEGA_FACING_CHECK()
iPhaseTimer = GET_GAME_TIMER()
ENDPROC
/// PURPOSE:
/// Check Omega's facing every so often, update if it's not going to look dodgy
PROC CHECK_OMEGA_FACING(g_structRCScriptArgs& sData)
IF GET_GAME_TIMER() - iPhaseTimer > 1250
IF IS_ENTITY_ALIVE(sData.pedID[0])
AND NOT IS_ENTITY_ON_SCREEN(sData.pedID[0])
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
AND NOT IS_ENTITY_IN_RANGE_ENTITY(PLAYER_PED_ID(), sData.pedID[0], 50.0)
VECTOR vEntity = GET_ENTITY_COORDS(sData.pedID[0])
VECTOR vLookAway = GET_ENTITY_COORDS(PLAYER_PED_ID())
float fAngle
float dX = vLookAway.x - vEntity.x
float dY = vLookAway.y - vEntity.y
IF dY != 0
fAngle = ATAN2(dX,dY)
ELSE
IF dX < 0
fAngle = -90
ELSE
fAngle = 90
ENDIF
ENDIF
fAngle *= -1.0
// Convert to facing away
fAngle -= 180
IF fAngle < 0
fAngle += 360
ENDIF
SET_ENTITY_HEADING(sData.pedID[0], fAngle)
ENDIF
ENDIF
iPhaseTimer = GET_GAME_TIMER()
ENDIF
ENDPROC
/// 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[2]
eRCMissions[0] = RC_OMEGA_1
eRCMissions[1] = RC_OMEGA_2
// 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
// Clears area of non-mission entities and blood decals
CLEAR_AREA(vInCoords, sRCLauncherData.activationRange, TRUE)
IF sRCLauncherData.eMissionID = RC_OMEGA_1
SET_UP_DETECTOR_SCREEN()
ELIF sRCLauncherData.eMissionID = RC_OMEGA_2
SETUP_OMEGA_FACING_CHECK()
ENDIF
// 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
SET_RC_AWAITING_TRIGGER(sRCLauncherData.eMissionID)
MANAGE_PRELOADING_RC_CUTSCENE(iCutsceneLoadRequestID, sRCLauncherData.sIntroCutscene, vInCoords)
IF sRCLauncherData.eMissionID = RC_OMEGA_1
PLAY_LAUNCHER_FULL_CONVERSATION_ONCE(sRCLauncherData, vInCoords, "SCRAPAU", "SCRAP_1_AMB", 3, "OMEGA", omega1ConvPState)
FORCE_NOT_FOUND_SCREEN_ON_DETECTOR()
ELIF sRCLauncherData.eMissionID = RC_OMEGA_2
PLAY_LAUNCHER_FULL_CONVERSATION_ONCE(sRCLauncherData, vInCoords, "SCRAPAU", "SCRAP_2_AMB", 3, "OMEGA", omega2ConvPState)
CHECK_OMEGA_FACING(sRCLauncherData)
ENDIF
//Is the player close enough to start the mission...
IF ARE_RC_TRIGGER_CONDITIONS_MET(sRCLauncherData)
// Launch the mission script
IF NOT LAUNCH_RC_MISSION(sRCLauncherData)
Script_Cleanup(sRCLauncherData)
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)
// No need to clean up entities, as we should have passed them over to the mission script
Script_Cleanup(sRCLauncherData, FALSE)
ENDIF
ENDIF
ENDWHILE
// Script should never reach here. Always terminate with cleanup function.
ENDSCRIPT