Files
gtav-src/script/dev_ng/singleplayer/include/private/randomChar/randomChar_private.sch
T
2025-09-29 00:52:08 +02:00

307 lines
11 KiB
Scheme
Executable File

USING "rage_builtins.sch"
USING "globals.sch"
USING "commands_script.sch"
#if not USE_CLF_DLC
#if not USE_NRM_DLC
USING "randomchar_private_gta5.sch"
#endif
#endif
USING "script_clock.sch"
USING "snapshot_private.sch"
USING "comms_control_public.sch"
USING "building_control_public.sch"
USING "mission_titles_private.sch"
USING "rich_presence_public.sch"
// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
//
// MISSION NAME : randomChar_Private.sch
// CREATED : Keith
// MAINTAINED : Andrew Minghella
// DESCRIPTION : Contains all Random Character private functions.
//
// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
/// PURPOSE:
/// Runs any custom script that needs to be executed for specific random character missions as they unlock.
/// PARAMS:
/// paramID - RC mission ID
PROC Run_RC_Mission_Unlock_Script(g_eRC_MissionIDs paramID)
SWITCH paramID
CASE RC_JOSH_4
CPRINTLN(DEBUG_RANDOM_CHAR, "Running custom script for RC mission: ", ENUM_TO_INT(paramID))
// Set Josh's house as destroyed
SET_BUILDING_STATE(BUILDINGNAME_IPL_JOSHHOUSE, BUILDINGSTATE_DESTROYED)
BREAK
CASE RC_EPSILON_7
CPRINTLN(DEBUG_RANDOM_CHAR, "Running custom script for RC mission: ", ENUM_TO_INT(paramID))
// set the plane vehicle gen for epsilon 6 to be off
SET_VEHICLE_GEN_AVAILABLE(VEHGEN_EPSILON6_PLANE, FALSE)
BREAK
DEFAULT
// no cutsom script to run
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Return the missionID (which gives the array position for this data) based on the scriptname.
/// PARAMS:
/// paramScriptName - the script we want the ID for
/// RETURNS:
/// g_eRC_MissionIDs: RC mission ID of specified script
#if not USE_CLF_DLC
#if not USE_NRM_DLC
FUNC g_eRC_MissionIDs Get_RC_MissionID_For_Script(STRING paramScriptName, BOOL bSuppressAssert = FALSE)
g_eRC_MissionIDs eRCMission
g_structRCMissionsStatic sRCMissionDetails
INT filenameHash = GET_HASH_KEY(paramScriptName)
// Search all the Random Character missions looking for this filenameHash
INT iMission = 0
REPEAT MAX_RC_MISSIONS iMission
eRCMission = INT_TO_ENUM(g_eRC_MissionIDs, iMission)
Retrieve_Random_Character_Static_Mission_Details(eRCMission, sRCMissionDetails)
IF (GET_HASH_KEY(sRCMissionDetails.rcScriptName) = filenameHash)
RETURN eRCMission
ENDIF
ENDREPEAT
CPRINTLN(DEBUG_RANDOM_CHAR, "ERROR: Unknown Random Character Script Name: ", paramScriptName)
IF bSuppressAssert = FALSE // added so replay controller can check this without assert
SCRIPT_ASSERT("Get_RC_MissionID_For_Script: Unknown Random Character mission script name")
ENDIF
RETURN NO_RC_MISSION
ENDFUNC
#endif
#endif
#if not USE_CLF_DLC
#if not USE_NRM_DLC
/// PURPOSE:
/// Return the missionID (which gives the array position for this data) based on the scriptname.
/// (This header will be included within the Random Character script so we don't need to pass the scriptname as a parameter.)
/// RETURNS:
/// g_eRC_MissionIDs Random Character Mission ID
FUNC g_eRC_MissionIDs Get_RC_MissionID_For_This_Script()
RETURN Get_RC_MissionID_For_Script(GET_THIS_SCRIPT_NAME())
ENDFUNC
#endif
#endif
/// PURPOSE:
/// Return the state of the 'Activated' state for this mission ID
/// PARAMS:
/// paramID - RC mission ID
/// RETURNS:
/// TRUE if activated, otherwise FALSE
FUNC BOOL Is_This_Random_Character_Mission_Active(g_eRC_MissionIDs paramID)
IF ((paramID = MAX_RC_MISSIONS) OR (paramID = NO_RC_MISSION))
SCRIPT_ASSERT("ERROR: Is_This_Random_Character_Mission_Active has been passed an illegal Random Character mission ID")
RETURN FALSE
ENDIF
// Return the Activation state of this RC mission
RETURN IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[paramID].rcFlags, ENUM_TO_INT(RC_FLAG_ACTIVATED))
ENDFUNC
/// PURPOSE:
/// Return the state of the 'Ready To Play' state for this mission ID
/// PARAMS:
/// paramID - RC mission ID
/// RETURNS:
/// BOOL TRUE if ready to play, otherwise FALSE
FUNC BOOL Is_This_Random_Character_Mission_Ready_To_Play(g_eRC_MissionIDs paramID)
IF ((paramID = MAX_RC_MISSIONS) OR (paramID = NO_RC_MISSION))
SCRIPT_ASSERT("ERROR: Is_This_Random_Character_Mission_Ready_To_Play has been passed an illegal Random Character mission ID")
RETURN FALSE
ENDIF
// Return the Ready To Play state of this RC mission
RETURN IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[paramID].rcFlags, ENUM_TO_INT(RC_FLAG_READY_TO_PLAY))
ENDFUNC
/// PURPOSE:
/// Activates a Random Character mission.
/// Activating a character doesn't mean it is Ready To Play, it just means the conditions
/// that allow it to be Ready To Play will get monitored.
/// If flow flag is specified, then paramHoursToWait will be considered after flow flag has been set to TRUE.
/// PARAMS:
/// paramID - RC mission ID
PROC Random_Character_Activate_Mission(g_eRC_MissionIDs paramID)
IF ((paramID = MAX_RC_MISSIONS) OR (paramID = NO_RC_MISSION))
SCRIPT_ASSERT("ERROR: Random_Character_Activate_Mission has been passed an illegal Random Character mission ID")
EXIT
ENDIF
CPRINTLN(DEBUG_RANDOM_CHAR, "Random character mission activated: ", ENUM_TO_INT(paramID))
//Run any mission specific script as this RC mission activates.
Run_RC_Mission_Unlock_Script(paramID)
// Activate this character
SET_BIT(g_savedGlobals.sRandomChars.savedRC[paramID].rcFlags, ENUM_TO_INT(RC_FLAG_ACTIVATED))
ENDPROC
/// PURPOSE:
/// Loads and starts an ambient script
/// RC missions should call this during cleanup routine to launch an ambient script if required.
/// This func should be called until TRUE has been returned.
/// PARAMS:
/// paramScriptName - script to launch
/// RETURNS:
/// BOOL Returns TRUE when the script has launched
FUNC BOOL Random_Character_Launch_Ambient_Script(STRING paramScriptName)
INT iStackSize = DEFAULT_STACK_SIZE
// Check for valid script name
IF NOT DOES_SCRIPT_EXIST(paramScriptName)
CERRORLN(DEBUG_RANDOM_CHAR, "ERROR: Random_Character_Launch_Ambient_Script has been passed a script name that doesn't exist")
SCRIPT_ASSERT("ERROR: Random_Character_Launch_Ambient_Script has been passed a script name that doesn't exist")
// Although an assert, allow it to continue to cleanup properly
RETURN TRUE
ENDIF
// Check for race controller already running (in the event that Sea Races are unlocked)
IF ARE_STRINGS_EQUAL(paramScriptName, "controller_Races")
IF GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(HASH("controller_Races")) > 0
CPRINTLN(DEBUG_RANDOM_CHAR, "Random_Character_Launch_Ambient_Script: controller_Races already running...")
RETURN TRUE
ENDIF
iStackSize = MICRO_STACK_SIZE
ENDIF
// Request and launch script
REQUEST_SCRIPT(paramScriptName)
IF HAS_SCRIPT_LOADED(paramScriptName)
START_NEW_SCRIPT(paramScriptName, iStackSize)
SET_SCRIPT_AS_NO_LONGER_NEEDED(paramScriptName)
CPRINTLN(DEBUG_RANDOM_CHAR, "Random_Character_Launch_Ambient_Script successfully launched: ", paramScriptName)
// Finished launching the ambient script
RETURN TRUE
ENDIF
// Still waiting for ambient script to load
RETURN FALSE
ENDFUNC
#if not USE_CLF_DLC
#if not USE_NRM_DLC
/// PURPOSE:
/// Calls the mission over and mission checkpoint playstats commands.
/// Call this whenever and RC is passed, failed or a replay is rejected.
/// PARAMS:
/// eRCMission -
PROC SET_RC_MISSION_OVER_PLAYSTATS(g_eRC_MissionIDs eRCMission, BOOL bFailed, BOOL bCancelled)
IF eRCMission <> NO_RC_MISSION
g_structRCMissionsStatic sRCMissionDetails
Retrieve_Random_Character_Static_Mission_Details(eRCMission, sRCMissionDetails)
TEXT_LABEL tStatLabel = GET_RC_STAT_ID(eRCMission)
PLAYSTATS_MISSION_CHECKPOINT(tStatLabel, 0, g_replayMissionStage, 0)
SCRIPT_PLAYSTATS_MISSION_OVER(tStatLabel, sRCMissionDetails.rcStatVariation, g_replayMissionStage, bFailed, bCancelled)
CPRINTLN(DEBUG_FLOW, "Flagging playstat MISSION OVER for RC mission. Script:", sRCMissionDetails.rcScriptName, " Variation:", sRCMissionDetails.rcStatVariation, " RC StatID = ", tStatLabel)
ENDIF
ENDPROC
#endif
#endif
/// PURPOSE:
/// Gets called by all RC mission ending routines to handle common requirements as we come off mission.
/// Currently used by rampages + Ambient Hunting too. Will split this up if required.
/// PARAMS:
/// eRCMission - ID for this RC mission
/// bUpdatePlayStats - set to FALSE to not do playstat update.
/// (This is used when rejecting a replay as playstats have already been done when mission was failed)
/// bFailed - was this RC mission failed?
/// bCancelled - has the player just rejected a replay of this RC?
PROC RC_MISSION_OVER(g_eRC_MissionIDs eRCMission, BOOL bUpdatePlayStats, BOOL bFailed = FALSE, BOOL bCancelled = FALSE)
#if USE_CLF_DLC
unused_parameter(eRCMission)
unused_parameter(bUpdatePlayStats)
unused_parameter(bFailed)
unused_parameter(bCancelled)
#endif
#if USE_NRM_DLC
unused_parameter(eRCMission)
unused_parameter(bUpdatePlayStats)
unused_parameter(bFailed)
unused_parameter(bCancelled)
#endif
#if not USE_CLF_DLC
#if not USE_NRM_DLC
//Reenable player flying through windscreens and taking crash damage.
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
SET_PED_CONFIG_FLAG(PLAYER_PED_ID(), PCF_WillFlyThroughWindscreen, TRUE)
SET_PED_CONFIG_FLAG(PLAYER_PED_ID(), PCF_WillTakeDamageWhenVehicleCrashes, TRUE)
ENDIF
// Reset player
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
SET_WANTED_LEVEL_MULTIPLIER(1.0)
SET_MAX_WANTED_LEVEL(5)
SET_ALL_RANDOM_PEDS_FLEE(PLAYER_ID(), FALSE)
SET_PLAYER_WEAPON_DAMAGE_MODIFIER(PLAYER_ID(), 1.0)
SET_PLAYER_WEAPON_DEFENSE_MODIFIER(PLAYER_ID(), 1.0)
// HUD Cleanup
DISPLAY_HUD(TRUE)
DISPLAY_RADAR(TRUE)
SET_WIDESCREEN_BORDERS(FALSE, 0)
// Normal time scale
SET_TIME_SCALE(1)
// Clear the mission titles
MISSION_FLOW_CLEAR_DISPLAY_MISSION_TITLE()
// Reset blocking of playerController setting the player chars cutscene variations
SET_PLAYER_PED_DATA_IN_CUTSCENES()
// Clear the Rich Presence value as we come off mission.
SET_DEFAULT_RICH_PRESENCE_FOR_SP()
// Reset time cycle
UPDATE_PLAYER_PED_TIMECYCLE_MODIFIER()
// Block all communications to the player for 20 seconds for pacing. #832692
ADD_GLOBAL_COMMUNICATION_DELAY(CC_GLOBAL_DELAY_POST_MISSION)
// Update playstats
IF bUpdatePlayStats = TRUE
SET_RC_MISSION_OVER_PLAYSTATS(eRCMission, bFailed, bCancelled)
ENDIF
// Tell code we're no longer on a mission
CPRINTLN(DEBUG_RANDOM_CHAR, "RC_MISSION_OVER clearing SET_MISSION_NAME")
SET_MISSION_NAME(FALSE)
// Metrics.
#IF IS_DEBUG_BUILD
//Clear the running mission autoplay label.
g_txtFlowAutoplayRunningMission = "NO MISSION"
Stop_Metrics_For_Mission_Over(GET_THIS_SCRIPT_NAME())
#ENDIF
CPRINTLN(DEBUG_RANDOM_CHAR, "RC_MISSION_OVER was called")
#endif
#endif
ENDPROC