Merge pull request #114 from samisalreadytaken/dev6

vscript additions
This commit is contained in:
Blixibon 2021-04-23 22:31:04 -05:00 committed by GitHub
commit ea98b2cd1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 361 additions and 143 deletions

View File

@ -428,6 +428,10 @@ BEGIN_RECV_TABLE_NOBASE( C_BaseEntity, DT_AnimTimeMustBeFirst )
RecvPropInt( RECVINFO(m_flAnimTime), 0, RecvProxy_AnimTime ),
END_RECV_TABLE()
#ifdef MAPBASE_VSCRIPT
ScriptHook_t CBaseEntity::g_Hook_UpdateOnRemove;
#endif
BEGIN_ENT_SCRIPTDESC_ROOT( C_BaseEntity, "Root class of all client-side entities" )
DEFINE_SCRIPT_INSTANCE_HELPER( &g_BaseEntityScriptInstanceHelper )
DEFINE_SCRIPTFUNC_NAMED( GetAbsOrigin, "GetOrigin", "" )
@ -550,7 +554,10 @@ BEGIN_ENT_SCRIPTDESC_ROOT( C_BaseEntity, "Root class of all client-side entities
DEFINE_SCRIPTFUNC_NAMED( ScriptSetContextThink, "SetContextThink", "Set a think function on this entity." )
#endif
DEFINE_SIMPLE_SCRIPTHOOK( CBaseEntity::g_Hook_UpdateOnRemove, "UpdateOnRemove", FIELD_VOID, "Called when the entity is being removed." )
#endif // MAPBASE_VSCRIPT
END_SCRIPTDESC();
@ -1340,6 +1347,12 @@ void C_BaseEntity::Term()
if ( m_hScriptInstance )
{
#ifdef MAPBASE_VSCRIPT
if ( m_ScriptScope.IsInitialized() )
{
g_Hook_UpdateOnRemove.Call( m_ScriptScope, NULL, NULL );
}
#endif
g_pScriptVM->RemoveInstance( m_hScriptInstance );
m_hScriptInstance = NULL;

View File

@ -164,10 +164,9 @@ struct thinkfunc_t
#ifdef MAPBASE_VSCRIPT
struct scriptthinkfunc_t
{
int m_nNextThinkTick;
HSCRIPT m_hfnThink;
unsigned short m_iContextHash;
bool m_bNoParam;
float m_flNextThink;
HSCRIPT m_hfnThink;
unsigned m_iContextHash;
};
#endif
@ -295,6 +294,8 @@ public:
string_t m_iszScriptId;
#ifdef MAPBASE_VSCRIPT
CScriptScope m_ScriptScope;
static ScriptHook_t g_Hook_UpdateOnRemove;
#endif
// IClientUnknown overrides.

View File

@ -150,6 +150,10 @@ private:
static const int ENTRY_IN_USE = -2;
};
#ifdef MAPBASE_VSCRIPT
// For unregistration boundary check
public:
#endif
CUtlVector< GlowObjectDefinition_t > m_GlowObjectDefinitions;
int m_nFirstFreeSlot;
};

View File

@ -2314,6 +2314,8 @@ BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities"
DEFINE_SCRIPTFUNC_NAMED( ScriptGetModelKeyValues, "GetModelKeyValues", "Get a KeyValue class instance on this entity's model")
#ifdef MAPBASE_VSCRIPT
DEFINE_SCRIPTFUNC( Activate, "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptIsVisible, "IsVisible", "Check if the specified position can be visible to this entity." )
DEFINE_SCRIPTFUNC_NAMED( ScriptIsEntVisible, "IsEntVisible", "Check if the specified entity can be visible to this entity." )
DEFINE_SCRIPTFUNC_NAMED( ScriptIsVisibleWithMask, "IsVisibleWithMask", "Check if the specified position can be visible to this entity with a specific trace mask." )
@ -2411,7 +2413,10 @@ BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities"
DEFINE_SCRIPTFUNC( SetFriction, "" )
DEFINE_SCRIPTFUNC( GetMass, "" )
DEFINE_SCRIPTFUNC( SetMass, "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetSolid, "GetSolid", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptSetSolid, "SetSolid", "" )
DEFINE_SCRIPTFUNC( GetSolidFlags, "Get solid flags" )
DEFINE_SCRIPTFUNC( AddSolidFlags, "Add solid flags" )
DEFINE_SCRIPTFUNC( RemoveSolidFlags, "Remove solid flags" )

View File

@ -352,10 +352,10 @@ struct thinkfunc_t
#ifdef MAPBASE_VSCRIPT
struct scriptthinkfunc_t
{
int m_nNextThinkTick;
HSCRIPT m_hfnThink;
unsigned short m_iContextHash;
bool m_bNoParam;
float m_flNextThink;
HSCRIPT m_hfnThink;
unsigned m_iContextHash;
bool m_bNoParam;
};
#endif
@ -2132,6 +2132,9 @@ public:
int ScriptGetMoveType() { return GetMoveType(); }
void ScriptSetMoveType( int iMoveType ) { SetMoveType( (MoveType_t)iMoveType ); }
int ScriptGetSolid() { return GetSolid(); }
void ScriptSetSolid( int i ) { SetSolid( (SolidType_t)i ); }
bool ScriptDispatchInteraction( int interactionType, HSCRIPT data, HSCRIPT sourceEnt );
int ScriptGetTakeDamage() { return m_takedamage; }

View File

@ -2713,13 +2713,20 @@ HSCRIPT CBaseEntity::ScriptGetPhysicsObject( void )
return NULL;
}
#ifdef GAME_DLL
#define SCRIPT_NEVER_THINK TICK_NEVER_THINK
#else
#define SCRIPT_NEVER_THINK CLIENT_THINK_NEVER
#endif
static inline void ScriptStopContextThink( scriptthinkfunc_t *context )
{
Assert( context->m_hfnThink );
Assert( context->m_flNextThink == SCRIPT_NEVER_THINK );
g_pScriptVM->ReleaseScript( context->m_hfnThink );
context->m_hfnThink = NULL;
//context->m_nNextThinkTick = TICK_NEVER_THINK;
}
//-----------------------------------------------------------------------------
@ -2728,55 +2735,56 @@ static inline void ScriptStopContextThink( scriptthinkfunc_t *context )
void CBaseEntity::ScriptContextThink()
{
float flNextThink = FLT_MAX;
int nScheduledTick = 0;
float flScheduled = 0.0f;
for ( int i = 0; i < m_ScriptThinkFuncs.Count(); ++i )
{
scriptthinkfunc_t *cur = m_ScriptThinkFuncs[i];
if ( cur->m_nNextThinkTick == TICK_NEVER_THINK )
if ( cur->m_flNextThink == SCRIPT_NEVER_THINK )
{
continue;
}
if ( cur->m_nNextThinkTick > gpGlobals->tickcount )
if ( cur->m_flNextThink > gpGlobals->curtime )
{
// There is more to execute, don't stop thinking if the rest are done.
// Find the shortest schedule
if ( !nScheduledTick || nScheduledTick > cur->m_nNextThinkTick )
if ( ( flScheduled == 0.0f ) || ( flScheduled > cur->m_flNextThink ) )
{
nScheduledTick = cur->m_nNextThinkTick;
flScheduled = cur->m_flNextThink;
}
continue;
}
#ifdef _DEBUG
// going to run the script func
cur->m_nNextThinkTick = 0;
cur->m_flNextThink = 0;
#endif
ScriptVariant_t varReturn;
#ifndef CLIENT_DLL
if ( !cur->m_bNoParam )
{
#endif
ScriptVariant_t arg = m_hScriptInstance;
if ( g_pScriptVM->ExecuteFunction( cur->m_hfnThink, &arg, 1, &varReturn, NULL, true ) == SCRIPT_ERROR )
{
cur->m_nNextThinkTick = TICK_NEVER_THINK;
cur->m_flNextThink = SCRIPT_NEVER_THINK;
continue;
}
#ifndef CLIENT_DLL
}
else
{
if ( g_pScriptVM->ExecuteFunction( cur->m_hfnThink, NULL, 0, &varReturn, NULL, true ) == SCRIPT_ERROR )
{
cur->m_nNextThinkTick = TICK_NEVER_THINK;
cur->m_flNextThink = SCRIPT_NEVER_THINK;
continue;
}
}
#endif
if ( cur->m_nNextThinkTick == TICK_NEVER_THINK )
if ( cur->m_flNextThink == SCRIPT_NEVER_THINK )
{
// stopped from script while thinking
continue;
@ -2785,13 +2793,13 @@ void CBaseEntity::ScriptContextThink()
float flReturn;
if ( !varReturn.AssignTo( &flReturn ) )
{
cur->m_nNextThinkTick = TICK_NEVER_THINK;
cur->m_flNextThink = SCRIPT_NEVER_THINK;
continue;
}
if ( flReturn < 0.0f )
{
cur->m_nNextThinkTick = TICK_NEVER_THINK;
cur->m_flNextThink = SCRIPT_NEVER_THINK;
continue;
}
@ -2800,95 +2808,60 @@ void CBaseEntity::ScriptContextThink()
flNextThink = flReturn;
}
cur->m_nNextThinkTick = TIME_TO_TICKS( gpGlobals->curtime + flReturn );
cur->m_flNextThink = gpGlobals->curtime + flReturn - 0.001;
}
// deferred safe removal
for ( int i = 0; i < m_ScriptThinkFuncs.Count(); )
{
if ( m_ScriptThinkFuncs[i]->m_nNextThinkTick == TICK_NEVER_THINK )
scriptthinkfunc_t *cur = m_ScriptThinkFuncs[i];
if ( cur->m_flNextThink == SCRIPT_NEVER_THINK )
{
ScriptStopContextThink( m_ScriptThinkFuncs[i] );
delete m_ScriptThinkFuncs[i];
ScriptStopContextThink( cur );
delete cur;
m_ScriptThinkFuncs.Remove(i);
}
else ++i;
}
bool bNewNext = flNextThink < FLT_MAX;
#ifdef _DEBUG
#ifdef GAME_DLL
int nNextThinkTick = GetNextThinkTick("ScriptContextThink"); // -1
#else
int nNextThinkTick = GetNextThinkTick(); // 0
#endif
if ( ( nNextThinkTick <= 0 ) || ( nNextThinkTick >= nScheduledTick ) || ( nNextThinkTick == gpGlobals->tickcount ) )
if ( flNextThink < FLT_MAX )
{
#endif
if ( nScheduledTick )
if ( flScheduled > 0.0f )
{
float flScheduledTime = TICKS_TO_TIME( nScheduledTick );
if ( bNewNext )
{
flNextThink = min( gpGlobals->curtime + flNextThink, flScheduledTime );
}
else
{
flNextThink = flScheduledTime;
}
flNextThink = min( gpGlobals->curtime + flNextThink, flScheduled );
}
else
{
if ( bNewNext )
{
flNextThink = gpGlobals->curtime + flNextThink;
}
else
{
#ifdef GAME_DLL
flNextThink = TICK_NEVER_THINK;
#else
flNextThink = CLIENT_THINK_NEVER;
#endif
}
flNextThink = gpGlobals->curtime + flNextThink;
}
#ifdef _DEBUG
}
else
{
// Next think was set (from script) to a sooner tick while thinking?
Assert(0);
if ( nScheduledTick )
if ( flScheduled > 0.0f )
{
int nNextSchedule = min( nScheduledTick, nNextThinkTick );
float flNextSchedule = TICKS_TO_TIME( nNextSchedule );
if ( bNewNext )
{
flNextThink = min( gpGlobals->curtime + flNextThink, flNextSchedule );
}
else
{
flNextThink = flNextSchedule;
}
flNextThink = flScheduled;
}
else
{
float nextthink = TICKS_TO_TIME( nNextThinkTick );
if ( bNewNext )
{
flNextThink = min( gpGlobals->curtime + flNextThink, nextthink );
}
else
{
flNextThink = nextthink;
}
flNextThink = SCRIPT_NEVER_THINK;
}
}
#ifdef _DEBUG
#ifdef GAME_DLL
int nNextThinkTick = GetNextThinkTick("ScriptContextThink");
float flNextThinkTime = TICKS_TO_TIME(nNextThinkTick);
// If internal next think tick is earlier than what we have here with flNextThink,
// whoever set that think may fail. In worst case scenario the entity may stop thinking.
if ( nNextThinkTick > gpGlobals->tickcount )
{
if ( flNextThink == SCRIPT_NEVER_THINK )
Assert(0);
if ( flNextThinkTime < flNextThink )
Assert(0);
}
#endif
#endif
#ifdef GAME_DLL
@ -2898,8 +2871,10 @@ void CBaseEntity::ScriptContextThink()
#endif
}
#ifndef CLIENT_DLL
// see ScriptSetThink
static bool s_bScriptContextThinkNoParam = false;
#endif
//-----------------------------------------------------------------------------
//
@ -2917,7 +2892,7 @@ void CBaseEntity::ScriptSetContextThink( const char* szContext, HSCRIPT hFunc, f
#endif
scriptthinkfunc_t *pf = NULL;
unsigned short hash = ( szContext && *szContext ) ? HashString( szContext ) : 0;
unsigned hash = szContext ? HashString( szContext ) : 0;
FOR_EACH_VEC( m_ScriptThinkFuncs, i )
{
@ -2939,14 +2914,16 @@ void CBaseEntity::ScriptSetContextThink( const char* szContext, HSCRIPT hFunc, f
m_ScriptThinkFuncs.SetGrowSize(1);
m_ScriptThinkFuncs.AddToTail( pf );
pf->m_bNoParam = s_bScriptContextThinkNoParam;
pf->m_iContextHash = hash;
#ifndef CLIENT_DLL
pf->m_bNoParam = s_bScriptContextThinkNoParam;
#endif
}
// update existing
else
{
#ifdef _DEBUG
if ( pf->m_nNextThinkTick == 0 )
if ( pf->m_flNextThink == 0 )
{
Warning("Script think ('%s') was changed while it was thinking!\n", szContext);
}
@ -2957,31 +2934,29 @@ void CBaseEntity::ScriptSetContextThink( const char* szContext, HSCRIPT hFunc, f
float nextthink = gpGlobals->curtime + flTime;
pf->m_hfnThink = hFunc;
pf->m_nNextThinkTick = TIME_TO_TICKS( nextthink );
pf->m_flNextThink = nextthink;
#ifdef GAME_DLL
int nexttick = GetNextThinkTick( RegisterThinkContext( "ScriptContextThink" ) );
#else
int nexttick = GetNextThinkTick();
#endif
// sooner than next think
if ( nexttick <= 0 || nexttick > pf->m_nNextThinkTick )
if ( nexttick <= 0 || TICKS_TO_TIME(nexttick) > nextthink )
{
#ifdef GAME_DLL
SetContextThink( &CBaseEntity::ScriptContextThink, nextthink, "ScriptContextThink" );
#else
SetNextClientThink( nextthink );
#endif
}
#else
{
// let it self adjust
SetNextClientThink( gpGlobals->curtime );
}
#endif
}
// null func input, think exists
else if ( pf )
{
pf->m_nNextThinkTick = TICK_NEVER_THINK;
pf->m_flNextThink = SCRIPT_NEVER_THINK;
}
}
#ifndef CLIENT_DLL
//-----------------------------------------------------------------------------
// m_bNoParam and s_bScriptContextThinkNoParam exist only to keep backwards compatibility
// and are an alternative to this script closure:
@ -2991,7 +2966,6 @@ void CBaseEntity::ScriptSetContextThink( const char* szContext, HSCRIPT hFunc, f
// SetContextThink( "", function(_){ return func() }, time )
// }
//-----------------------------------------------------------------------------
#ifndef CLIENT_DLL
void CBaseEntity::ScriptSetThink( HSCRIPT hFunc, float time )
{
s_bScriptContextThinkNoParam = true;

View File

@ -30,6 +30,10 @@
#include "c_te_legacytempents.h"
#include "iefx.h"
#include "dlight.h"
#if !defined(NO_STEAM)
#include "steam/steam_api.h"
#endif
#endif
#include "vscript_singletons.h"
@ -2183,12 +2187,13 @@ public:
~CScriptConCommand()
{
Unregister();
delete m_cmd;
delete m_pBase;
}
CScriptConCommand( const char *name, HSCRIPT fn, const char *helpString, int flags )
CScriptConCommand( const char *name, HSCRIPT fn, const char *helpString, int flags, ConCommand *pLinked = NULL )
{
m_cmd = new ConCommand( name, this, helpString, flags, 0 );
m_pBase = new ConCommand( name, this, helpString, flags, 0 );
m_pLinked = pLinked;
m_hCallback = fn;
m_hCompletionCallback = NULL;
m_nCmdNameLen = V_strlen(name) + 1;
@ -2204,10 +2209,15 @@ public:
{
vArgv[i] = command[i];
}
if ( g_pScriptVM->ExecuteFunction( m_hCallback, vArgv, count, NULL, NULL, true ) == SCRIPT_ERROR )
ScriptVariant_t ret;
if ( g_pScriptVM->ExecuteFunction( m_hCallback, vArgv, count, &ret, NULL, true ) == SCRIPT_ERROR )
{
DevWarning( 1, "CScriptConCommand: invalid callback for '%s'\n", command[0] );
}
if ( m_pLinked && (ret.m_type == FIELD_BOOLEAN) && ret.m_bool )
{
m_pLinked->Dispatch( command );
}
}
int CommandCompletionCallback( const char *partial, CUtlVector< CUtlString > &commands )
@ -2262,17 +2272,17 @@ public:
if (fn)
{
if ( !m_cmd->IsRegistered() )
if ( !m_pBase->IsRegistered() )
return;
m_cmd->m_pCommandCompletionCallback = this;
m_cmd->m_bHasCompletionCallback = true;
m_pBase->m_pCommandCompletionCallback = this;
m_pBase->m_bHasCompletionCallback = true;
m_hCompletionCallback = fn;
}
else
{
m_cmd->m_pCommandCompletionCallback = NULL;
m_cmd->m_bHasCompletionCallback = false;
m_pBase->m_pCommandCompletionCallback = NULL;
m_pBase->m_bHasCompletionCallback = false;
m_hCompletionCallback = NULL;
}
}
@ -2281,7 +2291,7 @@ public:
{
if (fn)
{
if ( !m_cmd->IsRegistered() )
if ( !m_pBase->IsRegistered() )
Register();
if ( m_hCallback )
@ -2296,8 +2306,8 @@ public:
inline void Unregister()
{
if ( g_pCVar && m_cmd->IsRegistered() )
g_pCVar->UnregisterConCommand( m_cmd );
if ( g_pCVar && m_pBase->IsRegistered() )
g_pCVar->UnregisterConCommand( m_pBase );
if ( g_pScriptVM )
{
@ -2314,13 +2324,14 @@ public:
inline void Register()
{
if ( g_pCVar )
g_pCVar->RegisterConCommand( m_cmd );
g_pCVar->RegisterConCommand( m_pBase );
}
HSCRIPT m_hCallback;
HSCRIPT m_hCompletionCallback;
int m_nCmdNameLen;
ConCommand *m_cmd;
ConCommand *m_pLinked;
ConCommand *m_pBase;
};
class CScriptConVar
@ -2329,30 +2340,58 @@ public:
~CScriptConVar()
{
Unregister();
delete m_cvar;
delete m_pBase;
}
CScriptConVar( const char *pName, const char *pDefaultValue, const char *pHelpString, int flags/*, float fMin, float fMax*/ )
{
m_cvar = new ConVar( pName, pDefaultValue, flags, pHelpString );
m_pBase = new ConVar( pName, pDefaultValue, flags, pHelpString );
m_hCallback = NULL;
}
void SetChangeCallback( HSCRIPT fn )
{
void ScriptConVarCallback( IConVar*, const char*, float );
if ( m_hCallback )
g_pScriptVM->ReleaseScript( m_hCallback );
if (fn)
{
m_hCallback = fn;
m_pBase->InstallChangeCallback( (FnChangeCallback_t)ScriptConVarCallback );
}
else
{
m_hCallback = NULL;
m_pBase->InstallChangeCallback( NULL );
}
}
inline void Unregister()
{
if ( g_pCVar && m_cvar->IsRegistered() )
g_pCVar->UnregisterConCommand( m_cvar );
if ( g_pCVar && m_pBase->IsRegistered() )
g_pCVar->UnregisterConCommand( m_pBase );
if ( g_pScriptVM )
{
SetChangeCallback( NULL );
}
}
ConVar *m_cvar;
HSCRIPT m_hCallback;
ConVar *m_pBase;
};
static CUtlMap< unsigned int, bool > g_ConVarsBlocked( DefLessFunc(unsigned int) );
static CUtlMap< unsigned int, bool > g_ConCommandsOverridable( DefLessFunc(unsigned int) );
static CUtlMap< unsigned int, CScriptConCommand* > g_ScriptConCommands( DefLessFunc(unsigned int) );
static CUtlMap< unsigned int, CScriptConVar* > g_ScriptConVars( DefLessFunc(unsigned int) );
class CScriptConvarAccessor : public CAutoGameSystem
{
public:
static CUtlMap< unsigned int, bool > g_ConVarsBlocked;
static CUtlMap< unsigned int, bool > g_ConCommandsOverridable;
static CUtlMap< unsigned int, CScriptConCommand* > g_ScriptConCommands;
static CUtlMap< unsigned int, CScriptConVar* > g_ScriptConVars;
static inline unsigned int Hash( const char*sz ){ return HashStringCaseless(sz); }
public:
@ -2366,7 +2405,7 @@ public:
int idx = g_ConCommandsOverridable.Find( hash );
if ( idx == g_ConCommandsOverridable.InvalidIndex() )
return false;
return g_ConCommandsOverridable[idx];
return true;
}
inline void AddBlockedConVar( const char *name )
@ -2379,7 +2418,7 @@ public:
int idx = g_ConVarsBlocked.Find( Hash(name) );
if ( idx == g_ConVarsBlocked.InvalidIndex() )
return false;
return g_ConVarsBlocked[idx];
return true;
}
public:
@ -2387,6 +2426,7 @@ public:
void SetCompletionCallback( const char *name, HSCRIPT fn );
void UnregisterCommand( const char *name );
void RegisterConvar( const char *name, const char *pDefaultValue, const char *helpString, int flags );
void SetChangeCallback( const char *name, HSCRIPT fn );
HSCRIPT GetCommandClient()
{
@ -2495,18 +2535,14 @@ public:
} g_ScriptConvarAccessor;
CUtlMap< unsigned int, bool > CScriptConvarAccessor::g_ConVarsBlocked( DefLessFunc(unsigned int) );
CUtlMap< unsigned int, bool > CScriptConvarAccessor::g_ConCommandsOverridable( DefLessFunc(unsigned int) );
CUtlMap< unsigned int, CScriptConCommand* > CScriptConvarAccessor::g_ScriptConCommands( DefLessFunc(unsigned int) );
CUtlMap< unsigned int, CScriptConVar* > CScriptConvarAccessor::g_ScriptConVars( DefLessFunc(unsigned int) );
void CScriptConvarAccessor::RegisterCommand( const char *name, HSCRIPT fn, const char *helpString, int flags )
{
unsigned int hash = Hash(name);
int idx = g_ScriptConCommands.Find(hash);
if ( idx == g_ScriptConCommands.InvalidIndex() )
{
if ( g_pCVar->FindVar(name) || ( g_pCVar->FindCommand(name) && !IsOverridable(hash) ) )
ConCommand *pLinked = NULL;
if ( g_pCVar->FindVar(name) || ( ((pLinked = g_pCVar->FindCommand(name)) != NULL) && !IsOverridable(hash) ) )
{
DevWarning( 1, "CScriptConvarAccessor::RegisterCommand unable to register blocked ConCommand: %s\n", name );
return;
@ -2515,14 +2551,13 @@ void CScriptConvarAccessor::RegisterCommand( const char *name, HSCRIPT fn, const
if ( !fn )
return;
CScriptConCommand *p = new CScriptConCommand( name, fn, helpString, flags );
CScriptConCommand *p = new CScriptConCommand( name, fn, helpString, flags, pLinked );
g_ScriptConCommands.Insert( hash, p );
}
else
{
CScriptConCommand *pCmd = g_ScriptConCommands[idx];
pCmd->SetCallback( fn );
pCmd->m_cmd->AddFlags( flags );
//CGMsg( 1, CON_GROUP_VSCRIPT, "CScriptConvarAccessor::RegisterCommand replacing command already registered: %s\n", name );
}
}
@ -2565,11 +2600,39 @@ void CScriptConvarAccessor::RegisterConvar( const char *name, const char *pDefau
}
else
{
g_ScriptConVars[idx]->m_cvar->AddFlags( flags );
//CGMsg( 1, CON_GROUP_VSCRIPT, "CScriptConvarAccessor::RegisterConvar convar %s already registered\n", name );
}
}
void CScriptConvarAccessor::SetChangeCallback( const char *name, HSCRIPT fn )
{
unsigned int hash = Hash(name);
int idx = g_ScriptConVars.Find(hash);
if ( idx != g_ScriptConVars.InvalidIndex() )
{
g_ScriptConVars[idx]->SetChangeCallback( fn );
}
}
void ScriptConVarCallback( IConVar *var, const char* pszOldValue, float flOldValue )
{
ConVar *cvar = (ConVar*)var;
const char *name = cvar->GetName();
unsigned int hash = CScriptConvarAccessor::Hash( name );
int idx = g_ScriptConVars.Find(hash);
if ( idx != g_ScriptConVars.InvalidIndex() )
{
Assert( g_ScriptConVars[idx]->m_hCallback );
ScriptVariant_t args[5] = { name, pszOldValue, flOldValue, cvar->GetString(), cvar->GetFloat() };
if ( g_pScriptVM->ExecuteFunction( g_ScriptConVars[idx]->m_hCallback, args, 5, NULL, NULL, true ) == SCRIPT_ERROR )
{
DevWarning( 1, "CScriptConVar: invalid change callback for '%s'\n", name );
}
}
}
bool CScriptConvarAccessor::Init()
{
static bool bExecOnce = false;
@ -2622,6 +2685,8 @@ bool CScriptConvarAccessor::Init()
AddOverridable( "-voicerecord" );
AddOverridable( "toggle_duck" );
AddOverridable( "impulse" );
AddOverridable( "use" );
AddOverridable( "lastinv" );
AddOverridable( "invnext" );
AddOverridable( "invprev" );
@ -2643,6 +2708,9 @@ bool CScriptConvarAccessor::Init()
AddOverridable( "save" );
AddOverridable( "load" );
AddOverridable( "say" );
AddOverridable( "say_team" );
AddBlockedConVar( "con_enable" );
AddBlockedConVar( "cl_allowdownload" );
@ -2655,7 +2723,8 @@ bool CScriptConvarAccessor::Init()
BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptConvarAccessor, "CConvars", SCRIPT_SINGLETON "Provides an interface to convars." )
DEFINE_SCRIPTFUNC( RegisterConvar, "register a new console variable." )
DEFINE_SCRIPTFUNC( RegisterCommand, "register a console command." )
DEFINE_SCRIPTFUNC( SetCompletionCallback, "callback is called with 3 parameters (cmdname, partial, commands), user strings must be appended to 'commands' array" )
DEFINE_SCRIPTFUNC( SetCompletionCallback, "callback is called with 3 parameters (cmd, partial, commands), user strings must be appended to 'commands' array" )
DEFINE_SCRIPTFUNC( SetChangeCallback, "callback is called with 5 parameters (var, szOldValue, flOldValue, szNewValue, flNewValue)" )
DEFINE_SCRIPTFUNC( UnregisterCommand, "unregister a console command." )
DEFINE_SCRIPTFUNC( GetCommandClient, "returns the player who issued this console command." )
#ifdef GAME_DLL
@ -2692,9 +2761,6 @@ END_SCRIPTDESC();
class CEffectsScriptHelper
{
private:
C_RecipientFilter filter;
public:
void DynamicLight( int index, const Vector& origin, int r, int g, int b, int exponent,
float radius, float die, float decay, int style = 0, int flags = 0 )
@ -2715,6 +2781,7 @@ public:
void Explosion( const Vector& pos, float scale, int radius, int magnitude, int flags )
{
C_RecipientFilter filter;
filter.AddAllPlayers();
// framerate, modelindex, normal and materialtype are unused
// radius for ragdolls
@ -2824,7 +2891,150 @@ BEGIN_SCRIPTDESC_ROOT_NAMED( CEffectsScriptHelper, "CEffects", SCRIPT_SINGLETON
DEFINE_SCRIPTFUNC( Sprite, "" )
DEFINE_SCRIPTFUNC( ClientProjectile, "" )
END_SCRIPTDESC();
#endif
//=============================================================================
//=============================================================================
extern CGlowObjectManager g_GlowObjectManager;
class CScriptGlowObjectManager : public CAutoGameSystem
{
public:
CUtlVector<int> m_RegisteredObjects;
void LevelShutdownPostEntity()
{
FOR_EACH_VEC( m_RegisteredObjects, i )
g_GlowObjectManager.UnregisterGlowObject( m_RegisteredObjects[i] );
m_RegisteredObjects.Purge();
}
public:
int Register( HSCRIPT hEntity, int r, int g, int b, int a, bool bRenderWhenOccluded, bool bRenderWhenUnoccluded )
{
Vector vGlowColor;
vGlowColor.x = r * ( 1.0f / 255.0f );
vGlowColor.y = g * ( 1.0f / 255.0f );
vGlowColor.z = b * ( 1.0f / 255.0f );
float flGlowAlpha = a * ( 1.0f / 255.0f );
int idx = g_GlowObjectManager.RegisterGlowObject( ToEnt(hEntity), vGlowColor, flGlowAlpha, bRenderWhenOccluded, bRenderWhenUnoccluded, -1 );
m_RegisteredObjects.AddToTail( idx );
return idx;
}
void Unregister( int nGlowObjectHandle )
{
if ( (nGlowObjectHandle < 0) || (nGlowObjectHandle >= g_GlowObjectManager.m_GlowObjectDefinitions.Count()) )
return;
g_GlowObjectManager.UnregisterGlowObject( nGlowObjectHandle );
m_RegisteredObjects.FindAndFastRemove( nGlowObjectHandle );
}
void SetEntity( int nGlowObjectHandle, HSCRIPT hEntity )
{
g_GlowObjectManager.SetEntity( nGlowObjectHandle, ToEnt(hEntity) );
}
void SetColor( int nGlowObjectHandle, int r, int g, int b )
{
Vector vGlowColor;
vGlowColor.x = r * ( 1.0f / 255.0f );
vGlowColor.y = g * ( 1.0f / 255.0f );
vGlowColor.z = b * ( 1.0f / 255.0f );
g_GlowObjectManager.SetColor( nGlowObjectHandle, vGlowColor );
}
void SetAlpha( int nGlowObjectHandle, int a )
{
float flGlowAlpha = a * ( 1.0f / 255.0f );
g_GlowObjectManager.SetAlpha( nGlowObjectHandle, flGlowAlpha );
}
void SetRenderFlags( int nGlowObjectHandle, bool bRenderWhenOccluded, bool bRenderWhenUnoccluded )
{
g_GlowObjectManager.SetRenderFlags( nGlowObjectHandle, bRenderWhenOccluded, bRenderWhenUnoccluded );
}
} g_ScriptGlowObjectManager;
BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptGlowObjectManager, "CGlowObjectManager", SCRIPT_SINGLETON "" )
DEFINE_SCRIPTFUNC( Register, "( HSCRIPT hEntity, int r, int g, int b, int a, bool bRenderWhenOccluded, bool bRenderWhenUnoccluded )" )
DEFINE_SCRIPTFUNC( Unregister, "" )
DEFINE_SCRIPTFUNC( SetEntity, "" )
DEFINE_SCRIPTFUNC( SetColor, "" )
DEFINE_SCRIPTFUNC( SetAlpha, "" )
DEFINE_SCRIPTFUNC( SetRenderFlags, "" )
END_SCRIPTDESC();
//=============================================================================
//=============================================================================
#if !defined(NO_STEAM)
class CScriptSteamAPI
{
public:
int GetSecondsSinceComputerActive()
{
if ( !steamapicontext || !steamapicontext->SteamUtils() )
return 0;
return steamapicontext->SteamUtils()->GetSecondsSinceComputerActive();
}
int GetCurrentBatteryPower()
{
if ( !steamapicontext || !steamapicontext->SteamUtils() )
return 0;
return steamapicontext->SteamUtils()->GetCurrentBatteryPower();
}
const char *GetIPCountry()
{
if ( !steamapicontext || !steamapicontext->SteamUtils() )
return NULL;
const char *get = steamapicontext->SteamUtils()->GetIPCountry();
if ( !get )
return NULL;
static char ret[3];
V_strncpy( ret, get, 3 );
return ret;
}
const char *GetCurrentGameLanguage()
{
if ( !steamapicontext || !steamapicontext->SteamApps() )
return NULL;
const char *lang = steamapicontext->SteamApps()->GetCurrentGameLanguage();
if ( !lang )
return NULL;
static char ret[16];
V_strncpy( ret, lang, sizeof(ret) );
return ret;
}
} g_ScriptSteamAPI;
BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptSteamAPI, "CSteamAPI", SCRIPT_SINGLETON "" )
//DEFINE_SCRIPTFUNC( IsVACBanned, "" )
DEFINE_SCRIPTFUNC( GetSecondsSinceComputerActive, "Returns the number of seconds since the user last moved the mouse." )
DEFINE_SCRIPTFUNC( GetCurrentBatteryPower, "Return the amount of battery power left in the current system in % [0..100], 255 for being on AC power" )
//DEFINE_SCRIPTFUNC( GetIPCountry, "Returns the 2 digit ISO 3166-1-alpha-2 format country code this client is running in (as looked up via an IP-to-location database)" )
DEFINE_SCRIPTFUNC( GetCurrentGameLanguage, "Gets the current language that the user has set as API language code. This falls back to the Steam UI language if the user hasn't explicitly picked a language for the title." )
END_SCRIPTDESC();
#endif // !NO_STEAM
#endif // CLIENT_DLL
void RegisterScriptSingletons()
@ -2852,6 +3062,11 @@ void RegisterScriptSingletons()
g_pScriptVM->RegisterInstance( &g_ScriptConvarAccessor, "Convars" );
#ifdef CLIENT_DLL
g_pScriptVM->RegisterInstance( &g_ScriptEffectsHelper, "effects" );
g_pScriptVM->RegisterInstance( &g_ScriptGlowObjectManager, "GlowObjectManager" );
#if !defined(NO_STEAM)
g_pScriptVM->RegisterInstance( &g_ScriptSteamAPI, "steam" );
#endif
#endif
// Singletons not unique to VScript (not declared or defined here)

View File

@ -688,7 +688,10 @@ ConVar::~ConVar( void )
//-----------------------------------------------------------------------------
void ConVar::InstallChangeCallback( FnChangeCallback_t callback )
{
#ifndef MAPBASE_VSCRIPT
Assert( !m_pParent->m_fnChangeCallback || !callback );
#endif
m_pParent->m_fnChangeCallback = callback;
if ( m_pParent->m_fnChangeCallback )