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

796 lines
36 KiB
Python
Executable File

USING "rage_builtins.sch"
USING "globals.sch"
USING "commands_script.sch"
USING "Mission_Flow_Initialiser.sch"
USING "minigame_blip_support.sch"
USING "savegame_private.sch"
USING "player_scene_initialiser.sch"
USING "comms_control_private.sch"
USING "rich_presence_public.sch"
USING "heist_ctrl_generic.sch"
USING "commands_graphics.sch"
// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
//
// MISSION NAME : initial.sc
// AUTHOR : Keith
// DESCRIPTION : Launches any system scripts where the script always remains in
// memory. Examples from GTA IV: cellphone, stats, etc.
//
// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
#IF IS_DEBUG_BUILD
PROC Waiting_On_Scripts_Loading_Debug()
IF NOT (HAS_SCRIPT_LOADED("blip_controller"))
CPRINTLN(DEBUG_INIT_SP, "...waiting for - blip_controller")
ENDIF
IF NOT (HAS_SCRIPT_LOADED("bootycallhandler"))
CPRINTLN(DEBUG_INIT_SP, "...waiting for - bootycallhandler")
ENDIF
IF NOT (HAS_SCRIPT_LOADED("candidate_controller"))
CPRINTLN(DEBUG_INIT_SP, "...waiting for - candidate_controller")
ENDIF
IF NOT (HAS_SCRIPT_LOADED("cheat_controller"))
CPRINTLN(DEBUG_INIT_SP, "...waiting for - cheat_controller")
ENDIF
IF NOT (HAS_SCRIPT_LOADED("CompletionPercentage_controller"))
CPRINTLN(DEBUG_INIT_SP, "...waiting for - CompletionPercentage_controller")
ENDIF
IF NOT (HAS_SCRIPT_LOADED("controller_AmbientArea"))
CPRINTLN(DEBUG_INIT_SP, "...waiting for - controller_AmbientArea")
ENDIF
IF NOT (HAS_SCRIPT_LOADED("email_controller"))
CPRINTLN(DEBUG_INIT_SP, "...waiting for - email_controller")
ENDIF
IF NOT (HAS_SCRIPT_LOADED("emergencycalllauncher"))
CPRINTLN(DEBUG_INIT_SP, "...waiting for - emergencycalllauncher")
ENDIF
IF NOT (HAS_SCRIPT_LOADED("event_controller"))
CPRINTLN(DEBUG_INIT_SP, "...waiting for - event_controller")
ENDIF
IF NOT (HAS_SCRIPT_LOADED("taxiLauncher"))
CPRINTLN(DEBUG_INIT_SP, "...waiting for - taxiLauncher")
ENDIF
IF NOT (HAS_SCRIPT_LOADED("restrictedAreas"))
CPRINTLN(DEBUG_INIT_SP, "...waiting for - restrictedAreas")
ENDIF
// IF NOT (HAS_SCRIPT_LOADED("flyUnderBridges"))
// CPRINTLN(DEBUG_INIT_SP, "...waiting for - flyUnderBridges")
// ENDIF
IF NOT (HAS_SCRIPT_LOADED("flow_controller"))
CPRINTLN(DEBUG_INIT_SP, "...waiting for - flow_controller")
ENDIF
// IF NOT (HAS_SCRIPT_LOADED("friends_controller"))
// CPRINTLN(DEBUG_INIT_SP, "...waiting for - friends_controller")
// ENDIF
IF NOT (HAS_SCRIPT_LOADED("pickup_controller"))
CPRINTLN(DEBUG_INIT_SP, "...waiting for - pickup_controller")
ENDIF
IF NOT (HAS_SCRIPT_LOADED("player_controller"))
CPRINTLN(DEBUG_INIT_SP, "...waiting for - player_controller")
ENDIF
IF NOT (HAS_SCRIPT_LOADED("randomchar_controller"))
CPRINTLN(DEBUG_INIT_SP, "...waiting for - randomchar_controller")
ENDIF
IF NOT (HAS_SCRIPT_LOADED("vehicle_gen_controller"))
CPRINTLN(DEBUG_INIT_SP, "...waiting for - vehicle_gen_controller")
ENDIF
#IF IS_DEBUG_BUILD
CPRINTLN(DEBUG_INIT_SP, "...waiting for - xml_menus")
#ENDIF
IF NOT (HAS_SCRIPT_LOADED("mission_stat_alerter"))
CPRINTLN(DEBUG_INIT_SP, "...waiting for - mission_stat_alerter")
ENDIF
IF NOT (HAS_SCRIPT_LOADED("stock_controller"))
CPRINTLN(DEBUG_INIT_SP, "...waiting for - stock_controller")
ENDIF
// IF NOT (HAS_SCRIPT_LOADED("spmc_preloader"))
// CPRINTLN(DEBUG_INIT_SP, "...waiting for - spmc_preloader")
// ENDIF
ENDPROC
#ENDIF
// PURPOSE: Launches any singleplayer scripts that need to run in the background throughout the game.
PROC Start_SP_Control_Scripts()
#IF IS_DEBUG_BUILD
CPRINTLN(DEBUG_INIT_SP, "Launching singleplayer control scripts.")
#ENDIF
REQUEST_SCRIPT("blip_controller")
REQUEST_SCRIPT("bootycallhandler")
REQUEST_SCRIPT("candidate_controller")
REQUEST_SCRIPT("cheat_controller")
REQUEST_SCRIPT("CompletionPercentage_controller")
REQUEST_SCRIPT("controller_AmbientArea")
REQUEST_SCRIPT("email_controller")
REQUEST_SCRIPT("emergencycalllauncher")
REQUEST_SCRIPT("event_controller")
REQUEST_SCRIPT("taxiLauncher")
REQUEST_SCRIPT("restrictedAreas")
REQUEST_SCRIPT("flow_controller")
REQUEST_SCRIPT("pickup_controller")
REQUEST_SCRIPT("player_controller")
REQUEST_SCRIPT("randomchar_controller")
REQUEST_SCRIPT("vehicle_gen_controller")
REQUEST_SCRIPT("mission_stat_alerter")
REQUEST_SCRIPT("MPStatsInit")
//REQUEST_SCRIPT("spmc_preloader")
REQUEST_SCRIPT("stock_controller")
#IF IS_DEBUG_BUILD
REQUEST_SCRIPT("xml_menus")
#ENDIF
//Wait for everything to be loaded
WHILE NOT (HAS_SCRIPT_LOADED("blip_controller"))
OR NOT (HAS_SCRIPT_LOADED("bootycallhandler"))
OR NOT (HAS_SCRIPT_LOADED("candidate_controller"))
OR NOT (HAS_SCRIPT_LOADED("cheat_controller"))
OR NOT (HAS_SCRIPT_LOADED("CompletionPercentage_controller"))
OR NOT (HAS_SCRIPT_LOADED("controller_AmbientArea"))
OR NOT (HAS_SCRIPT_LOADED("email_controller"))
OR NOT (HAS_SCRIPT_LOADED("emergencycalllauncher"))
OR NOT (HAS_SCRIPT_LOADED("event_controller"))
OR NOT (HAS_SCRIPT_LOADED("taxiLauncher"))
OR NOT (HAS_SCRIPT_LOADED("restrictedAreas"))
// OR NOT (HAS_SCRIPT_LOADED("flyUnderBridges"))
OR NOT (HAS_SCRIPT_LOADED("flow_controller"))
// OR NOT (HAS_SCRIPT_LOADED("friends_controller"))
OR NOT (HAS_SCRIPT_LOADED("pickup_controller"))
OR NOT (HAS_SCRIPT_LOADED("player_controller"))
OR NOT (HAS_SCRIPT_LOADED("randomchar_controller"))
OR NOT (HAS_SCRIPT_LOADED("vehicle_gen_controller"))
OR NOT (HAS_SCRIPT_LOADED("mission_stat_alerter"))
OR NOT (HAS_SCRIPT_LOADED("MPStatsInit"))
//OR NOT (HAS_SCRIPT_LOADED("spmc_preloader"))
OR NOT (HAS_SCRIPT_LOADED("stock_controller"))
#IF IS_DEBUG_BUILD
OR NOT (HAS_SCRIPT_LOADED("xml_menus"))
#ENDIF
#IF IS_DEBUG_BUILD
Waiting_On_Scripts_Loading_Debug()
#ENDIF
WAIT(0)
REQUEST_SCRIPT("blip_controller")
REQUEST_SCRIPT("bootycallhandler")
REQUEST_SCRIPT("candidate_controller")
REQUEST_SCRIPT("cheat_controller")
REQUEST_SCRIPT("CompletionPercentage_controller")
REQUEST_SCRIPT("controller_AmbientArea")
REQUEST_SCRIPT("email_controller")
REQUEST_SCRIPT("emergencycalllauncher")
REQUEST_SCRIPT("event_controller")
REQUEST_SCRIPT("taxiLauncher")
REQUEST_SCRIPT("restrictedAreas")
// REQUEST_SCRIPT("flyUnderBridges")
REQUEST_SCRIPT("flow_controller")
// REQUEST_SCRIPT("friends_controller")
REQUEST_SCRIPT("pickup_controller")
REQUEST_SCRIPT("player_controller")
REQUEST_SCRIPT("randomchar_controller")
REQUEST_SCRIPT("vehicle_gen_controller")
REQUEST_SCRIPT("mission_stat_alerter")
REQUEST_SCRIPT("MPStatsInit")
//REQUEST_SCRIPT("spmc_preloader")
REQUEST_SCRIPT("stock_controller")
#IF IS_DEBUG_BUILD
REQUEST_SCRIPT("xml_menus")
#ENDIF
ENDWHILE
// KEITH NOTE 2/8/10
// Need to mark these scripts as No Longer Needed now. They get ditched when the player enters
// multiplayer and then relaunched by script on return to singleplayer.
// (For Info, In GTA IV, multiplayer used to be a separate script image - not now for GTA 5)
//default blip controller
START_NEW_SCRIPT("blip_controller", DEFAULT_STACK_SIZE)
SET_SCRIPT_AS_NO_LONGER_NEEDED("blip_controller")
START_NEW_SCRIPT("bootycallhandler", DEFAULT_STACK_SIZE)
SET_SCRIPT_AS_NO_LONGER_NEEDED("bootycallhandler")
START_NEW_SCRIPT("candidate_controller", DEFAULT_STACK_SIZE)
SET_SCRIPT_AS_NO_LONGER_NEEDED("candidate_controller")
START_NEW_SCRIPT("cheat_controller", DEFAULT_STACK_SIZE)
SET_SCRIPT_AS_NO_LONGER_NEEDED("cheat_controller")
START_NEW_SCRIPT("CompletionPercentage_controller", DEFAULT_STACK_SIZE)
SET_SCRIPT_AS_NO_LONGER_NEEDED("CompletionPercentage_controller")
START_NEW_SCRIPT("controller_AmbientArea", DEFAULT_STACK_SIZE)
SET_SCRIPT_AS_NO_LONGER_NEEDED("controller_AmbientArea")
START_NEW_SCRIPT("email_controller", DEFAULT_STACK_SIZE)
SET_SCRIPT_AS_NO_LONGER_NEEDED("email_controller")
START_NEW_SCRIPT("emergencycalllauncher", DEFAULT_STACK_SIZE)
SET_SCRIPT_AS_NO_LONGER_NEEDED("emergencycalllauncher")
START_NEW_SCRIPT("event_controller", DEFAULT_STACK_SIZE)
SET_SCRIPT_AS_NO_LONGER_NEEDED("event_controller")
START_NEW_SCRIPT("taxiLauncher", DEFAULT_STACK_SIZE)
SET_SCRIPT_AS_NO_LONGER_NEEDED("taxiLauncher")
START_NEW_SCRIPT("restrictedAreas", DEFAULT_STACK_SIZE)
SET_SCRIPT_AS_NO_LONGER_NEEDED("restrictedAreas")
// START_NEW_SCRIPT("flyUnderBridges", DEFAULT_STACK_SIZE)
// SET_SCRIPT_AS_NO_LONGER_NEEDED("flyUnderBridges")
START_NEW_SCRIPT("flow_controller", DEFAULT_STACK_SIZE)
SET_SCRIPT_AS_NO_LONGER_NEEDED("flow_controller")
// START_NEW_SCRIPT("friends_controller", FRIEND_STACK_SIZE)
// SET_SCRIPT_AS_NO_LONGER_NEEDED("friends_controller")
#IF IS_DEBUG_BUILD
START_NEW_SCRIPT("player_controller", SHOP_STACK_SIZE)
#ENDIF
#IF NOT IS_DEBUG_BUILD
START_NEW_SCRIPT("player_controller", DEFAULT_STACK_SIZE)
#ENDIF
SET_SCRIPT_AS_NO_LONGER_NEEDED("player_controller")
START_NEW_SCRIPT("pickup_controller", DEFAULT_STACK_SIZE)
SET_SCRIPT_AS_NO_LONGER_NEEDED("pickup_controller")
START_NEW_SCRIPT("randomchar_controller", DEFAULT_STACK_SIZE)
SET_SCRIPT_AS_NO_LONGER_NEEDED("randomchar_controller")
START_NEW_SCRIPT("vehicle_gen_controller", SPECIAL_ABILITY_STACK_SIZE)
SET_SCRIPT_AS_NO_LONGER_NEEDED("vehicle_gen_controller")
#IF IS_DEBUG_BUILD
START_NEW_SCRIPT("xml_menus", DEFAULT_STACK_SIZE)
SET_SCRIPT_AS_NO_LONGER_NEEDED("xml_menus")
#ENDIF
START_NEW_SCRIPT("mission_stat_alerter", DEFAULT_STACK_SIZE)
SET_SCRIPT_AS_NO_LONGER_NEEDED("mission_stat_alerter")
START_NEW_SCRIPT("MPStatsInit", DEFAULT_STACK_SIZE)
SET_SCRIPT_AS_NO_LONGER_NEEDED("MPStatsInit")
// START_NEW_SCRIPT("spmc_preloader", DEFAULT_STACK_SIZE)
// SET_SCRIPT_AS_NO_LONGER_NEEDED("spmc_preloader")
START_NEW_SCRIPT("stock_controller", DEFAULT_STACK_SIZE)
SET_SCRIPT_AS_NO_LONGER_NEEDED("stock_controller")
ENDPROC
#IF IS_DEBUG_BUILD
/// PURPOSE: Requests the 'Debug' script, waits for it to stream in, then launches it
///
PROC Request_And_Launch_Metrics_Script_With_Wait()
STRING MetricsScriptName = "script_metrics"
REQUEST_SCRIPT(MetricsScriptName)
WHILE NOT (HAS_SCRIPT_LOADED(MetricsScriptName))
REQUEST_SCRIPT(MetricsScriptName)
WAIT(0)
ENDWHILE
START_NEW_SCRIPT(MetricsScriptName, MINI_STACK_SIZE)
ENDPROC
#ENDIF
// ===========================================================================================================
// Assign_Name_and_Stacksize_for_Script
// ===========================================================================================================
// PURPOSE: Fills the fields of g_Restore_Launched_Script[n] with the passed data.
//
PROC Assign_Name_and_Stacksize_for_Script (STRING passedScriptName, INT passedScripthash, INT passedStackSize, INT passedEntryNum )
g_Restore_Launched_Script[passedEntryNum].Name = passedScriptName
g_Restore_Launched_Script[passedEntryNum].NameHash = passedScripthash
g_Restore_Launched_Script[passedEntryNum].Stacksize = passedStackSize
ENDPROC
// ===========================================================================================================
// Define_Restore_Launched_ScriptNames
// ===========================================================================================================
// PURPOSE: Specifies the names of flow progress dependent scripts which are automatically relaunched
// upon save game restoration.
//
// NOTE: Please ensure to add any new script to the bottom of the list and that an associated bit enum has
// also been added to flow_globals.sch in the e_g_Restore_Launched_ScriptBits section.
PROC Define_Restore_Launched_ScriptNames()
Assign_Name_and_Stacksize_for_Script ("heist_ctrl_agency", HASH("heist_ctrl_agency"), FRIEND_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_HEIST_CTRL_AGENCY) )
Assign_Name_and_Stacksize_for_Script ("heist_ctrl_docks", HASH("heist_ctrl_docks"), FRIEND_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_HEIST_CTRL_DOCKS) )
Assign_Name_and_Stacksize_for_Script ("heist_ctrl_finale", HASH("heist_ctrl_finale"), FRIEND_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_HEIST_CTRL_FINALE) )
Assign_Name_and_Stacksize_for_Script ("heist_ctrl_jewel", HASH("heist_ctrl_jewel"), FRIEND_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_HEIST_CTRL_JEWEL) )
Assign_Name_and_Stacksize_for_Script ("heist_ctrl_rural", HASH("heist_ctrl_rural"), FRIEND_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_HEIST_CTRL_RURAL) )
Assign_Name_and_Stacksize_for_Script ("epsCars", HASH("epsCars"), DEFAULT_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_RC_AMB_EPSILON_CARS) )
Assign_Name_and_Stacksize_for_Script ("epsDesert", HASH("epsDesert"), DEFAULT_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_RC_AMB_EPSILON_DESERT) )
Assign_Name_and_Stacksize_for_Script ("epsRobes", HASH("epsRobes"), DEFAULT_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_RC_AMB_EPSILON_ROBES) )
Assign_Name_and_Stacksize_for_Script ("epsilonTract", HASH("epsilonTract"), DEFAULT_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_RC_AMB_EPSILON_TRACT) )
Assign_Name_and_Stacksize_for_Script ("ambient_MrsPhilips", HASH("ambient_MrsPhilips"), DEFAULT_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_RC_AMB_MRS_PHILIPS) )
Assign_Name_and_Stacksize_for_Script ("forSaleSigns", HASH("forSaleSigns"), DEFAULT_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_RC_AMB_FOR_SALE_SIGNS) )
Assign_Name_and_Stacksize_for_Script ("letterScraps", HASH("letterScraps"), DEFAULT_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_RC_AMB_LETTER_SCRAPS) )
Assign_Name_and_Stacksize_for_Script ("ambient_Sonar", HASH("ambient_Sonar"), DEFAULT_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_RC_AMB_SONAR_COLLECTION) )
Assign_Name_and_Stacksize_for_Script ("spaceshipParts", HASH("spaceshipParts"), DEFAULT_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_RC_AMB_SPACESHIP_PARTS) )
Assign_Name_and_Stacksize_for_Script ("controller_towing", HASH("controller_towing"), DEFAULT_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_MG_CTRL_TOWING) )
Assign_Name_and_Stacksize_for_Script ("controller_Taxi", HASH("controller_Taxi"), DEFAULT_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_MG_CTRL_TAXI) )
Assign_Name_and_Stacksize_for_Script ("controller_Trafficking", HASH("controller_Trafficking"), DEFAULT_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_MG_CTRL_TRAF) )
Assign_Name_and_Stacksize_for_Script ("exile_city_denial", HASH("exile_city_denial"), DEFAULT_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_EXILE_CITY_DENIAL) )
Assign_Name_and_Stacksize_for_Script ("buildingSiteAmbience", HASH("buildingSiteAmbience"), MICRO_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_FLOW_BUILDINGSITE_AUD) )
Assign_Name_and_Stacksize_for_Script ("finale_choice", HASH("finale_choice"), MINI_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_FLOW_FINALE_CHOICE) )
Assign_Name_and_Stacksize_for_Script ("pickupVehicles", HASH("pickupVehicles"), MICRO_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_FLOW_PICKUP_VEHICLES) )
Assign_Name_and_Stacksize_for_Script ("BailBond_Launcher", HASH("BailBond_Launcher"), DEFAULT_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_BAIL_BOND_CONTROLLER) )
Assign_Name_and_Stacksize_for_Script ("rampage_controller", HASH("rampage_controller"), DEFAULT_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_RAMPAGE_CONTROLLER) )
Assign_Name_and_Stacksize_for_Script ("SH_Intro_F_Hills", HASH("SH_Intro_F_Hills"), DEFAULT_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_SH_INTRO_F_HILLS) )
Assign_Name_and_Stacksize_for_Script ("SH_Intro_M_Home", HASH("SH_Intro_M_Home"), DEFAULT_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_SH_INTRO_M_HOME) )
Assign_Name_and_Stacksize_for_Script ("FBI4_Prep3Amb", HASH("FBI4_Prep3Amb"), FRIEND_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_FBI4_PREP3) )
Assign_Name_and_Stacksize_for_Script ("finale_heist_prepEamb", HASH("finale_heist_prepEamb"), FRIEND_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_HEIST_FINALE_PREP_E) )
Assign_Name_and_Stacksize_for_Script ("agency_prep2Amb", HASH("agency_prep2Amb"), FRIEND_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_HEIST_AGENCY_PREP_2) )
Assign_Name_and_Stacksize_for_Script ("ambient_Diving", HASH("ambient_Diving"), DEFAULT_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_AMB_DIVING_PICKUPS) )
Assign_Name_and_Stacksize_for_Script ("ambient_Tonya", HASH("ambient_Tonya"), DEFAULT_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_RC_AMB_TONYA) )
Assign_Name_and_Stacksize_for_Script ("AF_Intro_T_Sandy", HASH("AF_Intro_T_Sandy"), DEFAULT_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_AF_INTRO_T_SANDY) )
Assign_Name_and_Stacksize_for_Script ("ambient_Solomon", HASH("ambient_Solomon"), DEFAULT_STACK_SIZE, ENUM_TO_INT(LAUNCH_BIT_AMBIENT_SOLOMON) )
CPRINTLN(DEBUG_INIT_SP, "Assigning names and stack size for relaunch scripts.")
ENDPROC
/// PURPOSE: Compares saved command hash IDs with restored command hash IDs and flags when there is a mismatch.
FUNC BOOL Does_Strands_Saved_Command_Match_Restored_Command(INT paramStrandIndex)
IF g_savedGlobals.sFlow.strandSavedVars[paramStrandIndex].thisCommandPos < MAX_MISSION_FLOW_COMMANDS
INT iSavedHashID = g_savedGlobals.sFlow.strandSavedVars[paramStrandIndex].thisCommandHashID
INT iRestoredHashID = GET_FLOW_COMMAND_HASH_ID(g_savedGlobals.sFlow.strandSavedVars[paramStrandIndex].thisCommandPos)
CPRINTLN(DEBUG_INIT_SP, "<FLOW-CHECK> STRAND[", GET_STRAND_DISPLAY_STRING_FROM_STRAND_ID(INT_TO_ENUM(STRANDS, paramStrandIndex)),
"] SAVED[", iSavedHashID, "] RESTORED[", iRestoredHashID, "]")
IF iSavedHashID != iRestoredHashID
CDEBUG1LN(DEBUG_INIT_SP, "Saved command hash ID does not match the restored command hash ID for strand ", GET_STRAND_DISPLAY_STRING_FROM_STRAND_ID(INT_TO_ENUM(STRANDS, paramStrandIndex)), ".")
CDEBUG1LN(DEBUG_INIT_SP, "Strand needs to be repaired.")
RETURN FALSE
ENDIF
RETURN TRUE
ENDIF
SCRIPT_ASSERT("Does_Restored_Strand_Command_Match_Saved_Strand_Command: Strand was set to an invalid command index.")
RETURN FALSE
ENDFUNC
/// PURPOSE: Seeks through all hashes in a strand to try and find a hash ID that matches the saved command.
/// Jumps the strand's command pointer to any matching command that is found.
FUNC BOOL Attempt_To_Restore_To_Saved_Strand_Command(INT paramStrandIndex)
CPRINTLN(DEBUG_INIT_SP, "<FLOW-CHECK> Attempting to restore command for strand ", GET_STRAND_DISPLAY_STRING_FROM_STRAND_ID(INT_TO_ENUM(STRANDS, paramStrandIndex)), ".")
INT iHashToFind = g_savedGlobals.sFlow.strandSavedVars[paramStrandIndex].thisCommandHashID
INT iCommandIndex
FOR iCommandIndex = g_flowUnsaved.flowCommandsIndex[paramStrandIndex].lower TO g_flowUnsaved.flowCommandsIndex[paramStrandIndex].upper
CDEBUG3LN(DEBUG_INIT_SP, "<FLOW-CHECK> Checking hash at index ", iCommandIndex, ".")
IF iHashToFind = GET_FLOW_COMMAND_HASH_ID(iCommandIndex)
g_savedGlobals.sFlow.strandSavedVars[paramStrandIndex].thisCommandPos = iCommandIndex
CPRINTLN(DEBUG_INIT_SP, "<FLOW-CHECK> Found hash match at index ", iCommandIndex, ". Strand repaired.")
RETURN TRUE
ENDIF
ENDFOR
CPRINTLN(DEBUG_INIT_SP, "<FLOW-CHECK> Could not find a matching command hash in the strand bounds. Failed to repair strand.")
RETURN FALSE
ENDFUNC
/// PURPOSE: Checks that all flow commands restored for each strand have hash IDs that match the saved hash IDs.
/// If any mismatches are found then the save has been rolled across versions of the flow and must be repaired.
/// Seeks through a strands other commands and tries to find the saved command has at a new command index.
/// Displays info screens to inform the player of the save repair process.
PROC Validate_And_Repair_Restored_Game()
CPRINTLN(DEBUG_INIT_SP, "<FLOW-CHECK> Running loaded flow repair checks.")
BOOL bRepairing = FALSE
//Validate the restored command hash for each strand in turn.
INT iStrandIndex
REPEAT MAX_STRANDS iStrandIndex
IF NOT Does_Strands_Saved_Command_Match_Restored_Command(iStrandIndex)
// Strand needs to be repaired.
IF NOT bRepairing
PRINTLN(DEBUG_INIT_SP, "<FLOW-CHECK> Flow data mismatch found. Starting repair.")
//SCRIPT_ASSERT("Show repair warning screen now.")
bRepairing = TRUE
ENDIF
IF NOT Attempt_To_Restore_To_Saved_Strand_Command(iStrandIndex)
PRINTLN(DEBUG_INIT_SP, "<FLOW-CHECK> Flow data repair failed.")
//SCRIPT_ASSERT("Show repair failed screen.")
EXIT
ENDIF
ENDIF
ENDREPEAT
IF bRepairing
PRINTLN(DEBUG_INIT_SP, "<FLOW-CHECK> Flow data repair succeeded.")
//SCRIPT_ASSERT("Show repair success screen.")
ENDIF
ENDPROC
PROC Setup_SP_Game_State()
CPRINTLN(DEBUG_INIT_SP, "Setting up singleplayer game state.")
#IF USE_FINAL_PRINTS
PRINTLN_FINAL("<2140379> Setting up singleplayer game state.")
#ENDIF
// Emergency check to catch SP starting up without the flow having being initialised.
// Could potentially happen if we auto switch in to MP before SP every runs.
IF g_bHaveBeenInMultiplayer
#IF IS_DEBUG_BUILD
IF NOT GET_COMMANDLINE_PARAM_EXISTS("DisableSPStartFromMP")
#ENDIF
// If we've somehow switched out of SP during the intro sequence without setting the
// "sequence displayed" bit, then set it now to safeguard Arm1 getting stuck waiting
// for it.
IF GET_MISSION_COMPLETE_STATE(SP_MISSION_PROLOGUE)
AND NOT IS_BIT_SET(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_TITLE_SEQUENCE_DISPLAYED)
AND GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(HASH("flowIntroTitle")) = 0
CPRINTLN(DEBUG_INIT_SP, "Setting the title displayed bit as it was left unset after passing Prologue.")
SET_BIT(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_TITLE_SEQUENCE_DISPLAYED)
ENDIF
BOOL bMissionAutostartFound = FALSE
IF NOT bMissionAutostartFound
IF NOT IS_BIT_SET(g_savedGlobals.sFlow.strandSavedVars[STRAND_PROLOGUE].savedBitflags, SAVED_BITS_STRAND_ACTIVATED)
OR NOT GET_MISSION_COMPLETE_STATE(SP_MISSION_PROLOGUE)
CPRINTLN(DEBUG_INIT_SP, "Prologue strand not started as SP initialised. Flagging it active now.")
SET_BIT(g_savedGlobals.sFlow.strandSavedVars[STRAND_PROLOGUE].savedBitflags, SAVED_BITS_STRAND_ACTIVATED)
IF NOT IS_SCREEN_FADED_OUT()
IF NOT IS_SCREEN_FADING_OUT()
CPRINTLN(DEBUG_INIT_SP, "Fading screen out in preparation for lead-in to Prologue mission.")
DO_SCREEN_FADE_OUT(DEFAULT_FADE_TIME)
ENDIF
ENDIF
bMissionAutostartFound = TRUE
ENDIF
endif
//Check to see if any strands are sitting on DO_MISSION_NOW flow commands that will autostart.
//If so fade the screen out to hide nasty transitions into the mission.
INT iStrandIndex
REPEAT MAX_STRANDS iStrandIndex
IF NOT bMissionAutostartFound
INT iCommandPos = g_savedGlobals.sFlow.strandSavedVars[iStrandIndex].thisCommandPos
IF iCommandPos != ILLEGAL_ARRAY_POSITION
IF g_flowUnsaved.flowCommands[iCommandPos].command = FLOW_DO_MISSION_NOW
IF NOT IS_SCREEN_FADED_OUT()
IF NOT IS_SCREEN_FADING_OUT()
DO_SCREEN_FADE_OUT(DEFAULT_FADE_TIME)
ENDIF
ENDIF
CPRINTLN(DEBUG_INIT_SP, "Fading screen out in preparation for lead-in for DO_MISSION_NOW mission.")
bMissionAutostartFound = TRUE
ENDIF
ENDIF
ENDIF
ENDREPEAT
#IF IS_DEBUG_BUILD
ENDIF
#ENDIF
ELSE
SET_GAME_BOOTED_TO_SP(TRUE)
CPRINTLN(DEBUG_INIT_SP, "g_bBootedToSP = TRUE")
ENDIF
#IF IS_DEBUG_BUILD
IF GET_INDEX_OF_CURRENT_LEVEL() != LEVEL_NET_TEST
#ENDIF
IF NOT g_bHaveBeenInMultiplayer
//Clear any persistent weather type that multiplayer scripts have set.
SET_WEATHER_TYPE_OVERTIME_PERSIST("SMOG", 25.0)
CLEAR_WEATHER_TYPE_PERSIST()
UNLOAD_ALL_CLOUD_HATS()
ELSE
CPRINTLN(DEBUG_INIT_SP, "Bypass setting weather in initial.sc, g_bHaveBeenInMultiplayer is TRUE.")
ENDIF
// Extra safeguard against initialising SP with bad weather. May occur if MP bombs
// out before setting a weather state. Swap out to a random safe weather type.
IF NOT IS_WEATHER_SAFE_FOR_SP()
INT iSafeWeatherHashes[6]
iSafeWeatherHashes[0] = HASH("EXTRASUNNY")
iSafeWeatherHashes[1] = HASH("CLEAR")
iSafeWeatherHashes[2] = HASH("CLOUDS")
iSafeWeatherHashes[3] = HASH("SMOG")
iSafeWeatherHashes[4] = HASH("OVERCAST")
iSafeWeatherHashes[5] = HASH("RAIN")
INT iRandomNow = GET_RANDOM_INT_IN_RANGE(0,6)
INT iRandomNext = GET_RANDOM_INT_IN_RANGE(0,6)
#IF IS_DEBUG_BUILD
STRING strSafeWeatherHashes[6]
strSafeWeatherHashes[0] = "EXTRASUNNY"
strSafeWeatherHashes[1] = "CLEAR"
strSafeWeatherHashes[2] = "CLOUDS"
strSafeWeatherHashes[3] = "SMOG"
strSafeWeatherHashes[4] = "OVERCAST"
strSafeWeatherHashes[5] = "RAIN"
CPRINTLN(DEBUG_INIT_SP, "Found unsafe weather for SP. Overriding to [Now:", strSafeWeatherHashes[iRandomNow], ", Next:", strSafeWeatherHashes[iRandomNext], "]")
#ENDIF
SET_CURR_WEATHER_STATE(iSafeWeatherHashes[iRandomNow], iSafeWeatherHashes[iRandomNext], 0.0)
ELSE
CPRINTLN(DEBUG_INIT_SP, "Found safe weather for SP.")
ENDIF
#IF IS_DEBUG_BUILD
ELSE
SET_OVERRIDE_WEATHER("SMOG")
ENDIF
#ENDIF
//Clean up any screen effects that might somehow be left from MP.
IF ANIMPOSTFX_IS_RUNNING("DeathFailOut")
ANIMPOSTFX_STOP("DeathFailOut")
ENDIF
SET_CAM_DEATH_FAIL_EFFECT_STATE(CAM_DEATH_FAIL_EFFECT_INACTIVE)
SET_TIME_SCALE(1.0)
//Unlock multiplayer if we are loading a save made after Prologue without
//the profile setting being flagged.
IF ARE_PROFILE_SETTINGS_VALID()
IF GET_PROFILE_SETTING(PROLOGUE_COMPLETE) = 0
IF GET_MISSION_COMPLETE_STATE(SP_MISSION_PROLOGUE)
CPRINTLN(DEBUG_INIT_SP, "Loading a save that has Prologue complete without MP unlocked. Unlocking MP as we init.")
SET_PROFILE_SETTING_PROLOGUE_COMPLETE()
ENDIF
ENDIF
IF GET_PROFILE_SETTING(SP_CHOP_MISSION_COMPLETE) = 0
IF GET_MISSION_COMPLETE_STATE(SP_MISSION_FRANKLIN_0)
CPRINTLN(DEBUG_INIT_SP, "Loading a save that has Franklin 0 without MP unlocked. Unlocking MP as we init.")
SET_PROFILE_SETTING_SP_CHOP_MISSION_COMPLETE()
ENDIF
ENDIF
ELSE
CPRINTLN(DEBUG_INIT_SP, "Loading a save that but ARE_PROFILE_SETTINGS_VALID = false so can't check prologue complete status. ")
ENDIF
ENABLE_STUNT_JUMP_SET(ciSINGLE_PLAYER_SJS_GROUP)
// #2173929 Ensure invites aren't blocked on an average SP startup.
NETWORK_BLOCK_INVITES(FALSE)
//Force all missions to reregister on returning to SP.
CLEAR_AVAILABLE_MISSIONS_ARRAY()
//Set the default SP Rich Presence.
SET_DEFAULT_RICH_PRESENCE_FOR_SP()
//Reinstate player's scuba gear and parachute state.
IF IS_PLAYER_PLAYING(PLAYER_ID())
SET_AUTO_GIVE_PARACHUTE_WHEN_ENTER_PLANE(PLAYER_ID(), GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_AIR_VEHICLE_PARACHUTE_UNLOCKED))
ENDIF
IF IS_PLAYER_PLAYING(PLAYER_ID())
SET_AUTO_GIVE_SCUBA_GEAR_WHEN_EXIT_VEHICLE(PLAYER_ID(), GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_WATER_VEHICLE_SCUBA_GEAR_UNLOCKED))
ENDIF
//Fix for 2140379. On SP startup always restore current player inventory if
//we are already a playable model. Safeguards agsinst returning from MP with
//our weapons blanked.
enumCharacterList ePlayerChar = GET_CURRENT_PLAYER_PED_ENUM()
IF IS_PLAYER_PED_PLAYABLE(ePlayerChar)
CPRINTLN(DEBUG_INIT_SP, "Restoring player inventory for ", GET_PLAYER_PED_STRING(ePlayerChar), " as SP sets up.")
IF HAS_DEFAULT_INFO_BEEN_SET()
RESTORE_PLAYER_PED_WEAPONS(PLAYER_PED_ID())
RESTORE_PLAYER_PED_ARMOUR(PLAYER_PED_ID())
RESTORE_PLAYER_PED_TATTOOS(PLAYER_PED_ID())
RESTORE_PLAYER_PED_VARIATIONS(PLAYER_PED_ID())
CDEBUG1LN(DEBUG_INIT_SP, "Inventory restored.")
ELSE
CDEBUG1LN(DEBUG_INIT_SP, "Default data wasn't set up. Didn't restore inventory.")
ENDIF
ENDIF
//Block all REs from launching for 1 minute after the game has started up.
g_iLastRandomEventLaunch = GET_GAME_TIMER() - 90000 // GET_GAME_TIMER() - (iMinTimeBetweenLaunches - 60000)
//Lock prison doors on first startup
SET_LOCKED_UNSTREAMED_IN_DOOR_OF_TYPE(PROP_GATE_PRISON_01, <<1845, 2605, 45>>, TRUE)
SET_LOCKED_UNSTREAMED_IN_DOOR_OF_TYPE(PROP_GATE_PRISON_01, << 1819.2744, 2608.5369, 44.6195 >>, TRUE, 0, 50)
// Ensure the flow initialises it's state as rapidly as possible by processing all strands on the first frame it runs.
g_flowUnsaved.bFlowProcessAllStrandsNextFrame = TRUE
ENDPROC
//Pre requests the MP_STATS_TEXT_SLOT for SP pause menu use
PROC PreRequestStatsTextSlot()
IF NOT HAS_ADDITIONAL_TEXT_LOADED(MP_STATS_TEXT_SLOT)
REQUEST_ADDITIONAL_TEXT("MISHSTA",MP_STATS_TEXT_SLOT)
CPRINTLN(debug_init_sp,"MISHSTA requested early in MP_STATS_TEXT_SLOT")
ENDIF
ENDPROC
PROC Output_Feature_List()
CPRINTLN(debug_init_sp, "List of features turned on:")
CPRINTLN(debug_init_sp, "...FEATURE_MENTAL_STATE")
CPRINTLN(debug_init_sp, "...FEATURE_FULL_BODY_INTERACTIONS")
#IF FEATURE_APARTMENT_FURNITURE
CPRINTLN(debug_init_sp, "...FEATURE_APARTMENT_FURNITURE")
#ENDIF
CPRINTLN(debug_init_sp, "...FEATURE_BIG_FEED_PLAYER_DATA")
CPRINTLN(debug_init_sp, "...FEATURE_NEW_DRINKING_ACTIVITIES")
#IF FEATURE_NEW_GYM_ACTIVITIES
CPRINTLN(debug_init_sp, "...FEATURE_NEW_GYM_ACTIVITIES")
#ENDIF
CPRINTLN(debug_init_sp, "...FEATURE_HEIST_PLANNING")
CPRINTLN(debug_init_sp, "...FEATURE_VS_MISSION_ROUNDS")
CPRINTLN(debug_init_sp, "...FEATURE_SELFIE_INTERACTIONS")
CPRINTLN(debug_init_sp, "...FEATURE_INTERACTIONS_BUSINESS2")
CPRINTLN(debug_init_sp, "...FEATURE_INTERACTIONS_HIPSTER")
#IF FEATURE_INTERACTIONS_SPORTS
CPRINTLN(debug_init_sp, "...FEATURE_INTERACTIONS_SPORTS")
#ENDIF
#IF FEATURE_INTERACTIONS_ARMY
CPRINTLN(debug_init_sp, "...FEATURE_INTERACTIONS_ARMY")
#ENDIF
#IF FEATURE_INTERACTIONS_UNKNOWN
CPRINTLN(debug_init_sp, "...FEATURE_INTERACTIONS_UNKNOWN")
#ENDIF
CPRINTLN(debug_init_sp, "...FEATURE_INTERACTIONS_REENTRY_IDLES")
CPRINTLN(debug_init_sp, "...FEATURE_SYNCED_INTERACTIONS")
#IF FEATURE_BATHROOM_ACTIVITIES
CPRINTLN(debug_init_sp, "...FEATURE_BATHROOM_ACTIVITIES")
#ENDIF
#IF FEATURE_BENCH_RELATIONSHIPS
CPRINTLN(debug_init_sp, "...FEATURE_BENCH_RELATIONSHIPS")
#ENDIF
CPRINTLN(debug_init_sp, "...FEATURE_INDEPENDENCE")
CPRINTLN(debug_init_sp, "...FEATURE_LASTTEAMSTANDING")
CPRINTLN(debug_init_sp, "...FEATURE_RADIO_ANIMS")
CPRINTLN(debug_init_sp, "...FEATURE_INDEPENDANT_RADIO")
CPRINTLN(debug_init_sp, "...FEATURE_32_PLAYERS_NG")
CPRINTLN(debug_init_sp, "...FEATURE_PILOT_SCHOOL")
#IF FEATURE_ARMY
CPRINTLN(debug_init_sp, "...FEATURE_ARMY")
#ENDIF
#IF FEATURE_CLIFFORD
CPRINTLN(debug_init_sp, "...FEATURE_CLIFFORD")
#ENDIF
CPRINTLN(debug_init_sp, "...FEATURE_XMAS_2014")
CPRINTLN(debug_init_sp, "...FEATURE_CASH_TRANSACTIONS")
ENDPROC
// ===========================================================================================================
SCRIPT
CPRINTLN(DEBUG_INIT_SP, "Initial.sc started.")
// Graeme - this doesn't seem like a good thing to do, but I need to make the script either safe for network game
// or make it clean up when HAS_FORCE_CLEANUP_OCCURRED(FORCE_CLEANUP_FLAG_SP_TO_MP) returns TRUE.
// The second option doesn't seem like a good idea either. How are we going to deal with the player entering
// multiplayer while this script is running e.g. the player accepts an invite on the XMB/Dashboard
NETWORK_SET_SCRIPT_IS_SAFE_FOR_NETWORK_GAME()
//Put in for Bug 1529877 - Joining MP got stuck waiting for Initial to end, but it was paused so never ended (Ryan, Alwyn, Brenda)
DISABLE_CONTROL_ACTION(FRONTEND_CONTROL, INPUT_FRONTEND_PAUSE)
Setup_SP_Game_State()
Initialise_Mission_Flow_Global_Variables_On_SP_Startup()
Initialise_Player_Scene_Global_Variables_On_SP_Startup()
PRIVATE_Clean_None_Save_Communications_On_Startup()
Clean_Non_Save_Help_Text_On_Startup()
// DO_MISSION_STAT_INITIAL_CONFIGURATION()
//CHECK_REPLAY_MISSION_STAT_STATE()
IF g_bRestoredSaveThisSession
IF NOT g_bHaveBeenInMultiplayer OR g_bRunMultiplayerOnStartup
Validate_And_Repair_Restored_Game()
PRIVATE_update_new_queue_timers_from_save()
PRIVATE_update_friend_timers_from_save()
PRIVATE_Update_Saved_Comms_Game_Clock()
ENDIF
ENDIF
g_bRunMultiplayerOnStartup = FALSE
IF GET_INDEX_OF_CURRENT_LEVEL() != LEVEL_NET_TEST
Start_SP_Control_Scripts()
ENDIF
Define_Restore_Launched_ScriptNames()
Request_and_Load_Scripts_for_Restore_Launch()
RESTORE_MINIGAME_BLIPS_AFTER_LOAD()
//B* 2147034: Pre-request the text slot since nothing else in SP uses it.
PreRequestStatsTextSlot()
// Request the debug script.
// Only needs to be done the first time initial is run as debug is persistent.
#IF IS_DEBUG_BUILD
IF GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(HASH("script_metrics")) = 0
Request_And_Launch_Metrics_Script_With_Wait()
ENDIF
//Check all jump labels have valid debug strings.
// INT iLabelIndex
// REPEAT MAX_LABELS iLabelIndex
// JUMP_LABEL_IDS eCurrentLabel = INT_TO_ENUM(JUMP_LABEL_IDS, iLabelIndex)
// CPRINTLN(DEBUG_INIT_SP, "Checking debug string for label ", GET_LABEL_DISPLAY_STRING_FROM_LABEL_ID(eCurrentLabel))
// ENDREPEAT
#ENDIF
//Clean up heist selections if the flow has stepped backwards.
Reset_Heist_Selections()
Output_Feature_List()
//Put in for Bug 1529877 - Joining MP got stuck waiting for Initial to end, but it was paused so never ended. (Ryan, Alwyn, Brenda)
ENABLE_CONTROL_ACTION(FRONTEND_CONTROL, INPUT_FRONTEND_PAUSE)
CPRINTLN(DEBUG_INIT_SP, "Initial.sc ended.\n")
TERMINATE_THIS_THREAD()
ENDSCRIPT