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, " 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, " 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, " Checking hash at index ", iCommandIndex, ".") IF iHashToFind = GET_FLOW_COMMAND_HASH_ID(iCommandIndex) g_savedGlobals.sFlow.strandSavedVars[paramStrandIndex].thisCommandPos = iCommandIndex CPRINTLN(DEBUG_INIT_SP, " Found hash match at index ", iCommandIndex, ". Strand repaired.") RETURN TRUE ENDIF ENDFOR CPRINTLN(DEBUG_INIT_SP, " 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, " 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 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 data repair failed.") //SCRIPT_ASSERT("Show repair failed screen.") EXIT ENDIF ENDIF ENDREPEAT IF bRepairing PRINTLN(DEBUG_INIT_SP, " 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