From c12418e1ce7527522733612acbb11e1ee8719776 Mon Sep 17 00:00:00 2001 From: Blixibon Date: Wed, 27 May 2020 10:22:45 -0500 Subject: [PATCH] Added new features and customization to base VScript functionality --- sp/src/game/client/c_world.cpp | 3 +++ sp/src/game/client/c_world.h | 7 +++++ sp/src/game/client/vscript_client.cpp | 11 ++++++++ sp/src/game/server/baseentity.cpp | 16 ++++++++++++ sp/src/game/server/baseentity.h | 1 + sp/src/game/server/variant_t.cpp | 16 ++++++++++++ sp/src/game/server/variant_t.h | 8 ++++++ sp/src/game/server/vscript_server.cpp | 26 +++++++++++++++++++ sp/src/game/server/world.cpp | 10 +++++++ sp/src/game/server/world.h | 8 ++++++ .../shared/mapbase/vscript_funcs_shared.cpp | 18 +++++++++++++ 11 files changed, 124 insertions(+) diff --git a/sp/src/game/client/c_world.cpp b/sp/src/game/client/c_world.cpp index 44a59723..238f4cb3 100644 --- a/sp/src/game/client/c_world.cpp +++ b/sp/src/game/client/c_world.cpp @@ -62,6 +62,9 @@ BEGIN_RECV_TABLE( C_World, DT_World ) #ifdef MAPBASE RecvPropString(RECVINFO(m_iszChapterTitle)), #endif +#ifdef MAPBASE_VSCRIPT + RecvPropInt(RECVINFO(m_iScriptLanguage)), +#endif END_RECV_TABLE() diff --git a/sp/src/game/client/c_world.h b/sp/src/game/client/c_world.h index 5f1538f9..aa1ce226 100644 --- a/sp/src/game/client/c_world.h +++ b/sp/src/game/client/c_world.h @@ -41,6 +41,10 @@ public: float GetWaveHeight() const; const char *GetDetailSpriteMaterial() const; +#ifdef MAPBASE_VSCRIPT + ScriptLanguage_t GetScriptLanguage() { return (ScriptLanguage_t)m_iScriptLanguage; } +#endif + public: enum { @@ -59,6 +63,9 @@ public: #ifdef MAPBASE char m_iszChapterTitle[64]; #endif +#ifdef MAPBASE_VSCRIPT + int m_iScriptLanguage; +#endif private: void RegisterSharedActivities( void ); diff --git a/sp/src/game/client/vscript_client.cpp b/sp/src/game/client/vscript_client.cpp index a62ebbf5..3713eb13 100644 --- a/sp/src/game/client/vscript_client.cpp +++ b/sp/src/game/client/vscript_client.cpp @@ -16,6 +16,9 @@ #ifdef _WIN32 //#include "vscript_client_nut.h" #endif +#ifdef MAPBASE_VSCRIPT +#include "c_world.h" +#endif extern IScriptManager *scriptmanager; extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * ); @@ -73,6 +76,14 @@ bool VScriptClientInit() ScriptLanguage_t scriptLanguage = SL_DEFAULT; char const *pszScriptLanguage; +#ifdef MAPBASE_VSCRIPT + if (GetClientWorldEntity()->GetScriptLanguage() != SL_NONE) + { + // Allow world entity to override script language + scriptLanguage = GetClientWorldEntity()->GetScriptLanguage(); + } + else +#endif if ( CommandLine()->CheckParm( "-scriptlang", &pszScriptLanguage ) ) { if( !Q_stricmp(pszScriptLanguage, "gamemonkey") ) diff --git a/sp/src/game/server/baseentity.cpp b/sp/src/game/server/baseentity.cpp index 5062ddda..f3efe54f 100644 --- a/sp/src/game/server/baseentity.cpp +++ b/sp/src/game/server/baseentity.cpp @@ -2032,6 +2032,7 @@ BEGIN_DATADESC_NO_BASE( CBaseEntity ) DEFINE_INPUTFUNC(FIELD_STRING, "CallScriptFunction", InputCallScriptFunction), #ifdef MAPBASE_VSCRIPT DEFINE_INPUTFUNC(FIELD_STRING, "RunScriptCodeQuotable", InputRunScriptQuotable), + DEFINE_INPUTFUNC(FIELD_VOID, "ClearScriptScope", InputClearScriptScope), #endif #ifdef MAPBASE @@ -4337,6 +4338,10 @@ bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, g_pScriptVM->SetValue( "activator", ( pActivator ) ? ScriptVariant_t( pActivator->GetScriptInstance() ) : SCRIPT_VARIANT_NULL ); g_pScriptVM->SetValue( "caller", ( pCaller ) ? ScriptVariant_t( pCaller->GetScriptInstance() ) : SCRIPT_VARIANT_NULL ); +#ifdef MAPBASE_VSCRIPT + Value.SetScriptVariant( functionReturn ); + g_pScriptVM->SetValue( "parameter", functionReturn ); +#endif if( CallScriptFunction( szScriptFunctionName, &functionReturn ) ) { @@ -4353,6 +4358,9 @@ bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, { g_pScriptVM->ClearValue( "activator" ); g_pScriptVM->ClearValue( "caller" ); +#ifdef MAPBASE_VSCRIPT + g_pScriptVM->ClearValue( "parameter" ); +#endif } } else if ( dmap->dataDesc[i].flags & FTYPEDESC_KEY ) @@ -8057,6 +8065,14 @@ void CBaseEntity::InputRunScriptQuotable(inputdata_t& inputdata) RunScript( inputdata.value.String(), "InputRunScriptQuotable" ); } } + +//--------------------------------------------------------- +// Clear this entity's script scope +//--------------------------------------------------------- +void CBaseEntity::InputClearScriptScope(inputdata_t& inputdata) +{ + m_ScriptScope.Term(); +} #endif // #define VMPROFILE // define to profile vscript calls diff --git a/sp/src/game/server/baseentity.h b/sp/src/game/server/baseentity.h index d1500601..79cf822f 100644 --- a/sp/src/game/server/baseentity.h +++ b/sp/src/game/server/baseentity.h @@ -756,6 +756,7 @@ public: void InputCallScriptFunction(inputdata_t& inputdata); #ifdef MAPBASE_VSCRIPT void InputRunScriptQuotable(inputdata_t& inputdata); + void InputClearScriptScope(inputdata_t& inputdata); #endif bool RunScriptFile(const char* pScriptFile, bool bUseRootScope = false); diff --git a/sp/src/game/server/variant_t.cpp b/sp/src/game/server/variant_t.cpp index 9d38368e..04d96f79 100644 --- a/sp/src/game/server/variant_t.cpp +++ b/sp/src/game/server/variant_t.cpp @@ -65,6 +65,22 @@ const char *variant_t::GetDebug() return UTIL_VarArgs("%s (%s)", String(), fieldtype); } +#ifdef MAPBASE_VSCRIPT +void variant_t::SetScriptVariant( ScriptVariant_t &var ) +{ + switch (FieldType()) + { + case FIELD_INTEGER: var = Int(); break; + case FIELD_FLOAT: var = Float(); break; + case FIELD_STRING: var = String(); break; + case FIELD_POSITION_VECTOR: + case FIELD_VECTOR: var = reinterpret_cast(&flVal); break; // HACKHACK + case FIELD_BOOLEAN: var = Bool(); break; + case FIELD_EHANDLE: var = ToHScript( Entity() ); break; + } +} +#endif + // cmp1 = val1 float // cmp2 = val2 float #define VariantToFloat(val1, val2, lenallowed) \ diff --git a/sp/src/game/server/variant_t.h b/sp/src/game/server/variant_t.h index ffd69144..fc460bfe 100644 --- a/sp/src/game/server/variant_t.h +++ b/sp/src/game/server/variant_t.h @@ -17,6 +17,10 @@ class CBaseEntity; +#ifdef MAPBASE_VSCRIPT +struct ScriptVariant_t; +#endif + // // A variant class for passing data in entity input/output connections. @@ -80,6 +84,10 @@ public: const char *GetDebug(); #endif +#ifdef MAPBASE_VSCRIPT + void SetScriptVariant( ScriptVariant_t &var ); +#endif + static typedescription_t m_SaveBool[]; static typedescription_t m_SaveInt[]; static typedescription_t m_SaveFloat[]; diff --git a/sp/src/game/server/vscript_server.cpp b/sp/src/game/server/vscript_server.cpp index 2b28c62d..0e2e6d19 100644 --- a/sp/src/game/server/vscript_server.cpp +++ b/sp/src/game/server/vscript_server.cpp @@ -18,6 +18,9 @@ #ifdef _WIN32 //#include "vscript_server_nut.h" #endif +#ifdef MAPBASE_VSCRIPT +#include "world.h" +#endif extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * ); @@ -480,6 +483,14 @@ bool VScriptServerInit() ScriptLanguage_t scriptLanguage = SL_DEFAULT; char const *pszScriptLanguage; +#ifdef MAPBASE_VSCRIPT + if (GetWorldEntity()->GetScriptLanguage() != SL_NONE) + { + // Allow world entity to override script language + scriptLanguage = GetWorldEntity()->GetScriptLanguage(); + } + else +#endif if ( CommandLine()->CheckParm( "-scriptlang", &pszScriptLanguage ) ) { if( !Q_stricmp(pszScriptLanguage, "gamemonkey") ) @@ -494,6 +505,12 @@ bool VScriptServerInit() { scriptLanguage = SL_PYTHON; } +#ifdef MAPBASE_VSCRIPT + else if( !Q_stricmp(pszScriptLanguage, "lua") ) + { + scriptLanguage = SL_LUA; + } +#endif else { DevWarning("-server_script does not recognize a language named '%s'. virtual machine did NOT start.\n", pszScriptLanguage ); @@ -716,8 +733,17 @@ public: CVScriptGameSystem g_VScriptGameSystem; +#ifdef MAPBASE_VSCRIPT +ConVar script_allow_entity_creation_midgame( "script_allow_entity_creation_midgame", "1", FCVAR_NOT_CONNECTED, "Allows VScript files to create entities mid-game, as opposed to only creating entities on startup." ); +#endif + bool IsEntityCreationAllowedInScripts( void ) { +#ifdef MAPBASE_VSCRIPT + if (script_allow_entity_creation_midgame.GetBool()) + return true; +#endif + return g_VScriptGameSystem.m_bAllowEntityCreationInScripts; } diff --git a/sp/src/game/server/world.cpp b/sp/src/game/server/world.cpp index 460809cd..211e2bda 100644 --- a/sp/src/game/server/world.cpp +++ b/sp/src/game/server/world.cpp @@ -393,6 +393,9 @@ BEGIN_DATADESC( CWorld ) DEFINE_KEYFIELD( m_flMaxPropScreenSpaceWidth, FIELD_FLOAT, "maxpropscreenwidth" ), DEFINE_KEYFIELD( m_flMinPropScreenSpaceWidth, FIELD_FLOAT, "minpropscreenwidth" ), DEFINE_KEYFIELD( m_iszDetailSpriteMaterial, FIELD_STRING, "detailmaterial" ), +#ifdef MAPBASE_VSCRIPT + DEFINE_KEYFIELD( m_iScriptLanguage, FIELD_INTEGER, "vscriptlanguage" ), +#endif DEFINE_KEYFIELD( m_bColdWorld, FIELD_BOOLEAN, "coldworld" ), #ifdef MAPBASE @@ -417,6 +420,9 @@ IMPLEMENT_SERVERCLASS_ST(CWorld, DT_WORLD) #ifdef MAPBASE SendPropStringT (SENDINFO(m_iszChapterTitle) ), #endif +#ifdef MAPBASE_VSCRIPT + SendPropInt (SENDINFO(m_iScriptLanguage), 2, SPROP_UNSIGNED ), +#endif END_SEND_TABLE() // @@ -476,6 +482,10 @@ CWorld::CWorld( ) SetSolid( SOLID_BSP ); SetMoveType( MOVETYPE_NONE ); +#ifdef MAPBASE_VSCRIPT + m_iScriptLanguage = SL_NONE; +#endif + m_bColdWorld = false; } diff --git a/sp/src/game/server/world.h b/sp/src/game/server/world.h index 3737eb49..4fd82d2e 100644 --- a/sp/src/game/server/world.h +++ b/sp/src/game/server/world.h @@ -61,6 +61,10 @@ public: void InputSetChapterTitle( inputdata_t &inputdata ); #endif +#ifdef MAPBASE_VSCRIPT + ScriptLanguage_t GetScriptLanguage() { return (ScriptLanguage_t)(m_iScriptLanguage.Get()); } +#endif + private: DECLARE_DATADESC(); @@ -84,6 +88,10 @@ private: CNetworkVar( float, m_flMaxPropScreenSpaceWidth ); CNetworkVar( string_t, m_iszDetailSpriteMaterial ); +#ifdef MAPBASE_VSCRIPT + CNetworkVar( int, m_iScriptLanguage ); +#endif + // start flags CNetworkVar( bool, m_bStartDark ); CNetworkVar( bool, m_bColdWorld ); diff --git a/sp/src/game/shared/mapbase/vscript_funcs_shared.cpp b/sp/src/game/shared/mapbase/vscript_funcs_shared.cpp index 8b7f9108..c5db0270 100644 --- a/sp/src/game/shared/mapbase/vscript_funcs_shared.cpp +++ b/sp/src/game/shared/mapbase/vscript_funcs_shared.cpp @@ -61,6 +61,12 @@ void ParseScriptTableKeyValues( CBaseEntity *pEntity, HSCRIPT hKV ) void PrecacheEntityFromTable( const char *pszClassname, HSCRIPT hKV ) { + if ( IsEntityCreationAllowedInScripts() == false ) + { + Warning( "VScript error: A script attempted to create an entity mid-game. Due to the server's settings, entity creation from scripts is only allowed during map init.\n" ); + return; + } + // This is similar to UTIL_PrecacheOther(), but we can't check if we can only precache it once. // Probably for the best anyway, as similar classes can still have different precachable properties. CBaseEntity *pEntity = CreateEntityByName( pszClassname ); @@ -79,6 +85,12 @@ void PrecacheEntityFromTable( const char *pszClassname, HSCRIPT hKV ) HSCRIPT SpawnEntityFromTable( const char *pszClassname, HSCRIPT hKV ) { + if ( IsEntityCreationAllowedInScripts() == false ) + { + Warning( "VScript error: A script attempted to create an entity mid-game. Due to the server's settings, entity creation from scripts is only allowed during map init.\n" ); + return NULL; + } + CBaseEntity *pEntity = CreateEntityByName( pszClassname ); if ( !pEntity ) { @@ -108,6 +120,12 @@ inline CScriptKeyValues *ToScriptKeyValues( HSCRIPT hKV ) HSCRIPT SpawnEntityFromKeyValues( const char *pszClassname, HSCRIPT hKV ) { + if ( IsEntityCreationAllowedInScripts() == false ) + { + Warning( "VScript error: A script attempted to create an entity mid-game. Due to the server's settings, entity creation from scripts is only allowed during map init.\n" ); + return NULL; + } + CBaseEntity *pEntity = CreateEntityByName( pszClassname ); if ( !pEntity ) {