// // filename: commands_streaming.cpp // description: Commands for streaming // // --- Include Files ------------------------------------------------------------ #include "script/commands_streaming.h" // C headers // Rage headers #include "script/hash.h" #include "script/wrapper.h" // Framework headers #include "fwscene/stores/mapdatastore.h" #include "fwanimation/anim_channel.h" #include "fwanimation/animmanager.h" #include "fwrenderer/renderthread.h" #include "fwscene/stores/imapgroup.h" #include "fwscene/stores/boxstreamerassets.h" #include "fwscene/stores/staticboundsstore.h" #include "vfx/channel.h" #include "vfx/ptfx/ptfxmanager.h" // Game headers #include "camera/CamInterface.h" #include "camera/switch/SwitchDirector.h" #include "control/replay/Effects/ParticleMiscFxPacket.h" #include "ModelInfo/ModelInfo.h" #include "ModelInfo/ModelInfo_Factories.h" #include "modelInfo/PedModelInfo.h" #include "modelInfo/MloModelInfo.h" #include "modelInfo/VehicleModelInfo.h" #include "network/NetworkInterface.h" #include "scene/entities/compEntity.h" #include "scene/FocusEntity.h" #include "scene/LoadScene.h" #include "scene/playerswitch/PlayerSwitchInterface.h" #include "scene/streamer/SceneStreamerMgr.h" #include "scene/streamer/StreamVolume.h" #include "scene/WarpManager.h" #include "scene/world/GameWorldHeightMap.h" #include "script/Handlers/GameScriptResources.h" #include "script/script.h" #include "script/script_cars_and_peds.h" #include "script/script_helper.h" #include "streaming/IslandHopper.h" #include "streaming/populationstreaming.h" #include "streaming/streaming.h" #include "streaming/streamingmodule.h" #include "streaming/streamingengine.h" #include "streaming/streamingrequestlist.h" #include "scene/portals/portal.h" #include "scene/lod/LodMgr.h" #include "scene/lod/LodScale.h" #include "fwsys/timer.h" #include "scene/ipl/IplCullBox.h" #include "scene/texLod.h" #include "spatialdata/sphere.h" #include "vfx/systems/vfxscript.h" #include "peds/ped.h" #include "renderer/HorizonObjects.h" #include "vehicleai/pathfind.h" #include "control/gamelogic.h" #include "peds/PlayerInfo.h" #include "vfx/particles/PtFxManager.h" #include "system/FileMgr.h" #if __BANK #include "debug/Rendering/DebugLighting.h" #endif #if __ASSERT #include "frontend/PauseMenu.h" #include "frontend/loadingscreens.h" #endif // --- Defines ------------------------------------------------------------------ // --- Constants ---------------------------------------------------------------- // --- Structure/Class Definitions ---------------------------------------------- // --- Globals ------------------------------------------------------------------ // --- Static Globals ----------------------------------------------------------- // --- Static class members ----------------------------------------------------- #if __ASSERT u32 g_lastLoadSceneFrame = 0; class scrThread* g_lastLoadThread = NULL; Vector3 g_lastLoadSceneCoord(0.0f, 0.0f, 0.0f); #define SET_LOAD_SCENE_FRAME(vCoord) { g_lastLoadSceneFrame = fwTimer::GetSystemFrameCount(); g_lastLoadThread = scrThread::GetActiveThread(); g_lastLoadSceneCoord=vCoord;} #define ASSERT_NO_LOAD_SCENE(cmd) Assertf(g_lastLoadSceneFrame != fwTimer::GetSystemFrameCount() || g_lastLoadThread != scrThread::GetActiveThread(), "SCRIPT: %s Running %s after a load scene could remove some of the scene you have just loaded", CTheScripts::GetCurrentScriptNameAndProgramCounter(), cmd); #define ASSERT_NO_LOAD_SCENE_AT_COORDS(cmd, vCoord) Assertf(g_lastLoadSceneFrame != fwTimer::GetSystemFrameCount() || g_lastLoadThread != scrThread::GetActiveThread() || (g_lastLoadSceneCoord.Dist(vCoord) < 5.0f), "SCRIPT: %s Running %s after a load scene could remove some of the scene you have just loaded. Original Coord=%f,%f,%f, New Coord=%f,%f,%f", CTheScripts::GetCurrentScriptNameAndProgramCounter(), cmd, g_lastLoadSceneCoord.x, g_lastLoadSceneCoord.y, g_lastLoadSceneCoord.z, vCoord.x, vCoord.y, vCoord.z); #else #define SET_LOAD_SCENE_FRAME(vCoord) #define ASSERT_NO_LOAD_SCENE(cmd) #define ASSERT_NO_LOAD_SCENE_AT_COORDS(cmd, vCoord) #endif // --- Code --------------------------------------------------------------------- namespace streaming_commands { u32 g_additionalStreamingRequestFlags=0; //PURPOSE: Does checks on HasLoaded requests from streaming class CScriptStreamingChecker { struct HasLoadedRecord { HasLoadedRecord() {numberOfChecks = 0;} bool IsOld() {return fwTimer::GetSystemFrameCount() - lastCheckTime > 1;} void IncrementCheck() {lastCheckTime = fwTimer::GetSystemFrameCount(); numberOfChecks++;} int lastCheckTime; int numberOfChecks; }; public: bool HasObjectLoaded(strLocalIndex objId, int moduleId); void RemoveEntry(int id) {m_hasLoadedRecordMap.Delete(id);} void RemoveOld() { atMap::Iterator iHasLoaded = m_hasLoadedRecordMap.CreateIterator(); while(!iHasLoaded.AtEnd()) { if(iHasLoaded.GetData().IsOld()) { m_hasLoadedRecordMap.Delete(iHasLoaded.GetKey()); iHasLoaded.Start(); } else iHasLoaded.Next(); } } void IncrementCheck(int id) {m_hasLoadedRecordMap[id].IncrementCheck();} int GetNumberOfChecks(int id) {return m_hasLoadedRecordMap[id].numberOfChecks;} private: atMap m_hasLoadedRecordMap; }; bool CScriptStreamingChecker::HasObjectLoaded(strLocalIndex objId, int moduleId) { #if __ASSERT int streamingId = strStreamingEngine::GetInfo().GetModuleMgr().GetModule(moduleId)->GetStreamingIndex(strLocalIndex(objId)).Get(); RemoveOld(); IncrementCheck(streamingId); int checks = GetNumberOfChecks(streamingId); if(checks > 100 && (checks%20) == 0) Displayf("Waiting on %s to load (%d times)", strStreamingEngine::GetInfo().GetModuleMgr().GetModule(moduleId)->GetName(strLocalIndex(objId)), checks); #endif bool rt = CStreaming::HasObjectLoaded(objId, moduleId); #if __ASSERT // Graeme already checks for this so this isnt necessary // scriptAssertf(rt == true || CStreaming::IsObjectRequested(objId, moduleId) || CStreaming::IsObjectLoading(objId, moduleId), // "You must request %s before checking if it has loaded", strStreamingEngine::GetInfo().GetModuleMgr().GetModule(moduleId)->GetName(objId)); if(rt) RemoveEntry(streamingId); #endif return rt; } static CScriptStreamingChecker g_streamingChecker; // // name: CommandRequestModel // description: Request a model to be loaded void CommandRequestModel(int ModelHashKey) { ASSERT_NO_LOAD_SCENE("REQUEST_MODEL"); fwModelId ModelId; CBaseModelInfo* pModelInfo = CModelInfo::GetBaseModelInfoFromHashKey((u32) ModelHashKey, &ModelId); if (scriptVerifyf(pModelInfo, "%s: REQUEST_MODEL - model with hash %d does not exist", CTheScripts::GetCurrentScriptNameAndProgramCounter(), ModelHashKey)) { if (scriptVerifyf(ModelId.IsValid(), "%s: REQUEST_MODEL - model with hash %d exists but its model index is invalid", CTheScripts::GetCurrentScriptNameAndProgramCounter(), ModelHashKey)) { CScriptResource_Model model(ModelHashKey, g_additionalStreamingRequestFlags); bool bHasJustBeenAdded = false; CTheScripts::GetCurrentGtaScriptHandler()->RegisterScriptResource(model, &bHasJustBeenAdded); if (bHasJustBeenAdded) { scriptHandler *pAnotherScriptWhichHasRequestedThisModel = CTheScripts::GetScriptHandlerMgr().GetScriptHandlerForResource(CGameScriptResource::SCRIPT_RESOURCE_MODEL, ModelHashKey, CTheScripts::GetCurrentGtaScriptHandler()); if (pAnotherScriptWhichHasRequestedThisModel == NULL) { fwArchetypeManager::AddArchetypeToTypeFileRef(pModelInfo); } else { scriptDisplayf("%s: REQUEST_MODEL - another script (%s) has already requested the model with hash %d so don't call AddArchetypeToTypeFileRef() for it", CTheScripts::GetCurrentScriptNameAndProgramCounter(), pAnotherScriptWhichHasRequestedThisModel->GetLogName(), ModelHashKey); } } g_additionalStreamingRequestFlags = 0; } } } void CommandRequestMenuPedModel(int ModelHashKey) { g_additionalStreamingRequestFlags |= STRFLAG_PRIORITY_LOAD | STRFLAG_FORCE_LOAD; CommandRequestModel(ModelHashKey); } // // name: HasModelLoaded // description: Return if a model has loaded bool HasModelLoaded(int ModelHashKey) { fwModelId modelId; CBaseModelInfo* pModelInfo = CModelInfo::GetBaseModelInfoFromHashKey(ModelHashKey, &modelId); if(SCRIPT_VERIFY( modelId.IsValid(), "HAS_MODEL_LOADED - this is not a valid model index")) { if(scriptVerifyf(pModelInfo, "HAS_MODEL_LOADED - Model [%d] does not exist", ModelHashKey)) { #if !__FINAL if (CTheScripts::GetCurrentGtaScriptHandler()) { scriptAssertf(CTheScripts::GetCurrentGtaScriptHandler()->GetScriptResource(CGameScriptResource::SCRIPT_RESOURCE_MODEL, ModelHashKey), "HAS_MODEL_LOADED - %s has not requested model %s", CTheScripts::GetCurrentScriptNameAndProgramCounter(), CModelInfo::GetBaseModelInfoName(modelId) ); } #endif // if not a MLO then check the object, otherwise check all objects in room 0 of MLO if (pModelInfo->GetModelType() == MI_TYPE_MLO) { return(static_cast(pModelInfo)->HaveObjectsInRoomLoaded("limbo")); // "limbo" is always the name of room 0 } else { strLocalIndex transientLocalIdx = CModelInfo::LookupLocalIndex(modelId); return (g_streamingChecker.HasObjectLoaded(transientLocalIdx, CModelInfo::GetStreamingModuleId())); } } } return false; } // // name: RequestInteriorModels // description: Request that all the models in the given room load in void RequestInteriorModels(int ModelHashKey, const char* pRoomName) { fwModelId ModelId; CBaseModelInfo* pModelInfo = CModelInfo::GetBaseModelInfoFromHashKey((u32) ModelHashKey, &ModelId); if(SCRIPT_VERIFY( ModelId.IsValid(), "REQUEST_INTERIOR_MODELS - this is not a valid model index")) { if(SCRIPT_VERIFY( (pModelInfo->GetModelType() == MI_TYPE_MLO), "REQUEST_INTERIOR_MODELS - model is not an interior")) { static_cast(pModelInfo)->RequestObjectsInRoom("limbo", g_additionalStreamingRequestFlags); // always attempt to load room 0 objects too static_cast(pModelInfo)->RequestObjectsInRoom((char *) pRoomName, g_additionalStreamingRequestFlags); } } g_additionalStreamingRequestFlags = 0; } // issue model requests for the given room in this interior void RequestModelsInRoom(int InteriorProxyIndex, const char* roomName) { if (SCRIPT_VERIFY( InteriorProxyIndex != NULL_IN_SCRIPTING_LANGUAGE, "REQUEST_MODELS_IN_ROOM - Interior index isn't valid")) { // get the interior CInteriorProxy *pIntProxy = CInteriorProxy::GetPool()->GetAt(InteriorProxyIndex); if (SCRIPT_VERIFY(pIntProxy, "REQUEST_MODELS_IN_ROOM - Interior proxy doesn't exist")) { // get the interior CInteriorInst *pIntInst = pIntProxy->GetInteriorInst(); if (SCRIPT_VERIFY(pIntInst, "REQUEST_MODELS_IN_ROOM - Interior is not yet populated")) { s32 roomId = pIntInst->FindRoomByHashcode(atHashString(roomName)); if (scriptVerifyf(roomId > -1, "%s: REQUEST_MODELS_IN_ROOM - unknown room (%s) in interior (%s)", CTheScripts::GetCurrentScriptNameAndProgramCounter(), roomName, pIntProxy->GetName().GetCStr())) { pIntInst->RequestRoom(roomId, g_additionalStreamingRequestFlags); } } } } } // // name: LoadSceneForRoomByKey // description: Loads the room models void LoadSceneForRoomByKey(int interiorInstance, int roomKey) { CInteriorProxy* pIntProxy = CInteriorProxy::GetPool()->GetAt(interiorInstance); Assert(pIntProxy); CInteriorInst* pInterior = pIntProxy->GetInteriorInst(); if(SCRIPT_VERIFY(pInterior, "LOAD_SCENE_FOR_ROOM_BY_KEY - Interior doesn't exist")) { s32 roomIndex = pInterior->FindRoomByHashcode(roomKey); if(SCRIPT_VERIFY(roomIndex > 0, "LOAD_SCENE_FOR_ROOM_BY_KEY - room key invalid")) { g_SceneStreamerMgr.LoadInteriorRoom(pInterior, roomIndex); } } } void CommandActivateInterior(int interiorInstance, bool bActivate) { CInteriorProxy* pIntProxy = CInteriorProxy::GetPool()->GetAt(interiorInstance); Assert(pIntProxy); CInteriorInst* pInterior = pIntProxy->GetInteriorInst(); if(SCRIPT_VERIFY(pInterior, "SET_INTERIOR_ACTIVE - Interior doesn't exist")) { if (bActivate) { // CPortal::AddToActiveInteriorList(pInterior); } else { // CPortal::RemoveFromActiveInteriorList(pInterior); } } } // // name: CommandMarkModelAsNoLongerNeeded // description: Set model to be deleteable void CommandMarkModelAsNoLongerNeeded(int ModelHashKey) { fwModelId ModelId; CBaseModelInfo* pModelInfo = CModelInfo::GetBaseModelInfoFromHashKey((u32) ModelHashKey, &ModelId); if (SCRIPT_VERIFY( pModelInfo, "SET_MODEL_AS_NO_LONGER_NEEDED - model does not exist")) { if (CTheScripts::GetCurrentGtaScriptHandler()) { CTheScripts::GetCurrentGtaScriptHandler()->RemoveScriptResource(CGameScriptResource::SCRIPT_RESOURCE_MODEL, ModelHashKey); } } } // // name: RequestCollisionAtPosn // description: Request collision about point is loaded void RequestCollisionAtPosn(const scrVector & scrVecCoors) { ASSERT_ONLY(Vector3 vCoord(scrVecCoors);) ASSERT_NO_LOAD_SCENE_AT_COORDS("REQUEST_COLLISION_AT_COORD", vCoord); g_StaticBoundsStore.GetBoxStreamer().Deprecated_AddSecondarySearch((Vec3V) scrVecCoors); } // // name: RequestMoverCollisionOnly // description: sets the standard collision streaming to only request mover collision and ignore weapon collision. // should be called each frame, otherwise we revert to requesting both weapon and mover collision void RequestMoverCollisionOnly() { g_StaticBoundsStore.GetBoxStreamer().OverrideRequiredAssets(fwBoxStreamerAsset::FLAG_STATICBOUNDS_MOVER); } // // name: RequestCollision // description: Request that collision (physics dictionary) be loaded void RequestCollisionForModel(int ModelHashKey) { CommandRequestModel(ModelHashKey); } bool HasCollisionForModelLoaded(int ModelHashKey) { fwModelId ModelId; CBaseModelInfo* pModelInfo = CModelInfo::GetBaseModelInfoFromHashKey((u32) ModelHashKey, &ModelId); // ignores return value if(SCRIPT_VERIFY( ModelId.IsValid(), "HAS_COLLISION_FOR_MODEL_LOADED - this is not a valid model index")) { if (pModelInfo->GetHasLoaded() && pModelInfo->GetHasBoundInDrawable()) return true; return (pModelInfo->GetPhysics() != NULL); } return false; } // // name: DoesAnimDictExist // description: Return if animation dictionary exists bool DoesAnimDictExist(const char* pName) { strLocalIndex index = fwAnimManager::FindSlot(pName); if(index.IsValid()) { return true; } return false; } // // name: RequestAnimDict // description: Request that animation dictionary be loaded void RequestAnimDict(const char* pName) { ASSERT_NO_LOAD_SCENE("REQUEST_ANIMS"); strLocalIndex index = fwAnimManager::FindSlot(pName); animDebugf3("REQUEST_ANIM_DICT - %s - Anim Dict %s (Slot index: %d)", CTheScripts::GetCurrentScriptNameAndProgramCounter(), pName, index.Get()); if(SCRIPT_VERIFY_TWO_STRINGS(index.IsValid(), "REQUEST_ANIM_DICT - Anim dict name does not exist: ", pName)) { if (CTheScripts::GetCurrentGtaScriptHandler()) { CScriptResource_Animation animation(index.Get(), g_additionalStreamingRequestFlags); CTheScripts::GetCurrentGtaScriptHandler()->RegisterScriptResource(animation); } } g_additionalStreamingRequestFlags = 0; } // // name: HasAnimDictLoaded // description: Return if animation dictionary is in memory bool HasAnimDictLoaded(const char* pName) { strLocalIndex index = fwAnimManager::FindSlot(pName); animDebugf3("HAS_ANIM_DICT_LOADED - %s - Anim Dict %s (Slot index: %d)", CTheScripts::GetCurrentScriptNameAndProgramCounter(), pName, index.Get()); if(SCRIPT_VERIFY_TWO_STRINGS(index != -1, "HAS_ANIM_DICT_LOADED - Anim dict name does not exist: ", pName)) { if (CTheScripts::GetCurrentGtaScriptHandler()) { scriptAssertf(CTheScripts::GetCurrentGtaScriptHandler()->GetScriptResource(CGameScriptResource::SCRIPT_RESOURCE_ANIMATION, index.Get()), "HAS_ANIM_DICT_LOADED - %s has not requested %s", CTheScripts::GetCurrentScriptNameAndProgramCounter(), pName); } return g_streamingChecker.HasObjectLoaded(index, fwAnimManager::GetStreamingModuleId()); } return false; } // // name: RemoveAnimDict // description: Remove animation dictionary void RemoveAnimDict(const char* pName) { s32 index = fwAnimManager::FindSlot(pName).Get(); animDebugf3("REMOVE_ANIM_DICT - %s - Anim Dict %s (Slot index: %d)", CTheScripts::GetCurrentScriptNameAndProgramCounter(), pName, index); if(SCRIPT_VERIFY_TWO_STRINGS(index != -1, "REMOVE_ANIM_DICT - Anim dict name does not exist: ", pName)) { if (CTheScripts::GetCurrentGtaScriptHandler()) { CTheScripts::GetCurrentGtaScriptHandler()->RemoveScriptResource(CGameScriptResource::SCRIPT_RESOURCE_ANIMATION, index); } } } // // name: RequestClipSet // description: Requests a clipset (and its fallbacks) to load void RequestClipSet(const char* pName) { ASSERT_NO_LOAD_SCENE("REQUEST_CLIP_SET"); fwMvClipSetId clipSetId(pName); animDebugf3("REQUEST_CLIP_SET - %s - ClipSet %s (ClipSetId: %u)", CTheScripts::GetCurrentScriptNameAndProgramCounter(), pName, clipSetId.GetHash()); fwClipSet* pSet = fwClipSetManager::GetClipSet(clipSetId); if (SCRIPT_VERIFY_TWO_STRINGS(pSet != NULL, "REQUEST_CLIP_SET - Invalid ClipSet name: ", pName)) { scriptResource* pResource = CTheScripts::GetCurrentGtaScriptHandler()->GetScriptResource(CGameScriptResource::SCRIPT_RESOURCE_CLIP_SET, clipSetId); if (!pResource) { CScriptResource_ClipSet newClipSetResource(clipSetId); CTheScripts::GetCurrentGtaScriptHandler()->RegisterScriptResource(newClipSetResource); fwClipSetManager::Script_AddAndRequestClipSet(clipSetId); } else { fwClipSetManager::Script_RequestClipSet(clipSetId); } } } // // name: HasClipSetLoaded // description: Return if the clipset is in memory bool HasClipSetLoaded(const char* pName) { fwMvClipSetId clipSetId(pName); fwClipSet* pSet = fwClipSetManager::GetClipSet(clipSetId); animDebugf3("HAS_CLIP_SET_LOADED - %s - ClipSet %s (ClipSetId: %u)", CTheScripts::GetCurrentScriptNameAndProgramCounter(), pName, clipSetId.GetHash()); if (SCRIPT_VERIFY_TWO_STRINGS(pSet != NULL, "HAS_CLIP_SET_LOADED - Invalid ClipSet name: ", pName)) { scriptResource* pResource = CTheScripts::GetCurrentGtaScriptHandler()->GetScriptResource(CGameScriptResource::SCRIPT_RESOURCE_CLIP_SET, clipSetId); if (pResource) { return fwClipSetManager::Script_HasClipSetLoaded(clipSetId); } else { scriptWarningf("HAS_CLIP_SET_LOADED - Could not find clip set resource for %s - was this clipset requested?", clipSetId.TryGetCStr()); } } return false; } // // name: RemoveClipSet // description: Remove/Unload a clipset (and its fallbacks). void RemoveClipSet(const char* pName) { fwMvClipSetId clipSetId(pName); fwClipSet* pSet = fwClipSetManager::GetClipSet(clipSetId); animDebugf3("REMOVE_CLIP_SET - %s - ClipSet %s (ClipSetId: %u)", CTheScripts::GetCurrentScriptNameAndProgramCounter(), pName, clipSetId.GetHash()); if (SCRIPT_VERIFY_TWO_STRINGS(pSet != NULL, "REMOVE_CLIP_SET - Invalid ClipSet name: ", pName)) { scriptResource* pResource = CTheScripts::GetCurrentGtaScriptHandler()->GetScriptResource(CGameScriptResource::SCRIPT_RESOURCE_CLIP_SET, clipSetId); if (pResource) { CTheScripts::GetCurrentGtaScriptHandler()->RemoveScriptResource(CGameScriptResource::SCRIPT_RESOURCE_CLIP_SET, clipSetId, false, true); } else { scriptWarningf("REMOVE_CLIP_SET - Could not find clip set resource for %s - was this clipset requested?", clipSetId.TryGetCStr()); } } } // // name: RequestIpl // description: Request Ipl file void RequestIpl(const char* pName) { s32 index = INSTANCE_STORE.FindSlot(pName).Get(); if(SCRIPT_VERIFY_TWO_STRINGS(index != -1, "REQUEST_IPL - IPL group does not exist", pName)) { u32 iplNameHash = atStringHash(pName); Displayf("%s called REQUEST_IPL(%s)", CTheScripts::GetCurrentScriptNameAndProgramCounter(), pName); scriptAssertf(!g_LoadScene.IsActive(), "[script] Don't modify Ipl groups (%s) whilst load scene is active! (Load scene triggered by %s)", pName, g_LoadScene.WasStartedByScript() ? g_LoadScene.GetScriptName().c_str() : "CODE"); INSTANCE_STORE.RequestGroup(strLocalIndex(index), iplNameHash); CCompEntity::UpdateCompEntitiesUsingGroup(index, CE_STATE_INIT); // url:bugstar:6571961 - enable the heightmap specifically for the heist island if(iplNameHash == ATSTRINGHASH("h4_islandx_mansion", 0x9a95c101)) { CGameWorldHeightMap::EnableHeightmap("heightmapheistisland", true); } } } // // name: RemoveIpl // description: Remove Ipl file void RemoveIpl(const char* pName) { strLocalIndex index = strLocalIndex(INSTANCE_STORE.FindSlot(pName)); if(SCRIPT_VERIFY_TWO_STRINGS(index != -1, "REMOVE_IPL - IPL group does not exist", pName)) { u32 iplNameHash = atStringHash(pName); Displayf("%s called REMOVE_IPL(%s)", CTheScripts::GetCurrentScriptNameAndProgramCounter(), pName); scriptAssertf(!g_LoadScene.IsActive(), "[script] Don't modify Ipl groups (%s) whilst load scene is active! (Load scene triggered by %s)", pName, g_LoadScene.WasStartedByScript() ? g_LoadScene.GetScriptName().c_str() : "CODE"); CCompEntity::UpdateCompEntitiesUsingGroup(index.Get(), CE_STATE_ABANDON); ////////////////////////////////////////////////////////////////////////// fwMapDataDef* pDef = fwMapDataStore::GetStore().GetSlot(index); if (pDef && (pDef->GetContentFlags()&fwMapData::CONTENTFLAG_MASK_LODLIGHTS)!=0) { #if __ASSERT const bool bGameIsNotRendering = (camInterface::IsFadedOut() || CLoadingScreens::AreActive() || CPauseMenu::GetPauseRenderPhasesStatus()); // special case - these types of IMAP files contain data that is consumed by GPU so may need to force RT flush if (!bGameIsNotRendering) { scriptWarningf("Script %s called REMOVE_IPL(%s) but the screen is not faded out - this is unsafe because %s contains LOD lights", CTheScripts::GetCurrentScriptNameAndProgramCounter(), pName, pName ); } #endif gRenderThreadInterface.Flush(); } ////////////////////////////////////////////////////////////////////////// INSTANCE_STORE.RemoveGroup(index, iplNameHash); // url:bugstar:6571961 - disable the heightmap specifically for the heist island if(iplNameHash == ATSTRINGHASH("h4_islandx_mansion", 0x9a95c101)) { CGameWorldHeightMap::EnableHeightmap("heightmapheistisland", false); } } } // // name: IsIplActive // description: return if the named ipl is set to be streamable or not bool IsIplActive(const char* pName) { strLocalIndex index = strLocalIndex(INSTANCE_STORE.FindSlot(pName)); if(SCRIPT_VERIFY_TWO_STRINGS(index != -1, "IS_IPL_ACTIVE - IPL group does not exist", pName)) { return(INSTANCE_STORE.GetIsStreamable(index)); } return(false); } // // Loads selected water.xml file: // 0 - main V water file // 1 - Island Heist DLC water file // void LoadGlobalWaterFile(s32 waterXmlID) { Assertf((waterXmlID==Water::WATERXML_V_DEFAULT) || (waterXmlID==Water::WATERXML_ISLANDHEIST), "LOAD_GLOBAL_WATER_FILE: Invalid waterID id (%d)!", waterXmlID); Water::RequestGlobalWaterXmlFile(waterXmlID); } // // // // s32 GetGlobalWaterFile() { return Water::GetGlobalWaterXmlFile(); } // // name: LoadAllObjectsNow // description: Loads all the objects on the request list void LoadAllObjectsNow() { Assertf(!camInterface::IsFadedIn(), "Don't call LOAD_ALL_OBJECTS_NOW while the game isn't faded out - it will cause stutters on disc builds."); // Ensure that all requests are issued this frame ThePaths.UpdateStreaming(true); CStreaming::LoadAllRequestedObjects(); } // // name: LoadScene // description: Load scene about point void LoadScene(const scrVector & scrVecCoors) { if ( scriptVerifyf(!g_PlayerSwitch.IsActive(), "Calling LOAD_SCENE while a player switch is in progress is not safe! %s", CTheScripts::GetCurrentScriptNameAndProgramCounter()) ) { SCRIPT_ASSERT( !NetworkInterface::IsGameInProgress(), "You should use NETWORK_START_LOAD_SCENE/NETWORK_UPDATE_LOAD_SCENE in network games!"); Vector3 VecCoors (scrVecCoors); ASSERT_NO_LOAD_SCENE_AT_COORDS("LOAD_SCENE", VecCoors); Printf("Script \"%s\" requested a load scene at %f,%f,%f\n", CTheScripts::GetCurrentScriptName(), VecCoors.x, VecCoors.y, VecCoors.z); g_SceneStreamerMgr.LoadScene(VecCoors); SET_LOAD_SCENE_FRAME(VecCoors); } } // // name: StartLoadScene // description: Load scene about point void StartLoadScene(const scrVector & scrVecCoors) { SCRIPT_ASSERT(false, "Script is calling NETWORK_START_LOAD_SCENE. Don't use that, use the NEW_LOAD_SCENE commands instead. Game may crash soon."); Vector3 VecCoors (scrVecCoors); ASSERT_NO_LOAD_SCENE_AT_COORDS("NETWORK_START_LOAD_SCENE", VecCoors); Printf("Script \"%s\" requested a load scene at %f,%f,%f\n", CTheScripts::GetCurrentScriptName(),VecCoors.x, VecCoors.y, VecCoors.z); g_SceneStreamerMgr.StartLoadScene(VecCoors); } // // name: UpdateLoadScene // description: Load scene about point bool UpdateLoadScene() { return g_SceneStreamerMgr.UpdateLoadScene(); } // name: StopLoadScene // description: abandon an async load scene if there is one in progress void StopLoadScene() { Printf("Script %s called NETWORK_STOP_LOAD_SCENE\n", CTheScripts::GetCurrentScriptName()); // if (g_SceneStreamerMgr.IsLoading()) { g_SceneStreamerMgr.StopLoadScene(); } } bool IsLoadSceneActive() { return g_SceneStreamerMgr.IsLoading(); } // // name: IsModelInCdImage // description: Returns if model is currently valid bool IsModelInCdImage(s32 modelHash) { fwModelId modelId; CModelInfo::GetBaseModelInfoFromHashKey(modelHash, &modelId); if (!modelId.IsValid()) { return false; } return true; } bool CommandIsModelValid(s32 modelHash) { fwModelId modelId; CModelInfo::GetBaseModelInfoFromHashKey(modelHash, &modelId); if (modelId.IsValid()) { if (modelId.IsGlobal()) { return true; } } return false; } bool CommandGetPedModelFromIndex(int iPedModelIndex, int &ReturnPedModelHashKey) { ReturnPedModelHashKey = 0; // Returns false if there is no ped model with that index. // iPedModelIndex starts at 0 and counts up till it returns false. fwArchetypeDynamicFactory& pedModelInfoStore = CModelInfo::GetPedModelInfoStore(); atArray pedTypesArray; pedModelInfoStore.GatherPtrs(pedTypesArray); int numPedsAvail = pedTypesArray.GetCount(); if (iPedModelIndex >= numPedsAvail) { return false; } CPedModelInfo& pedModelInfo = *pedTypesArray[iPedModelIndex]; ReturnPedModelHashKey = (int) pedModelInfo.GetHashKey(); return true; } bool CommandGetVehicleModelFromIndex(int iVehicleModelIndex, int &ReturnVehicleModelHashKey) { ReturnVehicleModelHashKey = 0; // Returns false if there is no vehicle model with that index. // iVehicleModelIndex starts at 0 and counts up till it returns false. fwArchetypeDynamicFactory& vehicleModelInfoStore = CModelInfo::GetVehicleModelInfoStore(); atArray vehicleTypes; vehicleModelInfoStore.GatherPtrs(vehicleTypes); int numVehiclesAvail = vehicleTypes.GetCount(); if (iVehicleModelIndex >= numVehiclesAvail) { return false; } CVehicleModelInfo& vehicleModelInfo = *vehicleTypes[iVehicleModelIndex]; ReturnVehicleModelHashKey = (int) vehicleModelInfo.GetHashKey(); return true; } bool CommandIsThisModelAPed(int ModelHashKey) { bool LatestCmpFlagResult = false; CBaseModelInfo* pModelInfo = CModelInfo::GetBaseModelInfoFromHashKey((u32) ModelHashKey, NULL); if(pModelInfo && pModelInfo->GetModelType()==MI_TYPE_PED) { LatestCmpFlagResult = true; } return LatestCmpFlagResult; } bool CommandIsThisModelAVehicle(int ModelHashKey) { bool LatestCmpFlagResult = false; CBaseModelInfo* pModelInfo = CModelInfo::GetBaseModelInfoFromHashKey((u32) ModelHashKey, NULL); if(pModelInfo && pModelInfo->GetModelType()==MI_TYPE_VEHICLE) { LatestCmpFlagResult = true; } return LatestCmpFlagResult; } // // name: SwitchStreaming // description: Switch streaming on and off void SwitchStreaming(bool bOn) { if (bOn) { CStreaming::EnableStreaming(); } else { CStreaming::DisableStreaming(); } } // // name: EnableSceneStreaming // description: Enable/Disable scene streaming void EnableSceneStreaming(bool bEnable) { CStreaming::EnableSceneStreaming(bEnable); } // Ensure game loads collision and ipls around an additional point. This function needs calling every frame the // additional data is required void AddNeededAtPosn(const scrVector & scrVecCoors) { g_StaticBoundsStore.GetBoxStreamer().Deprecated_AddSecondarySearch((Vec3V)scrVecCoors); } // This should only be called by the end credits script. The credits will call it with FALSE at the start and // TRUE at the end. This is to stop the scrolling of the credits from pausing when the player warps from // one area of the city to another during the screen fades. void AllowGameToPauseForStreaming(bool bAllowPause) { CTheScripts::SetAllowGameToPauseForStreaming(bAllowPause); } void SetReducePedModelBudget(bool bReduce) { gPopStreaming.SetReduceAmbientPedModelBudget(bReduce); } void SetReduceVehicleModelBudget(bool bReduce) { gPopStreaming.SetReduceAmbientVehicleModelBudget(bReduce); } void SetDitchPoliceModels(bool UNUSED_PARAM(bDitch)) { } s32 GetNumStreamingRequests() { return strStreamingEngine::GetInfo().GetNumberRealObjectsRequested(); } bool IsStreamingPriorityRequests() { return strStreamingEngine::GetIsLoadingPriorityObjects(); } // // name: RequestPtFxAsset // description: Request the particle asset be loaded void RequestPtFxAsset() { ASSERT_NO_LOAD_SCENE("REQUEST_PTFX_ASSET"); const char* pScriptName = CTheScripts::GetCurrentScriptName(); atHashWithStringNotFinal ptfxAssetName = g_vfxScript.GetScriptPtFxAssetName(pScriptName); if (ptfxVerifyf(ptfxAssetName.GetHash(), "script %s has no particle asset set up - can't request the asset", pScriptName)) { strLocalIndex slot = ptfxManager::GetAssetStore().FindSlotFromHashKey(ptfxAssetName); if (scriptVerifyf(slot.IsValid(), "%s REQUEST_PTFX_ASSET - cannot find particle asset slot (%s)", CTheScripts::GetCurrentScriptNameAndProgramCounter(), ptfxAssetName.GetCStr())) { CScriptResource_PTFX_Asset ptfxAsset(slot.Get(), g_additionalStreamingRequestFlags); CTheScripts::GetCurrentGtaScriptHandler()->RegisterScriptResource(ptfxAsset); #if GTA_REPLAY g_ptFxManager.SetReplayScriptPtfxAssetID(slot.Get()); #endif } } g_additionalStreamingRequestFlags = 0; } // // name: HasPtFxAssetLoaded // description: Return if particle asset is in memory bool HasPtFxAssetLoaded() { const char* pScriptName = CTheScripts::GetCurrentScriptName(); atHashWithStringNotFinal ptfxAssetName = g_vfxScript.GetScriptPtFxAssetName(pScriptName); if (ptfxVerifyf(ptfxAssetName.GetHash(), "script %s has no particle asset set up - can't check if the asset has loaded", pScriptName)) { strLocalIndex slot = strLocalIndex(ptfxManager::GetAssetStore().FindSlotFromHashKey(ptfxAssetName)); if (scriptVerifyf(slot.IsValid(), "%s HAS_PTFX_ASSET_LOADED - cannot find particle asset slot (%s)", CTheScripts::GetCurrentScriptNameAndProgramCounter(), ptfxAssetName.GetCStr())) { if (CTheScripts::GetCurrentGtaScriptHandler()) { scriptAssertf(CTheScripts::GetCurrentGtaScriptHandler()->GetScriptResource(CGameScriptResource::SCRIPT_RESOURCE_PTFX_ASSET, slot.Get()), "HAS_PTFX_ASSET_LOADED - %s has not requested %s", CTheScripts::GetCurrentScriptNameAndProgramCounter(), ptfxAssetName.GetCStr()); } return ptfxManager::GetAssetStore().HasObjectLoaded(slot); } } return false; } // // name: RemovePtFxAsset // description: Remove particle asset void RemovePtFxAsset() { const char* pScriptName = CTheScripts::GetCurrentScriptName(); atHashWithStringNotFinal ptfxAssetName = g_vfxScript.GetScriptPtFxAssetName(pScriptName); if (ptfxVerifyf(ptfxAssetName.GetHash(), "script %s has no particle asset set up - can't remove the asset", pScriptName)) { if (SCRIPT_VERIFY(ptfxAssetName, "invalid particle asset name")) { strLocalIndex slot = ptfxManager::GetAssetStore().FindSlotFromHashKey(ptfxAssetName); if (scriptVerifyf(slot.IsValid(), "%s REMOVE_PTFX_ASSET - cannot find particle asset slot (%s)", CTheScripts::GetCurrentScriptNameAndProgramCounter(), ptfxAssetName.GetCStr())) { CTheScripts::GetCurrentGtaScriptHandler()->RemoveScriptResource(CGameScriptResource::SCRIPT_RESOURCE_PTFX_ASSET, slot.Get()); #if GTA_REPLAY g_ptFxManager.SetReplayScriptPtfxAssetID(-1); #endif } } } } // // name: RequestNamedPtFxAsset // description: Request that a named particle asset be loaded void RequestNamedPtFxAsset(const char* pPtFxAssetName) { ASSERT_NO_LOAD_SCENE("REQUEST_NAMED_PTFX_ASSET"); u32 assetHash = atStringHash(pPtFxAssetName); s32 slot = ptfxManager::GetAssetStore().FindSlotFromHashKey(assetHash).Get(); if (scriptVerifyf(slot != -1, "%s REQUEST_NAMED_PTFX_ASSET - cannot find particle asset slot (%s)", CTheScripts::GetCurrentScriptNameAndProgramCounter(), pPtFxAssetName)) { CScriptResource_PTFX_Asset ptfxAsset(slot, g_additionalStreamingRequestFlags); CTheScripts::GetCurrentGtaScriptHandler()->RegisterScriptResource(ptfxAsset); #if GTA_REPLAY if(CPacketRequestNamedPtfxAsset::CheckRequestedHash(assetHash)) { CReplayMgr::RecordFx(CPacketRequestNamedPtfxAsset(assetHash)); } #endif // GTA_REPLAY } g_additionalStreamingRequestFlags = 0; } // // name: HasNamedPtFxAssetLoaded // description: Return if particle asset is in memory bool HasNamedPtFxAssetLoaded(const char* pPtFxAssetName) { s32 slot = ptfxManager::GetAssetStore().FindSlotFromHashKey(atStringHash(pPtFxAssetName)).Get(); if (scriptVerifyf(slot != -1, "%s HAS_NAMED_PTFX_ASSET_LOADED - cannot find particle asset slot (%s)", CTheScripts::GetCurrentScriptNameAndProgramCounter(), pPtFxAssetName)) { if (CTheScripts::GetCurrentGtaScriptHandler()) { scriptAssertf(CTheScripts::GetCurrentGtaScriptHandler()->GetScriptResource(CGameScriptResource::SCRIPT_RESOURCE_PTFX_ASSET, slot), "HAS_NAMED_PTFX_ASSET_LOADED - %s has not requested %s", CTheScripts::GetCurrentScriptNameAndProgramCounter(), pPtFxAssetName); } return ptfxManager::GetAssetStore().HasObjectLoaded(strLocalIndex(slot)); } return false; } // // name: RemoveNamedPtFxAsset // description: Remove particle asset void RemoveNamedPtFxAsset(const char* pPtFxAssetName) { u32 assetHash = atStringHash(pPtFxAssetName); s32 slot = ptfxManager::GetAssetStore().FindSlotFromHashKey(assetHash).Get(); if (scriptVerifyf(slot != -1, "%s REMOVE_NAMED_PTFX_ASSET - cannot find particle asset slot (%s)", CTheScripts::GetCurrentScriptNameAndProgramCounter(), pPtFxAssetName)) { CTheScripts::GetCurrentGtaScriptHandler()->RemoveScriptResource(CGameScriptResource::SCRIPT_RESOURCE_PTFX_ASSET, slot); REPLAY_ONLY(CPacketRequestNamedPtfxAsset::RemoveRequestedHash(assetHash)); } } // // name: SetVehiclePopulationBudget // description: Set the memory budget level for the vehicle population void SetVehiclePopulationBudget(int budgetLevel) { Displayf("SET_VEHICLE_POPULATION_BUDGET(%i) - called from script \"%s\".", budgetLevel, CTheScripts::GetCurrentScriptNameAndProgramCounter()); if (SCRIPT_VERIFY(budgetLevel >= 0 && budgetLevel < MAX_MEM_LEVELS, "Invalid vehicle population budget level specified")) { gPopStreaming.SetVehMemoryBudgetLevel(budgetLevel); } } // // name: SetPedPopulationBudget // description: Set the memory budget level for the ped population void SetPedPopulationBudget(int budgetLevel) { Displayf("SET_PED_POPULATION_BUDGET(%i) - called from script \"%s\".", budgetLevel, CTheScripts::GetCurrentScriptNameAndProgramCounter()); if (SCRIPT_VERIFY(budgetLevel >= 0 && budgetLevel < MAX_MEM_LEVELS, "Invalid ped population budget level specified")) { gPopStreaming.SetPedMemoryBudgetLevel(budgetLevel); } } // // name: ClearFocus // description: resets the streaming focus entity to default (player ped) void ClearFocus() { CFocusEntityMgr::GetMgr().SetDefault(); #if !__FINAL scriptDebugf1("%s: CLEAR_FOCUS()", CTheScripts::GetCurrentScriptNameAndProgramCounter()); scrThread::PrePrintStackTrace(); #endif //__FINAL } // // name: SetFocusPosAndVel // description: overrides the streaming focus to specified position and velocity void SetFocusPosAndVel(const scrVector & pos, const scrVector & vel) { #if __ASSERT if (g_PlayerSwitch.IsActive()) { Displayf("Changing focus during player switch! Call stack follows"); scrThread::PrePrintStackTrace(); } #endif if ( Verifyf(!g_PlayerSwitch.IsActive(), "%s called SET_FOCUS_POS_AND_VEL during player switch - this is unsafe!", CTheScripts::GetCurrentScriptNameAndProgramCounter()) ) { SCRIPT_ASSERT(!(pos.x == 0.0f && pos.y == 0.0f && pos.z == 0.0f), "SET_FOCUS_POS_AND_VEL was passed a zero vector for the position"); Displayf("Script %s called SET_FOCUS_POS_AND_VEL() pos=(%.2f, %.2f, %.2f), vel=(%.2f, %.2f, %.2f)", CTheScripts::GetCurrentScriptNameAndProgramCounter(), pos.x, pos.y, pos.z, vel.x, vel.y, vel.z ); Vector3 vFocusPos(pos); Vector3 vFocusVel(vel); #if GTA_REPLAY bool shouldRecord = false; CPed* pPlayer = FindPlayerPed(); if(pPlayer) { // For url:bugstar:4252330 - Record the focus entity manager being given a position and velocity... // BUT only do it if we're in the interior of the Avenger (as this call is used in many places in script // and we don't want to risk suddenly recording something we've managed without so far and causing bother) fwInteriorLocation interiorLoc = pPlayer->GetInteriorLocation(); CInteriorProxy *pInteriorProxy = CInteriorProxy::GetFromLocation(interiorLoc); if(pInteriorProxy) { const u32 interiorHashesForRoomOneToRecord[] = { 0xdababf3e, /*"xm_x17dlc_int_01"*/ // Avenger interior 0x90d05f68, /*"ba_dlc_int_03_ba"*/ // Terrorbyte truck interior - url:bugstar:5065997 0x82396e18, /*"ch_dlc_plan"*/ // Arcade interior - url:bugstar:6139015 }; const u32 interiorHashesForAnyRoomTorRecord[] = { 0x92455476, /*"h4_int_sub_h4"*/ // Submarine interior - url:bugstar:6794037 }; bool matchesInterior = false; if(interiorLoc.GetRoomIndex() == 1) { for(int i = 0; i < NELEM(interiorHashesForRoomOneToRecord); ++i) { if(interiorHashesForRoomOneToRecord[i] == pInteriorProxy->GetNameHash()) matchesInterior = true; } } else { for(int i = 0; i < NELEM(interiorHashesForAnyRoomTorRecord); ++i) { if(interiorHashesForAnyRoomTorRecord[i] == pInteriorProxy->GetNameHash()) matchesInterior = true; } } if(matchesInterior) { if(CFocusEntityMgr::GetMgr().GetFocusState() != CFocusEntityMgr::FOCUS_OVERRIDE_POS) { shouldRecord = true; } else if(CFocusEntityMgr::GetMgr().GetPos() != pos || CFocusEntityMgr::GetMgr().GetVel() != vel) { shouldRecord = true; } } } } #endif // GTA_REPLAY CFocusEntityMgr::GetMgr().SetPosAndVel(vFocusPos, vFocusVel); #if !__FINAL scriptDebugf1("%s: SET_FOCUS_POS_AND_VEL((%.2f, %.2f, %.2f),(%.2f, %.2f, %.2f))", CTheScripts::GetCurrentScriptNameAndProgramCounter(), pos.x, pos.y, pos.z, vel.x, vel.y, vel.z); scrThread::PrePrintStackTrace(); #endif //__FINAL #if GTA_REPLAY if(CReplayMgr::ShouldRecord() && shouldRecord) { CReplayMgr::RecordFx(CPacketFocusPosAndVel(vFocusPos, vFocusVel)); } #endif // GTA_REPLAY } } // // name: SetFocusEntity // description: overrides the streaming focus to specified entity void SetFocusEntity(int entityIndex) { #if __ASSERT if (g_PlayerSwitch.IsActive()) { Displayf("Changing focus during player switch! Call stack follows"); scrThread::PrePrintStackTrace(); } #endif if ( Verifyf(!g_PlayerSwitch.IsActive(), "%s called SET_FOCUS_ENTITY during player switch - this is unsafe!", CTheScripts::GetCurrentScriptNameAndProgramCounter()) ) { const CEntity* pEntity = CTheScripts::GetEntityToQueryFromGUID(entityIndex, CTheScripts::GUID_ASSERT_FLAG_ENTITY_EXISTS); if (SCRIPT_VERIFY(pEntity, "SET_FOCUS_ENTITY - entity does not exist")) { CFocusEntityMgr::GetMgr().SetEntity(*pEntity); #if !__FINAL scriptDebugf1("%s: SET_FOCUS_ENITTY(%d)", CTheScripts::GetCurrentScriptNameAndProgramCounter(), entityIndex); scrThread::PrePrintStackTrace(); #endif //__FINAL #if GTA_REPLAY if(CReplayMgr::ShouldRecord()) { const u32 entityHashes[] = {0x5993f939, /*"trailerlarge"*/ 0x81bd2ed0, /*avenger*/ 0x897afc65, /*"terbyte"*/}; bool recordPacket = false; for(int i = 0; i < NELEM(entityHashes); ++i) { if(pEntity->GetModelNameHash() == entityHashes[i]) { recordPacket = true; break; } } if(recordPacket) { CReplayMgr::RecordFx(CPacketFocusEntity(), pEntity); } } #endif // GTA_REPLAY } } } // very special case - restore focus to specified entity after player switch void SetRestoreFocusEntity(int entityIndex) { #if __ASSERT if (!g_PlayerSwitch.IsActive()) { Displayf("Changing restore focus only permitted during player switch! Call stack follows"); scrThread::PrePrintStackTrace(); } #endif if ( Verifyf(g_PlayerSwitch.IsActive(), "%s called SET_RESTORE_FOCUS_ENTITY outside of player switch - this is unsafe!", CTheScripts::GetCurrentScriptNameAndProgramCounter()) ) { const CEntity* pEntity = CTheScripts::GetEntityToQueryFromGUID(entityIndex, CTheScripts::GUID_ASSERT_FLAG_ENTITY_EXISTS); if (SCRIPT_VERIFY(pEntity, "SET_RESTORE_FOCUS_ENTITY - entity does not exist")) { CFocusEntityMgr::GetMgr().SetSavedOverrideEntity(*pEntity); #if !__FINAL scriptDebugf1("%s: SET_RESTORE_FOCUS_ENTITY(%d)", CTheScripts::GetCurrentScriptNameAndProgramCounter(), entityIndex); scrThread::PrePrintStackTrace(); #endif //__FINAL } } } bool IsEntityFocus(int entityIndex) { const CEntity* pEntity = CTheScripts::GetEntityToQueryFromGUID(entityIndex, CTheScripts::GUID_ASSERT_FLAG_ENTITY_EXISTS); if ( pEntity && pEntity==CFocusEntityMgr::GetMgr().GetEntity() ) { return true; } return false; } // // name: SetMapDataCullBoxEnabled // description: allows script to enable and disable specific map data cull boxes referred to by name. // typically in GTAV this allows us to cull out the entire GTAV map when playing prologue void SetMapDataCullBoxEnabled(const char* boxName, bool bEnabled) { u32 nameHash = atStringHash(boxName); // If the cullbox isn't already enabled and it's to be enabled then regenerate the cull list // as the map data may have changed if(bEnabled && !CIplCullBox::IsBoxEnabled(nameHash)) { INSTANCE_STORE.CreateChildrenCache(); CIplCullBox::GenerateCullListForBox(nameHash); #if !__BANK INSTANCE_STORE.DestroyChildrenCache(); // used by cull box editor #endif // !__BANK } CIplCullBox::SetBoxEnabled(nameHash, bEnabled); } // // name: SetAllMapDataCulled // description: allows script to cull all map data in one go, or not void SetAllMapDataCulled(bool /*bCulled*/) { //I am killing off this command - IK // CIplCullBox::CullEverything(bCulled); // CHorizonObjects::CullEverything(bCulled); } // // name: SetHorizonObjectsCulled // description: allows script to cull all horizon objects void SetHorizonObjectsCulled(bool bCulled) { CHorizonObjects::CullEverything(bCulled); } // // name: CommandStreamVolCreateSphere // description: registers a new spherical stream volume for the specified asset types int CommandStreamVolCreateSphere(const scrVector & vPos, float fRadius, s32 assetFlags, s32 lodFlags=LODTYPES_MASK_ALL) { if ( scriptVerifyf(!g_PlayerSwitch.IsActive(), "Calling STREAMVOL_CREATE_SPHERE while a player switch is in progress is not safe! %s", CTheScripts::GetCurrentScriptNameAndProgramCounter()) ) { // create spherical streaming volume GtaThread* pGtaThread = CTheScripts::GetCurrentGtaScriptThread(); bool bSceneStreaming = ( assetFlags & fwBoxStreamerAsset::MASK_MAPDATA ) != 0; spdSphere streamVolSphere((Vec3V)vPos, ScalarV(fRadius)); CStreamVolumeMgr::RegisterSphere(streamVolSphere, (fwBoxStreamerAssetFlags)assetFlags, bSceneStreaming, CStreamVolumeMgr::VOLUME_SLOT_PRIMARY); CStreamVolumeMgr::SetVolumeScriptInfo(pGtaThread->GetThreadId(), pGtaThread->GetScriptName()); // only request specific lod levels CStreamVolume& volume = CStreamVolumeMgr::GetVolume( CStreamVolumeMgr::VOLUME_SLOT_PRIMARY ); if ( volume.IsActive() ) { volume.SetLodMask( lodFlags ); } } return 0; } int CommandStreamVolCreateFrustum(const scrVector & vPos, const scrVector & vDir, float fFarClip, s32 assetFlags, s32 lodFlags=LODTYPES_MASK_ALL) { if ( scriptVerifyf(!g_PlayerSwitch.IsActive(), "Calling STREAMVOL_CREATE_FRUSTUM while a player switch is in progress is not safe! %s", CTheScripts::GetCurrentScriptNameAndProgramCounter()) ) { // create frustum streaming volume GtaThread* pGtaThread = CTheScripts::GetCurrentGtaScriptThread(); bool bSceneStreaming = ( assetFlags & fwBoxStreamerAsset::MASK_MAPDATA ) != 0; CStreamVolumeMgr::RegisterFrustum(Vec3V(vPos), Vec3V(vDir), fFarClip, (fwBoxStreamerAssetFlags)assetFlags, bSceneStreaming, CStreamVolumeMgr::VOLUME_SLOT_PRIMARY); CStreamVolumeMgr::SetVolumeScriptInfo(pGtaThread->GetThreadId(), pGtaThread->GetScriptName()); // only request specific lod levels CStreamVolume& volume = CStreamVolumeMgr::GetVolume( CStreamVolumeMgr::VOLUME_SLOT_PRIMARY ); if ( volume.IsActive() ) { volume.SetLodMask( lodFlags ); } } return 0; } int CommandStreamVolCreateLine(const scrVector & vPos1, const scrVector & vPos2, s32 assetFlags) { if ( scriptVerifyf(!g_PlayerSwitch.IsActive(), "Calling STREAMVOL_CREATE_LINE while a player switch is in progress is not safe! %s", CTheScripts::GetCurrentScriptNameAndProgramCounter()) ) { // create line segment streaming volume scriptAssertf(assetFlags==fwBoxStreamerAsset::FLAG_STATICBOUNDS_MOVER, "STREAMVOL_CREATE_LINE only supports mover collision at present- %s", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); GtaThread* pGtaThread = CTheScripts::GetCurrentGtaScriptThread(); bool bSceneStreaming = ( assetFlags & fwBoxStreamerAsset::MASK_MAPDATA ) != 0; CStreamVolumeMgr::RegisterLine(Vec3V(vPos1), Vec3V(vPos2), (fwBoxStreamerAssetFlags)assetFlags, bSceneStreaming, CStreamVolumeMgr::VOLUME_SLOT_PRIMARY); CStreamVolumeMgr::SetVolumeScriptInfo(pGtaThread->GetThreadId(), pGtaThread->GetScriptName()); } return 0; } // // name: CommandStreamVolDelete // description: removes an existing streaming volume, specified by index void CommandStreamVolDelete(int UNUSED_PARAM(volumeIndex)) { if ( scriptVerifyf(!g_LoadScene.IsActive(), "Calling STREAMVOL_DELETE while a new load scene is in progress is not permitted. Calling script is %s, new load scene started by %s", CTheScripts::GetCurrentScriptNameAndProgramCounter(), g_LoadScene.GetScriptName().c_str() )) { CStreamVolumeMgr::Deregister( CStreamVolumeMgr::VOLUME_SLOT_PRIMARY ); } } // // name: CommandStreamVolHasLoaded // description: returns true if the stream volume at the specified index is all loaded, false otherwise bool CommandStreamVolHasLoaded(int UNUSED_PARAM(volumeIndex)) { return CStreamVolumeMgr::HasLoaded( CStreamVolumeMgr::VOLUME_SLOT_PRIMARY ); } // // name: CommandStreamVolIsValid // description: returns true if there is a valid, active stream volume at the specified index, false otherwise bool CommandStreamVolIsValid(int UNUSED_PARAM(volumeIndex)) { return CStreamVolumeMgr::IsVolumeActive( CStreamVolumeMgr::VOLUME_SLOT_PRIMARY ); } // // name: CommandIsStreamVolActive // description: return true if there is some active streaming volume currently bool CommandIsStreamVolActive() { return CStreamVolumeMgr::IsVolumeActive( CStreamVolumeMgr::VOLUME_SLOT_PRIMARY ); } // // name: CommandNewLoadSceneStartFrustum // description: starts a new load scene at the specified pos, with specified camera direction and farclip bool CommandNewLoadSceneStartFrustum(const scrVector & vPos, const scrVector & vDir, float fFarClip, s32 controlFlags=0) { if ( scriptVerifyf(!g_PlayerSwitch.IsActive(), "Calling NEW_LOAD_SCENE_START while a player switch is in progress is not safe! %s", CTheScripts::GetCurrentScriptNameAndProgramCounter()) ) { Displayf("Script %s called NEW_LOAD_SCENE_START pos=(%.2f, %.2f, %.2f), dir=(%.2f, %.2f, %.2f), farClip=%.2f, flags=%d", CTheScripts::GetCurrentScriptNameAndProgramCounter(), vPos.x, vPos.y, vPos.z, vDir.x, vDir.y, vDir.z, fFarClip, controlFlags ); GtaThread* pGtaThread = CTheScripts::GetCurrentGtaScriptThread(); g_LoadScene.StartFromScript((Vec3V) vPos, (Vec3V) vDir, fFarClip, pGtaThread->GetThreadId(), true, controlFlags); return true; } return false; } // // name: CommandNewLoadSceneStartSphere // description: starts a new load scene at the specified pos, and radius bool CommandNewLoadSceneStartSphere(const scrVector & vPos, float fRadius, s32 controlFlags=0) { if ( scriptVerifyf(!g_PlayerSwitch.IsActive(), "Calling NEW_LOAD_SCENE_START_SPHERE while a player switch is in progress is not safe! %s", CTheScripts::GetCurrentScriptNameAndProgramCounter()) ) { Displayf("Script %s called NEW_LOAD_SCENE_START_SPHERE pos=(%.2f, %.2f, %.2f), radius=%.2f, flags=%d", CTheScripts::GetCurrentScriptNameAndProgramCounter(), vPos.x, vPos.y, vPos.z, fRadius, controlFlags ); GtaThread* pGtaThread = CTheScripts::GetCurrentGtaScriptThread(); g_LoadScene.StartFromScript((Vec3V) vPos, Vec3V(V_ZERO), fRadius, pGtaThread->GetThreadId(), false, controlFlags); return true; } return false; } // // name: CommandNewLoadSceneStop // description: stops the new load scene, if active void CommandNewLoadSceneStop() { Displayf("Script %s called NEW_LOAD_SCENE_STOP", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); g_LoadScene.Stop(); } // // name: CommandIsNewLoadSceneActive // description: returns true if the new load scene is active, false otherwise bool CommandIsNewLoadSceneActive() { return g_LoadScene.IsActive(); } // // name: CommandIsNewLoadSceneLoaded // description: returns true of the new load scene is fully loaded, false otherwise bool CommandIsNewLoadSceneLoaded() { scriptAssertf( g_LoadScene.IsActive(), "IS_NEW_LOAD_SCENE_LOADED called, but no load scene is currently active: %s", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); return g_LoadScene.IsLoaded(); } // // name: CommandIsSafeToStartPlayerSwitch // description: Sees if it's OK to start a player switch, not in the middle of death or arrest bool CommandIsSafeToStartPlayerSwitch() { #if __BANK ////////////////////////////////////////////////////////////////////////// // some debug spew to help track down B* 1941681 // if ( !CGameLogic::IsGameStateInPlay() ) { scriptDisplayf("Script %s call to IS_SAFE_TO_START_PLAYER_SWITCH returns false because gamestate is not PLAYING (state=%d)", CTheScripts::GetCurrentScriptName(), CGameLogic::GetGameState() ); } else { CPlayerInfo* pPlayerInfo = CGameWorld::GetMainPlayerInfo(); if (!pPlayerInfo) { scriptDisplayf("Script %s call to IS_SAFE_TO_START_PLAYER_SWITCH returns false because player info is NULL", CTheScripts::GetCurrentScriptName() ); } else { if ( !pPlayerInfo->GetPlayerPed() ) { scriptDisplayf("Script %s call to IS_SAFE_TO_START_PLAYER_SWITCH returns false because player ped is NULL", CTheScripts::GetCurrentScriptName() ); } else if ( pPlayerInfo->GetPlayerState() != CPlayerInfo::PLAYERSTATE_PLAYING ) { scriptDisplayf("Script %s call to IS_SAFE_TO_START_PLAYER_SWITCH returning false because player state is not PLAYING (state=%d)", CTheScripts::GetCurrentScriptName(), pPlayerInfo->GetPlayerState() ); } } } ////////////////////////////////////////////////////////////////////////// #endif //__BANK if( CGameLogic::IsGameStateInPlay() ) { // We're in the GAME_PLAY state CPlayerInfo *pPlayerInfo = CGameWorld::GetMainPlayerInfo(); // Is the player about to die or get arrested? if( pPlayerInfo && pPlayerInfo->GetPlayerPed()) { if( pPlayerInfo->GetPlayerState() == CPlayerInfo::PLAYERSTATE_PLAYING ) { // no return true; } } } return false; } // // name: CommandStartPlayerSwitch // description: starts a player switch void CommandStartPlayerSwitch(int oldPedIndex, int newPedIndex, int flags, s32 switchType=CPlayerSwitchInterface::SWITCH_TYPE_AUTO) { scriptAssertf( CommandIsSafeToStartPlayerSwitch(), "Script %s called START_PLAYER_SWITCH but IS_SAFE_TO_START_PLAYER_SWITCH is false", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); scriptAssertf( !CWarpManager::IsActive(), "Script %s calling START_PLAYER_SWITCH while a warp is in progress!", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); CPed *pOldPed = CTheScripts::GetEntityToModifyFromGUID(oldPedIndex, 0); CPed *pNewPed = CTheScripts::GetEntityToModifyFromGUID(newPedIndex, 0); scriptAssertf(pOldPed, "Invalid old ped index %d passed from script %s. Switch will not proceed", oldPedIndex, CTheScripts::GetCurrentScriptNameAndProgramCounter()); scriptAssertf(pNewPed, "Invalid new ped index %d passed from script %s. Switch will not proceed", newPedIndex, CTheScripts::GetCurrentScriptNameAndProgramCounter()); #if !__FINAL if (!pOldPed || !pNewPed) return; Vector3 vOldPos = VEC3V_TO_VECTOR3( pOldPed->GetTransform().GetPosition() ); Vector3 vNewPos = VEC3V_TO_VECTOR3( pNewPed->GetTransform().GetPosition() ); Displayf( "START_PLAYER_SWITCH called by %s", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); Displayf( "... src=(%.2f, %.2f, %.2f) dst=(%.2f, %.2f, %.2f) flags=0x%x switchType=%d", vOldPos.x, vOldPos.y, vOldPos.z, vNewPos.x, vNewPos.y, vNewPos.z, flags, switchType ); #endif //!__FINAL #if __ASSERT ////////////////////////////////////////////////////////////////////////// // check to see if script is forcing us to do a switch that is unlikely to work well if ((flags & CPlayerSwitchInterface::CONTROL_FLAG_UNKNOWN_DEST) != 0) { scriptAssertf( switchType!=CPlayerSwitchInterface::SWITCH_TYPE_SHORT, "Script %s is calling START_PLAYER_SWITCH for short range switch to unknown destination. That won't work", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); } else { s32 idealSwitchType = g_PlayerSwitch.GetIdealSwitchType( pOldPed->GetTransform().GetPosition(), pNewPed->GetTransform().GetPosition() ); switch (switchType) { case CPlayerSwitchInterface::SWITCH_TYPE_MEDIUM: scriptAssertf( idealSwitchType!=CPlayerSwitchInterface::SWITCH_TYPE_LONG, "Script %s forcing START_PLAYER_SWITCH to do a medium range switch over too great a distance", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); break; case CPlayerSwitchInterface::SWITCH_TYPE_SHORT: // scriptWarningf( idealSwitchType!=CPlayerSwitchInterface::SWITCH_TYPE_MEDIUM, // "Script %s forcing START_PLAYER_SWITCH to do a short range switch over too great a distance", // CTheScripts::GetCurrentScriptNameAndProgramCounter() ); break; default: break; } } ////////////////////////////////////////////////////////////////////////// #endif //__ASSERT if ( pOldPed && pNewPed && scriptVerifyf(!g_PlayerSwitch.IsActive(), "START_PLAYER_SWITCH - a switch is already in progress") ) { g_PlayerSwitch.Start(switchType, *pOldPed, *pNewPed, flags); } } // // name: CommandGetPlayerSwitchType // description: returns the current player switch type s32 CommandGetPlayerSwitchType() { return g_PlayerSwitch.GetSwitchType(); } // // name: CommandGetIdealPlayerSwitchType // description: returns the ideal desired switch type based on the distance from start to end s32 CommandGetIdealPlayerSwitchType(const scrVector & vStartPos, const scrVector & vEndPos) { return g_PlayerSwitch.GetIdealSwitchType((Vec3V) vStartPos, (Vec3V) vEndPos); } // name: CommandSetPlayerSwitchOutro // description: overrides the end scene which is streamed - use if the end scene position differs from the ped pos void CommandSetPlayerSwitchOutro(const scrVector & vCamPos, const scrVector & vCamRot, float fCamFov, float fCamFarClip, int rotOrder) { if (scriptVerifyf(g_PlayerSwitch.IsActive(), "SET_PLAYER_SWITCH_OUTRO called by %s but switch is not active", CTheScripts::GetCurrentScriptNameAndProgramCounter())) { if (scriptVerifyf( g_PlayerSwitch.GetSwitchType()!=CPlayerSwitchInterface::SWITCH_TYPE_SHORT, "SET_PLAYER_SWITCH_OUTRO called by %s but that's not valid for a short range switch", CTheScripts::GetCurrentScriptNameAndProgramCounter())) { // Vector3 vPos(vCamPos); Vector3 vRot(vCamRot); Matrix34 worldMatrix; CScriptEulers::MatrixFromEulers( worldMatrix, vRot*DtoR, static_cast(rotOrder) ); worldMatrix.d = vCamPos; g_PlayerSwitch.GetLongRangeMgr().OverrideOutroScene( RCC_MAT34V(worldMatrix), fCamFov, fCamFarClip ); } } } // name: CommandSetPlayerSwitchEstablishingShot // description: sets an establishing which occurs before the outro void CommandSetPlayerSwitchEstablishingShot(const char* pszShotName) { g_PlayerSwitch.GetLongRangeMgr().SetEstablishingShot(atHashString(pszShotName)); } // // name: CommandIsPlayerSwitchInProgress // description: returns true if a switch is in progress, false otherwise bool CommandIsPlayerSwitchInProgress() { return g_PlayerSwitch.IsActive(); } // // name: CommandGetPlayerSwitchState // description: returns the current state of an active player switch int CommandGetPlayerSwitchState() { scriptAssertf( g_PlayerSwitch.IsActive(), "GET_PLAYER_SWITCH_STATE called by %s but switch is not active", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); scriptAssertf(g_PlayerSwitch.GetSwitchType()!=CPlayerSwitchInterface::SWITCH_TYPE_SHORT, "GET_PLAYER_SWITCH_STATE called by %s - not valid for short range switches", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); return g_PlayerSwitch.GetLongRangeMgr().GetState(); } // // name: CommandGetPlayerShortSwitchState // description: returns the current state of an active player short-range switch int CommandGetPlayerShortSwitchState() { scriptAssertf( g_PlayerSwitch.IsActive(), "GET_PLAYER_SHORT_SWITCH_STATE called by %s but switch is not active", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); scriptAssertf(g_PlayerSwitch.GetSwitchType()==CPlayerSwitchInterface::SWITCH_TYPE_SHORT, "GET_PLAYER_SHORT_SWITCH_STATE called by %s - only valid for short range switches", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); return g_PlayerSwitch.GetShortRangeMgr().GetState(); } void CommandSetPlayerShortSwitchStyle(int style) { scriptAssertf( style >= 0, "SET_PLAYER_SHORT_SWITCH_STYLE - called by %s, invalid style", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); scriptAssertf( style < CPlayerSwitchMgrShort::NUM_SHORT_SWITCH_STYLES, "SET_PLAYER_SHORT_SWITCH_STYLE - called by %s, invalid style", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); g_PlayerSwitch.GetShortRangeMgr().SetStyle( (CPlayerSwitchMgrShort::eStyle)style ); } // // name: CommandGetPlayerSwitchJumpCutIndex // description: returns the index of the current jump cut of an active player switch int CommandGetPlayerSwitchJumpCutIndex() { scriptAssertf( g_PlayerSwitch.IsActive(), "GET_PLAYER_SWITCH_JUMP_CUT_INDEX called by %s but switch is not active", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); scriptAssertf(g_PlayerSwitch.GetSwitchType()!=CPlayerSwitchInterface::SWITCH_TYPE_SHORT, "GET_PLAYER_SWITCH_JUMP_CUT_INDEX called by %s - not valid for short range switches", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); return static_cast(g_PlayerSwitch.GetLongRangeMgr().GetCurrentJumpCutIndex()); } // // name: CommandAllowPlayerSwitchPan // description: if script requires the switch to pause before proceeding with the pan // (e.g. to stream in some script requested assets etc) this command // gives the switch mgr the go-ahead to proceed void CommandAllowPlayerSwitchPan() { if ( scriptVerifyf(g_PlayerSwitch.IsActive(), "ALLOW_PLAYER_SWITCH_PAN called by %s but switch is not active", CTheScripts::GetCurrentScriptNameAndProgramCounter()) ) { scriptAssertf(g_PlayerSwitch.GetSwitchType()!=CPlayerSwitchInterface::SWITCH_TYPE_SHORT, "ALLOW_PLAYER_SWITCH_PAN called by %s - not valid for short range switches", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); g_PlayerSwitch.GetLongRangeMgr().SetControlFlag(CPlayerSwitchInterface::CONTROL_FLAG_PAUSE_BEFORE_PAN, false); } } // // name: CommandAllowPlayerSwitchOutro // description: if script requires the switch to pause before proceeding with the outro // (e.g. to stream in some script requested assets etc) this command // gives the switch mgr the go-ahead to proceed void CommandAllowPlayerSwitchOutro() { if ( scriptVerifyf(g_PlayerSwitch.IsActive(), "ALLOW_PLAYER_SWITCH_OUTRO called by %s but switch is not active", CTheScripts::GetCurrentScriptNameAndProgramCounter()) ) { scriptAssertf(g_PlayerSwitch.GetSwitchType()!=CPlayerSwitchInterface::SWITCH_TYPE_SHORT, "ALLOW_PLAYER_SWITCH_OUTRO called by %s - not valid for short range switches", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); g_PlayerSwitch.GetLongRangeMgr().SetControlFlag(CPlayerSwitchInterface::CONTROL_FLAG_PAUSE_BEFORE_OUTRO, false); } } // // name: CommandAllowPlayerSwitchAscent // description: if script requires the switch to pause before proceeding with the ascent // this command gives the switch mgr the go-ahead to proceed when ready void CommandAllowPlayerSwitchAscent() { if ( scriptVerifyf(g_PlayerSwitch.IsActive(), "ALLOW_PLAYER_SWITCH_ASCENT called by %s but switch is not active", CTheScripts::GetCurrentScriptNameAndProgramCounter()) ) { scriptAssertf(g_PlayerSwitch.GetSwitchType()!=CPlayerSwitchInterface::SWITCH_TYPE_SHORT, "ALLOW_PLAYER_SWITCH_ASCENT called by %s - not valid for short range switches", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); g_PlayerSwitch.GetLongRangeMgr().SetControlFlag(CPlayerSwitchInterface::CONTROL_FLAG_PAUSE_BEFORE_ASCENT, false); } } // // name: CommandAllowPlayerSwitchDescent // description: if script requires the switch to pause before proceeding with the descent // this command gives the switch mgr the go-ahead to proceed when ready void CommandAllowPlayerSwitchDescent() { if ( scriptVerifyf(g_PlayerSwitch.IsActive(), "ALLOW_PLAYER_SWITCH_DESCENT called by %s but switch is not active", CTheScripts::GetCurrentScriptNameAndProgramCounter()) ) { scriptAssertf(g_PlayerSwitch.GetSwitchType()!=CPlayerSwitchInterface::SWITCH_TYPE_SHORT, "ALLOW_PLAYER_SWITCH_DESCENT called by %s - not valid for short range switches", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); g_PlayerSwitch.GetLongRangeMgr().SetControlFlag(CPlayerSwitchInterface::CONTROL_FLAG_PAUSE_BEFORE_DESCENT, false); } } bool CommandIsSwitchReadyForAscent() { if ( scriptVerifyf(g_PlayerSwitch.IsActive(), "IS_SWITCH_READY_FOR_ASCENT called by %s but switch is not active", CTheScripts::GetCurrentScriptNameAndProgramCounter()) ) { scriptAssertf(g_PlayerSwitch.GetSwitchType()!=CPlayerSwitchInterface::SWITCH_TYPE_SHORT, "IS_SWITCH_READY_FOR_ASCENT called by %s - not valid for short range switches", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); return g_PlayerSwitch.GetLongRangeMgr().ReadyForAscent(); } return false; } bool CommandIsSwitchReadyForDescent() { if ( scriptVerifyf(g_PlayerSwitch.IsActive(), "IS_SWITCH_READY_FOR_DESCENT called by %s but switch is not active", CTheScripts::GetCurrentScriptNameAndProgramCounter()) ) { scriptAssertf(g_PlayerSwitch.GetSwitchType()!=CPlayerSwitchInterface::SWITCH_TYPE_SHORT, "IS_SWITCH_READY_FOR_DESCENT called by %s - not valid for short range switches", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); return g_PlayerSwitch.GetLongRangeMgr().ReadyForDescent(); } return false; } void CommandEnableSwitchPauseBeforeDescent() { if ( scriptVerifyf(g_PlayerSwitch.IsActive(), "ENABLE_SWITCH_PAUSE_BEFORE_DESCENT called by %s but switch is not active", CTheScripts::GetCurrentScriptNameAndProgramCounter()) ) { scriptAssertf(g_PlayerSwitch.GetSwitchType()!=CPlayerSwitchInterface::SWITCH_TYPE_SHORT, "ENABLE_SWITCH_PAUSE_BEFORE_DESCENT called by %s - not valid for short range switches", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); Displayf("[Playerswitch] Script %s calling ENABLE_SWITCH_PAUSE_BEFORE_DESCENT. Switch will hang before descent until script permit progress", CTheScripts::GetCurrentScriptName()); g_PlayerSwitch.GetLongRangeMgr().EnablePauseBeforeDescent(); } } void CommandDisableSwitchOutroFX() { if ( scriptVerifyf(g_PlayerSwitch.IsActive(), "DISABLE_SWITCH_OUTRO_FX called by %s but switch is not active", CTheScripts::GetCurrentScriptNameAndProgramCounter()) ) { Displayf("[Playerswitch] Script %s calling DISABLE_SWITCH_OUTRO_FX. Switch will skip outro FX", CTheScripts::GetCurrentScriptName()); s32 switchType = g_PlayerSwitch.GetSwitchType(); CPlayerSwitchMgrBase* mgr = g_PlayerSwitch.GetMgr(switchType); mgr->SetControlFlag(CPlayerSwitchInterface::CONTROL_FLAG_SUPPRESS_OUTRO_FX,true); } } bool CommandIsSwitchSkippingDescent() { if ( scriptVerifyf(g_PlayerSwitch.IsActive(), "IS_SWITCH_SKIPPING_DESCENT called by %s but switch is not active", CTheScripts::GetCurrentScriptNameAndProgramCounter()) ) { return g_PlayerSwitch.GetLongRangeMgr().IsSkippingDescent(); } return false; } // // name: CommandSwitchToMultiFirstPart // description: perform the first part of the player switch (ascent part) when the destination // is currently unknown (pending user input during character selection screen etc) void CommandSwitchToMultiFirstPart(int oldPedIndex, int flags, s32 switchType=CPlayerSwitchInterface::SWITCH_TYPE_LONG) { scriptAssertf( !CWarpManager::IsActive(), "Script %s calling SWITCH_TO_MULTI_FIRSTPART while a warp is in progress!", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); scriptAssertf( CommandIsSafeToStartPlayerSwitch(), "Script %s called SWITCH_TO_MULTI_FIRSTPART but IS_SAFE_TO_START_PLAYER_SWITCH is false", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); CPed *pOldPed = CTheScripts::GetEntityToModifyFromGUID(oldPedIndex, 0); if ( pOldPed && scriptVerifyf(!g_PlayerSwitch.IsActive(), "SWITCH_TO_MULTI_FIRSTPART - a switch is already in progress") ) { #if !__FINAL Vector3 vOldPos = VEC3V_TO_VECTOR3( pOldPed->GetTransform().GetPosition() ); Displayf( "SWITCH_TO_MULTI_FIRSTPART called by %s", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); Displayf( "... src=(%.2f, %.2f, %.2f) flags=0x%x type=%d", vOldPos.x, vOldPos.y, vOldPos.z, flags, switchType ); #endif //!__FINAL g_PlayerSwitch.Start(switchType, *pOldPed, *pOldPed, flags | CPlayerSwitchInterface::CONTROL_FLAG_UNKNOWN_DEST); } } // // name: CommandIsSwitchToMultiFirstPartFinished // description: returns true if the player switch is currently finished its ascent and is holding, // waiting for more information about the destination of the switch bool CommandIsSwitchToMultiFirstPartFinished() { return ( g_PlayerSwitch.GetLongRangeMgr().GetState() == CPlayerSwitchMgrLong::STATE_WAITFORINPUT ); } // // name: CommandSwitchToMultiSecondPart // description: perform the second part of the player switch (pan and descent parts) because the destination ped // is now known. void CommandSwitchToMultiSecondPart(int newPedIndex) { CPed *pNewPed = CTheScripts::GetEntityToModifyFromGUID(newPedIndex, 0); if ( pNewPed && scriptVerifyf(g_PlayerSwitch.IsActive(), "START_PLAYER_SWITCH - a switch is not already in progress") ) { #if !__FINAL Vector3 vNewPos = VEC3V_TO_VECTOR3( pNewPed->GetTransform().GetPosition() ); Displayf( "[Playerswitch] SWITCH_TO_MULTI_SECONDPART called by %s", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); Displayf( "... dst=(%.2f, %.2f, %.2f)", vNewPos.x, vNewPos.y, vNewPos.z ); #endif //!__FINAL #if __ASSERT scriptAssertf(g_PlayerSwitch.GetSwitchType()!=CPlayerSwitchInterface::SWITCH_TYPE_SHORT, "SWITCH_TO_MULTI_SECOND_PART is not valid for short range switching"); ////////////////////////////////////////////////////////////////////////// s32 idealSwitchType = g_PlayerSwitch.GetIdealSwitchType( g_PlayerSwitch.GetLongRangeMgr().GetStartPos(), pNewPed->GetTransform().GetPosition() ); switch (g_PlayerSwitch.GetSwitchType()) { case CPlayerSwitchInterface::SWITCH_TYPE_MEDIUM: scriptAssertf( idealSwitchType!=CPlayerSwitchInterface::SWITCH_TYPE_LONG, "Script %s forcing SWITCH_TO_MULTI_SECOND_PART to do a medium range switch over too great a distance!", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); break; case CPlayerSwitchInterface::SWITCH_TYPE_SHORT: scriptAssertf( idealSwitchType!=CPlayerSwitchInterface::SWITCH_TYPE_MEDIUM, "Script %s forcing SWITCH_TO_MULTI_SECOND_PART to do a short range switch over too great a distance", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); break; default: break; } ////////////////////////////////////////////////////////////////////////// #endif //__ASSERT g_PlayerSwitch.SetDest(*pNewPed); } } // // name: CommandSstopPlayerSwitch // description: abandon a switch, if active void CommandStopPlayerSwitch() { Displayf( "STOP_PLAYER_SWITCH called by %s", CTheScripts::GetCurrentScriptNameAndProgramCounter() ); if (g_PlayerSwitch.IsActive()) { g_PlayerSwitch.Stop(); } } // name: CommandGetPlayerSwitchInterpOutDuration // description: returns the duration of any interpolation out of an establishing shot, in milliseconds, or 0 if invalid int CommandGetPlayerSwitchInterpOutDuration() { const CPlayerSwitchEstablishingShotMetadata* pEstablishingShotData = g_PlayerSwitch.GetLongRangeMgr().GetEstablishingShotData(); s32 duration = pEstablishingShotData ? static_cast(pEstablishingShotData->m_InterpolateOutDuration) : 0; return duration; } void CommandSetSceneStreamingTracksCamPosThisFrame() { CSceneStreamerMgr::ForceSceneStreamerToTrackWithCameraPosThisFrame(); } float CommandGetLodScale() { return g_LodScale.GetGlobalScale(); } // name: CommandGetPlayerSwitchInterpOutCurrentTime // description: returns the current interpolation time out of an establishing shot, in milliseconds. -1 will be returned if interpolation is not in progress int CommandGetPlayerSwitchInterpOutCurrentTime() { const camSwitchDirector& switchDirector = camInterface::GetSwitchDirector(); camBaseDirector::eRenderStates renderState = switchDirector.GetRenderState(); s32 currentTime = (renderState == camBaseDirector::RS_INTERPOLATING_OUT) ? switchDirector.GetInterpolationTime() : -1; return currentTime; } // // name: CommandOverrideLodScaleThisFrame // void CommandOverrideLodScaleThisFrame(float fLodScale) { g_LodScale.SetGlobalScaleFromScript(fLodScale); } void CommandRemapLodScaleRangeThisFrame(float fOldMin, float fOldMax, float fNewMin, float fNewMax) { g_LodScale.SetRemappingFromScript(fOldMin, fOldMax, fNewMin, fNewMax); } void CommandSuppressHdMapStreamingThisFrame() { CStreaming::ScriptSuppressHdImapsThisFrame(); } void CommandForceAllowTimeBasedFadingThisFrame() { g_LodMgr.ScriptForceAllowTimeBasedFadingThisFrame(); } // // name: CommandSetRenderHdOnly // void CommandSetRenderHdOnly(bool bHdOnly) { if ( scriptVerifyf(!g_PlayerSwitch.IsActive(), "Calling SET_RENDER_HD_ONLY while a player switch is in progress is not safe! %s", CTheScripts::GetCurrentScriptNameAndProgramCounter()) ) { Displayf( "Script called SET_RENDER_HD_ONLY(%s) - %s", (bHdOnly?"true":"false"), CTheScripts::GetCurrentScriptNameAndProgramCounter() ); if (bHdOnly) { g_LodMgr.ScriptRequestRenderHdOnly(); } else { g_LodMgr.StopSlodMode(); } } } // // name: CommandIplGroupSwapStart // // allows user to seamlessly switch between two IPL groups in a frame, by pre-streaming the assets for the second group // before switching it on (and switching off the first one) // void CommandIplGroupSwapStart(const char* iplGroupBefore, const char* iplGroupAfter) { Displayf("Script %s called IPL_GROUP_SWAP_START(%s, %s)", CTheScripts::GetCurrentScriptNameAndProgramCounter(), iplGroupBefore, iplGroupAfter); strLocalIndex indexBefore = strLocalIndex(INSTANCE_STORE.FindSlot(iplGroupBefore)); strLocalIndex indexAfter = strLocalIndex(INSTANCE_STORE.FindSlot(iplGroupAfter)); scriptAssertf(indexBefore!=-1, "IPL_GROUP_SWAP_START called by %s but %s is missing", CTheScripts::GetCurrentScriptNameAndProgramCounter(), iplGroupBefore); scriptAssertf(indexAfter!=-1, "IPL_GROUP_SWAP_START called by %s but %s is missing", CTheScripts::GetCurrentScriptNameAndProgramCounter(), iplGroupAfter); const bool bBothIplGroupsExist = (indexBefore != -1) && (indexAfter != -1); if (bBothIplGroupsExist) { scriptAssertf( g_MapDataStore.GetIsStreamable(indexBefore), "IPL_GROUP_SWAP_START: %s should be enabled", iplGroupBefore ); scriptAssertf( !g_MapDataStore.GetIsStreamable(indexAfter), "IPL_GROUP_SWAP_START: %s should be disabled", iplGroupAfter ); const bool bCorrectInitialState = (g_MapDataStore.GetIsStreamable(indexBefore) && !g_MapDataStore.GetIsStreamable(indexAfter)); if (bCorrectInitialState) { // register new swap, mark as script owned, and return swap index atHashString startNameHash(iplGroupBefore); atHashString endNameHash(iplGroupAfter); GtaThread* pGtaThread = CTheScripts::GetCurrentGtaScriptThread(); g_MapDataStore.GetGroupSwapper().CreateNewSwapForScript(startNameHash, endNameHash, pGtaThread->GetThreadId()); } } } // // name: CommandIplGroupSwapIsReady // // returns true if the IPL group swap is fully loaded and ready to transition, false otherwise // bool CommandIplGroupSwapIsReady() { return g_MapDataStore.GetGroupSwapper().GetIsLoaded(fwImapGroupMgr::SCRIPT_INDEX); } // // name: CommandIplGroupSwapFinish // // performs the swap - switches on the end state, switches off the start state, removes the active swapper // void CommandIplGroupSwapFinish() { Displayf("Script %s called IPL_GROUP_SWAP_FINISH", CTheScripts::GetCurrentScriptNameAndProgramCounter()); scriptAssertf(g_MapDataStore.GetGroupSwapper().GetIsActive(fwImapGroupMgr::SCRIPT_INDEX), "IPL group swap is not active (ie has been completed or canceled)"); g_MapDataStore.GetGroupSwapper().CompleteSwap(fwImapGroupMgr::SCRIPT_INDEX, false); } // // name: CommandIplGroupSwapCancel // // abandon a currently active IPL group swap void CommandIplGroupSwapCancel() { Displayf("Script %s called IPL_GROUP_SWAP_CANCEL", CTheScripts::GetCurrentScriptNameAndProgramCounter()); scriptAssertf( g_MapDataStore.GetGroupSwapper().GetIsActive(fwImapGroupMgr::SCRIPT_INDEX), "IPL group swap is not active (ie has been completed or canceled)"); g_MapDataStore.GetGroupSwapper().AbandonSwap(fwImapGroupMgr::SCRIPT_INDEX); } bool CommandIplGroupSwapIsActive() { return g_MapDataStore.GetGroupSwapper().GetIsActive(fwImapGroupMgr::SCRIPT_INDEX); } #if __BANK ////////////////////////////////////////////////////////////////////////// // TRAILER 2 ONLY void CommandEnableExtraDistantLights(const scrVector & vPos, float fRadius) { DebugLighting::EnableExtraDistantLights(vPos, fRadius); } void CommandDisableExtraDistantLights() { // TRAILER 2 ONLY DebugLighting::DisableExtraDistantLights(); } ////////////////////////////////////////////////////////////////////////// #else void CommandEnableExtraDistantLights(const scrVector &, float) {} void CommandDisableExtraDistantLights() {} #endif void CommandPrefetchSrl(const char *srlName) { gStreamingRequestList.BeginPrestream(srlName, true); } bool CommandIsSrlLoaded() { return gStreamingRequestList.AreAllAssetsLoaded(); } void CommandBeginSrl() { gStreamingRequestList.Start(); } void CommandEndSrl() { gStreamingRequestList.Finish(); } void CommandSetSrlTime(float time) { gStreamingRequestList.SetTime(time); } void CommandSetSrlPostCutsceneCamera(const scrVector & vPos, const scrVector & vDir) { gStreamingRequestList.SetPostCutsceneCamera(vPos, vDir); } void CommandSetSrlReadAheadTimes(int prestreamMap, int prestreamAssets, int playbackMap, int playbackAssets) { gStreamingRequestList.SetSrlReadAheadTimes(prestreamMap, prestreamAssets, playbackMap, playbackAssets); } void CommandSetSrlLongJumpMode(bool enableLongJumpMode) { gStreamingRequestList.SetLongJumpMode(enableLongJumpMode); } void CommandSetSrlForcePrestream(s32 prestreamMode) { gStreamingRequestList.SetPrestreamMode((SrlPrestreamMode) prestreamMode); } void CommandSetHdArea(const scrVector& scrPos, float radius) { CTexLod::SetHdArea(scrPos.x, scrPos.y, scrPos.z, radius); } void CommandClearHdArea() { CTexLod::ClearHdArea(); } void CommandInitCreatorBudget() { MissionCreatorAssets::Init(); } void CommandShutdownCreatorBudget() { MissionCreatorAssets::Shutdown(); } bool CommandHasRoomForModelInCreatorBudget(int modelHash) { fwModelId modelId; CBaseModelInfo* pModelInfo = CModelInfo::GetBaseModelInfoFromHashKey((u32)modelHash, &modelId); if (scriptVerifyf(pModelInfo, "%s: HAS_ROOM_FOR_MODEL_IN_CREATOR_BUDGET - model with hash %d does not exist", CTheScripts::GetCurrentScriptNameAndProgramCounter(), modelHash)) { if (scriptVerifyf(modelId.IsValid(), "%s: HAS_ROOM_FOR_MODEL_IN_CREATOR_BUDGET - model with hash %d exists but its model index is invalid", CTheScripts::GetCurrentScriptNameAndProgramCounter(), modelHash)) { return MissionCreatorAssets::HasRoomForModel(modelId); } } return false; } bool CommandAddModelToCreatorBudget(int modelHash) { fwModelId modelId; CBaseModelInfo* pModelInfo = CModelInfo::GetBaseModelInfoFromHashKey((u32)modelHash, &modelId); if (scriptVerifyf(pModelInfo, "%s: ADD_MODEL_TO_CREATOR_BUDGET - model with hash %d does not exist", CTheScripts::GetCurrentScriptNameAndProgramCounter(), modelHash)) { if (scriptVerifyf(modelId.IsValid(), "%s: ADD_MODEL_TO_CREATOR_BUDGET - model with hash %d exists but its model index is invalid", CTheScripts::GetCurrentScriptNameAndProgramCounter(), modelHash)) { return MissionCreatorAssets::AddModel(modelId); } } return false; } void CommandRemoveModelFromCreatorBudget(int modelHash) { fwModelId modelId; CBaseModelInfo* pModelInfo = CModelInfo::GetBaseModelInfoFromHashKey((u32)modelHash, &modelId); if (scriptVerifyf(pModelInfo, "%s: REMOVE_MODEL_FROM_CREATOR_BUDGET - model with hash %d does not exist", CTheScripts::GetCurrentScriptNameAndProgramCounter(), modelHash)) { if (scriptVerifyf(modelId.IsValid(), "%s: REMOVE_MODEL_FROM_CREATOR_BUDGET - model with hash %d exists but its model index is invalid", CTheScripts::GetCurrentScriptNameAndProgramCounter(), modelHash)) { MissionCreatorAssets::RemoveModel(modelId); } } } float CommandGetUsedCreatorBudget() { return MissionCreatorAssets::GetUsedBudget(); } void CommandSetIslandEnabled(char const* pIslandName, bool enable) { CIslandHopper::GetInstance().RequestToggleIsland(pIslandName, enable); } bool CommandAreIslandIPLsActive() { return CIslandHopper::GetInstance().AreCurrentIslandIPLsActive(); } bool CommandIsGameInstalled() { return CFileMgr::IsGameInstalled(); } // // name: SetupScriptCommands // description: Setup streaming script commands void SetupScriptCommands() { SCR_REGISTER_SECURE(LOAD_ALL_OBJECTS_NOW,0x0f3dc7925afebdfc, LoadAllObjectsNow); SCR_REGISTER_SECURE(LOAD_SCENE,0x42c4310e76ad635a, LoadScene); SCR_REGISTER_UNUSED(NETWORK_START_LOAD_SCENE,0xba65ca1a62ca5efa, StartLoadScene); SCR_REGISTER_SECURE(NETWORK_UPDATE_LOAD_SCENE,0x5ee9da6c0c12274b, UpdateLoadScene); SCR_REGISTER_UNUSED(NETWORK_STOP_LOAD_SCENE,0x61c0d41714aac740, StopLoadScene); SCR_REGISTER_SECURE(IS_NETWORK_LOADING_SCENE,0x340c8b9022477b2f, IsLoadSceneActive); SCR_REGISTER_UNUSED(LOAD_SCENE_FOR_ROOM_BY_KEY,0x77266ff77886d086, LoadSceneForRoomByKey); SCR_REGISTER_SECURE(SET_INTERIOR_ACTIVE,0x28a0a1eb9d59910d, CommandActivateInterior); SCR_REGISTER_SECURE(REQUEST_MODEL,0xd69a0c3662175e68, CommandRequestModel); SCR_REGISTER_SECURE(REQUEST_MENU_PED_MODEL,0x24f2c68f9513392f, CommandRequestMenuPedModel); SCR_REGISTER_SECURE(HAS_MODEL_LOADED,0x0152aa00fa3130f1, HasModelLoaded); SCR_REGISTER_UNUSED(REQUEST_INTERIOR_MODELS,0x620e68adda3d0a93, RequestInteriorModels); SCR_REGISTER_SECURE(REQUEST_MODELS_IN_ROOM,0x0f1bef3db99b3f66, RequestModelsInRoom); SCR_REGISTER_SECURE(SET_MODEL_AS_NO_LONGER_NEEDED,0xf1a23b343dfedfd0, CommandMarkModelAsNoLongerNeeded); SCR_REGISTER_SECURE(IS_MODEL_IN_CDIMAGE,0x51046eee00e2bbda, IsModelInCdImage); SCR_REGISTER_SECURE(IS_MODEL_VALID,0x61adf697df551da6, CommandIsModelValid); SCR_REGISTER_UNUSED(GET_PED_MODEL_FROM_INDEX,0x25a52190ae4733a7, CommandGetPedModelFromIndex); SCR_REGISTER_UNUSED(GET_VEHICLE_MODEL_FROM_INDEX,0x0c5271cf0ccaf6e4, CommandGetVehicleModelFromIndex); SCR_REGISTER_SECURE(IS_MODEL_A_PED,0x5a01a43be2689db0, CommandIsThisModelAPed); SCR_REGISTER_SECURE(IS_MODEL_A_VEHICLE,0x2886b1bfe0896a9a, CommandIsThisModelAVehicle); SCR_REGISTER_UNUSED(REQUEST_MOVER_COLLISION_ONLY,0xfeab902a1748345f, RequestMoverCollisionOnly); SCR_REGISTER_SECURE(REQUEST_COLLISION_AT_COORD,0xe49a23f069c82c93, RequestCollisionAtPosn); SCR_REGISTER_SECURE(REQUEST_COLLISION_FOR_MODEL,0xb557c195bbd7d051, RequestCollisionForModel); SCR_REGISTER_SECURE(HAS_COLLISION_FOR_MODEL_LOADED,0x30229254f181806b, HasCollisionForModelLoaded); SCR_REGISTER_SECURE(REQUEST_ADDITIONAL_COLLISION_AT_COORD,0x616bf5910d72dca9, AddNeededAtPosn); SCR_REGISTER_SECURE(DOES_ANIM_DICT_EXIST,0xa430c2581c66a9ad, DoesAnimDictExist); SCR_REGISTER_SECURE(REQUEST_ANIM_DICT,0x8fb472886552d737, RequestAnimDict); SCR_REGISTER_SECURE(HAS_ANIM_DICT_LOADED,0x6f940c2636c076ad, HasAnimDictLoaded); SCR_REGISTER_SECURE(REMOVE_ANIM_DICT,0xafc1fbf3f6ae7b9a, RemoveAnimDict); // START OF DEPRECATED SCR_REGISTER_SECURE(REQUEST_ANIM_SET,0x3aca4f727ac4606e, RequestClipSet); SCR_REGISTER_SECURE(HAS_ANIM_SET_LOADED,0xbb103a5dec572725,HasClipSetLoaded); SCR_REGISTER_SECURE(REMOVE_ANIM_SET,0x5f75840181672fad, RemoveClipSet); // END OF DEPRECATED SCR_REGISTER_SECURE(REQUEST_CLIP_SET,0x511a0af0e8b0bf9a, RequestClipSet); SCR_REGISTER_SECURE(HAS_CLIP_SET_LOADED,0xa7a5d14f877c9047,HasClipSetLoaded); SCR_REGISTER_SECURE(REMOVE_CLIP_SET,0x840dce5f5f53d8e0, RemoveClipSet); SCR_REGISTER_SECURE(REQUEST_IPL,0x13a763a67ba2a95b, RequestIpl); SCR_REGISTER_SECURE(REMOVE_IPL,0x9d2accf306f3a0c5, RemoveIpl); SCR_REGISTER_SECURE(IS_IPL_ACTIVE,0x8dd54478cfa35f08, IsIplActive); SCR_REGISTER_SECURE(SET_STREAMING,0x8e4329fd81081a2a, SwitchStreaming); SCR_REGISTER_UNUSED(SET_SCENE_STREAMING,0xafa0231603f22be9, EnableSceneStreaming); SCR_REGISTER_SECURE(LOAD_GLOBAL_WATER_FILE,0x11f9af5e230d40d6, LoadGlobalWaterFile); SCR_REGISTER_SECURE(GET_GLOBAL_WATER_FILE,0xcb446f8296efd9bb, GetGlobalWaterFile); SCR_REGISTER_SECURE(SET_GAME_PAUSES_FOR_STREAMING,0x47c032cd609587ee, AllowGameToPauseForStreaming); SCR_REGISTER_SECURE(SET_REDUCE_PED_MODEL_BUDGET,0x718886bcae2bd894, SetReducePedModelBudget); SCR_REGISTER_SECURE(SET_REDUCE_VEHICLE_MODEL_BUDGET,0x9a78aa1fbfc8a2ac, SetReduceVehicleModelBudget); SCR_REGISTER_SECURE(SET_DITCH_POLICE_MODELS,0x2613fa815056d2d9, SetDitchPoliceModels); SCR_REGISTER_SECURE(GET_NUMBER_OF_STREAMING_REQUESTS,0xee21e8a6031cea47, GetNumStreamingRequests); SCR_REGISTER_UNUSED(IS_STREAMING_PRIORITY_REQUESTS,0x443cd194a3b45769, IsStreamingPriorityRequests); SCR_REGISTER_SECURE(REQUEST_PTFX_ASSET,0x9e63031c188793e1, RequestPtFxAsset); SCR_REGISTER_SECURE(HAS_PTFX_ASSET_LOADED,0x51b6c2ef8dbe2e1a, HasPtFxAssetLoaded); SCR_REGISTER_SECURE(REMOVE_PTFX_ASSET,0xe6239ccb98b8ab66, RemovePtFxAsset); SCR_REGISTER_SECURE(REQUEST_NAMED_PTFX_ASSET,0xd86c99569d4749b0, RequestNamedPtFxAsset); SCR_REGISTER_SECURE(HAS_NAMED_PTFX_ASSET_LOADED,0x6264b811e8d92198, HasNamedPtFxAssetLoaded); SCR_REGISTER_SECURE(REMOVE_NAMED_PTFX_ASSET,0x416ba6ce9f7e648b, RemoveNamedPtFxAsset); SCR_REGISTER_SECURE(SET_VEHICLE_POPULATION_BUDGET,0xa121d58142738a8d, SetVehiclePopulationBudget); SCR_REGISTER_SECURE(SET_PED_POPULATION_BUDGET,0x8c5e1b04c94ff212, SetPedPopulationBudget); SCR_REGISTER_SECURE(CLEAR_FOCUS,0x5639e771f6085bf6, ClearFocus); SCR_REGISTER_SECURE(SET_FOCUS_POS_AND_VEL,0x7d5c42a7cdb11db6, SetFocusPosAndVel); SCR_REGISTER_SECURE(SET_FOCUS_ENTITY,0x34582635da718e5a, SetFocusEntity); SCR_REGISTER_SECURE(IS_ENTITY_FOCUS,0xf184bef0dbd3ad20, IsEntityFocus); SCR_REGISTER_SECURE(SET_RESTORE_FOCUS_ENTITY,0xe35fcef2127afccf, SetRestoreFocusEntity); SCR_REGISTER_SECURE(SET_MAPDATACULLBOX_ENABLED,0xa624331352defdcd, SetMapDataCullBoxEnabled); SCR_REGISTER_SECURE(SET_ALL_MAPDATA_CULLED,0x4c6cbcfdd1730e10, SetAllMapDataCulled); SCR_REGISTER_UNUSED(SET_HORIZON_OBJECTS_CULLED,0x0243893e8540fa67, SetHorizonObjectsCulled); SCR_REGISTER_SECURE(STREAMVOL_CREATE_SPHERE,0xd6d670d39e5eb332, CommandStreamVolCreateSphere); SCR_REGISTER_SECURE(STREAMVOL_CREATE_FRUSTUM,0xedf40cc24ee4ff61, CommandStreamVolCreateFrustum); SCR_REGISTER_SECURE(STREAMVOL_CREATE_LINE,0x83a445abf2242661, CommandStreamVolCreateLine); SCR_REGISTER_SECURE(STREAMVOL_DELETE,0x7de67eeefec38205, CommandStreamVolDelete); SCR_REGISTER_SECURE(STREAMVOL_HAS_LOADED,0x247b9cd82fd64f32, CommandStreamVolHasLoaded); SCR_REGISTER_SECURE(STREAMVOL_IS_VALID,0x52d132f41e04cb67, CommandStreamVolIsValid); SCR_REGISTER_SECURE(IS_STREAMVOL_ACTIVE,0xff4a0a9572c2f565, CommandIsStreamVolActive); SCR_REGISTER_SECURE(NEW_LOAD_SCENE_START,0xb37c5672ee23d04f, CommandNewLoadSceneStartFrustum); SCR_REGISTER_SECURE(NEW_LOAD_SCENE_START_SPHERE,0xca60df1d01dbd440, CommandNewLoadSceneStartSphere); SCR_REGISTER_SECURE(NEW_LOAD_SCENE_STOP,0xee3a19a84a10f8b9, CommandNewLoadSceneStop); SCR_REGISTER_SECURE(IS_NEW_LOAD_SCENE_ACTIVE,0x2981c54770e1d19c, CommandIsNewLoadSceneActive); SCR_REGISTER_SECURE(IS_NEW_LOAD_SCENE_LOADED,0x8a6ab093d1ee5368, CommandIsNewLoadSceneLoaded); SCR_REGISTER_SECURE(IS_SAFE_TO_START_PLAYER_SWITCH,0x3510bf4043201732, CommandIsSafeToStartPlayerSwitch); SCR_REGISTER_SECURE(START_PLAYER_SWITCH,0xccd7aa32a884016d, CommandStartPlayerSwitch); SCR_REGISTER_SECURE(STOP_PLAYER_SWITCH,0x310f3c51704851d4, CommandStopPlayerSwitch); SCR_REGISTER_SECURE(IS_PLAYER_SWITCH_IN_PROGRESS,0x04458b4e5d9e466a, CommandIsPlayerSwitchInProgress); SCR_REGISTER_SECURE(GET_PLAYER_SWITCH_TYPE,0xb6bdac890771ed04, CommandGetPlayerSwitchType); SCR_REGISTER_SECURE(GET_IDEAL_PLAYER_SWITCH_TYPE,0x22c67338735160aa, CommandGetIdealPlayerSwitchType); SCR_REGISTER_SECURE(GET_PLAYER_SWITCH_STATE,0xeefb36b938654045, CommandGetPlayerSwitchState); SCR_REGISTER_SECURE(GET_PLAYER_SHORT_SWITCH_STATE,0xaa8fd727e9cd9929, CommandGetPlayerShortSwitchState); SCR_REGISTER_SECURE(SET_PLAYER_SHORT_SWITCH_STYLE,0xe48e4b99dba9eaa1, CommandSetPlayerShortSwitchStyle); SCR_REGISTER_SECURE(GET_PLAYER_SWITCH_JUMP_CUT_INDEX,0x39c67356e2acaf22, CommandGetPlayerSwitchJumpCutIndex); SCR_REGISTER_SECURE(SET_PLAYER_SWITCH_OUTRO,0xd6466d9b50e967e5, CommandSetPlayerSwitchOutro); SCR_REGISTER_SECURE(SET_PLAYER_SWITCH_ESTABLISHING_SHOT,0x6c31ccf5981b2c06, CommandSetPlayerSwitchEstablishingShot); SCR_REGISTER_SECURE(ALLOW_PLAYER_SWITCH_PAN,0x4e554357e32f827c, CommandAllowPlayerSwitchPan); SCR_REGISTER_SECURE(ALLOW_PLAYER_SWITCH_OUTRO,0x92fe9bfdb58c08b1, CommandAllowPlayerSwitchOutro); SCR_REGISTER_SECURE(ALLOW_PLAYER_SWITCH_ASCENT,0x01aa29ae1a82b574, CommandAllowPlayerSwitchAscent); SCR_REGISTER_SECURE(ALLOW_PLAYER_SWITCH_DESCENT,0x2192f61b6fb23e19, CommandAllowPlayerSwitchDescent); SCR_REGISTER_UNUSED(IS_SWITCH_READY_FOR_ASCENT,0xa7589c3c447ac818, CommandIsSwitchReadyForAscent); SCR_REGISTER_SECURE(IS_SWITCH_READY_FOR_DESCENT,0xf7fa5e5f48d7ef30, CommandIsSwitchReadyForDescent); SCR_REGISTER_SECURE(ENABLE_SWITCH_PAUSE_BEFORE_DESCENT,0xe28d19155d6799a8, CommandEnableSwitchPauseBeforeDescent); SCR_REGISTER_SECURE(DISABLE_SWITCH_OUTRO_FX,0x3e99c894fa419af2, CommandDisableSwitchOutroFX); SCR_REGISTER_SECURE(SWITCH_TO_MULTI_FIRSTPART,0xa1bc090595ba935f, CommandSwitchToMultiFirstPart); SCR_REGISTER_SECURE(SWITCH_TO_MULTI_SECONDPART,0xbaac2fbaae6257db, CommandSwitchToMultiSecondPart); SCR_REGISTER_SECURE(IS_SWITCH_TO_MULTI_FIRSTPART_FINISHED,0x5e9ec8eea03bcec7, CommandIsSwitchToMultiFirstPartFinished); SCR_REGISTER_SECURE(GET_PLAYER_SWITCH_INTERP_OUT_DURATION,0x78fd52dd96d53522, CommandGetPlayerSwitchInterpOutDuration); SCR_REGISTER_SECURE(GET_PLAYER_SWITCH_INTERP_OUT_CURRENT_TIME,0x5ad9f5341c05bc7d, CommandGetPlayerSwitchInterpOutCurrentTime); SCR_REGISTER_SECURE(IS_SWITCH_SKIPPING_DESCENT,0x9fd60deda01f20a5, CommandIsSwitchSkippingDescent); SCR_REGISTER_SECURE(SET_SCENE_STREAMING_TRACKS_CAM_POS_THIS_FRAME,0xa63f1768421c7a80, CommandSetSceneStreamingTracksCamPosThisFrame); SCR_REGISTER_SECURE(GET_LODSCALE,0xb32301583643b6b3, CommandGetLodScale); SCR_REGISTER_SECURE(OVERRIDE_LODSCALE_THIS_FRAME,0x9b8b94a1196f345f, CommandOverrideLodScaleThisFrame); SCR_REGISTER_SECURE(REMAP_LODSCALE_RANGE_THIS_FRAME,0x34666baa70bf66df, CommandRemapLodScaleRangeThisFrame); SCR_REGISTER_SECURE(SUPPRESS_HD_MAP_STREAMING_THIS_FRAME,0xb1a39942d4e31aa5, CommandSuppressHdMapStreamingThisFrame); SCR_REGISTER_SECURE(SET_RENDER_HD_ONLY,0xd2726749ba8dac02, CommandSetRenderHdOnly); SCR_REGISTER_SECURE(FORCE_ALLOW_TIME_BASED_FADING_THIS_FRAME,0x7426ead34c015246, CommandForceAllowTimeBasedFadingThisFrame); SCR_REGISTER_SECURE(IPL_GROUP_SWAP_START,0x25cf3b0410cd653c, CommandIplGroupSwapStart); SCR_REGISTER_SECURE(IPL_GROUP_SWAP_CANCEL,0x8de9b7e224bcb723, CommandIplGroupSwapCancel); SCR_REGISTER_SECURE(IPL_GROUP_SWAP_IS_READY,0x329d6926716ee57f, CommandIplGroupSwapIsReady); SCR_REGISTER_SECURE(IPL_GROUP_SWAP_FINISH,0x015da57f7a0fa1a6, CommandIplGroupSwapFinish); SCR_REGISTER_SECURE(IPL_GROUP_SWAP_IS_ACTIVE,0x29978d4627985414, CommandIplGroupSwapIsActive); SCR_REGISTER_UNUSED(ENABLE_EXTRA_DISTANTLIGHTS,0x0ea9823cbd5fc533, CommandEnableExtraDistantLights); SCR_REGISTER_UNUSED(DISABLE_EXTRA_DISTANTLIGHTS,0x04ea50ecc60d4da3, CommandDisableExtraDistantLights); SCR_REGISTER_SECURE(PREFETCH_SRL,0x0728c4d61e5ace06, CommandPrefetchSrl); SCR_REGISTER_SECURE(IS_SRL_LOADED,0xd66fb6b74ee3da66, CommandIsSrlLoaded); SCR_REGISTER_SECURE(BEGIN_SRL,0x670baa84466115ca, CommandBeginSrl); SCR_REGISTER_SECURE(END_SRL,0x7e8f5ae44588d398, CommandEndSrl); SCR_REGISTER_SECURE(SET_SRL_TIME,0x7e887f52de52d931, CommandSetSrlTime); SCR_REGISTER_SECURE(SET_SRL_POST_CUTSCENE_CAMERA,0xf5d67a1497505f00, CommandSetSrlPostCutsceneCamera); SCR_REGISTER_SECURE(SET_SRL_READAHEAD_TIMES,0x125f5e3a0150ab0d, CommandSetSrlReadAheadTimes); SCR_REGISTER_SECURE(SET_SRL_LONG_JUMP_MODE,0xa694a53a397fc676, CommandSetSrlLongJumpMode); SCR_REGISTER_SECURE(SET_SRL_FORCE_PRESTREAM,0xa8b7321f953cff17, CommandSetSrlForcePrestream); SCR_REGISTER_SECURE(SET_HD_AREA,0x74f17c1a1b5f2f56, CommandSetHdArea); SCR_REGISTER_SECURE(CLEAR_HD_AREA,0x41bb0bac020b994f, CommandClearHdArea); SCR_REGISTER_SECURE(INIT_CREATOR_BUDGET,0x3e2d4acdeb176503, CommandInitCreatorBudget); SCR_REGISTER_SECURE(SHUTDOWN_CREATOR_BUDGET,0xdd631a688bd16327, CommandShutdownCreatorBudget); SCR_REGISTER_UNUSED(HAS_ROOM_FOR_MODEL_IN_CREATOR_BUDGET,0x9fa7ce1e863f69fb, CommandHasRoomForModelInCreatorBudget); SCR_REGISTER_SECURE(ADD_MODEL_TO_CREATOR_BUDGET,0x66eb6fa2c84f8e14, CommandAddModelToCreatorBudget); SCR_REGISTER_SECURE(REMOVE_MODEL_FROM_CREATOR_BUDGET,0xac51edc6ac06cfee, CommandRemoveModelFromCreatorBudget); SCR_REGISTER_SECURE(GET_USED_CREATOR_BUDGET,0x67b39fa5cb56f775, CommandGetUsedCreatorBudget); SCR_REGISTER_SECURE(SET_ISLAND_ENABLED,0x17d70b6d85547996, CommandSetIslandEnabled); SCR_REGISTER_UNUSED(ARE_ISLAND_IPLS_ACTIVE,0x24bed3d8303d66b6, CommandAreIslandIPLsActive); #if GEN9_STANDALONE_ENABLED SCR_REGISTER_UNUSED(IS_GAME_INSTALLED,0xa6fa11b890aaa882, CommandIsGameInstalled); #endif } };