mirror of
https://github.com/celisej567/BCWSsrc.git
synced 2026-09-15 20:12:39 +03:00
694 lines
26 KiB
C++
694 lines
26 KiB
C++
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose: Due to this being a custom integration of VScript based on the Alien Swarm SDK, we don't have access to
|
|
// some of the code normally available in games like L4D2 or Valve's original VScript DLL.
|
|
// Instead, that code is recreated here, shared between server and client.
|
|
//
|
|
// It also contains other functions unique to Mapbase.
|
|
//
|
|
// $NoKeywords: $
|
|
//=============================================================================//
|
|
|
|
#include "cbase.h"
|
|
#include "matchers.h"
|
|
#include "takedamageinfo.h"
|
|
|
|
#ifndef CLIENT_DLL
|
|
#include "globalstate.h"
|
|
#include "vscript_server.h"
|
|
#endif
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
class CScriptNetPropManager
|
|
{
|
|
public:
|
|
|
|
#ifdef CLIENT_DLL
|
|
RecvProp *RecurseTable( RecvTable *pTable, const char *pszPropName )
|
|
#else
|
|
SendProp *RecurseTable( SendTable *pTable, const char *pszPropName )
|
|
#endif
|
|
{
|
|
#ifdef CLIENT_DLL
|
|
RecvProp *pProp = NULL;
|
|
#else
|
|
SendProp *pProp = NULL;
|
|
#endif
|
|
for (int i = 0; i < pTable->GetNumProps(); i++)
|
|
{
|
|
pProp = pTable->GetProp( i );
|
|
if (pProp->GetType() == DPT_DataTable)
|
|
{
|
|
pProp = RecurseTable(pProp->GetDataTable(), pszPropName);
|
|
if (pProp)
|
|
return pProp;
|
|
}
|
|
else
|
|
{
|
|
if (FStrEq( pProp->GetName(), pszPropName ))
|
|
return pProp;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
#ifdef CLIENT_DLL
|
|
RecvProp *RecurseNetworkClass( ClientClass *pClass, const char *pszPropName )
|
|
#else
|
|
SendProp *RecurseNetworkClass( ServerClass *pClass, const char *pszPropName )
|
|
#endif
|
|
{
|
|
#ifdef CLIENT_DLL
|
|
RecvProp *pProp = RecurseTable( pClass->m_pRecvTable, pszPropName );
|
|
#else
|
|
SendProp *pProp = RecurseTable( pClass->m_pTable, pszPropName );
|
|
#endif
|
|
if (pProp)
|
|
return pProp;
|
|
|
|
if (pClass->m_pNext)
|
|
return RecurseNetworkClass( pClass->m_pNext, pszPropName );
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
#ifdef CLIENT_DLL
|
|
RecvProp *GetPropByName( CBaseEntity *pEnt, const char *pszPropName )
|
|
{
|
|
if (pEnt)
|
|
{
|
|
return RecurseNetworkClass( pEnt->GetClientClass(), pszPropName );
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
#else
|
|
SendProp *GetPropByName( CBaseEntity *pEnt, const char *pszPropName )
|
|
{
|
|
if (pEnt)
|
|
{
|
|
return RecurseNetworkClass( pEnt->GetServerClass(), pszPropName );
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
int GetPropArraySize( HSCRIPT hEnt, const char *pszPropName )
|
|
{
|
|
CBaseEntity *pEnt = ToEnt( hEnt );
|
|
auto *pProp = GetPropByName( pEnt, pszPropName );
|
|
if (pProp)
|
|
{
|
|
// TODO: Is this what this function wants?
|
|
return pProp->GetNumElements();
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
#define GetPropFunc( name, varType, propType, defaultval ) \
|
|
varType name( HSCRIPT hEnt, const char *pszPropName ) \
|
|
{ \
|
|
CBaseEntity *pEnt = ToEnt( hEnt ); \
|
|
auto *pProp = GetPropByName( pEnt, pszPropName ); \
|
|
if (pProp && pProp->GetType() == propType) \
|
|
{ \
|
|
return *(varType*)((char *)pEnt + pProp->GetOffset()); \
|
|
} \
|
|
return defaultval; \
|
|
} \
|
|
|
|
#define GetPropFuncArray( name, varType, propType, defaultval ) \
|
|
varType name( HSCRIPT hEnt, const char *pszPropName, int iArrayElement ) \
|
|
{ \
|
|
CBaseEntity *pEnt = ToEnt( hEnt ); \
|
|
auto *pProp = GetPropByName( pEnt, pszPropName ); \
|
|
if (pProp && pProp->GetType() == propType) \
|
|
{ \
|
|
return ((varType*)((char *)pEnt + pProp->GetOffset()))[iArrayElement]; \
|
|
} \
|
|
return defaultval; \
|
|
} \
|
|
|
|
GetPropFunc( GetPropFloat, float, DPT_Float, -1 );
|
|
GetPropFuncArray( GetPropFloatArray, float, DPT_Float, -1 );
|
|
GetPropFunc( GetPropInt, int, DPT_Int, -1 );
|
|
GetPropFuncArray( GetPropIntArray, int, DPT_Int, -1 );
|
|
GetPropFunc( GetPropVector, Vector, DPT_Vector, vec3_invalid );
|
|
GetPropFuncArray( GetPropVectorArray, Vector, DPT_Vector, vec3_invalid );
|
|
|
|
HSCRIPT GetPropEntity( HSCRIPT hEnt, const char *pszPropName )
|
|
{
|
|
CBaseEntity *pEnt = ToEnt( hEnt );
|
|
auto *pProp = GetPropByName( pEnt, pszPropName );
|
|
if (pProp && pProp->GetType() == DPT_Int)
|
|
{
|
|
return ToHScript( *(CHandle<CBaseEntity>*)((char *)pEnt + pProp->GetOffset()) );
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
HSCRIPT GetPropEntityArray( HSCRIPT hEnt, const char *pszPropName, int iArrayElement )
|
|
{
|
|
CBaseEntity *pEnt = ToEnt( hEnt );
|
|
auto *pProp = GetPropByName( pEnt, pszPropName );
|
|
if (pProp && pProp->GetType() == DPT_Int)
|
|
{
|
|
return ToHScript( ((CHandle<CBaseEntity>*)((char *)pEnt + pProp->GetOffset()))[iArrayElement] );
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
const char *GetPropString( HSCRIPT hEnt, const char *pszPropName )
|
|
{
|
|
CBaseEntity *pEnt = ToEnt( hEnt );
|
|
auto *pProp = GetPropByName( pEnt, pszPropName );
|
|
if (pProp && pProp->GetType() == DPT_Int)
|
|
{
|
|
return (const char*)((char *)pEnt + pProp->GetOffset());
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
const char *GetPropStringArray( HSCRIPT hEnt, const char *pszPropName, int iArrayElement )
|
|
{
|
|
CBaseEntity *pEnt = ToEnt( hEnt );
|
|
auto *pProp = GetPropByName( pEnt, pszPropName );
|
|
if (pProp && pProp->GetType() == DPT_Int)
|
|
{
|
|
return ((const char**)((char *)pEnt + pProp->GetOffset()))[iArrayElement];
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
const char *GetPropType( HSCRIPT hEnt, const char *pszPropName )
|
|
{
|
|
CBaseEntity *pEnt = ToEnt( hEnt );
|
|
auto *pProp = GetPropByName( pEnt, pszPropName );
|
|
if (pProp)
|
|
{
|
|
switch (pProp->GetType())
|
|
{
|
|
case DPT_Int: return "integer";
|
|
case DPT_Float: return "float";
|
|
case DPT_Vector: return "vector";
|
|
case DPT_VectorXY: return "vector2d";
|
|
case DPT_String: return "string";
|
|
case DPT_Array: return "array";
|
|
case DPT_DataTable: return "datatable";
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
bool HasProp( HSCRIPT hEnt, const char *pszPropName )
|
|
{
|
|
CBaseEntity *pEnt = ToEnt( hEnt );
|
|
return GetPropByName( pEnt, pszPropName ) != NULL;
|
|
}
|
|
|
|
#define SetPropFunc( name, varType, propType ) \
|
|
void name( HSCRIPT hEnt, const char *pszPropName, varType value ) \
|
|
{ \
|
|
CBaseEntity *pEnt = ToEnt( hEnt ); \
|
|
auto *pProp = GetPropByName( pEnt, pszPropName ); \
|
|
if (pProp && pProp->GetType() == propType) \
|
|
{ \
|
|
*(varType*)((char *)pEnt + pProp->GetOffset()) = value; \
|
|
} \
|
|
} \
|
|
|
|
#define SetPropFuncArray( name, varType, propType ) \
|
|
void name( HSCRIPT hEnt, const char *pszPropName, varType value, int iArrayElement ) \
|
|
{ \
|
|
CBaseEntity *pEnt = ToEnt( hEnt ); \
|
|
auto *pProp = GetPropByName( pEnt, pszPropName ); \
|
|
if (pProp && pProp->GetType() == propType) \
|
|
{ \
|
|
((varType*)((char *)pEnt + pProp->GetOffset()))[iArrayElement] = value; \
|
|
} \
|
|
} \
|
|
|
|
SetPropFunc( SetPropFloat, float, DPT_Float );
|
|
SetPropFuncArray( SetPropFloatArray, float, DPT_Float );
|
|
SetPropFunc( SetPropInt, int, DPT_Int );
|
|
SetPropFuncArray( SetPropIntArray, int, DPT_Int );
|
|
SetPropFunc( SetPropVector, Vector, DPT_Vector );
|
|
SetPropFuncArray( SetPropVectorArray, Vector, DPT_Vector );
|
|
SetPropFunc( SetPropString, const char*, DPT_String );
|
|
SetPropFuncArray( SetPropStringArray, const char*, DPT_String );
|
|
|
|
void SetPropEntity( HSCRIPT hEnt, const char *pszPropName, HSCRIPT value )
|
|
{
|
|
CBaseEntity *pEnt = ToEnt( hEnt );
|
|
auto *pProp = GetPropByName( pEnt, pszPropName );
|
|
if (pProp && pProp->GetType() == DPT_Int)
|
|
{
|
|
*((CHandle<CBaseEntity>*)((char *)pEnt + pProp->GetOffset())) = ToEnt(value);
|
|
}
|
|
}
|
|
|
|
HSCRIPT SetPropEntityArray( HSCRIPT hEnt, const char *pszPropName, HSCRIPT value, int iArrayElement )
|
|
{
|
|
CBaseEntity *pEnt = ToEnt( hEnt );
|
|
auto *pProp = GetPropByName( pEnt, pszPropName );
|
|
if (pProp && pProp->GetType() == DPT_Int)
|
|
{
|
|
((CHandle<CBaseEntity>*)((char *)pEnt + pProp->GetOffset()))[iArrayElement] = ToEnt(value);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
private:
|
|
} g_ScriptNetPropManager;
|
|
|
|
BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptNetPropManager, "CNetPropManager", SCRIPT_SINGLETON "Allows reading and updating the network properties of an entity." )
|
|
DEFINE_SCRIPTFUNC( GetPropArraySize, "Returns the size of an netprop array, or -1." )
|
|
DEFINE_SCRIPTFUNC( GetPropEntity, "Reads an EHANDLE valued netprop (21 bit integer). Returns the script handle of the entity." )
|
|
DEFINE_SCRIPTFUNC( GetPropEntityArray, "Reads an EHANDLE valued netprop (21 bit integer) from an array. Returns the script handle of the entity." )
|
|
DEFINE_SCRIPTFUNC( GetPropFloat, "Reads a float valued netprop." )
|
|
DEFINE_SCRIPTFUNC( GetPropFloatArray, "Reads a float valued netprop from an array." )
|
|
DEFINE_SCRIPTFUNC( GetPropInt, "Reads an integer valued netprop." )
|
|
DEFINE_SCRIPTFUNC( GetPropIntArray, "Reads an integer valued netprop from an array." )
|
|
DEFINE_SCRIPTFUNC( GetPropString, "Reads a string valued netprop." )
|
|
DEFINE_SCRIPTFUNC( GetPropStringArray, "Reads a string valued netprop from an array." )
|
|
DEFINE_SCRIPTFUNC( GetPropVector, "Reads a 3D vector valued netprop." )
|
|
DEFINE_SCRIPTFUNC( GetPropVectorArray, "Reads a 3D vector valued netprop from an array." )
|
|
DEFINE_SCRIPTFUNC( GetPropType, "Returns the name of the netprop type as a string." )
|
|
DEFINE_SCRIPTFUNC( HasProp, "Checks if a netprop exists." )
|
|
DEFINE_SCRIPTFUNC( SetPropEntity, "Sets an EHANDLE valued netprop (21 bit integer) to reference the specified entity." )
|
|
DEFINE_SCRIPTFUNC( SetPropEntityArray, "Sets an EHANDLE valued netprop (21 bit integer) from an array to reference the specified entity." )
|
|
DEFINE_SCRIPTFUNC( SetPropFloat, "Sets a netprop to the specified float." )
|
|
DEFINE_SCRIPTFUNC( SetPropFloatArray, "Sets a netprop from an array to the specified float." )
|
|
DEFINE_SCRIPTFUNC( SetPropInt, "Sets a netprop to the specified integer." )
|
|
DEFINE_SCRIPTFUNC( SetPropIntArray, "Sets a netprop from an array to the specified integer." )
|
|
DEFINE_SCRIPTFUNC( SetPropString, "Sets a netprop to the specified string." )
|
|
DEFINE_SCRIPTFUNC( SetPropStringArray, "Sets a netprop from an array to the specified string." )
|
|
DEFINE_SCRIPTFUNC( SetPropVector, "Sets a netprop to the specified vector." )
|
|
DEFINE_SCRIPTFUNC( SetPropVectorArray, "Sets a netprop from an array to the specified vector." )
|
|
END_SCRIPTDESC();
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
class CScriptConvarLookup
|
|
{
|
|
public:
|
|
|
|
#ifndef CLIENT_DLL
|
|
const char *GetClientConvarValue( const char *pszConVar, int entindex )
|
|
{
|
|
return engine->GetClientConVarValue( entindex, pszConVar );
|
|
}
|
|
#endif
|
|
|
|
const char *GetStr( const char *pszConVar )
|
|
{
|
|
ConVarRef cvar( pszConVar );
|
|
return cvar.GetString();
|
|
}
|
|
|
|
float GetFloat( const char *pszConVar )
|
|
{
|
|
ConVarRef cvar( pszConVar );
|
|
return cvar.GetFloat();
|
|
}
|
|
|
|
void SetValue( const char *pszConVar, const char *pszValue )
|
|
{
|
|
ConVarRef cvar( pszConVar );
|
|
if (!cvar.IsValid())
|
|
return;
|
|
|
|
// FCVAR_NOT_CONNECTED can be used to protect specific convars from nefarious interference
|
|
if (cvar.IsFlagSet(FCVAR_NOT_CONNECTED))
|
|
return;
|
|
|
|
cvar.SetValue( pszValue );
|
|
}
|
|
|
|
private:
|
|
} g_ScriptConvarLookup;
|
|
|
|
BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptConvarLookup, "CConvars", SCRIPT_SINGLETON "Provides an interface for getting and setting convars." )
|
|
#ifndef CLIENT_DLL
|
|
DEFINE_SCRIPTFUNC( GetClientConvarValue, "Returns the convar value for the entindex as a string. Only works with client convars with the FCVAR_USERINFO flag." )
|
|
#endif
|
|
DEFINE_SCRIPTFUNC( GetStr, "Returns the convar as a string. May return null if no such convar." )
|
|
DEFINE_SCRIPTFUNC( GetFloat, "Returns the convar as a float. May return null if no such convar." )
|
|
DEFINE_SCRIPTFUNC( SetValue, "Sets the value of the convar. Supported types are bool, int, float, string." )
|
|
END_SCRIPTDESC();
|
|
|
|
#ifndef CLIENT_DLL
|
|
extern ConVar sv_script_think_interval;
|
|
|
|
void AddThinkToEnt( HSCRIPT entity, const char *pszFuncName )
|
|
{
|
|
CBaseEntity *pEntity = ToEnt( entity );
|
|
if (!pEntity)
|
|
return;
|
|
|
|
if (pszFuncName == NULL || pszFuncName[0] == '\0')
|
|
pEntity->m_iszScriptThinkFunction = NULL_STRING;
|
|
else
|
|
pEntity->m_iszScriptThinkFunction = AllocPooledString(pszFuncName);
|
|
|
|
pEntity->SetContextThink( &CBaseEntity::ScriptThink, gpGlobals->curtime + sv_script_think_interval.GetFloat(), "ScriptThink" );
|
|
}
|
|
|
|
HSCRIPT EntIndexToHScript( int index )
|
|
{
|
|
return ToHScript( UTIL_EntityByIndex( index ) );
|
|
}
|
|
|
|
void ParseScriptTableKeyValues( CBaseEntity *pEntity, HSCRIPT hKV )
|
|
{
|
|
int nIterator = -1;
|
|
ScriptVariant_t varKey, varValue;
|
|
while ((nIterator = g_pScriptVM->GetKeyValue( hKV, nIterator, &varKey, &varValue )) != -1)
|
|
{
|
|
switch (varValue.m_type)
|
|
{
|
|
case FIELD_CSTRING: pEntity->KeyValue( varKey.m_pszString, varValue.m_pszString ); break;
|
|
case FIELD_FLOAT: pEntity->KeyValue( varKey.m_pszString, varValue.m_float ); break;
|
|
case FIELD_VECTOR: pEntity->KeyValue( varKey.m_pszString, *varValue.m_pVector ); break;
|
|
}
|
|
|
|
g_pScriptVM->ReleaseValue( varKey );
|
|
g_pScriptVM->ReleaseValue( varValue );
|
|
}
|
|
}
|
|
|
|
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 );
|
|
if (!pEntity)
|
|
{
|
|
Assert( !"PrecacheEntityFromTable: only works for CBaseEntities" );
|
|
return;
|
|
}
|
|
|
|
ParseScriptTableKeyValues( pEntity, hKV );
|
|
|
|
pEntity->Precache();
|
|
|
|
UTIL_RemoveImmediate( pEntity );
|
|
}
|
|
|
|
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 )
|
|
{
|
|
Assert( !"SpawnEntityFromTable: only works for CBaseEntities" );
|
|
return NULL;
|
|
}
|
|
|
|
gEntList.NotifyCreateEntity( pEntity );
|
|
|
|
ParseScriptTableKeyValues( pEntity, hKV );
|
|
|
|
DispatchSpawn( pEntity );
|
|
|
|
return ToHScript( pEntity );
|
|
}
|
|
#endif
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Mapbase-specific functions start here
|
|
//-----------------------------------------------------------------------------
|
|
|
|
static void ScriptColorPrint( int r, int g, int b, const char *pszMsg )
|
|
{
|
|
const Color clr(r, g, b, 255);
|
|
ConColorMsg( clr, "%s", pszMsg );
|
|
}
|
|
|
|
static void ScriptColorPrintL( int r, int g, int b, const char *pszMsg )
|
|
{
|
|
const Color clr(r, g, b, 255);
|
|
ConColorMsg( clr, "%s\n", pszMsg );
|
|
}
|
|
|
|
#ifndef CLIENT_DLL
|
|
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 )
|
|
{
|
|
Assert( !"SpawnEntityFromKeyValues: only works for CBaseEntities" );
|
|
return NULL;
|
|
}
|
|
|
|
gEntList.NotifyCreateEntity( pEntity );
|
|
|
|
CScriptKeyValues *pScriptKV = hKV ? HScriptToClass<CScriptKeyValues>( hKV ) : NULL;
|
|
if (pScriptKV)
|
|
{
|
|
KeyValues *pKV = pScriptKV->m_pKeyValues;
|
|
for (pKV = pKV->GetFirstSubKey(); pKV != NULL; pKV = pKV->GetNextKey())
|
|
{
|
|
pEntity->KeyValue( pKV->GetName(), pKV->GetString() );
|
|
}
|
|
}
|
|
|
|
DispatchSpawn( pEntity );
|
|
|
|
return ToHScript( pEntity );
|
|
}
|
|
|
|
void ScriptDispatchSpawn( HSCRIPT hEntity )
|
|
{
|
|
CBaseEntity *pEntity = ToEnt( hEntity );
|
|
if (pEntity)
|
|
{
|
|
DispatchSpawn( pEntity );
|
|
}
|
|
}
|
|
#endif
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
static HSCRIPT CreateDamageInfo( HSCRIPT hInflictor, HSCRIPT hAttacker, const Vector &vecForce, const Vector &vecDamagePos, float flDamage, int iDamageType )
|
|
{
|
|
// The script is responsible for deleting this via DestroyDamageInfo().
|
|
CTakeDamageInfo *damageInfo = new CTakeDamageInfo(ToEnt(hInflictor), ToEnt(hAttacker), flDamage, iDamageType);
|
|
HSCRIPT hScript = g_pScriptVM->RegisterInstance( damageInfo );
|
|
|
|
damageInfo->SetDamagePosition( vecDamagePos );
|
|
damageInfo->SetDamageForce( vecForce );
|
|
|
|
return hScript;
|
|
}
|
|
|
|
static void DestroyDamageInfo( HSCRIPT hDamageInfo )
|
|
{
|
|
if (hDamageInfo)
|
|
{
|
|
CTakeDamageInfo *pInfo = (CTakeDamageInfo*)g_pScriptVM->GetInstanceValue( hDamageInfo, GetScriptDescForClass( CTakeDamageInfo ) );
|
|
if (pInfo)
|
|
{
|
|
g_pScriptVM->RemoveInstance( hDamageInfo );
|
|
delete pInfo;
|
|
}
|
|
}
|
|
}
|
|
|
|
void ScriptCalculateExplosiveDamageForce( HSCRIPT info, const Vector &vecDir, const Vector &vecForceOrigin, float flScale ) { CalculateExplosiveDamageForce( HScriptToClass<CTakeDamageInfo>(info), vecDir, vecForceOrigin, flScale ); }
|
|
void ScriptCalculateBulletDamageForce( HSCRIPT info, int iBulletType, const Vector &vecBulletDir, const Vector &vecForceOrigin, float flScale ) { CalculateBulletDamageForce( HScriptToClass<CTakeDamageInfo>(info), iBulletType, vecBulletDir, vecForceOrigin, flScale ); }
|
|
void ScriptCalculateMeleeDamageForce( HSCRIPT info, const Vector &vecMeleeDir, const Vector &vecForceOrigin, float flScale ) { CalculateMeleeDamageForce( HScriptToClass<CTakeDamageInfo>( info ), vecMeleeDir, vecForceOrigin, flScale ); }
|
|
void ScriptGuessDamageForce( HSCRIPT info, const Vector &vecForceDir, const Vector &vecForceOrigin, float flScale ) { GuessDamageForce( HScriptToClass<CTakeDamageInfo>( info ), vecForceDir, vecForceOrigin, flScale ); }
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
class CTraceInfoAccessor
|
|
{
|
|
public:
|
|
|
|
// CGrameTrace stuff
|
|
bool DidHitWorld() const { return m_tr.DidHitWorld(); }
|
|
bool DidHitNonWorldEntity() const { return m_tr.DidHitNonWorldEntity(); }
|
|
int GetEntityIndex() const { return m_tr.GetEntityIndex(); }
|
|
bool DidHit() const { return m_tr.DidHit(); }
|
|
|
|
float FractionLeftSolid() const { return m_tr.fractionleftsolid; }
|
|
int HitGroup() const { return m_tr.hitgroup; }
|
|
int PhysicsBone() const { return m_tr.physicsbone; }
|
|
|
|
HSCRIPT Entity() const { return ToHScript(m_tr.m_pEnt); }
|
|
|
|
int HitBox() const { return m_tr.hitbox; }
|
|
|
|
// CBaseTrace stuff
|
|
bool IsDispSurface() { return m_tr.IsDispSurface(); }
|
|
bool IsDispSurfaceWalkable() { return m_tr.IsDispSurfaceWalkable(); }
|
|
bool IsDispSurfaceBuildable() { return m_tr.IsDispSurfaceBuildable(); }
|
|
bool IsDispSurfaceProp1() { return m_tr.IsDispSurfaceProp1(); }
|
|
bool IsDispSurfaceProp2() { return m_tr.IsDispSurfaceProp2(); }
|
|
|
|
Vector StartPos() const { return m_tr.startpos; }
|
|
Vector EndPos() const { return m_tr.endpos; }
|
|
|
|
float Fraction() const { return m_tr.fraction; }
|
|
|
|
int Contents() const { return m_tr.contents; }
|
|
int DispFlags() const { return m_tr.dispFlags; }
|
|
|
|
bool AllSolid() const { return m_tr.allsolid; }
|
|
bool StartSolid() const { return m_tr.startsolid; }
|
|
|
|
trace_t &GetTrace() { return m_tr; }
|
|
void Destroy() { delete this; }
|
|
|
|
private:
|
|
trace_t m_tr;
|
|
|
|
};
|
|
|
|
BEGIN_SCRIPTDESC_ROOT_NAMED( CTraceInfoAccessor, "CGameTrace", "Handle for accessing trace_t info." )
|
|
DEFINE_SCRIPTFUNC( DidHitWorld, "Returns whether the trace hit the world entity or not." )
|
|
DEFINE_SCRIPTFUNC( DidHitNonWorldEntity, "Returns whether the trace hit something other than the world entity." )
|
|
DEFINE_SCRIPTFUNC( GetEntityIndex, "Returns the index of whatever entity this trace hit." )
|
|
DEFINE_SCRIPTFUNC( DidHit, "Returns whether the trace hit anything." )
|
|
|
|
DEFINE_SCRIPTFUNC( FractionLeftSolid, "If this trace started within a solid, this is the point in the trace's fraction at which it left that solid." )
|
|
DEFINE_SCRIPTFUNC( HitGroup, "Returns the specific hit group this trace hit if it hit an entity." )
|
|
DEFINE_SCRIPTFUNC( PhysicsBone, "Returns the physics bone this trace hit if it hit an entity." )
|
|
DEFINE_SCRIPTFUNC( Entity, "Returns the entity this trace has hit." )
|
|
DEFINE_SCRIPTFUNC( HitBox, "Returns the hitbox of the entity this trace has hit. If it hit the world entity, this returns the static prop index." )
|
|
|
|
DEFINE_SCRIPTFUNC( IsDispSurface, "Returns whether this trace hit a displacement." )
|
|
DEFINE_SCRIPTFUNC( IsDispSurfaceWalkable, "Returns whether DISPSURF_FLAG_WALKABLE is ticked on the displacement this trace hit." )
|
|
DEFINE_SCRIPTFUNC( IsDispSurfaceBuildable, "Returns whether DISPSURF_FLAG_BUILDABLE is ticked on the displacement this trace hit." )
|
|
DEFINE_SCRIPTFUNC( IsDispSurfaceProp1, "Returns whether DISPSURF_FLAG_SURFPROP1 is ticked on the displacement this trace hit." )
|
|
DEFINE_SCRIPTFUNC( IsDispSurfaceProp2, "Returns whether DISPSURF_FLAG_SURFPROP2 is ticked on the displacement this trace hit." )
|
|
|
|
DEFINE_SCRIPTFUNC( StartPos, "Gets the trace's start position." )
|
|
DEFINE_SCRIPTFUNC( EndPos, "Gets the trace's end position." )
|
|
|
|
DEFINE_SCRIPTFUNC( Fraction, "Gets the fraction of the trace completed. For example, if the trace stopped exactly halfway to the end position, this would be 0.5." )
|
|
DEFINE_SCRIPTFUNC( Contents, "Gets the contents of the surface the trace has hit." )
|
|
DEFINE_SCRIPTFUNC( DispFlags, "Gets the displacement flags of the surface the trace has hit." )
|
|
|
|
DEFINE_SCRIPTFUNC( AllSolid, "Returns whether the trace is completely within a solid." )
|
|
DEFINE_SCRIPTFUNC( StartSolid, "Returns whether the trace started within a solid." )
|
|
|
|
DEFINE_SCRIPTFUNC( Destroy, "Deletes this instance. Important for preventing memory leaks." )
|
|
END_SCRIPTDESC();
|
|
|
|
static HSCRIPT ScriptTraceLineComplex( const Vector &vecStart, const Vector &vecEnd, HSCRIPT entIgnore, int iMask, int iCollisionGroup )
|
|
{
|
|
// The script is responsible for deleting this via Destroy().
|
|
CTraceInfoAccessor *traceInfo = new CTraceInfoAccessor();
|
|
HSCRIPT hScript = g_pScriptVM->RegisterInstance( traceInfo );
|
|
|
|
CBaseEntity *pLooker = ToEnt(entIgnore);
|
|
UTIL_TraceLine( vecStart, vecEnd, iMask, pLooker, iCollisionGroup, &traceInfo->GetTrace());
|
|
return hScript;
|
|
}
|
|
|
|
static HSCRIPT ScriptTraceHullComplex( const Vector &vecStart, const Vector &vecEnd, const Vector &hullMin, const Vector &hullMax,
|
|
HSCRIPT entIgnore, int iMask, int iCollisionGroup )
|
|
{
|
|
// The script is responsible for deleting this via Destroy().
|
|
CTraceInfoAccessor *traceInfo = new CTraceInfoAccessor();
|
|
HSCRIPT hScript = g_pScriptVM->RegisterInstance( traceInfo );
|
|
|
|
CBaseEntity *pLooker = ToEnt(entIgnore);
|
|
UTIL_TraceHull( vecStart, vecEnd, hullMin, hullMax, iMask, pLooker, iCollisionGroup, &traceInfo->GetTrace());
|
|
return hScript;
|
|
}
|
|
|
|
bool ScriptMatcherMatch( const char *pszQuery, const char *szValue ) { return Matcher_Match( pszQuery, szValue ); }
|
|
|
|
void RegisterSharedScriptFunctions()
|
|
{
|
|
//
|
|
// Due to this being a custom integration of VScript based on the Alien Swarm SDK, we don't have access to
|
|
// some of the code normally available in games like L4D2 or Valve's original VScript DLL.
|
|
// Instead, that code is recreated here, shared between server and client.
|
|
//
|
|
ScriptRegisterFunction( g_pScriptVM, RandomFloat, "Generate a random floating point number within a range, inclusive." );
|
|
ScriptRegisterFunction( g_pScriptVM, RandomInt, "Generate a random integer within a range, inclusive." );
|
|
|
|
ScriptRegisterFunction( g_pScriptVM, AngleDiff, "Returns the number of degrees difference between two yaw angles." );
|
|
|
|
#ifndef CLIENT_DLL
|
|
ScriptRegisterFunctionNamed( g_pScriptVM, NDebugOverlay::BoxDirection, "DebugDrawBoxDirection", "Draw a debug forward box" );
|
|
ScriptRegisterFunctionNamed( g_pScriptVM, NDebugOverlay::Text, "DebugDrawText", "Draw a debug overlay text" );
|
|
|
|
ScriptRegisterFunction( g_pScriptVM, AddThinkToEnt, "This will put a think function onto an entity, or pass null to remove it. This is NOT chained, so be careful." );
|
|
ScriptRegisterFunction( g_pScriptVM, EntIndexToHScript, "Returns the script handle for the given entity index." );
|
|
ScriptRegisterFunction( g_pScriptVM, PrecacheEntityFromTable, "Precache an entity from KeyValues in a table." );
|
|
ScriptRegisterFunction( g_pScriptVM, SpawnEntityFromTable, "Native function for entity spawning." );
|
|
#endif
|
|
|
|
g_pScriptVM->RegisterInstance( &g_ScriptConvarLookup, "Convars" );
|
|
g_pScriptVM->RegisterInstance( &g_ScriptNetPropManager, "NetProps" );
|
|
|
|
// Functions unique to Mapbase
|
|
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptColorPrint, "printc", "Version of print() which takes a color before the message." );
|
|
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptColorPrintL, "printcl", "Version of printl() which takes a color before the message." );
|
|
|
|
#ifndef CLIENT_DLL
|
|
ScriptRegisterFunction( g_pScriptVM, SpawnEntityFromKeyValues, "Spawns an entity with the keyvalues in a CScriptKeyValues handle." );
|
|
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptDispatchSpawn, "DispatchSpawn", "Spawns an unspawned entity." );
|
|
#endif
|
|
|
|
ScriptRegisterFunction( g_pScriptVM, CreateDamageInfo, "Creates damage info." );
|
|
ScriptRegisterFunction( g_pScriptVM, DestroyDamageInfo, "Destroys damage info." );
|
|
ScriptRegisterFunction( g_pScriptVM, ImpulseScale, "Returns an impulse scale required to push an object." );
|
|
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCalculateExplosiveDamageForce, "CalculateExplosiveDamageForce", "Fill out a damage info handle with a damage force for an explosive." );
|
|
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCalculateBulletDamageForce, "CalculateBulletDamageForce", "Fill out a damage info handle with a damage force for a bullet impact." );
|
|
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCalculateMeleeDamageForce, "CalculateMeleeDamageForce", "Fill out a damage info handle with a damage force for a melee impact." );
|
|
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptGuessDamageForce, "GuessDamageForce", "Try and guess the physics force to use." );
|
|
|
|
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptTraceLineComplex, "TraceLineComplex", "Complex version of TraceLine which takes 2 points, an ent to ignore, a trace mask, and a collision group. Returns a handle which can access all trace info." );
|
|
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptTraceHullComplex, "TraceHullComplex", "Takes 2 points, min/max hull bounds, an ent to ignore, a trace mask, and a collision group to trace to a point using a hull. Returns a handle which can access all trace info." );
|
|
|
|
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptMatcherMatch, "Matcher_Match", "Compares a string to a query using Mapbase's matcher system, supporting wildcards, RS matchers, etc." );
|
|
ScriptRegisterFunction( g_pScriptVM, Matcher_NamesMatch, "Compares a string to a query using Mapbase's matcher system using wildcards only." );
|
|
ScriptRegisterFunction( g_pScriptVM, AppearsToBeANumber, "Checks if the given string appears to be a number." );
|
|
|
|
#ifdef CLIENT_DLL
|
|
VScriptRunScript( "vscript_client", true );
|
|
#else
|
|
VScriptRunScript( "vscript_server", true );
|
|
#endif
|
|
}
|