mirror of
https://github.com/celisej567/source-sdk-2013.git
synced 2026-09-11 20:11:33 +03:00
baseentity_shared.cpp baseentity.cpp c_baseentity.h c_baseentity.cpp c_world.h - Fixed critical ScriptSetContextThink bugs - Added C_BaseEntity::SetContextThink (ScriptSetContextThink) - Added C_BaseEntity::SetSize - Added C_BaseEntity::SetModel - Added C_BaseEntity::Destroy baseentity.h baseentity.cpp - Removed duplicate functions ScriptSetSize and ScriptUtilRemove player.cpp - Moved player script instance registration before player_spawn event vscript_server.cpp - Added CEntities::FindByClassNearestFacing vscript_funcs_shared.cpp - Added GetFrameCount - Added IntervalPerTick vscript_singletons.cpp - Better game event descriptors for CScriptGameEventListener - Added ::effects (CEffectsScriptHelper) - Added ::Convars (CScriptConvarAccessor) vscript_shared.cpp - Fixed clientside entity printing in script VM mapbase_con_groups.h mapbase_con_groups.cpp - Improved performance by changing string comparisons to direct array access vscript_bindings_base.h vscript_bindings_base.cpp - Added CScriptKeyValues::SubKeysToTable vscript_bindings_math.cpp - Added ::SimpleSplineRemapVal - Added ::SimpleSplineRemapValClamped - Added ::Bias - Added ::Gain - Added ::SmoothCurve - Added ::SmoothCurve_Tweak - Added ::ExponentialDecay vscript_squirrel.nut - Added ::Lerp - Added ::FLerp - Added ::SimpleSpline vscript_squirrel.cpp - Added Vector::_unm - Added Vector::Set - Added Vector::Add - Added Vector::Subtract - Added Vector::Multiply - Added Vector::Divide - Added Vector::DistTo - Added Vector::DistToSqr - Added Vector::IsEqualTo - Added Vector::WithinAABox - Added Vector::FromKVString - Changed vector print syntax
360 lines
10 KiB
C++
360 lines
10 KiB
C++
//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============//
|
|
//
|
|
// Purpose: Mapbase's implementation of VScript in VBSP, allowing users to modify map compilation behavior with scripts.
|
|
//
|
|
// $NoKeywords: $
|
|
//=============================================================================//
|
|
|
|
#include "tier1/KeyValues.h"
|
|
#include "tier1/fmtstr.h"
|
|
|
|
#include "vbsp.h"
|
|
#include "map.h"
|
|
#include "fgdlib/fgdlib.h"
|
|
#include "convar.h"
|
|
|
|
#include "vscript_vbsp.h"
|
|
#include "vscript_vbsp.nut"
|
|
#include "vscript_funcs_vmfs.h"
|
|
#include "vscript_funcs_vis.h"
|
|
|
|
IScriptVM *g_pScriptVM;
|
|
IScriptManager *scriptmanager = NULL;
|
|
|
|
extern ScriptLanguage_t g_iScripting;
|
|
|
|
extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * );
|
|
|
|
// #define VMPROFILE 1
|
|
|
|
#ifdef VMPROFILE
|
|
|
|
#define VMPROF_START float debugStartTime = Plat_FloatTime();
|
|
#define VMPROF_SHOW( funcname, funcdesc ) DevMsg("***VSCRIPT PROFILE***: %s %s: %6.4f milliseconds\n", (##funcname), (##funcdesc), (Plat_FloatTime() - debugStartTime)*1000.0 );
|
|
|
|
#else // !VMPROFILE
|
|
|
|
#define VMPROF_START
|
|
#define VMPROF_SHOW
|
|
|
|
#endif // VMPROFILE
|
|
|
|
// This is to ensure a dependency exists between the vscript library and the game DLLs
|
|
extern int vscript_token;
|
|
int vscript_token_hack = vscript_token;
|
|
|
|
HSCRIPT VScriptCompileScript( const char *pszScriptName, bool bWarnMissing )
|
|
{
|
|
if ( !g_pScriptVM )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
static const char *pszExtensions[] =
|
|
{
|
|
"", // SL_NONE
|
|
".gm", // SL_GAMEMONKEY
|
|
".nut", // SL_SQUIRREL
|
|
".lua", // SL_LUA
|
|
".py", // SL_PYTHON
|
|
};
|
|
|
|
const char *pszVMExtension = pszExtensions[g_pScriptVM->GetLanguage()];
|
|
const char *pszIncomingExtension = V_strrchr( pszScriptName , '.' );
|
|
if ( pszIncomingExtension && V_strcmp( pszIncomingExtension, pszVMExtension ) != 0 )
|
|
{
|
|
Warning( "Script file type does not match VM type\n" );
|
|
return NULL;
|
|
}
|
|
|
|
CFmtStr scriptPath;
|
|
if ( pszIncomingExtension )
|
|
{
|
|
scriptPath = pszScriptName;
|
|
}
|
|
else
|
|
{
|
|
scriptPath.sprintf( "%s%s", pszScriptName, pszVMExtension );
|
|
}
|
|
|
|
const char *pBase;
|
|
CUtlBuffer bufferScript;
|
|
|
|
if ( g_pScriptVM->GetLanguage() == SL_PYTHON )
|
|
{
|
|
// python auto-loads raw or precompiled modules - don't load data here
|
|
pBase = NULL;
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
FileFindHandle_t handle = NULL;
|
|
const char *file = g_pFullFileSystem->FindFirst( "*", &handle );
|
|
while (file)
|
|
{
|
|
Msg( "File in this directory: %s\n", file );
|
|
file = g_pFullFileSystem->FindNext(handle);
|
|
}
|
|
|
|
Msg( "File exists: %d\n", g_pFullFileSystem->FileExists( scriptPath ) );
|
|
*/
|
|
|
|
|
|
bool bResult = g_pFullFileSystem->ReadFile( scriptPath, NULL, bufferScript );
|
|
|
|
if ( !bResult && bWarnMissing )
|
|
{
|
|
Warning( "Script not found (%s) \n", scriptPath.operator const char *() );
|
|
Assert( "Error running script" );
|
|
}
|
|
|
|
pBase = (const char *) bufferScript.Base();
|
|
|
|
if ( !pBase || !*pBase )
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
const char *pszFilename = V_strrchr( scriptPath, '\\' );
|
|
pszFilename++;
|
|
HSCRIPT hScript = g_pScriptVM->CompileScript( pBase, pszFilename );
|
|
if ( !hScript )
|
|
{
|
|
Warning( "FAILED to compile and execute script file named %s\n", scriptPath.operator const char *() );
|
|
Assert( "Error running script" );
|
|
}
|
|
return hScript;
|
|
}
|
|
|
|
static int g_ScriptVBSPRunScriptDepth;
|
|
|
|
bool VScriptRunScript( const char *pszScriptName, HSCRIPT hScope, bool bWarnMissing )
|
|
{
|
|
if ( !g_pScriptVM )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if ( !pszScriptName || !*pszScriptName )
|
|
{
|
|
Warning( "Cannot run script: NULL script name\n" );
|
|
return false;
|
|
}
|
|
|
|
// Prevent infinite recursion in VM
|
|
if ( g_ScriptVBSPRunScriptDepth > 16 )
|
|
{
|
|
Warning( "IncludeScript stack overflow\n" );
|
|
return false;
|
|
}
|
|
|
|
g_ScriptVBSPRunScriptDepth++;
|
|
HSCRIPT hScript = VScriptCompileScript( pszScriptName, bWarnMissing );
|
|
bool bSuccess = false;
|
|
if ( hScript )
|
|
{
|
|
bSuccess = ( g_pScriptVM->Run( hScript, hScope ) != SCRIPT_ERROR );
|
|
if ( !bSuccess )
|
|
{
|
|
Warning( "Error running script named %s\n", pszScriptName );
|
|
Assert( "Error running script" );
|
|
}
|
|
}
|
|
g_ScriptVBSPRunScriptDepth--;
|
|
return bSuccess;
|
|
}
|
|
|
|
BEGIN_SCRIPTDESC_ROOT( CMapFile, "Map file" )
|
|
|
|
DEFINE_SCRIPTFUNC( GetMins, "Get the map's mins." )
|
|
DEFINE_SCRIPTFUNC( GetMaxs, "Get the map's maxs." )
|
|
|
|
DEFINE_SCRIPTFUNC( GetEntityOrigin, "Get the origin of the entity with the specified index." )
|
|
DEFINE_SCRIPTFUNC( GetEntityFirstBrush, "Get the first brush ID of the entity with the specified index." )
|
|
DEFINE_SCRIPTFUNC( GetEntityNumBrushes, "Get the number of brushes in the entity with the specified index." )
|
|
|
|
DEFINE_SCRIPTFUNC_NAMED( ScriptGetEntityKeyValues, "GetEntityKeyValues", "Export an entity's keyvalues to two arrays." )
|
|
|
|
DEFINE_SCRIPTFUNC_NAMED( ScriptAddSimpleEntityKV, "AddSimpleEntityKV", "Add a simple entity from a keyvalue table." )
|
|
DEFINE_SCRIPTFUNC_NAMED( ScriptAddInstance, "AddInstance", "Add an instance to the map." )
|
|
|
|
DEFINE_SCRIPTFUNC( GetNumEntities, "Get the number of entities in the map." )
|
|
|
|
END_SCRIPTDESC();
|
|
|
|
|
|
static float cvar_getf( const char* sz )
|
|
{
|
|
ConVarRef cvar(sz);
|
|
if ( cvar.IsFlagSet( FCVAR_SERVER_CANNOT_QUERY ) )
|
|
return NULL;
|
|
return cvar.GetFloat();
|
|
}
|
|
|
|
static bool cvar_setf( const char* sz, float val )
|
|
{
|
|
ConVarRef cvar(sz);
|
|
if ( !cvar.IsValid() )
|
|
return false;
|
|
|
|
if ( cvar.IsFlagSet( FCVAR_SERVER_CANNOT_QUERY ) )
|
|
return false;
|
|
|
|
cvar.SetValue(val);
|
|
return true;
|
|
}
|
|
|
|
static const char *GetSource()
|
|
{
|
|
return source;
|
|
}
|
|
|
|
static const char *GetMapBase()
|
|
{
|
|
return mapbase;
|
|
}
|
|
|
|
static HSCRIPT GetMainMap()
|
|
{
|
|
return g_MainMap ? g_MainMap->GetScriptInstance() : NULL;
|
|
}
|
|
|
|
static HSCRIPT GetLoadingMap()
|
|
{
|
|
return g_LoadingMap ? g_LoadingMap->GetScriptInstance() : NULL;
|
|
}
|
|
|
|
static const char *DoUniqueString( const char *pszBase )
|
|
{
|
|
static char szBuf[512];
|
|
g_pScriptVM->GenerateUniqueKey( pszBase, szBuf, ARRAYSIZE(szBuf) );
|
|
return szBuf;
|
|
}
|
|
|
|
bool DoIncludeScript( const char *pszScript, HSCRIPT hScope )
|
|
{
|
|
if ( !VScriptRunScript( pszScript, hScope, true ) )
|
|
{
|
|
g_pScriptVM->RaiseException( CFmtStr( "Failed to include script \"%s\"", ( pszScript ) ? pszScript : "unknown" ) );
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
extern qboolean glview;
|
|
extern qboolean onlyents;
|
|
extern bool onlyprops;
|
|
extern qboolean noleaktest;
|
|
extern qboolean verboseentities;
|
|
extern qboolean g_bLowPriority;
|
|
extern bool g_bKeepStaleZip;
|
|
extern bool g_bNoDefaultCubemaps;
|
|
extern bool g_bSkyboxCubemaps;
|
|
extern int g_iDefaultCubemapSize;
|
|
|
|
bool VScriptVBSPInit()
|
|
{
|
|
VMPROF_START
|
|
|
|
if( g_iScripting != SL_NONE && scriptmanager != NULL )
|
|
{
|
|
if ( g_pScriptVM == NULL )
|
|
g_pScriptVM = scriptmanager->CreateVM( g_iScripting );
|
|
|
|
if( g_pScriptVM )
|
|
{
|
|
Log( "VSCRIPT VBSP: Started VScript virtual machine using script language '%s'\n", g_pScriptVM->GetLanguageName() );
|
|
|
|
ScriptRegisterFunction( g_pScriptVM, cvar_getf, "Gets the value of the given cvar, as a float." );
|
|
ScriptRegisterFunction( g_pScriptVM, cvar_setf, "Sets the value of the given cvar, as a float." );
|
|
|
|
ScriptRegisterFunction( g_pScriptVM, GetSource, "Gets the base directory of the first map loaded." );
|
|
ScriptRegisterFunction( g_pScriptVM, GetMapBase, "Gets the base name of the first map loaded." );
|
|
ScriptRegisterFunction( g_pScriptVM, GetMainMap, "Gets the first map loaded." );
|
|
ScriptRegisterFunction( g_pScriptVM, GetLoadingMap, "Gets the map which is currently loading (e.g. an instance)." );
|
|
|
|
ScriptRegisterFunction( g_pScriptVM, DoUniqueString, SCRIPT_ALIAS( "UniqueString", "Generate a string guaranteed to be unique across the life of the script VM, with an optional root string. Useful for adding data to tables when not sure what keys are already in use in that table." ) );
|
|
ScriptRegisterFunction( g_pScriptVM, DoIncludeScript, "Execute a script (internal)" );
|
|
|
|
ScriptRegisterConstantNamed( g_pScriptVM, GameData::NAME_FIXUP_PREFIX, "NAME_FIXUP_PREFIX", "Prefix name fixup" );
|
|
ScriptRegisterConstantNamed( g_pScriptVM, GameData::NAME_FIXUP_POSTFIX, "NAME_FIXUP_PREFIX", "Postfix name fixup" );
|
|
ScriptRegisterConstantNamed( g_pScriptVM, GameData::NAME_FIXUP_NONE, "NAME_FIXUP_NONE", "No name fixup" );
|
|
|
|
ScriptRegisterConstant( g_pScriptVM, microvolume, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, noprune, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, glview, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, nodetail, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, fulldetail, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, onlyents, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, onlyprops, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, nomerge, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, nomergewater, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, nowater, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, nocsg, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, noweld, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, noshare, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, nosubdiv, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, notjunc, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, noopt, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, noleaktest, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, verboseentities, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, dumpcollide, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, g_bLowPriority, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, g_DumpStaticProps, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, g_bSkyVis, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, g_bLightIfMissing, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, g_snapAxialPlanes, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, g_bKeepStaleZip, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, g_NodrawTriggers, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, g_DisableWaterLighting, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, g_bAllowDetailCracks, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, g_bNoVirtualMesh, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, g_bNoHiddenManifestMaps, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, g_bNoDefaultCubemaps, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, g_bSkyboxCubemaps, "" );
|
|
ScriptRegisterConstant( g_pScriptVM, g_iDefaultCubemapSize, "" );
|
|
|
|
if (g_iScripting == SL_SQUIRREL)
|
|
{
|
|
g_pScriptVM->Run( g_Script_vscript_vbsp );
|
|
}
|
|
|
|
RegisterVMFScriptFunctions();
|
|
|
|
// Run the map's script
|
|
char script[96];
|
|
Q_snprintf( script, sizeof(script), "%s_vbsp", source );
|
|
//Msg("VBSP script: \"%s\"\n", script);
|
|
VScriptRunScript( script, true );
|
|
|
|
VMPROF_SHOW( g_iScripting, "virtual machine startup" );
|
|
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
DevWarning("VM Did not start!\n");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Log( "\nVSCRIPT: Scripting is disabled.\n" );
|
|
}
|
|
g_pScriptVM = NULL;
|
|
return false;
|
|
}
|
|
|
|
void VScriptVBSPTerm()
|
|
{
|
|
if( g_pScriptVM != NULL )
|
|
{
|
|
if( g_pScriptVM )
|
|
{
|
|
scriptmanager->DestroyVM( g_pScriptVM );
|
|
g_pScriptVM = NULL;
|
|
}
|
|
}
|
|
}
|