From 749f9ffae001a161b45c89a77f27fb341b11c541 Mon Sep 17 00:00:00 2001 From: Peter Covington Date: Sun, 17 Apr 2022 15:57:37 -0400 Subject: [PATCH] Finished parser for vscript weapon --- .../server/mapbase/custom_weapon_factory.cpp | 5 +- .../shared/mapbase/weapon_custom_scripted.cpp | 118 ++++++++++++++++-- .../shared/mapbase/weapon_custom_scripted.h | 4 + 3 files changed, 119 insertions(+), 8 deletions(-) diff --git a/sp/src/game/server/mapbase/custom_weapon_factory.cpp b/sp/src/game/server/mapbase/custom_weapon_factory.cpp index dea0380c..5a5d74cb 100644 --- a/sp/src/game/server/mapbase/custom_weapon_factory.cpp +++ b/sp/src/game/server/mapbase/custom_weapon_factory.cpp @@ -2,7 +2,8 @@ #include "custom_weapon_factory.h" #define GENERIC_MANIFEST_FILE "scripts/mapbase_default_manifest.txt" -#define AUTOLOADED_MANIFEST_FILE UTIL_VarArgs("maps/%s_manifest.txt", MapName()) +#define AUTOLOADED_MANIFEST_FILE UTIL_VarArgs("maps/%s_manifest.txt", STRING(gpGlobals->mapname)) +#define GLOBAL_WEAPONS_MANIFEST "scripts/custom_weapon_manifest.txt" extern ConVar mapbase_load_default_manifest; @@ -14,6 +15,8 @@ CCustomWeaponSystem::CCustomWeaponSystem() : CAutoGameSystem("CustomWeaponFactor void CCustomWeaponSystem::LevelInitPreEntity() { + AddManifestFile(GLOBAL_WEAPONS_MANIFEST); + // Check for a generic "mapname_manifest.txt" file and load it. if (filesystem->FileExists(AUTOLOADED_MANIFEST_FILE, "GAME")) { diff --git a/sp/src/game/shared/mapbase/weapon_custom_scripted.cpp b/sp/src/game/shared/mapbase/weapon_custom_scripted.cpp index a3ca9d57..10553de5 100644 --- a/sp/src/game/shared/mapbase/weapon_custom_scripted.cpp +++ b/sp/src/game/shared/mapbase/weapon_custom_scripted.cpp @@ -7,6 +7,7 @@ #include "cbase.h" #include "tier1/fmtstr.h" +#include "tier1/utlvector.h" #include "weapon_custom_scripted.h" // memdbgon must be the last include file in a .cpp file!!! @@ -193,13 +194,6 @@ bool CWeaponCustomScripted::RunWeaponHook( ScriptHook_t &hook, HSCRIPT &cached, //----------------------------------------------------------------------------- void CWeaponCustomScripted::Spawn( void ) { -#ifdef CLIENT_DLL - if (m_iszClientScripts[0] != '\0' && ValidateScriptScope()) - { - RunScriptFile( m_iszClientScripts ); - } -#endif - BaseClass::Spawn(); } @@ -586,6 +580,23 @@ DEFINE_CUSTOM_WEAPON_FACTORY(vscript, CWeaponCustomScripted); void CWeaponCustomScripted::ParseCustomFromWeaponFile(const char* pFileName) { Q_FileBase(pFileName, m_iszWeaponScriptName.GetForModify(), 256); + KeyValuesAD pKVWeapon("WeaponData"); + if (pKVWeapon->LoadFromFile(filesystem, pFileName, "GAME")) + { + Q_strncpy(m_iszClientScripts.GetForModify(), pKVWeapon->GetString("vscript_file"), 256); + } +} + +extern ConVar sv_script_think_interval; +#else +void CWeaponCustomScripted::OnDataChanged(DataUpdateType_t type) +{ + BaseClass::OnDataChanged(type); + + if (!m_ScriptScope.IsInitialized()) + { + RunVScripts(); + } } #endif @@ -605,3 +616,96 @@ int CWeaponCustomScripted::ActivityListCount( void ) return BaseClass::ActivityListCount(); } + +void CWeaponCustomScripted::RunVScripts() +{ +#ifdef CLIENT_DLL + if (m_iszClientScripts[0] != '\0' && ValidateScriptScope()) + { + RunScriptFile(m_iszClientScripts); + } +#else + if (m_iszVScripts == NULL_STRING && m_iszClientScripts[0] == '\0') + { + return; + } + +#ifdef MAPBASE_VSCRIPT + if (g_pScriptVM == NULL) + { + return; + } +#endif + + ValidateScriptScope(); + + // All functions we want to have call chained instead of overwritten + // by other scripts in this entities list. + static const char* sCallChainFunctions[] = + { + "OnPostSpawn", + "Precache" + }; + + ScriptLanguage_t language = g_pScriptVM->GetLanguage(); + + // Make a call chainer for each in this entities scope + for (int j = 0; j < ARRAYSIZE(sCallChainFunctions); ++j) + { + + if (language == SL_PYTHON) + { + // UNDONE - handle call chaining in python + ; + } + else if (language == SL_SQUIRREL) + { + //TODO: For perf, this should be precompiled and the %s should be passed as a parameter + HSCRIPT hCreateChainScript = g_pScriptVM->CompileScript(CFmtStr("%sCallChain <- CSimpleCallChainer(\"%s\", self.GetScriptScope(), true)", sCallChainFunctions[j], sCallChainFunctions[j])); + g_pScriptVM->Run(hCreateChainScript, (HSCRIPT)m_ScriptScope); + } + } + + CUtlStringList szScripts; + if (m_iszVScripts != NULL_STRING) + { + V_SplitString(STRING(m_iszVScripts), " ", szScripts); + } + + if (m_iszClientScripts[0] != '\0') + { + szScripts.AddToHead(strdup(m_iszClientScripts.Get())); + } + + for (int i = 0; i < szScripts.Count(); i++) + { +#ifdef MAPBASE + CGMsg(0, CON_GROUP_VSCRIPT, "%s executing script: %s\n", GetDebugName(), szScripts[i]); +#else + Log("%s executing script: %s\n", GetDebugName(), szScripts[i]); +#endif + + RunScriptFile(szScripts[i], IsWorld()); + + for (int j = 0; j < ARRAYSIZE(sCallChainFunctions); ++j) + { + if (language == SL_PYTHON) + { + // UNDONE - handle call chaining in python + ; + } + else if (language == SL_SQUIRREL) + { + //TODO: For perf, this should be precompiled and the %s should be passed as a parameter. + HSCRIPT hRunPostScriptExecute = g_pScriptVM->CompileScript(CFmtStr("%sCallChain.PostScriptExecute()", sCallChainFunctions[j])); + g_pScriptVM->Run(hRunPostScriptExecute, (HSCRIPT)m_ScriptScope); + } + } + } + + if (m_iszScriptThinkFunction != NULL_STRING) + { + SetContextThink(&CBaseEntity::ScriptThink, gpGlobals->curtime + sv_script_think_interval.GetFloat(), "ScriptThink"); + } +#endif +} \ No newline at end of file diff --git a/sp/src/game/shared/mapbase/weapon_custom_scripted.h b/sp/src/game/shared/mapbase/weapon_custom_scripted.h index f2a2a77d..8cc05cd3 100644 --- a/sp/src/game/shared/mapbase/weapon_custom_scripted.h +++ b/sp/src/game/shared/mapbase/weapon_custom_scripted.h @@ -50,6 +50,8 @@ public: bool KeyValue( const char *szKeyName, const char *szValue ); bool GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen ); + void RunVScripts(); + // Base script has a function for this //void Precache( void ); @@ -114,6 +116,8 @@ public: // Inherited via ICustomWeapon virtual void ParseCustomFromWeaponFile(const char* pFileName) override; +#else + void OnDataChanged(DataUpdateType_t type); #endif ALLOW_SCRIPT_ACCESS();