///////////////////////////////////////////////////////////////////////////////// // // FILE : script.cpp // PURPOSE : Scripting and stuff. // AUTHOR : Graeme & Obbe. // anyway) // CREATED : 12-11-99 // ///////////////////////////////////////////////////////////////////////////////// #include "script/script.h" // Rage headers #include "audioengine/engine.h" #include "system/param.h" #include "vector/quaternion.h" // Framework headers #include "fwnet/nettypes.h" #include "fwscene/stores/mapdatastore.h" #include "fwscript/scriptInterface.h" // Security headers #include "security/ragesecwinapi.h" // Game headers #include "animation/AnimScene/AnimSceneManager.h" #include "audio/scriptaudioentity.h" #include "camera/CamInterface.h" #include "control/replay/replay.h" #include "cutscene/CutSceneManagerNew.h" #include "debug/BugstarIntegration.h" #include "event/EventErrors.h" #include "event/EventGroup.h" #include "event/EventNetwork.h" #include "frontend/landing_page/LandingPageArbiter.h" #include "frontend/landing_page/LandingPageConfig.h" #include "Network/Events/NetworkEventTypes.h" #include "Network/Network.h" #include "Network/NetworkInterface.h" #include "Network/Live/NetworkTelemetry.h" #include "Objects/DummyObject.h" #include "Objects/object.h" #include "peds/ped.h" #include "peds/Ped.h" #include "scene/MapChange.h" #include "scene/ExtraContentDefs.h" #include "scene/worldpoints.h" #include "scene/world/GameWorld.h" #include "script/commands_apps.h" #include "script/commands_audio.h" #include "script/commands_brains.h" #include "script/commands_camera.h" #include "script/commands_cutscene.h" #include "script/commands_datafile.h" #include "script/commands_debug.h" #include "script/commands_decorator.h" #include "script/commands_extrametadata.h" #include "script/commands_entity.h" #include "script/commands_event.h" #include "script/commands_gamestream.h" #include "script/commands_gang.h" #include "script/commands_hud.h" #include "script/commands_interiors.h" #include "script/commands_itemsets.h" #include "script/commands_landingpage.h" #include "script/commands_law.h" #include "script/commands_localization.h" #include "script/commands_misc.h" #include "script/commands_money.h" #include "script/commands_object.h" #include "script/commands_pad.h" #include "script/commands_path.h" #include "script/commands_ped.h" #include "script/commands_player.h" #include "script/commands_physics.h" #include "script/commands_script.h" #include "script/commands_security.h" #include "script/commands_shapetest.h" #include "script/commands_socialclub.h" #include "script/commands_stats.h" #include "script/commands_streaming.h" #include "script/commands_task.h" #include "script/commands_vehicle.h" #include "script/commands_volume.h" #include "script/commands_weapon.h" #include "script/commands_fire.h" #include "script/commands_zone.h" #include "script/commands_graphics.h" #include "script/commands_clock.h" #include "script/commands_network.h" #include "script/commands_lobby.h" #include "script/commands_inventory.h" #include "script/commands_water.h" #include "script/commands_xml.h" #include "script/commands_ny.h" #include "script/commands_dlc.h" #include "script/commands_recording.h" #include "script/commands_replay.h" #include "script/commands_netshopping.h" #include "script/commands_savemigration.h" #include "script/script_areas.h" #include "script/script_brains.h" #include "script/script_cars_and_peds.h" #include "script/script_debug.h" #include "script/script_hud.h" #include "script/handlers/GameScriptEntity.h" #include "script/Handlers/GameScriptResources.h" #include "script/script_helper.h" #include "script/streamedscripts.h" #include "script/script_channel.h" #include "script/ScriptMetadataManager.h" #include "security/plugins/apicheckplugin.h" #include "streaming/streaming.h" #include "system/controlMgr.h" #include "system/exception.h" #include "system/FileMgr.h" #include "system/hangdetect.h" #include "task/Scenario/info/ScenarioInfoManager.h" #include "vfx/misc/MovieMeshManager.h" #include "control/replay/replay.h" SCRIPT_OPTIMISATIONS () NETWORK_OPTIMISATIONS () PARAM(startupscript, "[script] load and run this script in place of startup.sc"); PARAM(scriptInstructionLimit, "[script] set the maximum number of instructions per frame to something other than the default of 1,000,000"); PARAM(scriptProtectGlobals, "[script] protects scripts global memory outide of the script update process"); //Define a script assert channel RAGE_DEFINE_CHANNEL(script) RAGE_DEFINE_SUBCHANNEL(script,hud) RAGE_DEFINE_SUBCHANNEL(script,camera) CScriptsForBrains CTheScripts::ms_ScriptsForBrains; CScriptBrainDispatcher CTheScripts::ms_ScriptBrainDispatcher; bool CTheScripts::ms_bPlayerIsOnAMission = false; bool CTheScripts::ms_bPlayerIsOnARandomEvent = false; u32 CTheScripts::ms_Frack = 0xEBEFC45E; parTree* CTheScripts::ms_pXmlTree = NULL; parTreeNode* CTheScripts::ms_pCurrentXmlTreeNode = NULL; bool CTheScripts::ms_bUpdatingScriptThreads = false; bool CTheScripts::ms_bPlayerIsRepeatingAMission = false; bool CTheScripts::ms_bPlayerIsInAnimalForm = false; bool CTheScripts::ms_bIsInDirectorMode = false; bool CTheScripts::ms_directorModeAvailable = true; s32 CTheScripts::ms_customMPHudColor = HUD_COLOUR_INVALID; CScriptPatrol CTheScripts::ms_ScriptPatrol; CMissionReplayStats CTheScripts::ms_MissionReplayStats; CHiddenObjects CTheScripts::ms_HiddenObjects; atBinaryMap CDLCScript::ms_scripts; #if __DEV static bool bDisplayUsedScriptResources = false; #endif int CTheScripts::ms_NumberOfMiniGamesInProgress = 0; #if !__PPU bool CTheScripts::ms_bSinglePlayerRestoreHasJustOccurred = false; #endif #if __BANK f32 CTheScripts::sm_fTimeFadedOut = 0.0f; #endif // __BANK #if !__FINAL bool CTheScripts::ms_bScriptLaunched = false; #endif //!__FINAL sysTimer CTheScripts::sm_ScriptTimer; char CTheScripts::ms_ContentIdOfCurrentUGCMission[RLUGC_MAX_CONTENTID_CHARS]; bool CTheScripts::ms_bAllowGameToPauseForStreaming = true; bool CTheScripts::ms_bScenarioPedsCanBeGrabbedByScript = false; bool CTheScripts::ms_bCodeRequestedAutosave = false; bool CTheScripts::ms_bProcessingTheScriptsDuringGameInit = false; CGameScriptHandlerMgr CTheScripts::ms_ScriptHandlerMgr(&CNetwork::GetBandwidthManager()); bool CTheScripts::ms_bKillingAllScriptThreads = false; CScriptOpList CTheScripts::ms_scriptOpList; static int s_InstructionLimit = 0; GEN9_STANDALONE_ONLY(CTheScripts::InitState CTheScripts::ms_initState = CTheScripts::InitState::Uninitialized); bool CTheScripts::GetClosestObjectCB(CEntity* pEntity, void* data) { Assert(pEntity); ClosestObjectDataStruct* pClosestObjectData = reinterpret_cast(data); if (pClosestObjectData->bCheckModelIndex && (pEntity->GetModelIndex() != pClosestObjectData->ModelIndexToCheck) ) { return true; } if (pClosestObjectData->bCheckStealableFlag) { scriptAssertf(pEntity->GetIsTypeObject(), "%s:GetClosestObjectCB - Object should be a real object (not a dummy) if you're checking if it's stealable. This is a code problem (probably not a script problem)", CTheScripts::GetCurrentScriptNameAndProgramCounter()); if (pEntity->GetIsTypeObject()) { CObject *pObj = (CObject *) pEntity; if (pObj->m_nObjectFlags.bIsStealable == false) { return true; } } } if(!((1 << pEntity->GetOwnedBy()) & pClosestObjectData->nOwnedByMask)) { return true; } Vector3 DiffVector = VEC3V_TO_VECTOR3(pEntity->GetTransform().GetPosition()) - pClosestObjectData->CoordToCalculateDistanceFrom; float ObjDistanceSquared = DiffVector.Mag2(); if (ObjDistanceSquared < pClosestObjectData->fClosestDistanceSquared) { pClosestObjectData->pClosestObject = pEntity; pClosestObjectData->fClosestDistanceSquared = ObjDistanceSquared; } return true; } bool CTheScripts::CountMissionEntitiesInAreaCB(CEntity* pEntity, void* data) { int* pNumberOfMissionEntities = reinterpret_cast(data); if (IsMissionEntity(pEntity)) (*pNumberOfMissionEntities)++; return(true); } bool CTheScripts::IsMissionEntity(CEntity * pEntity) { Assert(pEntity); switch (pEntity->GetType()) { case ENTITY_TYPE_VEHICLE : if (((CVehicle *)pEntity)->PopTypeIsMission()) { return true; } break; case ENTITY_TYPE_PED : if (((CPed *)pEntity)->PopTypeIsMission()) { return true; } break; case ENTITY_TYPE_OBJECT : if (((CObject *)pEntity)->GetOwnedBy() == ENTITY_OWNEDBY_SCRIPT) // || (((CObject *)pEntity)->GetOwnedBy() == MISSION_BRAIN_OBJECT) ) { return true; } break; default : break; } return false; } extern scrCommandHash s_CommandHash; typedef void (*regFunction) (); void CTheScripts::ScrambleAndRegister() { atArray sourceArray; sourceArray.Reserve(100); sourceArray.Push(netshopping_commands::SetupScriptCommands); sourceArray.Push(script_commands::SetupScriptCommands); sourceArray.Push(object_commands::SetupScriptCommands); sourceArray.Push(xml_commands::SetupScriptCommands); sourceArray.Push(volume_commands::SetupScriptCommands); sourceArray.Push(brain_commands::SetupScriptCommands); sourceArray.Push(replay_commands::SetupScriptCommands); sourceArray.Push(weapon_commands::SetupScriptCommands); sourceArray.Push(apps_commands::SetupScriptCommands); sourceArray.Push(ped_commands::SetupScriptCommands); sourceArray.Push(fire_commands::SetupScriptCommands); sourceArray.Push(clock_commands::SetupScriptCommands); sourceArray.Push(interior_commands::SetupScriptCommands); sourceArray.Push(pad_commands::SetupScriptCommands); sourceArray.Push(graphics_commands::SetupScriptCommands); sourceArray.Push(inventory_commands::SetupScriptCommands); sourceArray.Push(localization_commands::SetupScriptCommands); sourceArray.Push(player_commands::SetupScriptCommands); sourceArray.Push(physics_commands::SetupScriptCommands); sourceArray.Push(entity_commands::SetupScriptCommands); sourceArray.Push(task_commands::SetupScriptCommands); sourceArray.Push(zone_commands::SetupScriptCommands); sourceArray.Push(misc_commands::SetupScriptCommands); sourceArray.Push(streaming_commands::SetupScriptCommands); sourceArray.Push(socialclub_commands::SetupScriptCommands); sourceArray.Push(law_commands::SetupScriptCommands); sourceArray.Push(audio_commands::SetupScriptCommands); sourceArray.Push(gta_commands::SetupScriptCommands); sourceArray.Push(path_commands::SetupScriptCommands); sourceArray.Push(itemsets_commands::SetupScriptCommands); sourceArray.Push(datafile_commands::SetupScriptCommands); sourceArray.Push(dlc_commands::SetupScriptCommands); sourceArray.Push(cutscene_commands::SetupScriptCommands); sourceArray.Push(stats_commands::SetupScriptCommands); sourceArray.Push(shapetest_commands::SetupScriptCommands); sourceArray.Push(recording_commands::SetupScriptCommands); sourceArray.Push(extrametadata_commands::SetupScriptCommands); sourceArray.Push(camera_commands::SetupScriptCommands); sourceArray.Push(vehicle_commands::SetupScriptCommands); sourceArray.Push(lobby_commands::SetupScriptCommands); sourceArray.Push(event_commands::SetupScriptCommands); sourceArray.Push(water_commands::SetupScriptCommands); sourceArray.Push(money_commands::SetupScriptCommands); sourceArray.Push(network_commands::SetupScriptCommands); sourceArray.Push(debug_commands::SetupScriptCommands); sourceArray.Push(gang_commands::SetupScriptCommands); sourceArray.Push(decorator_commands::SetupScriptCommands); sourceArray.Push(hud_commands::SetupScriptCommands); sourceArray.Push(savemigration_commands::SetupScriptCommands); sourceArray.Push(landingpage_commands::SetupScriptCommands); sourceArray.Push(security_commands::SetupScriptCommands); // scramble the function array u32 size = sourceArray.GetCount(); for(u32 scrambleCount = 0; scrambleCount < 1000; scrambleCount++) { u32 randomIndex = fwRandom::GetRandomNumberInRange(0, size); regFunction temp = sourceArray[randomIndex]; sourceArray.DeleteFast(randomIndex); sourceArray.Push(temp); } // execute all the functions in the scambled array for(u32 i = 0; i < sourceArray.GetCount(); i++) { sourceArray[i](); } ApiCheckPlugin_StopNativeHash(); s_CommandHash.RegistrationComplete(true); } void CTheScripts::RegisterScriptCommands() { #if 1 ScrambleAndRegister(); #else // //@@: location CTHESCRIPTS_REGISTER_SCRIPTCOMMANDS netshopping_commands::SetupScriptCommands(); script_commands::SetupScriptCommands(); object_commands::SetupScriptCommands(); xml_commands::SetupScriptCommands(); volume_commands::SetupScriptCommands(); brain_commands::SetupScriptCommands(); replay_commands::SetupScriptCommands(); weapon_commands::SetupScriptCommands(); apps_commands::SetupScriptCommands(); ped_commands::SetupScriptCommands(); fire_commands::SetupScriptCommands(); clock_commands::SetupScriptCommands(); interior_commands::SetupScriptCommands(); pad_commands::SetupScriptCommands(); graphics_commands::SetupScriptCommands(); inventory_commands::SetupScriptCommands(); localization_commands::SetupScriptCommands(); player_commands::SetupScriptCommands(); physics_commands::SetupScriptCommands(); entity_commands::SetupScriptCommands(); task_commands::SetupScriptCommands(); zone_commands::SetupScriptCommands(); misc_commands::SetupScriptCommands(); streaming_commands::SetupScriptCommands(); socialclub_commands::SetupScriptCommands(); law_commands::SetupScriptCommands(); audio_commands::SetupScriptCommands(); gta_commands::SetupScriptCommands(); path_commands::SetupScriptCommands(); itemsets_commands::SetupScriptCommands(); datafile_commands::SetupScriptCommands(); dlc_commands::SetupScriptCommands(); cutscene_commands::SetupScriptCommands(); stats_commands::SetupScriptCommands(); shapetest_commands::SetupScriptCommands(); recording_commands::SetupScriptCommands(); extrametadata_commands::SetupScriptCommands(); camera_commands::SetupScriptCommands(); vehicle_commands::SetupScriptCommands(); lobby_commands::SetupScriptCommands(); event_commands::SetupScriptCommands(); water_commands::SetupScriptCommands(); money_commands::SetupScriptCommands(); network_commands::SetupScriptCommands(); debug_commands::SetupScriptCommands(); gang_commands::SetupScriptCommands(); decorator_commands::SetupScriptCommands(); hud_commands::SetupScriptCommands(); savemigration_commands::SetupScriptCommands(); landingpage_commands::SetupScriptCommands(); security_commands::SetupScriptCommands(); #endif // 1 } void CTheScripts::GtaFaultHandler(const char *ASSERT_ONLY(CauseOfFault), scrThread*, scrThreadFaultID faultType) { if (GetCurrentGtaScriptThread()) { sErrorScriptID scriptID; scriptID.m_scriptNameHash = GetCurrentGtaScriptThread()->m_HashOfScriptName; switch(faultType) { case THREAD_ARRAY_OVERFLOW: GetEventScriptErrorsGroup()->Add(CEventErrorArrayOverflow(scriptID)); break; case THREAD_STACK_OVERFLOW: GetEventScriptErrorsGroup()->Add(CEventErrorStackOverflow(scriptID)); break; case THREAD_INSTRUCTION_COUNT_OVERFLOW: GetEventScriptErrorsGroup()->Add(CEventErrorInstructionLimit(scriptID)); break; case THREAD_UNKNOWN_ERROR_TYPE: default: GetEventScriptErrorsGroup()->Add(CEventErrorUnknownError(scriptID)); break; } #if __ASSERT // display the program counter of the current script here char ErrorString[1024]; sprintf(ErrorString, "%s : Program Counter = %d - Check the .scd file\n", GetCurrentScriptName(), GetCurrentGtaScriptThread()->GetThreadPC()); scriptAssertf(0, "%s:%s", ErrorString, CauseOfFault); #endif } else { scriptAssertf(0, "%s:%s", "Unknown script name", CauseOfFault); } } // KS - WR 156 - added stacksize argument scrThreadId CTheScripts::GtaStartNewThreadOverride(const char *progname,const void *argStruct,int argStructSize, int stackSize) { if (!progname || (strlen(progname) == 0) ) { if (GetCurrentGtaScriptThread()) { scriptAssertf(0, "%s:CTheScripts::GtaStartNewThreadOverride - trying to start a script without passing in a script name", GetCurrentScriptNameAndProgramCounter()); } else { scriptAssertf(0, "CTheScripts::GtaStartNewThreadOverride - trying to start a script without passing in a script name"); } } scrProgramId pid = scrProgram::IsCompiledAndResident(progname); if (!pid) { strLocalIndex id = g_StreamedScripts.FindSlot(progname); scriptAssertf(id != -1, "%s:Script doesn't exist", progname); if (id == -1) return THREAD_INVALID; scriptAssertf(g_StreamedScripts.Get(id), "%s:Script is not in memory", progname); scriptDisplayf("About to start script thread %s", progname); pid = g_StreamedScripts.GetProgramId(id.Get()); } return GtaStartNewThreadWithProgramId(pid, argStruct,argStructSize, stackSize, progname); } scrThreadId CTheScripts::GtaStartNewThreadWithNameHashOverride(atHashValue hashOfProgName,const void *argStruct,int argStructSize, int stackSize) { if (hashOfProgName.GetHash() == 0) { if (GetCurrentGtaScriptThread()) { scriptAssertf(0, "%s:CTheScripts::GtaStartNewThreadWithNameHashOverride - the hash of the script to be started is 0", GetCurrentScriptNameAndProgramCounter()); } else { scriptAssertf(0, "CTheScripts::GtaStartNewThreadWithNameHashOverride - the hash of the script to be started is 0"); } } // I'm not sure what to do with IsCompiledAndResident. It seems to be using a different hash function - scrComputeHash scrProgramId pid = srcpidNONE; // = scrProgram::IsCompiledAndResident(progname); // if (!pid) { strLocalIndex id = g_StreamedScripts.FindSlotFromHashKey(hashOfProgName.GetHash()); scriptAssertf(id != -1, "Script with hash %u doesn't exist", hashOfProgName.GetHash()); if (id == -1) return THREAD_INVALID; scriptAssertf(g_StreamedScripts.Get(id), "Script with hash %u is not in memory", hashOfProgName.GetHash()); scriptDisplayf("About to start script thread with hash %u", hashOfProgName.GetHash()); pid = g_StreamedScripts.GetProgramId(id.Get()); } char debugStringContainingHash[32]; formatf(debugStringContainingHash, "0x%x", hashOfProgName.GetHash()); return GtaStartNewThreadWithProgramId(pid, argStruct,argStructSize, stackSize, debugStringContainingHash); } scrThreadId CTheScripts::GtaStartNewThreadWithProgramId(scrProgramId progId,const void *argStruct,int argStructSize,int stackSize, const char* OUTPUT_ONLY(progname) ) { scrThreadId threadId = scrThread::CreateThread(progId, argStruct, argStructSize, stackSize); #if !__NO_OUTPUT if (threadId == THREAD_INVALID) { #if __BANK GtaThread::DisplayAllRunningScripts(false); #endif // __BANK #if __ASSERT scriptAssertf(0, "%s:Failed to create a new thread (stack %d)", progname, stackSize); #else scriptErrorf("%s:Failed to create a new thread (stack %d)", progname, stackSize); #endif // __ASSERT } #endif // !__NO_OUTPUT GtaThread *pNewOne = static_cast (scrThread::GetThread(threadId)); if (pNewOne == NULL) { #if __ASSERT scriptAssertf(0, "CTheScripts::GtaStartNewThreadWithProgramId - Could not get a pointer to the new thread %s", progname); #else scriptErrorf("CTheScripts::GtaStartNewThreadWithProgramId - Could not get a pointer to the new thread %s", progname); #endif // __ASSERT return THREAD_INVALID; } pNewOne->Initialise(); ms_ScriptHandlerMgr.RegisterScript(*pNewOne); #if __BANK if (CScriptDebug::ShouldThisScriptBeDebugged(progname)) { GtaThread::AllocateDebuggerForThread(threadId); } CScriptDebug::SetComboBoxOfThreadNamesNeedsUpdated(true); #endif #if BACKTRACE_ENABLED sysException::BacktraceNotifyScriptLaunched((u32)progId, fwTimer::GetSystemTimeInMilliseconds()); #endif // BACKTRACE_ENABLED scriptDisplayf("Started new script thread %s(%d) with stack size %d", progname, threadId, stackSize); return threadId; } #if !__PPU void CTheScripts::SetSinglePlayerRestoreHasJustOccurred(bool bRestoreJustOccurred) { ms_bSinglePlayerRestoreHasJustOccurred = bRestoreJustOccurred; } bool CTheScripts::GetSinglePlayerRestoreHasJustOccurred() { return ms_bSinglePlayerRestoreHasJustOccurred; } #endif // !__PPU void CScriptPatrol::Init() { bPatrolRouteOpen = false; ScriptPatrolNodeIndex = 0; ScriptPatrolLinkIndex = 0; ScriptPatrolRouteHash = 0; // fwIplPatrolNode ScriptPatrolNodes[MAX_NUMBER_OF_PATROL_NODES]; // fwIplPatrolLink ScriptPatrolLinks[MAX_NUMBER_OF_PATROL_LINKS]; // int ScriptPatrolNodeIDs[MAX_NUMBER_OF_PATROL_NODES]; } void CScriptPatrol::OpenPatrolRoute(const char* RouteName) { if (SCRIPT_VERIFY((strnicmp ("miss_", RouteName,5) == 0), "CScriptPatrol::OpenPatrolRoute - Script patrol routes name must start with miss_")) { if (SCRIPT_VERIFY(bPatrolRouteOpen == false, "CScriptPatrol::OpenPatrolRoute - Patrol route must be closed before being opened")) { ScriptPatrolRouteHash = atStringHash(RouteName); bPatrolRouteOpen = true; ScriptPatrolNodeIndex = 0; ScriptPatrolLinkIndex = 0; } } } void CScriptPatrol::ClosePatrolRoute() { bPatrolRouteOpen = false; } void CScriptPatrol::AddPatrolNode(int NodeId, const char* NodeType, Vector3 &vNodePos, Vector3 &vNodeHeading, int Duration) { if (!vNodeHeading.IsZero()) { vNodeHeading = vNodeHeading - vNodePos; } int iDuration = (int) Duration / 1000; // Check if the node type references a valid scenario right away, rather than waiting for // a more cryptic assert from the tasks. u32 nodeTypeHash = atStringHash(NodeType); scriptAssertf(!nodeTypeHash || SCENARIOINFOMGR.GetScenarioIndex(nodeTypeHash, false) >= 0, "%s:ADD_PATROL_NODE - failed for find scenario '%s'.", CTheScripts::GetCurrentScriptNameAndProgramCounter(), NodeType); if (SCRIPT_VERIFY(bPatrolRouteOpen == true, "CScriptPatrol::AddPatrolNode- Patrol route must be open before adding nodes")) { if (SCRIPT_VERIFY((ScriptPatrolNodeIndex <= MAX_NUMBER_OF_PATROL_NODES - 1) , "CScriptPatrol::AddPatrolNode - Patrol route can have no more than 16 nodes")) { ScriptPatrolNodes[ScriptPatrolNodeIndex].x = vNodePos.x; ScriptPatrolNodes[ScriptPatrolNodeIndex].y = vNodePos.y; ScriptPatrolNodes[ScriptPatrolNodeIndex].z = vNodePos.z; ScriptPatrolNodes[ScriptPatrolNodeIndex].headingX = vNodeHeading.x; ScriptPatrolNodes[ScriptPatrolNodeIndex].headingY = vNodeHeading.y; ScriptPatrolNodes[ScriptPatrolNodeIndex].headingZ = vNodeHeading.z; ScriptPatrolNodes[ScriptPatrolNodeIndex].nodeTypeHash = nodeTypeHash; ScriptPatrolNodes[ScriptPatrolNodeIndex].routeNameHash = ScriptPatrolRouteHash; ScriptPatrolNodes[ScriptPatrolNodeIndex].duration = iDuration; ScriptPatrolNodeIDs[ScriptPatrolNodeIndex] = NodeId; ScriptPatrolNodeIndex++; } } } void CScriptPatrol::AddPatrolLink(int NodeID1, int NodeID2) { if (SCRIPT_VERIFY(bPatrolRouteOpen == true, "CScriptPatrol::AddPatrolLink - Patrol route must be open before adding nodes")) { if (SCRIPT_VERIFY(ScriptPatrolLinkIndex <= MAX_NUMBER_OF_PATROL_LINKS -1, "CScriptPatrol::AddPatrolLink - Patrol links must be less than 64")) { ScriptPatrolLinks[ScriptPatrolLinkIndex].node1 = NodeID1; ScriptPatrolLinks[ScriptPatrolLinkIndex].node2 = NodeID2; ScriptPatrolLinkIndex++; } } } void CScriptPatrol::CreatePatrolRoute() { if (SCRIPT_VERIFY(bPatrolRouteOpen == false, "CScriptPatrol::CreatePatrolRoute - Must close the nodes before adding the route")) { CScriptResource_PatrolRoute patrolRoute(ScriptPatrolRouteHash, ScriptPatrolNodes, ScriptPatrolNodeIDs, ScriptPatrolNodeIndex, ScriptPatrolLinks, ScriptPatrolLinkIndex, 0); CTheScripts::GetCurrentGtaScriptHandler()->RegisterScriptResource(patrolRoute); } } void CTheScripts::Init(unsigned initMode) { USE_MEMBUCKET(MEMBUCKET_SCRIPT); //@@: location CTHESCRIPTS_INIT_INIT_ENTRY_POINT GtaThread::StaticInit(initMode); if(initMode == INIT_CORE) { GEN9_STANDALONE_ONLY(Assertf(ms_initState == InitState::Uninitialized, "Unexpected state %d, should be %d", ms_initState, InitState::Uninitialized)); GEN9_STANDALONE_ONLY(ms_initState = InitState::Initialized); RAGE_TRACK(CTheScripts); #if ENABLE_SCRIPT_GLOBALS_HEAP const int globalsHeapSize = fwConfigManager::GetInstance().GetSizeOfPool(atHashString("scrGlobals", 0xC780FC5), CONFIGURED_FROM_FILE); sysMemStartPool(); u8* heapMem = rage_new u8[globalsHeapSize]; sysMemEndPool(); scrProgram::InitGlobalsHeap(heapMem, globalsHeapSize); #endif // ENABLE_SCRIPT_GLOBALS_HEAP scrProgram::InitClass(); scrThread::InitClass(); GtaThread::AllocateThreads(); ms_ScriptHandlerMgr.Init(); scriptInterface::Init(ms_ScriptHandlerMgr); CGameScriptResource::Init(initMode); //@@: location CTHESCRIPTS_INIT_INIT_SCRIPTSMETADATAMANAGER CScriptMetadataManager::Init(); scrThread::AppFaultHandler = GtaFaultHandler; scrThread::StartNewThreadOverride = GtaStartNewThreadOverride; scrThread::StartNewThreadWithNameHashOverride = GtaStartNewThreadWithNameHashOverride; #if !__PPU ms_bSinglePlayerRestoreHasJustOccurred = false; #endif ms_bProcessingTheScriptsDuringGameInit = false; // register commands //@@: location CTHESCRIPTS_INIT_REGISTER_BUILTIN_COMMANDS scrThread::RegisterBuiltinCommands(); RegisterScriptCommands(); #if SCRIPT_DEBUGGING // Process the -nativetrace command line argument to update actions for specified natives scrThread::ParseNativeTraceCommandLine(); #endif ms_pXmlTree = NULL; ms_pCurrentXmlTreeNode = NULL; ms_bUpdatingScriptThreads = false; s_InstructionLimit = 0; #if !__FINAL if (PARAM_scriptInstructionLimit.Get()) { PARAM_scriptInstructionLimit.Get(s_InstructionLimit); } #endif // !__FINAL #if RSG_PC && ENABLE_SCRIPT_TAMPER_CHECKER // Add the listener CScriptGlobalTamperChecker::Initialize(); #endif } #if GEN9_STANDALONE_ENABLED // We want to run this exactly once during INIT_CORE for first launch. If the game session is // subsequently shut down, we want to run this again when it is rebuilt during INIT_SESSION. if(ms_initState == InitState::Initialized) #else if (initMode == INIT_SESSION) #endif // GEN9_STANDALONE_ENABLED { GEN9_STANDALONE_ONLY(ms_initState = InitState::Running); #if __DEV g_StreamedScripts.ValidateAllScripts(); #endif scriptAssertf (ms_pXmlTree== NULL, "CTheScripts::Init - XmlNodeTree is not Null"); ms_pXmlTree = NULL; ms_pCurrentXmlTreeNode = NULL; ms_bUpdatingScriptThreads = false; //patrol routes ms_ScriptPatrol.Init(); ms_ScriptsForBrains.Init(); ms_ScriptBrainDispatcher.Init(); #if __DEV bDisplayUsedScriptResources = false; #endif ms_bPlayerIsOnAMission = false; ms_bPlayerIsOnARandomEvent = false; ms_bPlayerIsRepeatingAMission = false; ms_NumberOfMiniGamesInProgress = 0; ms_HiddenObjects.Init(); ms_bAllowGameToPauseForStreaming = true; ms_bScenarioPedsCanBeGrabbedByScript = false; ms_bCodeRequestedAutosave = false; ms_bKillingAllScriptThreads = false; ms_bProcessingTheScriptsDuringGameInit = false; #if __BANK sm_fTimeFadedOut = 0.0f; #endif // __BANK #if !__FINAL ms_bScriptLaunched = false; #endif //!__FINAL sm_ScriptTimer.Reset(); SetContentIdOfCurrentUGCMission(""); static const int kDefaultItemSetBufferSize = 128; // May want to override this to be much larger through the configuration file, RDR2 needed 2048. Memory per unit should be 4 byets. const int itemSetBufferSize = fwConfigManager::GetInstance().GetSizeOfPool(ATSTRINGHASH("ItemSetBuffer", 0x04e2adf9b), kDefaultItemSetBufferSize); CItemSetManager::InitClass(itemSetBufferSize); LaunchStartupScript(); } //@@: location CTHESCRIPTS_INIT_INITIALIZE_SCRIPT_SHAPE_TEST_MANAGER CScriptShapeTestManager::Init(initMode); //@@: location CTHESCRIPTS_INIT_INITIALIZE_MISSION_REPLAY_STATS_INIT ms_MissionReplayStats.Init(initMode); } void CTheScripts::LaunchStartupScript() { // if (!bLoadingAPreviouslySavedGame) { strLocalIndex mainScriptId = strLocalIndex(-1); // Gen9 Landing Page: There is now a pre-startup script that runs before the game session exists. // The -startupscript commandline param is delayed until the game session is created, // then it is loaded in script by landing_pre_startup. #if GEN9_LANDING_PAGE_ENABLED const char *pScriptName = "landing_pre_startup"; #else // GEN9_LANDING_PAGE_ENABLED const char *pScriptName = CFileMgr::IsGameInstalled() ? "startup" : "startup_install"; NOTFINAL_ONLY(PARAM_startupscript.Get(pScriptName)); #endif // GEN9_LANDING_PAGE_ENABLED #if !__FINAL ms_bScriptLaunched = true; #endif //!__FINAL mainScriptId = g_StreamedScripts.FindSlot(pScriptName); if(mainScriptId != -1) { g_StreamedScripts.StreamingRequest(mainScriptId, STRFLAG_DONTDELETE); CStreaming::LoadAllRequestedObjects(); if (g_StreamedScripts.HasObjectLoaded(mainScriptId)) { #if EXECUTABLE_SCRIPTS // Load all of the precompiled controller scripts now. (multiple scripts per PRX/DLL now) // We need to do this after we've registered all script commands, and also after all globals // have been registered as well. // See x:\gta5\script\dev\singleplayer\make_controllers.bat and build_controllers.bat. scrProgram::RegisterBinary("controllers"); #endif // EXECUTABLE_SCRIPTS scrThreadId NewScrThreadId = scrThread::CreateThread(g_StreamedScripts.GetProgramId(mainScriptId.Get()), NULL, 0, GtaThread::GetDefaultStackSize()); scrThread *pNewScriptThread = scrThread::GetThread(NewScrThreadId); if (pNewScriptThread) { GtaThread *pNewGtaThread = (GtaThread*) pNewScriptThread; pNewGtaThread->Initialise(); ms_ScriptHandlerMgr.RegisterScript(*pNewScriptThread); #if __BANK if (CScriptDebug::ShouldThisScriptBeDebugged(pNewScriptThread->GetScriptName())) { GtaThread::AllocateDebuggerForThread(NewScrThreadId); } #endif } g_StreamedScripts.ClearRequiredFlag(mainScriptId.Get(), STRFLAG_DONTDELETE); } else { Quitf(ERR_SCR_LAUNCH_1,"CTheScripts::LaunchStartupScript - the %s script has not loaded despite LoadAllRequestedObjects() being called", pScriptName); } } else { Quitf(ERR_SCR_LAUNCH_2,"CTheScripts::LaunchStartupScript - failed to find a script with the name %s in the script.rpf", pScriptName); } } } // // name: CTheScripts::Shutdown // description: void CTheScripts::Shutdown(unsigned shutdownMode) { if(shutdownMode == SHUTDOWN_CORE) { GEN9_STANDALONE_ONLY(ms_initState = InitState::Uninitialized); // shutdown script event queues GetEventScriptErrorsGroup()->Shutdown(); GetEventScriptAIGroup()->Shutdown(); GetEventScriptNetworkGroup()->Shutdown(); g_ScriptAudioEntity.StopStream(); ms_ScriptHandlerMgr.Shutdown(); g_StreamedScripts.Shutdown(); CScriptMetadataManager::Shutdown(); GtaThread::DeallocateThreads(); scrProgram::ShutdownClass(); scriptInterface::Shutdown(); } else if(shutdownMode == SHUTDOWN_SESSION) { // Inform the script engine that it will need to relaunch scripts if the game session is initialised GEN9_STANDALONE_ONLY(ms_initState = InitState::Initialized); ms_bKillingAllScriptThreads = true; scrThread::KillAllThreads(); ms_bKillingAllScriptThreads = false; CItemSetManager::ShutdownClass(); g_ScriptAudioEntity.StopStream(); g_StreamedScripts.ShutdownLevel(); ms_HiddenObjects.UndoHiddenObjects(); CScriptHud::Shutdown(shutdownMode); ms_scriptOpList.Flush(); CGameScriptResource::Shutdown(shutdownMode); #if ENABLE_SCRIPT_GLOBALS_HEAP ASSERT_ONLY(scrProgram::AssertGlobalsHeapEmpty();) #endif // ENABLE_SCRIPT_GLOBALS_HEAP } CScriptShapeTestManager::Shutdown(shutdownMode); } ///////////////////////////////////////////////////////////////////////////////// // FUNCTION : Update // PURPOSE : Called by the main update loop. ///////////////////////////////////////////////////////////////////////////////// void CTheScripts::Update() { } bool CTheScripts::ShouldBeProcessed() { if ( (fwTimer::IsGamePaused()) && (fwTimer::ShouldScriptsBePaused()) ) { return false; } // Graeme - 14.06.10 - I had to comment this out to allow the scripts to run for one frame during initialisation // if(CGame::IsChangingSessionState()) // { // If the network connection is lost then a message is displayed telling the player this and waiting // for A to be pressed. It's probably a bad idea to continue processing the scripts while a session restart is pending. // This return will stop any scripts running until the session has ended and a new one has started. // return false; // } // scripts are only processed when the game is performing a full update/render or HTML is being displayed // or the player is on the player settings screen in a network game // or the scripts are processing for one frame during the initialisation phase // or the Gen9 landing page is displayed before the game session is initialized if(!CGame::ShouldDoFullUpdateRender() && !NetworkInterface::IsGameInProgress() && !GetProcessingTheScriptsDuringGameInit() GEN9_LANDING_PAGE_ONLY(&& (!CLandingPageArbiter::IsLandingPageActive() || CGame::IsSessionInitialized())) ) { return false; } ReFrack(); // Don't process the scripts with a replay going on. #if GTA_REPLAY if (CReplayMgr::IsEditModeActive() && !CReplayMgr::ShouldUpdateScripts()) { return false; } #endif return true; } ///////////////////////////////////////////////////////////////////////////////// // FUNCTION : Process // PURPOSE : Wrapper for InternalProcess so we can protect script globals from // Tampering on PC MP ///////////////////////////////////////////////////////////////////////////////// void CTheScripts::Process(void) { #if RSG_PC && ENABLE_SCRIPT_TAMPER_CHECKER ////////////////////////////////////////////////////////////////////////// // PC only - check for memory-tampering in script globals static bool s_bReportedPlayer = false; #if !__FINAL static bool s_bProtectMemory = true; if(PARAM_scriptProtectGlobals.Get()) { s_bProtectMemory = true; } #endif int page = -1; bool isMultiplayer = NetworkInterface::IsAnySessionActive() && NetworkInterface::IsGameInProgress(); if ( #if !__FINAL s_bProtectMemory && #endif !CPauseMenu::IsActive() && CScriptGlobalTamperChecker::CurrentGlobalsDifferFromPreviousFrame(page)) { if ( !s_bReportedPlayer && isMultiplayer ) { s_bReportedPlayer = true; RageSecPluginGameReactionObject obj(REACT_GAMESERVER, GENERIC_GAME_ID, 0x20C8C138, 0x611E42B9, 0x23346609); rageSecGamePluginManager::GetRageSecGameReactionObjectQueue()->Push(obj); } } { //unchecked scope on PC only CScriptGlobalTamperChecker::UncheckedScope uncheckedScope; #endif //RSG_PC InternalProcess(); #if RSG_PC && ENABLE_SCRIPT_TAMPER_CHECKER } // end unchecked scope on PC CScriptGlobalTamperChecker::Update(); #if !__FINAL if(s_bProtectMemory) #endif { #if __BANK if(CScriptDebug::GetFakeTampering()) { CScriptGlobalTamperChecker::FakeTamper(0); } #endif //__BANK } #endif } ///////////////////////////////////////////////////////////////////////////////// // FUNCTION : Process // PURPOSE : Processes the scripts. ///////////////////////////////////////////////////////////////////////////////// void CTheScripts::InternalProcess(void) { AUTO_HANG_DETECT_CRASH_ZONE; ms_ScriptHandlerMgr.Update(); #if __BANK if (camInterface::IsFadedOut()) { sm_fTimeFadedOut += fwTimer::GetTimeStep(); } else { sm_fTimeFadedOut = 0.0f; } if (DisplayScriptProcessMessagesWhileScreenIsFaded()) { scriptDisplayf("CTheScripts::Process called while screen is faded"); } #endif // __BANK CControlMgr::UpdateVirtualKeyboard(); if (!ShouldBeProcessed()) { return; } #if GTA_REPLAY if(!CReplayMgr::IsReplayDisabled() && !CReplayMgr::IsRecordingEnabled() && !CReplayMgr::ShouldUpdateScripts()) { // update movie mesh manager g_movieMeshMgr.Update(); return; } #endif //GTA_REPLAY PF_START_TIMEBAR_DETAIL("Script update"); NetworkInterface::UpdateBeforeScripts(); #if RSG_PC NtDll::VerifyProtection(); Kernel32::VerifyProtection(); #endif sm_ScriptTimer.Reset(); CScriptAreas::Process(); CScriptCars::Process(); CScriptPeds::Process(); CScriptDebug::Process(); CScriptHud::Process(); #if __DEV if (bDisplayUsedScriptResources) { ms_ScriptHandlerMgr.DisplayObjectAndResourceInfo(); } #endif #if __BANK ms_ScriptHandlerMgr.DisplayScriptHandlerInfo(); #endif if (CGameWorld::GetMainPlayerInfo() REPLAY_ONLY(&& CReplayMgr::IsReplayInControlOfWorld() == false)) { CWorldPoints::ScanForScriptTriggerWorldPoints(CGameWorld::FindLocalPlayerCentreOfWorld()); } ms_ScriptBrainDispatcher.Process(); #if __BANK if (CScriptDebug::GetOutputScriptDisplayTextCommands()) { scripthudDisplayf("CTheScripts::Process - Start of processing script threads"); } #endif // __BANK scrThread::SetTimeStep(fwTimer::GetTimeStep()); ms_bUpdatingScriptThreads = true; scrThread::UpdateAll(s_InstructionLimit); ms_bUpdatingScriptThreads = false; #if __BANK if (CScriptDebug::GetOutputScriptDisplayTextCommands()) { scripthudDisplayf("CTheScripts::Process - End of processing script threads"); } #endif // __BANK //Doing this immediately after threads update to minimise time spent with shapetest requests enqueued CScriptShapeTestManager::Update(); // To free .sco files faster so that they can be used within the Preview folder GtaThread::KillAllAbortedScriptThreads(); // flush script event queues GetEventScriptErrorsGroup()->FlushAllAndMovePending(); GetEventScriptAIGroup()->FlushAllAndMovePending(); GetEventScriptNetworkGroup()->FlushAllAndMovePending(); // update movie mesh manager g_movieMeshMgr.Update(); CutSceneManager::GetInstance()->RenderBinkMovieAndUpdateRenderTargets(); #if __BANK if (DisplayScriptProcessMessagesWhileScreenIsFaded()) { sm_fTimeFadedOut -= 4.0f; } #endif // __BANK NetworkInterface::UpdateAfterScripts(); CAnimSceneManager::Update(kAnimSceneUpdatePostScript); } void CTheScripts::RegisterEntity(CPhysical* pEntity, bool bScriptHostObject, bool bNetworked, bool bNewEntity) { if (AssertVerify(pEntity) && scriptVerifyf(!pEntity->GetExtension(), "CTheScripts::RegisterEntity - The entity with model %s and PopType %s is already registered as a mission entity", pEntity->GetModelName(), CTheScripts::GetPopTypeName(pEntity->PopTypeGet()) )) { CScriptEntityExtension* pNewExtension = rage_new CScriptEntityExtension(*pEntity); Assert(pEntity->GetExtension()); scriptHandler* pScriptHandler = GetCurrentGtaScriptThread()->m_Handler; if (bScriptHostObject && NetworkInterface::IsGameInProgress()) { if (!bNetworked) { sysStack::PrintStackTrace(); Displayf("CTheScripts::RegisterEntity - trying to register a non-networked script host entity. Forcing networking."); Assertf(0, "CTheScripts::RegisterEntity - trying to register a non-networked script host entity. Forcing networking."); bNetworked = true; } if (bNetworked && !pEntity->GetNetworkObject()) { sysStack::PrintStackTrace(); Displayf("CTheScripts::RegisterEntity - trying to register a script host entity with no network object. Forcing client object."); Assertf(0, "CTheScripts::RegisterEntity - trying to register a script host entity with no network object. Forcing client object."); bScriptHostObject = false; bNetworked = false; } } // cache the networked state so that we know whether to register the object with the network code when a network game starts pNewExtension->SetIsNetworked(bNetworked); // all non-networked entities must be client ones as no other machine will know about them if (!bNetworked) { bScriptHostObject = false; } if (AssertVerify(pScriptHandler)) { pScriptHandler->RegisterNewScriptObject(static_cast(*pNewExtension), bScriptHostObject, bNetworked); if (pEntity->GetNetworkObject() && pScriptHandler->GetNetworkComponent()) { if (bScriptHostObject) { static_cast(pScriptHandler)->ValidateRegistrationRequest(pEntity, bNewEntity); // host objects should always be cloned on all machines running the script pEntity->GetNetworkObject()->SetGlobalFlag(CNetObjGame::GLOBALFLAG_CLONEALWAYS_SCRIPT, true); if (pEntity->GetNetworkObject()) { // update the scope state immediately so that the clone creates will go out a.s.a.p NetworkInterface::GetObjectManager().UpdateAllInScopeStateImmediately(pEntity->GetNetworkObject()); } } } } pEntity->ProtectStreamedArchetype(); } } void CTheScripts::UnregisterEntity(CPhysical* pEntity, bool bCleanupScriptState) { // unregister the ped from its associated script handler. CScriptEntityExtension* pExtension = pEntity->GetExtension(); scriptHandler* pScriptHandler = pExtension ? pExtension->GetScriptHandler() : NULL; if (pExtension && pScriptHandler) { // don't cleanup the script state of the target object if the object is about to be destroyed pExtension->SetCleanupTargetEntity(bCleanupScriptState); // set the no longer needed flag here so that the script handler knows that it needs to clean up the script info for the entity pExtension->SetNoLongerNeeded(true); pScriptHandler->UnregisterScriptObject(*pExtension); pEntity->UnprotectStreamedArchetype(); } // Graeme - the correct thing to do would be to delete the script guid for this entity here so that the entity can no longer be referenced by script // A few scripts are relying on being able to make a temp copy of an entityId, mark the entity as no longer needed and then call a few extra commands through the copied entityId // This wouldn't be possible if the line below was uncommented // fwScriptGuid::DeleteGuid(*pEntity); } CEntity** CTheScripts::GetAllScriptEntities(u32& numEntities) { const u32 maxNumberOfScriptEntities = 700; static CEntity* entities[maxNumberOfScriptEntities]; DEV_ONLY(memset(entities, 0, sizeof(entities))); scriptAssertf(maxNumberOfScriptEntities == (u32) CScriptEntityExtension::GetPool()->GetSize(), "CTheScripts::GetAllScriptEntities - maxNumberOfScriptEntities is %u. Change it to match the size of the CScriptEntityExtension pool which is defined in gameconfig.xml to be %d", maxNumberOfScriptEntities, CScriptEntityExtension::GetPool()->GetSize()); numEntities = ms_ScriptHandlerMgr.GetAllScriptHandlerEntities(entities, maxNumberOfScriptEntities); return entities; } bool CTheScripts::GetPlayerIsOnAMission(void) { if (ms_bPlayerIsOnAMission) { return true; } return false; } bool CTheScripts::IsPlayerPlaying(CPed *pPlayerPed) { if (scriptVerifyf(pPlayerPed, "CTheScripts::IsPlayerPlaying - ped pointer is NULL")) { CPlayerInfo *pPlayerInfo = pPlayerPed->GetPlayerInfo(); if (scriptVerifyf(pPlayerInfo, "CTheScripts::IsPlayerPlaying - ped doesn't have PlayerInfo")) { if (pPlayerInfo->IsRestartingAfterDeath() || pPlayerPed->IsInjured() || pPlayerInfo->IsRestartingAfterArrest()) { return false; } else { return true; } } } return false; } #if __DEV void CTheScripts::ClearAllEntityCheckedForDeadFlags(void) { CPed::Pool *pedpool = CPed::GetPool(); CPed *pPed; CVehicle::Pool *vehpool = CVehicle::GetPool(); CVehicle *pVehicle; s32 i; i = (s32) pedpool->GetSize(); while (i--) { pPed = pedpool->GetSlot(i); if (pPed) // && !pPed->IsPlayer()) { pPed->m_nDEflags.bCheckedForDead = FALSE; } } i = (s32) vehpool->GetSize(); while (i--) { pVehicle = vehpool->GetSlot(i); if (pVehicle) { pVehicle->m_nDEflags.bCheckedForDead = FALSE; } } } #endif // __DEV GtaThread *CTheScripts::GetCurrentGtaScriptThread(void) { return static_cast(scrThread::GetActiveThread()); } CGameScriptHandler *CTheScripts::GetCurrentGtaScriptHandler(void) { return (scrThread::GetActiveThread() ? static_cast(scrThread::GetActiveThread())->m_Handler : NULL); } CGameScriptHandlerNetwork *CTheScripts::GetCurrentGtaScriptHandlerNetwork(void) { CGameScriptHandler *pHandler = GetCurrentGtaScriptHandler(); if (pHandler && pHandler->RequiresANetworkComponent()) { return static_cast(pHandler); } return NULL; } void CTheScripts::PrioritizeRequestsFromMissionScript(s32 &streamingFlags) { if (!GetCurrentGtaScriptThread() || !GetCurrentGtaScriptThread()->m_bIsHighPrio) return; if (GetCurrentGtaScriptThread()->IsThisAMissionScript || GetCurrentGtaScriptThread()->GetIsARandomEventScript() || GetCurrentGtaScriptThread()->GetIsATriggerScript()) { streamingFlags |= STRFLAG_PRIORITY_LOAD; } } u32 CTheScripts::GetCurrentScriptHash(void) { const u32 noScript = 0; if (ms_bUpdatingScriptThreads) { return scrThread::GetActiveThread()->GetScriptNameHash(); } else { return noScript; } } const char *CTheScripts::GetCurrentScriptName(void) { const char* noScript = ""; if (ms_bUpdatingScriptThreads) { return scrThread::GetActiveThread()->GetScriptName(); } else { return noScript; } } #if !__NO_OUTPUT const char *CTheScripts::GetCurrentScriptNameAndProgramCounter(void) { static char text[256]; if (ms_bUpdatingScriptThreads) { sprintf(text, "SCRIPT: Script Name = %s : Program Counter = %d", GetCurrentScriptName(), GetCurrentGtaScriptThread()->GetThreadPC() ); } else { sprintf(text, " "); } return text; } #endif // !__NO_OUTPUT void CTheScripts::SetContentIdOfCurrentUGCMission(const char *pContentIdString) { if (pContentIdString == NULL) { scriptAssertf(0, "CTheScripts::SetContentIdOfCurrentUGCMission called with a NULL string so setting the string to empty"); pContentIdString = ""; } safecpy(ms_ContentIdOfCurrentUGCMission, pContentIdString, NELEM(ms_ContentIdOfCurrentUGCMission)); } // ********************* CMissionReplayStats ************************** void CMissionReplayStats::Init(unsigned initMode) { // Don't clear the structure in INIT_SESSION if(initMode == INIT_CORE) { ClearReplayStatsStructure(); } } // When a Replay Mission is passed void CMissionReplayStats::BeginReplayStatsStructure(s32 missionId, s32 missionType) { if (scriptVerifyf(m_bStatsHaveBeenStored == false, "CMissionReplayStats::BeginReplayStatsStructure - stats have already been stored")) { if (scriptVerifyf(m_bConstructingStructureOfStats == false, "CMissionReplayStats::BeginReplayStatsStructure - structure of stats is already being constructed")) { m_bConstructingStructureOfStats = true; m_nMissionId = missionId; m_nMissionType = missionType; m_ArrayOfMissionStats.Reset(); } } } void CMissionReplayStats::AddStatValueToReplayStatsStructure(s32 valueOfStat) { if (scriptVerifyf(m_bConstructingStructureOfStats, "CMissionReplayStats::AddStatValueToReplayStatsStructure - structure of stats is not being constructed. Check that BEGIN_REPLAY_STATS has been called first")) { if (scriptVerifyf(m_bStatsHaveBeenStored == false, "CMissionReplayStats::AddStatValueToReplayStatsStructure - stats have already been stored")) { m_ArrayOfMissionStats.PushAndGrow(valueOfStat); } } } void CMissionReplayStats::EndReplayStatsStructure() { if (scriptVerifyf(m_bConstructingStructureOfStats, "CMissionReplayStats::EndReplayStatsStructure - structure of stats is not being constructed. Check that BEGIN_REPLAY_STATS has been called first")) { if (scriptVerifyf(m_bStatsHaveBeenStored == false, "CMissionReplayStats::EndReplayStatsStructure - stats have already been stored")) { m_bStatsHaveBeenStored = true; m_bConstructingStructureOfStats = false; } } } // End of "When a Replay Mission is passed" // When a Load happens and the script detects that it’s a Replay save file s32 CMissionReplayStats::GetNumberOfMissionStats() { if (scriptVerifyf(m_bStatsHaveBeenStored, "CMissionReplayStats::GetNumberOfMissionStats - stats haven't been stored")) { return m_ArrayOfMissionStats.GetCount(); } return 0; } s32 CMissionReplayStats::GetStatValueAtIndex(s32 arrayIndex) { if (scriptVerifyf(m_bStatsHaveBeenStored, "CMissionReplayStats::GetStatValueAtIndex - stats haven't been stored")) { if (scriptVerifyf( (arrayIndex >= 0) && (arrayIndex < m_ArrayOfMissionStats.GetCount()), "CMissionReplayStats::GetStatValueAtIndex - arrayIndex %d is out of range 0 to %d", arrayIndex, m_ArrayOfMissionStats.GetCount())) { return m_ArrayOfMissionStats[arrayIndex]; } } return 0; } void CMissionReplayStats::ClearReplayStatsStructure() { m_bStatsHaveBeenStored = false; m_bConstructingStructureOfStats = false; m_nMissionId = 0; m_nMissionType = 0; m_ArrayOfMissionStats.Reset(); } // End of "When a Load happens and the script detects that it’s a Replay save file" // ********************* CHiddenObjects ************************** void CHiddenObjects::Init() { m_MapOfHiddenObjects.Reset(); } #if !__NO_OUTPUT void CHiddenObjects::DisplayInteriorDetails(fwInteriorLocation &interiorLoc) { if (interiorLoc.IsValid()) { scriptDisplayf("CHiddenObjects::DisplayInteriorDetails - interiorLoc is valid"); scriptDisplayf("CHiddenObjects::DisplayInteriorDetails - interior proxy index is %d", interiorLoc.GetInteriorProxyIndex()); if (interiorLoc.IsAttachedToRoom()) { scriptDisplayf("CHiddenObjects::DisplayInteriorDetails - interiorLoc is attached to room. Room index is %d", interiorLoc.GetRoomIndex()); } if (interiorLoc.IsAttachedToPortal()) { scriptDisplayf("CHiddenObjects::DisplayInteriorDetails - interiorLoc is attached to portal. Portal index is %d. PortalToExterior=%s", interiorLoc.GetPortalIndex(), interiorLoc.IsPortalToExterior()?"true":"false"); } } else { scriptDisplayf("CHiddenObjects::DisplayInteriorDetails - interiorLoc is not valid"); } } #endif // !__NO_OUTPUT void CHiddenObjects::AddToHiddenObjectMap(s32 ScriptGUIDOfEntity, spdSphere &SearchVolume, s32 ModelHash, CDummyObject *pDummyObj, fwInteriorLocation DummyInteriorLocation, s32 IplIndex) { if (m_MapOfHiddenObjects.Access(ScriptGUIDOfEntity) == NULL) { hidden_object_struct HiddenObjStruct; HiddenObjStruct.m_SearchVolume = SearchVolume; HiddenObjStruct.m_ModelHash = ModelHash; #if !__NO_OUTPUT fwModelId modelId; CBaseModelInfo* pModelInfo = CModelInfo::GetBaseModelInfoFromHashKey(static_cast< u32 >( ModelHash ), &modelId); if (scriptVerifyf(modelId.IsValid(), "CHiddenObjects::AddToHiddenObjectMap - %d (signed) %u (unsigned) is not a valid model hash", ModelHash, (u32) ModelHash)) { Vec3V SearchPos = SearchVolume.GetCenter(); scriptDisplayf("CHiddenObjects::AddToHiddenObjectMap - called for %s at %f %f %f", pModelInfo->GetModelName(), SearchPos.GetXf(), SearchPos.GetYf(), SearchPos.GetZf()); } #endif // !__NO_OUTPUT HiddenObjStruct.m_pRelatedDummyForObjectGrabbedFromTheWorld = pDummyObj; HiddenObjStruct.m_InteriorLocationOfRelatedDummyForObjectGrabbedFromTheWorld = DummyInteriorLocation; HiddenObjStruct.m_IplIndexOfObjectGrabbedFromTheWorld = IplIndex; #if !__NO_OUTPUT scriptDisplayf("CHiddenObjects::AddToHiddenObjectMap - interior location details are"); DisplayInteriorDetails(DummyInteriorLocation); #endif // !__NO_OUTPUT m_MapOfHiddenObjects.Insert(ScriptGUIDOfEntity, HiddenObjStruct); } g_MapChangeMgr.Add((u32) ModelHash, (u32) ModelHash, SearchVolume, true, CMapChange::TYPE_HIDE, true, true); } void CHiddenObjects::ReregisterInHiddenObjectMap(s32 oldScriptGUIDOfEntity, s32 newScriptGUIDOfEntity) { if (oldScriptGUIDOfEntity != newScriptGUIDOfEntity) { // Get entry for old GUID hidden_object_struct *pHideDataForThisEntity = m_MapOfHiddenObjects.Access(oldScriptGUIDOfEntity); if (pHideDataForThisEntity) { hidden_object_struct HiddenObjStruct = *pHideDataForThisEntity; // Remove entry for old GUID m_MapOfHiddenObjects.Delete(oldScriptGUIDOfEntity); if (scriptVerifyf(m_MapOfHiddenObjects.Access(newScriptGUIDOfEntity) == NULL, "CHiddenObjects::ReregisterInHiddenObjectMap - MapOfHiddenObjects contains data for old GUID %d, but we didn't expect it to also contain data for the new GUID %d", oldScriptGUIDOfEntity, newScriptGUIDOfEntity)) { #if !__NO_OUTPUT fwModelId modelId; CBaseModelInfo* pModelInfo = CModelInfo::GetBaseModelInfoFromHashKey(static_cast< u32 >( HiddenObjStruct.m_ModelHash ), &modelId); if (scriptVerifyf(modelId.IsValid(), "CHiddenObjects::ReregisterInHiddenObjectMap - %d (signed) %u (unsigned) is not a valid model hash", HiddenObjStruct.m_ModelHash, (u32) HiddenObjStruct.m_ModelHash)) { Vec3V SearchPos = HiddenObjStruct.m_SearchVolume.GetCenter(); scriptDisplayf("CHiddenObjects::ReregisterInHiddenObjectMap - called for %s at %f %f %f (Old GUID=%d, New GUID=%d)", pModelInfo->GetModelName(), SearchPos.GetXf(), SearchPos.GetYf(), SearchPos.GetZf(), oldScriptGUIDOfEntity, newScriptGUIDOfEntity); } scriptDisplayf("CHiddenObjects::ReregisterInHiddenObjectMap - interior location details are"); DisplayInteriorDetails(HiddenObjStruct.m_InteriorLocationOfRelatedDummyForObjectGrabbedFromTheWorld); #endif // !__NO_OUTPUT // Add entry for new GUID m_MapOfHiddenObjects.Insert(newScriptGUIDOfEntity, HiddenObjStruct); } } } } bool CHiddenObjects::RemoveFromHiddenObjectMap(s32 ScriptGUIDOfEntity, bool bHandleRelatedDummy) { bool bReturnValue = false; hidden_object_struct *pHideDataForThisEntity = m_MapOfHiddenObjects.Access(ScriptGUIDOfEntity); if (pHideDataForThisEntity) { g_MapChangeMgr.Remove(pHideDataForThisEntity->m_ModelHash, pHideDataForThisEntity->m_ModelHash, pHideDataForThisEntity->m_SearchVolume, CMapChange::TYPE_HIDE, false); CObject *pObject = CTheScripts::GetEntityToModifyFromGUID(ScriptGUIDOfEntity, 0); if (bHandleRelatedDummy && pObject) { #if !__NO_OUTPUT Vec3V SearchPos = pHideDataForThisEntity->m_SearchVolume.GetCenter(); scriptDisplayf("CHiddenObjects::RemoveFromHiddenObjectMap has been called for %s at %f %f %f", pObject->GetModelName(), SearchPos.GetXf(), SearchPos.GetYf(), SearchPos.GetZf()); #endif // !__NO_OUTPUT if (!pObject->GetIsRetainedByInteriorProxy()) { // If the object is on a retained list then that means the interior is shut down so skip the following code // and just make the object ENTITY_OWNEDBY_TEMP CDummyObject *pRelatedDummy = pHideDataForThisEntity->m_pRelatedDummyForObjectGrabbedFromTheWorld; fwInteriorLocation RelatedDummyLocation = pHideDataForThisEntity->m_InteriorLocationOfRelatedDummyForObjectGrabbedFromTheWorld; s32 IplIndex = pHideDataForThisEntity->m_IplIndexOfObjectGrabbedFromTheWorld; if (!pRelatedDummy) { scriptDisplayf("CHiddenObjects::RemoveFromHiddenObjectMap - pointer to related dummy for object %s has been lost so start a world search", pObject->GetModelName()); pRelatedDummy = FindClosestMatchingDummy(pHideDataForThisEntity, pObject); } if (pRelatedDummy) { pObject->SetIplIndex(IplIndex); pObject->SetRelatedDummy(pRelatedDummy, RelatedDummyLocation); // Can I just call CDummyObject::Disable() and let CObjectPopulation::ManageObject decide whether the object // should be swapped to the dummy? pRelatedDummy->Disable(); scriptDisplayf("CHiddenObjects::RemoveFromHiddenObjectMap - related dummy for object %s has been set up", pObject->GetModelName()); bReturnValue = true; } } else { scriptDisplayf("CHiddenObjects::RemoveFromHiddenObjectMap - object %s is on a retained list so skipping the code to re-establish a connection with the related dummy", pObject->GetModelName()); } } m_MapOfHiddenObjects.Delete(ScriptGUIDOfEntity); } return bReturnValue; } void CHiddenObjects::UndoHiddenObjects() { scriptAssertf(m_MapOfHiddenObjects.GetNumUsed() == 0, "CHiddenObjects::UndoHiddenObjects - expected all hidden objects to have been dealt with already during Shutdown Session"); // If any objects haven't already been unhidden then do that now atMap::Iterator mapIterator = m_MapOfHiddenObjects.CreateIterator(); while (!mapIterator.AtEnd()) { s32 ScriptGUID = mapIterator.GetKey(); // Can I assume that all CObjects will be deleted in Shutdown Session // and that UndoHiddenObjects() will only be called during Shutdown Session RemoveFromHiddenObjectMap(ScriptGUID, false); mapIterator.Start(); } } struct ClosestDummyObjectStruct { CEntity *m_pClosestDummyObject; u32 m_ModelHash; fwInteriorLocation m_InteriorLocation; s32 m_IplIndex; float m_fClosestDistanceSquared; Vec3V m_vCoordToCalculateDistanceFrom; }; bool GetClosestDummyObjectCB(CEntity* pEntity, void* data) { if (scriptVerifyf(pEntity, "GetClosestDummyObjectCB - entity pointer is NULL")) { if (scriptVerifyf(data, "GetClosestDummyObjectCB - data pointer is NULL")) { ClosestDummyObjectStruct* pClosestDummyObjectData = reinterpret_cast(data); if(pEntity->GetIsTypeDummyObject()) { if (pEntity->GetBaseModelInfo()->GetModelNameHash() == pClosestDummyObjectData->m_ModelHash) { if (pEntity->GetIplIndex() == pClosestDummyObjectData->m_IplIndex) { if (pEntity->GetInteriorLocation().IsSameLocation(pClosestDummyObjectData->m_InteriorLocation)) { //Get the distance between the centre of the locate and the entities position Vec3V DiffVector = pEntity->GetTransform().GetPosition() - pClosestDummyObjectData->m_vCoordToCalculateDistanceFrom; const float ObjDistanceSquared = MagSquared(DiffVector).Getf(); if (ObjDistanceSquared < pClosestDummyObjectData->m_fClosestDistanceSquared) { pClosestDummyObjectData->m_pClosestDummyObject = pEntity; pClosestDummyObjectData->m_fClosestDistanceSquared = ObjDistanceSquared; } } } } } } } return true; } // Debug function to print reason for failure of FindClosestMatchingDummy void CHiddenObjects::DisplayFailReason(const char* ASSERT_ONLY(pFailReason), const hidden_object_struct* ASSERT_ONLY(pHideData), const CObject* ASSERT_ONLY(pObject)) { #if __ASSERT Vector3 vObjectCoors(0.0f, 0.0f, 0.0f); const char *pObjectName = "Unknown Object"; if (pObject) { vObjectCoors = VEC3V_TO_VECTOR3(pObject->GetTransform().GetPosition()); pObjectName = pObject->GetModelName(); } Vec3V SearchPos = pHideData->m_SearchVolume.GetCenter(); scriptAssertf(0, "%s Object Name = %s, Object Pos = %f %f %f, Original Search Pos = %f %f %f", pFailReason, pObjectName, vObjectCoors.GetX(), vObjectCoors.GetY(), vObjectCoors.GetZ(), SearchPos.GetXf(), SearchPos.GetYf(), SearchPos.GetZf()); #endif // __ASSERT } CDummyObject *CHiddenObjects::FindClosestMatchingDummy(hidden_object_struct *pHideData, const CObject* pObject) { CDummyObject *pDummyObject = NULL; fwInteriorLocation InteriorLoc = pHideData->m_InteriorLocationOfRelatedDummyForObjectGrabbedFromTheWorld; bool bInteriorIsLoaded = false; bool bExteriorIsLoaded = false; if (InteriorLoc.IsValid()) { #if !__NO_OUTPUT scriptDisplayf("CHiddenObjects::FindClosestMatchingDummy - interior location details are"); DisplayInteriorDetails(InteriorLoc); #endif // !__NO_OUTPUT CInteriorProxy *pInteriorProxy = CInteriorProxy::GetFromLocation(InteriorLoc); if (pInteriorProxy) { if (pInteriorProxy->GetCurrentState() >= CInteriorProxy::PS_FULL) { bInteriorIsLoaded = true; scriptDisplayf("CHiddenObjects::FindClosestMatchingDummy - interior %d is instanced", InteriorLoc.GetInteriorProxyIndex()); } else { scriptDisplayf("CHiddenObjects::FindClosestMatchingDummy - current state of interior proxy is %u", pInteriorProxy->GetCurrentState()); scriptDisplayf("---"); scriptDisplayf("interior & object dump...\n"); scriptDisplayf("interior : %s, room : %d\n",pInteriorProxy->GetModelName(),InteriorLoc.GetRoomIndex()); CDebug::DumpEntity(pObject); // this assert isn't a real problem - object may have been pushed into exterior //DisplayFailReason("CHiddenObjects::FindClosestMatchingDummy - expected interior to be instanced at this stage. If this was not the case, we should have earlied-out due to the CObject being retained.", pHideData, pObject); } } else { DisplayFailReason("CHiddenObjects::FindClosestMatchingDummy - pInteriorProxy is NULL.", pHideData, pObject); } } else { // fwMapDataDef* pDef = fwMapDataStore::GetStore().GetSlot(pHideData->m_IplIndexOfObjectGrabbedFromTheWorld); // if (pDef && pDef->IsLoaded()) if ( fwMapDataStore::GetStore().HasObjectLoaded(strLocalIndex(pHideData->m_IplIndexOfObjectGrabbedFromTheWorld)) ) { bExteriorIsLoaded = true; scriptDisplayf("CHiddenObjects::FindClosestMatchingDummy - ipl %d is loaded", pHideData->m_IplIndexOfObjectGrabbedFromTheWorld); } } if (bInteriorIsLoaded || bExteriorIsLoaded) { ClosestDummyObjectStruct searchData; searchData.m_pClosestDummyObject = NULL; searchData.m_ModelHash = (u32) pHideData->m_ModelHash; searchData.m_InteriorLocation = InteriorLoc; searchData.m_IplIndex = pHideData->m_IplIndexOfObjectGrabbedFromTheWorld; searchData.m_fClosestDistanceSquared = pHideData->m_SearchVolume.GetRadiusSquaredf() * 4.0f; // set this to larger than the scan range (remember it's squared distance) searchData.m_vCoordToCalculateDistanceFrom = pHideData->m_SearchVolume.GetCenter(); SEARCH_LOCATION_FLAGS SearchFlags = SEARCH_LOCATION_EXTERIORS; // Search exteriors only if (bInteriorIsLoaded) { SearchFlags = SEARCH_LOCATION_INTERIORS; // Search interiors only } fwIsSphereIntersecting searchSphere(pHideData->m_SearchVolume); CGameWorld::ForAllEntitiesIntersecting(&searchSphere, GetClosestDummyObjectCB, (void*) &searchData, ENTITY_TYPE_MASK_DUMMY_OBJECT, SearchFlags, SEARCH_LODTYPE_HIGHDETAIL, SEARCH_OPTION_NONE, WORLDREP_SEARCHMODULE_SCRIPT); if (searchData.m_pClosestDummyObject) { if (scriptVerifyf(searchData.m_pClosestDummyObject->GetIsTypeDummyObject(), "CHiddenObjects::FindClosestMatchingDummy - expected entity to be a dummy object")) { pDummyObject = static_cast(searchData.m_pClosestDummyObject); } } } return pDummyObject; } // ********************* End of CHiddenObjects ************************** #if __ASSERT bool CTheScripts::IsValidGlobalVariable(int *AddressToTest) { for (int i=0; iGetType() == ENTITY_TYPE_VEHICLE || pEntity->GetType() == ENTITY_TYPE_PED || pEntity->GetType() == ENTITY_TYPE_OBJECT)) { const CPhysical* pPhysical = static_cast(pEntity); if (assertFlags & GUID_ASSERT_FLAG_DEAD_CHECK && pEntity->GetType() != ENTITY_TYPE_OBJECT) { scriptAssertf (pPhysical->m_nDEflags.bCheckedForDead == TRUE, "%s: %s - Check entity is alive this frame", GetCurrentScriptNameAndProgramCounter(), scrThread::GetCurrentCmdName()); } if (assertFlags & GUID_ASSERT_FLAG_NOT_CLONE) { if (pPhysical->IsNetworkClone() || (pPhysical->GetNetworkObject() && pPhysical->GetNetworkObject()->IsPendingOwnerChange())) { scriptAssertf (0, "%s: %s - Cannot call this command on an entity (%s) owned by another machine! (Clone: %s, migrating: %s)", GetCurrentScriptNameAndProgramCounter(), scrThread::GetCurrentCmdName(), pPhysical->GetNetworkObject()->GetLogName(), pPhysical->IsNetworkClone() ? "true" : "false", pPhysical->GetNetworkObject()->IsPendingOwnerChange() ? "true" : "false"); } } } } } #endif // __ASSERT #if __BANK const char *CTheScripts::GetPopTypeName(ePopType PopType) { switch (PopType) { case POPTYPE_UNKNOWN : return "POPTYPE_UNKNOWN"; case POPTYPE_RANDOM_PERMANENT : return "POPTYPE_RANDOM_PERMANENT"; case POPTYPE_RANDOM_PARKED : return "POPTYPE_RANDOM_PARKED"; case POPTYPE_RANDOM_PATROL : return "POPTYPE_RANDOM_PATROL"; case POPTYPE_RANDOM_SCENARIO : return "POPTYPE_RANDOM_SCENARIO"; case POPTYPE_RANDOM_AMBIENT : return "POPTYPE_RANDOM_AMBIENT"; case POPTYPE_PERMANENT : return "POPTYPE_PERMANENT"; case POPTYPE_MISSION : return "POPTYPE_MISSION"; case POPTYPE_REPLAY : return "POPTYPE_REPLAY"; case POPTYPE_TOOL : return "POPTYPE_TOOL"; case POPTYPE_CACHE : return "POPTYPE_CACHE"; case NUM_POPTYPES : return "NUM_POPTYPES"; } return "Unknown PopType"; } #endif // __BANK fwExtensibleBase* CTheScripts::GetExtensibleBaseToModifyFromGUID(int guid, const char* ASSERT_ONLY(commandName), unsigned ASSERT_ONLY(assertFlags)) { fwExtensibleBase* pBase = fwScriptGuid::FromGuid(guid); #if __ASSERT if (commandName) { if (assertFlags & GUID_ASSERT_FLAG_ENTITY_EXISTS) { scriptAssertf(pBase, "%s: %s - Object doesn't exist", GetCurrentScriptNameAndProgramCounter(), commandName); } } #endif // __ASSERT return pBase; } CItemSet* CTheScripts::GetItemSetToModifyFromGUID(int guid, const char* ASSERT_ONLY(commandName), unsigned ASSERT_ONLY(assertFlags)) { CItemSet* pItemSet = fwScriptGuid::FromGuid(guid); #if __ASSERT if (commandName) { if (assertFlags & GUID_ASSERT_FLAG_ENTITY_EXISTS) { scriptAssertf(pItemSet, "%s: %s - Item set doesn't exist", GetCurrentScriptNameAndProgramCounter(), commandName); } } #endif // __ASSERT return pItemSet; } CScriptedCoverPoint* CTheScripts::GetScriptedCoverPointToModifyFromGUID(int guid, const char* ASSERT_ONLY(commandName), unsigned ASSERT_ONLY(assertFlags)) { CScriptedCoverPoint* pScriptedCoverPoint = fwScriptGuid::FromGuid(guid); #if __ASSERT if (commandName) { if (assertFlags & GUID_ASSERT_FLAG_ENTITY_EXISTS) { scriptAssertf(pScriptedCoverPoint, "%s: %s - Scripted coverpoint doesn't exist", GetCurrentScriptNameAndProgramCounter(), commandName); } } #endif // __ASSERT return pScriptedCoverPoint; } const fwExtensibleBase* CTheScripts::GetExtensibleBaseToQueryFromGUID(int guid, const char* commandName, unsigned assertFlags) { assertFlags &= (~GUID_ASSERT_FLAG_NOT_CLONE); return GetExtensibleBaseToModifyFromGUID(guid, commandName, assertFlags); } const CItemSet* CTheScripts::GetItemSetToQueryFromGUID(int guid, const char* commandName, unsigned assertFlags) { assertFlags &= (~GUID_ASSERT_FLAG_NOT_CLONE); return GetItemSetToModifyFromGUID(guid, commandName, assertFlags); } const CScriptedCoverPoint* CTheScripts::GetScriptedCoverPointToQueryFromGUID(int guid, const char* commandName, unsigned assertFlags) { return GetScriptedCoverPointToModifyFromGUID(guid, commandName, assertFlags); } int CTheScripts::GetGUIDFromEntity(fwEntity& entity) { return fwScriptGuid::CreateGuid(entity); } int CTheScripts::GetGUIDFromExtensibleBase(fwExtensibleBase& base) { return fwScriptGuid::GetGuidFromBase(base); } int CTheScripts::GetGUIDFromPreferredCoverPoint(CScriptedCoverPoint& preferredCoverPoint) { return fwScriptGuid::CreateGuid(preferredCoverPoint); } #if !__FINAL EXTERN_PARSER_ENUM(ScriptTaskTypes); const char* CTheScripts::GetScriptTaskName( s32 iCommandIndex ) { return PARSER_ENUM(ScriptTaskTypes).NameFromValue(iCommandIndex); } const char* CTheScripts::GetScriptStatusName( u8 iScriptStatus ) { switch( iScriptStatus ) { case CPedScriptedTaskRecordData::EVENT_STAGE: return "WAITING_TO_START_TASK"; case CPedScriptedTaskRecordData::ACTIVE_TASK_STAGE: return "PERFORMING_TASK"; case CPedScriptedTaskRecordData::DORMANT_TASK_STAGE: return "DORMANT_TASK"; case CPedScriptedTaskRecordData::VACANT_STAGE: return "VACANT_STAGE"; case CPedScriptedTaskRecordData::GROUP_TASK_STAGE: return "GROUP_TASK_STAGE"; case CPedScriptedTaskRecordData::UNUSED_ATTRACTOR_SCRIPT_TASK_STAGE: return "ATTRACTOR_SCRIPT_TASK_STAGE"; case CPedScriptedTaskRecordData::SECONDARY_TASK_STAGE: return "SECONDARY_TASK_STAGE"; default: return "FINISHED_TASK"; } } #endif //!__FINAL CPed* CTheScripts::FindLocalPlayerPed( int playerIndex, bool ASSERT_ONLY(bAssert) ) { CPed* pPlayerPed = NULL; if (NetworkInterface::IsGameInProgress()) { CNetGamePlayer* pNetPlayer = NetworkInterface::GetPhysicalPlayerFromIndex(static_cast(playerIndex)); if (scriptVerifyf(pNetPlayer && pNetPlayer->IsMyPlayer(), "%s : %s - Can only be called on the local player", CTheScripts::GetCurrentScriptNameAndProgramCounter(), scrThread::GetCurrentCmdName())) { pPlayerPed = pNetPlayer->GetPlayerPed(); } } else if (scriptVerifyf(playerIndex==0, "%s : %s - Can only be called on the local player", CTheScripts::GetCurrentScriptNameAndProgramCounter(), scrThread::GetCurrentCmdName())) { pPlayerPed = CGameWorld::FindLocalPlayer(); } #if __ASSERT if (bAssert) { scriptAssertf(pPlayerPed, "%s : %s - Player ped doesn't exist", CTheScripts::GetCurrentScriptNameAndProgramCounter(), scrThread::GetCurrentCmdName()); } #endif return pPlayerPed; } CPed* CTheScripts::FindNetworkPlayerPed( int playerIndex, bool ASSERT_ONLY(bAssert) ) { CPed* pPlayerPed = NULL; CNetGamePlayer* pNetPlayer = NULL; if (NetworkInterface::IsGameInProgress()) { if (SCRIPT_VERIFY_PLAYER_INDEX(scrThread::GetCurrentCmdName(), playerIndex)) { pNetPlayer = NetworkInterface::GetPhysicalPlayerFromIndex(static_cast(playerIndex)); if (pNetPlayer) { pPlayerPed = pNetPlayer->GetPlayerPed(); } } } else if (scriptVerifyf(playerIndex==0, "%s : %s - Can only be called on the local player", CTheScripts::GetCurrentScriptNameAndProgramCounter(), scrThread::GetCurrentCmdName())) { pPlayerPed = CGameWorld::FindLocalPlayer(); } #if __ASSERT if (bAssert) { scriptAssertf(!pPlayerPed || pPlayerPed->GetPlayerInfo(), "%s : %s - Player %d (%s) has no player info", CTheScripts::GetCurrentScriptNameAndProgramCounter(), scrThread::GetCurrentCmdName(), playerIndex, pNetPlayer ? pNetPlayer->GetLogName() : "-none-"); } #endif return pPlayerPed; } CNetGamePlayer *CTheScripts::FindNetworkPlayer( int playerIndex, bool ASSERT_ONLY(bAssert)) { CNetGamePlayer* pNetPlayer = NULL; if (scriptVerifyf(NetworkInterface::IsGameInProgress(), "%s : %s - A network game is not running", CTheScripts::GetCurrentScriptNameAndProgramCounter(), scrThread::GetCurrentCmdName())) { if (SCRIPT_VERIFY_PLAYER_INDEX(scrThread::GetCurrentCmdName(), playerIndex)) { pNetPlayer = NetworkInterface::GetPhysicalPlayerFromIndex(static_cast(playerIndex)); #if __ASSERT if (bAssert) { scriptAssertf(pNetPlayer, "%s : %s - Network player doesn't exist", CTheScripts::GetCurrentScriptNameAndProgramCounter(), scrThread::GetCurrentCmdName()); } #endif } } return pNetPlayer; } bool CTheScripts::ExportGamerHandle(const rlGamerHandle* phGamer, int& handleData, int sizeOfData ASSERT_ONLY(, const char* szCommand)) { #if __NO_OUTPUT if(!scriptVerifyf(phGamer->IsValid(), "%s : %s - Invalid handle!", CTheScripts::GetCurrentScriptNameAndProgramCounter(), szCommand)) #else #if __ASSERT char szToString[RL_MAX_GAMER_HANDLE_CHARS]; #endif // __ASSERT if(!scriptVerifyf(phGamer->IsValid(), "%s : %s - Invalid handle! As String: %s", CTheScripts::GetCurrentScriptNameAndProgramCounter(), szCommand, phGamer->ToString(szToString))) #endif return false; // script returns size in script words if(!scriptVerifyf(sizeOfData == SCRIPT_GAMER_HANDLE_SIZE, "%s : %s - Invalid data size!", CTheScripts::GetCurrentScriptNameAndProgramCounter(), szCommand)) return false; sizeOfData *= sizeof(scrValue); // buffer to write our handle into u8* pHandleBuffer = reinterpret_cast(&handleData); // retrieve gamer handle unsigned nExported = 0; #if __NO_OUTPUT if(!scriptVerifyf(phGamer->Export(pHandleBuffer, sizeOfData, &nExported), "%s : %s - Export failed!", CTheScripts::GetCurrentScriptNameAndProgramCounter(), szCommand)) #else if(!scriptVerifyf(phGamer->Export(pHandleBuffer, sizeOfData, &nExported), "%s : %s - Export failed! As String: %s", CTheScripts::GetCurrentScriptNameAndProgramCounter(), szCommand, phGamer->ToString(szToString))) #endif return false; if(!scriptVerifyf(nExported < GAMER_HANDLE_SIZE, "%s : %s - Increase GAMER_HANDLE_SIZE!", CTheScripts::GetCurrentScriptNameAndProgramCounter(), szCommand)) return false; return true; } bool CTheScripts::ImportGamerHandle(rlGamerHandle* phGamer, int& handleData, int sizeOfData ASSERT_ONLY(, const char* szCommand)) { // script returns size in script words if(!scriptVerifyf(sizeOfData == SCRIPT_GAMER_HANDLE_SIZE, "%s : %s - Invalid data size!", CTheScripts::GetCurrentScriptNameAndProgramCounter(), szCommand)) return false; sizeOfData *= sizeof(scrValue); // buffer to write our handle into u8* pHandleBuffer = reinterpret_cast(&handleData); // retrieve gamer handle unsigned nImported = 0; if(!scriptVerifyf(phGamer->Import(pHandleBuffer, sizeOfData, &nImported), "%s : %s - Import failed!", CTheScripts::GetCurrentScriptNameAndProgramCounter(), szCommand)) { #if !__NO_OUTPUT if (sizeOfData == SCRIPT_GAMER_HANDLE_SIZE) { scriptErrorf("CTheScripts::ImportGamerHandle() - FAILED - left to right - Service 1st 8bits from left:"); int* handleDataOut = &handleData; for (int i=0; iIsValid(), "%s : %s - Invalid handle!", CTheScripts::GetCurrentScriptNameAndProgramCounter(), szCommand); } bool CTheScripts::ImportGamerHandle(rlGamerHandle* phGamer, u8* pData ASSERT_ONLY(, const char* szCommand)) { // retrieve gamer handle unsigned nImported = 0; if(!scriptVerifyf(phGamer->Import(pData, GAMER_HANDLE_SIZE, &nImported), "%s : %s - Import failed! Invalid gamerhandle: %s", CTheScripts::GetCurrentScriptNameAndProgramCounter(), szCommand, pData)) return false; if(!scriptVerifyf(nImported < GAMER_HANDLE_SIZE, "%s : %s - Increase GAMER_HANDLE_SIZE!", CTheScripts::GetCurrentScriptNameAndProgramCounter(), szCommand)) return false; return scriptVerifyf(phGamer->IsValid(), "%s : %s - Invalid handle!", CTheScripts::GetCurrentScriptNameAndProgramCounter(), szCommand); } bool CTheScripts::HasEntityBeenRegisteredWithCurrentThread(const CPhysical* pPhysical) { const CScriptEntityExtension* pExtension = pPhysical->GetExtension(); return (pExtension && pExtension->GetScriptInfo() && pExtension->GetScriptInfo()->GetScriptId() == CGameScriptId(*GetCurrentGtaScriptThread())); } int CTheScripts::GetIdForEntityRegisteredWithCurrentThread(const CPhysical* pPhysical) { if (AssertVerify(HasEntityBeenRegisteredWithCurrentThread(pPhysical))) { const CScriptEntityExtension* pExtension = pPhysical->GetExtension(); return static_cast(pExtension->GetScriptInfo()->GetObjectId()); } return NULL_IN_SCRIPTING_LANGUAGE; } void CScriptEulers::MatrixFromEulers(Matrix34& matrix, const Vector3& eulers, EulerAngleOrder rotationOrder) { switch(rotationOrder) { case EULER_XYZ: matrix.FromEulersXYZ(eulers); break; case EULER_XZY: matrix.FromEulersXZY(eulers); break; case EULER_YXZ: matrix.FromEulersYXZ(eulers); break; case EULER_YZX: matrix.FromEulersYZX(eulers); break; case EULER_ZXY: matrix.FromEulersZXY(eulers); break; case EULER_ZYX: matrix.FromEulersZYX(eulers); break; default: scriptAssertf(false, "Invalid Euler rotation order"); matrix.Identity(); break; } } Vector3 CScriptEulers::MatrixToEulers(const Matrix34& matrix, EulerAngleOrder rotationOrder) { Vector3 eulers; switch(rotationOrder) { case EULER_XYZ: matrix.ToEulersXYZ(eulers); break; case EULER_XZY: matrix.ToEulersXZY(eulers); break; case EULER_YXZ: matrix.ToEulersYXZ(eulers); break; case EULER_YZX: matrix.ToEulersYZX(eulers); break; case EULER_ZXY: matrix.ToEulersZXY(eulers); break; case EULER_ZYX: matrix.ToEulersZYX(eulers); break; default: scriptAssertf(false, "Invalid Euler rotation order"); eulers.Zero(); break; } return eulers; } void CScriptEulers::QuaternionFromEulers(Quaternion& quat, const Vector3& eulers, EulerAngleOrder rotationOrder) { switch(rotationOrder) { case EULER_XYZ: quat.FromEulers(eulers, eEulerOrderXYZ); break; case EULER_XZY: quat.FromEulers(eulers, eEulerOrderXZY); break; case EULER_YXZ: quat.FromEulers(eulers, eEulerOrderYXZ); break; case EULER_YZX: quat.FromEulers(eulers, eEulerOrderYZX); break; case EULER_ZXY: quat.FromEulers(eulers, eEulerOrderZXY); break; case EULER_ZYX: quat.FromEulers(eulers, eEulerOrderZYX); break; default: scriptAssertf(false, "CScriptEulers::QuaternionFromEulers - Invalid Euler rotation order"); quat.Identity(); break; } } Vector3 CScriptEulers::QuaternionToEulers(Quaternion& quat, EulerAngleOrder rotationOrder) { Vector3 eulers; switch(rotationOrder) { case EULER_XYZ: quat.ToEulers(eulers, eEulerOrderXYZ); break; case EULER_XZY: quat.ToEulers(eulers, eEulerOrderXZY); break; case EULER_YXZ: quat.ToEulers(eulers, eEulerOrderYXZ); break; case EULER_YZX: quat.ToEulers(eulers, eEulerOrderYZX); break; case EULER_ZXY: quat.ToEulers(eulers, eEulerOrderZXY); break; case EULER_ZYX: quat.ToEulers(eulers, eEulerOrderZYX); break; default: scriptAssertf(false, "CScriptEulers::QuaternionToEulers - Invalid Euler rotation order"); eulers.Zero(); break; } return eulers; } // ************************************************************************************************* // CPersistentScriptGlobals CTheScripts::PersistentScriptGlobals; /* void CPersistentScriptGlobals::Init() { m_nSizeOfPersistentGlobalsBuffer = 0; m_pBackupOfPersistentGlobalsBuffer = NULL; m_nOffsetToStartOfPersistentGlobalsBuffer = -1; } void CPersistentScriptGlobals::Clear() { m_nSizeOfPersistentGlobalsBuffer = 0; if (m_pBackupOfPersistentGlobalsBuffer) { delete[] m_pBackupOfPersistentGlobalsBuffer; } m_pBackupOfPersistentGlobalsBuffer = NULL; m_nOffsetToStartOfPersistentGlobalsBuffer = -1; } void CPersistentScriptGlobals::RegisterPersistentGlobalVariables(int *pStartOfPersistentGlobals, int nSizeOfBuffer) { u8 *pStartOfGlobalsMemory = reinterpret_cast(scrProgram::GetGlobals()); u8 *pStartOfPersistents = reinterpret_cast(pStartOfPersistentGlobals); int nOffsetToGlobalsInBytes = pStartOfPersistents - pStartOfGlobalsMemory; scriptAssertf( (nOffsetToGlobalsInBytes >= 0) && (nOffsetToGlobalsInBytes < static_cast(sizeof(scrValue) * scrProgram::GetGlobalSize())), "CPersistentScriptGlobals::RegisterPersistentGlobalVariables - offset to persistent globals is out of range"); scriptAssertf( (nOffsetToGlobalsInBytes + nSizeOfBuffer) <= static_cast(sizeof(scrValue) * scrProgram::GetGlobalSize()), "CPersistentScriptGlobals::RegisterPersistentGlobalVariables - persistent globals structure extends past the end of the global script memory"); scriptAssertf((scrProgram::GetGlobals() + (nOffsetToGlobalsInBytes/sizeof(scrValue)) ) == reinterpret_cast(pStartOfPersistentGlobals), "CPersistentScriptGlobals::RegisterPersistentGlobalVariables - I've made a mistake in my calculations - Graeme"); scriptAssertf( (m_nSizeOfPersistentGlobalsBuffer == 0) || (m_nSizeOfPersistentGlobalsBuffer == nSizeOfBuffer), "CPersistentScriptGlobals::RegisterPersistentGlobalVariables - attempting to change the size of the persistent globals structure"); scriptAssertf( (m_nOffsetToStartOfPersistentGlobalsBuffer == -1) || (m_nOffsetToStartOfPersistentGlobalsBuffer == nOffsetToGlobalsInBytes), "CPersistentScriptGlobals::RegisterPersistentGlobalVariables - attempting to change the offset of the persistent globals structure"); scriptAssertf(!m_pBackupOfPersistentGlobalsBuffer, "CPersistentScriptGlobals::RegisterPersistentGlobalVariables - didn't expect the backup buffer to be allocated at this point"); Clear(); m_nSizeOfPersistentGlobalsBuffer = nSizeOfBuffer; m_nOffsetToStartOfPersistentGlobalsBuffer = nOffsetToGlobalsInBytes; } bool CPersistentScriptGlobals::StorePersistentGlobalsInBackupBuffer() { if (m_nSizeOfPersistentGlobalsBuffer == 0) { scriptAssertf(m_nOffsetToStartOfPersistentGlobalsBuffer == -1, "CPersistentScriptGlobals::StorePersistentGlobalsInBackupBuffer - size of buffer is 0 but offset is not -1"); return true; // returning false would probably suggest that the function had failed rather than that the buffer didn't need to be allocated } if (m_pBackupOfPersistentGlobalsBuffer) { scriptAssertf(0, "CPersistentScriptGlobals::StorePersistentGlobalsInBackupBuffer - didn't expect backup buffer to already be allocated at this stage"); delete[] m_pBackupOfPersistentGlobalsBuffer; m_pBackupOfPersistentGlobalsBuffer = NULL; } scriptAssertf( (m_nOffsetToStartOfPersistentGlobalsBuffer >= 0) && (m_nOffsetToStartOfPersistentGlobalsBuffer < static_cast(sizeof(scrValue) * scrProgram::GetGlobalSize())), "CPersistentScriptGlobals::StorePersistentGlobalsInBackupBuffer - offset to persistent globals is out of range"); scriptAssertf( (m_nOffsetToStartOfPersistentGlobalsBuffer + m_nSizeOfPersistentGlobalsBuffer) <= static_cast(sizeof(scrValue) * scrProgram::GetGlobalSize()), "CPersistentScriptGlobals::StorePersistentGlobalsInBackupBuffer - persistent globals structure extends past the end of the global script memory"); // Allocate buffer of the correct size m_pBackupOfPersistentGlobalsBuffer = rage_new u8[m_nSizeOfPersistentGlobalsBuffer]; if (m_pBackupOfPersistentGlobalsBuffer) { // Copy the global data into this buffer const u8 *pStartOfPersistentStructureInGlobalsMemory = reinterpret_cast(scrProgram::GetGlobals()) + m_nOffsetToStartOfPersistentGlobalsBuffer; sysMemCpy(m_pBackupOfPersistentGlobalsBuffer, pStartOfPersistentStructureInGlobalsMemory, m_nSizeOfPersistentGlobalsBuffer); } else { scriptAssertf(0, "CPersistentScriptGlobals::StorePersistentGlobalsInBackupBuffer - failed to allocate memory for the backup buffer"); return false; } return true; } bool CPersistentScriptGlobals::RestorePersistentGlobalsFromBackupBuffer() { bool bSucceeded = true; if (scrProgram::GetGlobalSize() > 0) { if (m_pBackupOfPersistentGlobalsBuffer) { scriptAssertf(m_nSizeOfPersistentGlobalsBuffer > 0, "CPersistentScriptGlobals::RestorePersistentGlobalsFromBackupBuffer - size of buffer to restore must be greater than 0"); scriptAssertf( (m_nOffsetToStartOfPersistentGlobalsBuffer >= 0) && (m_nOffsetToStartOfPersistentGlobalsBuffer < static_cast(sizeof(scrValue) * scrProgram::GetGlobalSize())), "CPersistentScriptGlobals::RestorePersistentGlobalsFromBackupBuffer - offset to persistent globals is out of range"); scriptAssertf( (m_nOffsetToStartOfPersistentGlobalsBuffer + m_nSizeOfPersistentGlobalsBuffer) <= static_cast(sizeof(scrValue) * scrProgram::GetGlobalSize()), "CPersistentScriptGlobals::RestorePersistentGlobalsFromBackupBuffer - persistent globals structure extends past the end of the global script memory"); // Copy the contents of the backup buffer back into the global data u8 *pStartOfPersistentStructureInGlobalsMemory = reinterpret_cast(scrProgram::GetGlobals()) + m_nOffsetToStartOfPersistentGlobalsBuffer; sysMemCpy(pStartOfPersistentStructureInGlobalsMemory, m_pBackupOfPersistentGlobalsBuffer, m_nSizeOfPersistentGlobalsBuffer); } else { if ( (m_nSizeOfPersistentGlobalsBuffer != 0) || (m_nOffsetToStartOfPersistentGlobalsBuffer != -1) ) { scriptAssertf(0, "CPersistentScriptGlobals::RestorePersistentGlobalsFromBackupBuffer - no backup buffer to restore from"); bSucceeded = false; } } } else { scriptAssertf(0, "CPersistentScriptGlobals::RestorePersistentGlobalsFromBackupBuffer - no global variables have been allocated at this stage"); bSucceeded = false; } // free the backup buffer if (m_pBackupOfPersistentGlobalsBuffer) { delete[] m_pBackupOfPersistentGlobalsBuffer; } m_pBackupOfPersistentGlobalsBuffer = NULL; return bSucceeded; } */ // ************************************************************************************************* class CDLCScriptDataMounter : public CDataFileMountInterface { virtual bool LoadDataFile(const CDataFileMgr::DataFile& file) { switch(file.m_fileType) { case CDataFileMgr::DLC_SCRIPT_METAFILE: { CDLCScript::AddScriptData(file.m_filename); return true; } break; default: return false; } } virtual void UnloadDataFile(const CDataFileMgr::DataFile & file) { CDLCScript::RemoveScriptData(file.m_filename); } }g_dlcScriptDataMounter; void CDLCScript::AddScriptData(const char* fileName) { CDLCScript* scriptData = rage_new CDLCScript; if(PARSER.LoadObject(fileName,NULL,*scriptData)) { if(!CDLCScript::ms_scripts.Access(scriptData->GetScriptLiteralName().GetHash())) { scriptData->InitScript(); CDLCScript::ms_scripts.SafeInsert(scriptData->GetScriptLiteralName().GetHash(),scriptData); CDLCScript::ms_scripts.FinishInsertion(); } return; } delete scriptData; } void CDLCScript::RemoveScriptData(const char* fileName) { CDLCScript* scriptData = rage_new CDLCScript; if(PARSER.LoadObject(fileName, NULL, *scriptData)) { RemoveScript(scriptData); } delete scriptData; } void CDLCScript::Init(unsigned initMode) { switch(initMode) { case INIT_CORE: CDataFileMount::RegisterMountInterface(CDataFileMgr::DLC_SCRIPT_METAFILE, &g_dlcScriptDataMounter); break; case INIT_SESSION: for(dlcScriptIterator it=ms_scripts.Begin(); it!= ms_scripts.End();++it) { (*it)->InitScript(); } break; } } void CDLCScript::Update() { for(dlcScriptIterator it=ms_scripts.Begin(); it!= ms_scripts.End();++it) { (*it)->UpdateScript(); } } void CDLCScript::Shutdown(unsigned shutdownMode) { switch(shutdownMode) { case SHUTDOWN_SESSION: { for(dlcScriptIterator it=ms_scripts.Begin(); it!= ms_scripts.End();++it) { (*it)->ShutdownScript(); } } break; case SHUTDOWN_WITH_MAP_LOADED: { for(dlcScriptIterator it=ms_scripts.Begin(); it!= ms_scripts.End();++it) { RemoveScript((*it)); } ms_scripts.Reset(); } break; //TODO map reset on tom's changes } } void CDLCScript::InitScript() { const strLocalIndex scrIndex = g_StreamedScripts.FindSlotFromHashKey(m_startupScript.GetHash()); if (Verifyf(scrIndex.IsValid(), "DLC Script %s can't be found", m_startupScript.GetCStr())) { m_request.Request(scrIndex, g_StreamedScripts.GetStreamingModuleId(), STRFLAG_PRIORITY_LOAD|STRFLAG_MISSION_REQUIRED); m_state = CDLCScript::DLC_SCR_REQUESTED; } } void CDLCScript::UpdateScript() { switch (m_state) { case CDLCScript::DLC_SCR_REQUESTED: { if ( m_request.HasLoaded() ) { const int objIdx = m_request.GetRequestId().Get(); const char* progName = ""; m_request.ClearRequiredFlags(STRFLAG_MISSION_REQUIRED); #if !__NO_OUTPUT if( m_startupScript.GetCStr() != NULL ) progName = m_startupScript.GetCStr(); #endif m_thread = CTheScripts::GtaStartNewThreadWithProgramId(g_StreamedScripts.GetProgramId(objIdx), NULL, 0, m_scriptCallstackSize, progName); m_request.Release(); if (Verifyf(m_thread!= THREAD_INVALID, "Error launching program %s", progName)) { m_state = CDLCScript::DLC_SCR_LOADED; } } } break; default: break; } } void CDLCScript::ShutdownScript() { m_request.Release(); if (m_thread != THREAD_INVALID) { scrThread::KillThread(m_thread); m_thread = THREAD_INVALID; strLocalIndex slot = g_StreamedScripts.FindSlotFromHashKey(GetScriptLiteralName().GetHash()); strIndex idx =g_StreamedScripts.GetStreamingIndex(slot); strStreamingEngine::GetInfo().RemoveObject(idx); } m_state = CDLCScript::DLC_SCR_NONE; } void CDLCScript::RemoveScript(CDLCScript* dlcScript) { if(CDLCScript** curScriptPtr = CDLCScript::ms_scripts.SafeGet(dlcScript->GetScriptLiteralName().GetHash())) { CDLCScript* curScript = (*curScriptPtr); if(curScript) { curScript->ShutdownScript(); curScript->GetRequest().StreamingRemove(); ms_scripts.Remove(ms_scripts.GetIndexFromDataPtr(curScriptPtr)); } } } bool CDLCScript::ContainsScript(atLiteralHashValue nameHash) { if(CDLCScript::ms_scripts.Access(nameHash.GetHash())) return true; return false; } #if RSG_PC && ENABLE_SCRIPT_TAMPER_CHECKER atRangeArray CScriptGlobalTamperChecker::ms_abValidPage; bool CScriptGlobalTamperChecker::ms_bTamperingDetected = false; s32 CScriptGlobalTamperChecker::ms_cUncheckedSection = 0; CScriptGlobalTamperCheckerTunablesListener CScriptGlobalTamperChecker::ms_pScriptGlobalTamperTunablesListener; void CScriptGlobalTamperChecker::Initialize() { // Add the listener Tunables::GetInstance().AddListener(&ms_pScriptGlobalTamperTunablesListener); } void CScriptGlobalTamperChecker::Reset() { for (s32 i=0; i