mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2024-12-27 07:15:31 +03:00
Merge pull request #80 from samisalreadytaken/_23
vscript additions and fixes 2
This commit is contained in:
commit
e55bfa0036
@ -492,14 +492,14 @@ C_BasePlayer::~C_BasePlayer()
|
||||
if ( this == s_pLocalPlayer )
|
||||
{
|
||||
s_pLocalPlayer = NULL;
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
if ( IsLocalPlayer() && g_pScriptVM )
|
||||
{
|
||||
g_pScriptVM->SetValue( "player", SCRIPT_VARIANT_NULL );
|
||||
}
|
||||
if ( g_pScriptVM )
|
||||
{
|
||||
g_pScriptVM->SetValue( "player", SCRIPT_VARIANT_NULL );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
delete m_pFlashlight;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "proxyentity.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#include "mapbase/vscript_singletons.h"
|
||||
#endif
|
||||
|
||||
extern IScriptManager *scriptmanager;
|
||||
@ -46,6 +47,11 @@ extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * );
|
||||
class CScriptClientEntityIterator
|
||||
{
|
||||
public:
|
||||
HSCRIPT GetLocalPlayer()
|
||||
{
|
||||
return ToHScript( C_BasePlayer::GetLocalPlayer() );
|
||||
}
|
||||
|
||||
HSCRIPT First() { return Next(NULL); }
|
||||
|
||||
HSCRIPT Next( HSCRIPT hStartEntity )
|
||||
@ -94,6 +100,7 @@ private:
|
||||
} g_ScriptEntityIterator;
|
||||
|
||||
BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptClientEntityIterator, "CEntities", SCRIPT_SINGLETON "The global list of entities" )
|
||||
DEFINE_SCRIPTFUNC( GetLocalPlayer, "Get local player" )
|
||||
DEFINE_SCRIPTFUNC( First, "Begin an iteration over the list of entities" )
|
||||
DEFINE_SCRIPTFUNC( Next, "Continue an iteration over the list of entities, providing reference to a previously found entity" )
|
||||
DEFINE_SCRIPTFUNC( CreateByClassname, "Creates an entity by classname" )
|
||||
@ -399,7 +406,7 @@ void CScriptMaterialProxy::SetVarVector( int i, const Vector &value )
|
||||
}
|
||||
|
||||
EXPOSE_INTERFACE( CScriptMaterialProxy, IMaterialProxy, "VScriptProxy" IMATERIAL_PROXY_INTERFACE_VERSION );
|
||||
#endif
|
||||
#endif // MAPBASE_VSCRIPT
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
@ -431,6 +438,39 @@ bool DoIncludeScript( const char *pszScript, HSCRIPT hScope )
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
static bool Con_IsVisible()
|
||||
{
|
||||
return engine->Con_IsVisible();
|
||||
}
|
||||
|
||||
static bool IsWindowedMode()
|
||||
{
|
||||
return engine->IsWindowedMode();
|
||||
}
|
||||
|
||||
int ScreenTransform( const Vector& point, Vector& screen );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Input array [x,y], set normalised screen space pos. Return true if on screen
|
||||
//-----------------------------------------------------------------------------
|
||||
static bool ScriptScreenTransform( const Vector &pos, HSCRIPT hArray )
|
||||
{
|
||||
if ( g_pScriptVM->GetNumTableEntries(hArray) >= 2 )
|
||||
{
|
||||
Vector v;
|
||||
bool r = ScreenTransform( pos, v );
|
||||
float x = 0.5f * ( 1.0f + v[0] );
|
||||
float y = 0.5f * ( 1.0f - v[1] );
|
||||
|
||||
g_pScriptVM->SetValue( hArray, ScriptVariant_t(0), x );
|
||||
g_pScriptVM->SetValue( hArray, 1, y );
|
||||
return !r;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool VScriptClientInit()
|
||||
{
|
||||
VMPROF_START
|
||||
@ -487,14 +527,30 @@ bool VScriptClientInit()
|
||||
if( g_pScriptVM )
|
||||
{
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
// Moved here from LevelInitPostEntity, which is executed before local player is spawned.
|
||||
// This is executed after C_World::OnDataChanged, which is after C_BasePlayer::Spawn
|
||||
if ( C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer() )
|
||||
{
|
||||
g_pScriptVM->SetValue( "player", pPlayer->GetScriptInstance() );
|
||||
}
|
||||
|
||||
CGMsg( 0, CON_GROUP_VSCRIPT, "VSCRIPT CLIENT: Started VScript virtual machine using script language '%s'\n", g_pScriptVM->GetLanguageName() );
|
||||
#else
|
||||
Log( "VSCRIPT: Started VScript virtual machine using script language '%s'\n", g_pScriptVM->GetLanguageName() );
|
||||
#endif
|
||||
ScriptRegisterFunction( g_pScriptVM, GetMapName, "Get the name of the map.");
|
||||
ScriptRegisterFunction( g_pScriptVM, Time, "Get the current server time" );
|
||||
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." ) );
|
||||
ScriptRegisterFunction( g_pScriptVM, DoIncludeScript, "Execute a script (internal)" );
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
ScriptRegisterFunction( g_pScriptVM, Con_IsVisible, "Returns true if the console is visible" );
|
||||
ScriptRegisterFunction( g_pScriptVM, ScreenWidth, "Width of the screen in pixels" );
|
||||
ScriptRegisterFunction( g_pScriptVM, ScreenHeight, "Height of the screen in pixels" );
|
||||
ScriptRegisterFunction( g_pScriptVM, IsWindowedMode, "" );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptScreenTransform, "ScreenTransform", "Get the x & y positions of a world position in screen space. Returns true if it's onscreen" );
|
||||
#endif
|
||||
|
||||
|
||||
if ( GameRules() )
|
||||
{
|
||||
GameRules()->RegisterScriptFunctions();
|
||||
@ -519,6 +575,7 @@ bool VScriptClientInit()
|
||||
g_pScriptVM->Run( g_Script_vscript_client );
|
||||
}
|
||||
|
||||
VScriptRunScript( "vscript_client", true );
|
||||
VScriptRunScript( "mapspawn", false );
|
||||
|
||||
VMPROF_SHOW( pszScriptLanguage, "virtual machine startup" );
|
||||
@ -579,20 +636,13 @@ public:
|
||||
virtual void LevelInitPostEntity( void )
|
||||
{
|
||||
m_bAllowEntityCreationInScripts = false;
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
if (g_pScriptVM)
|
||||
{
|
||||
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
if (pPlayer)
|
||||
{
|
||||
g_pScriptVM->SetValue( "player", pPlayer->GetScriptInstance() );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual void LevelShutdownPostEntity( void )
|
||||
{
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
g_ScriptNetMsg->LevelShutdownPreVM();
|
||||
#endif
|
||||
VScriptClientTerm();
|
||||
}
|
||||
|
||||
|
@ -2190,7 +2190,7 @@ BEGIN_DATADESC_NO_BASE( CBaseEntity )
|
||||
DEFINE_THINKFUNC( ShadowCastDistThink ),
|
||||
DEFINE_THINKFUNC( ScriptThink ),
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DEFINE_THINKFUNC( ScriptThinkH ),
|
||||
DEFINE_THINKFUNC( ScriptContextThink ),
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE
|
||||
@ -2442,6 +2442,7 @@ BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities"
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetThinkFunction, "SetThinkFunction", "" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptStopThinkFunction, "StopThinkFunction", "" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetContextThink, "SetContextThink", "Set a think function on this entity." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetThink, "SetThink", "" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptStopThink, "StopThink", "" )
|
||||
|
||||
@ -2590,11 +2591,12 @@ void CBaseEntity::UpdateOnRemove( void )
|
||||
m_hScriptInstance = NULL;
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
if ( m_hfnThink )
|
||||
FOR_EACH_VEC( m_ScriptThinkFuncs, i )
|
||||
{
|
||||
g_pScriptVM->ReleaseScript( m_hfnThink );
|
||||
m_hfnThink = NULL;
|
||||
HSCRIPT h = m_ScriptThinkFuncs[i].m_hfnThink;
|
||||
if ( h ) g_pScriptVM->ReleaseScript( h );
|
||||
}
|
||||
m_ScriptThinkFuncs.Purge();
|
||||
#endif // MAPBASE_VSCRIPT
|
||||
}
|
||||
}
|
||||
@ -8653,60 +8655,172 @@ void CBaseEntity::ScriptStopThinkFunction()
|
||||
SetContextThink( NULL, TICK_NEVER_THINK, "ScriptThink" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseEntity::ScriptThinkH()
|
||||
|
||||
static inline void ScriptStopContextThink( scriptthinkfunc_t *context )
|
||||
{
|
||||
ScriptVariant_t varThinkRetVal;
|
||||
if ( g_pScriptVM->ExecuteFunction(m_hfnThink, NULL, 0, &varThinkRetVal, NULL, true) == SCRIPT_ERROR )
|
||||
{
|
||||
DevWarning("%s FAILED to call script think function (invalid closure)!\n", GetDebugName());
|
||||
ScriptStopThink();
|
||||
return;
|
||||
}
|
||||
|
||||
float flThinkFrequency = 0.f;
|
||||
if ( !varThinkRetVal.AssignTo(&flThinkFrequency) )
|
||||
{
|
||||
// no return value stops thinking
|
||||
ScriptStopThink();
|
||||
return;
|
||||
}
|
||||
|
||||
SetNextThink( gpGlobals->curtime + flThinkFrequency, "ScriptThinkH" );
|
||||
g_pScriptVM->ReleaseScript( context->m_hfnThink );
|
||||
context->m_hfnThink = NULL;
|
||||
context->m_nNextThinkTick = TICK_NEVER_THINK;
|
||||
}
|
||||
|
||||
void CBaseEntity::ScriptSetThink( HSCRIPT hFunc, float flTime )
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseEntity::ScriptContextThink()
|
||||
{
|
||||
if ( hFunc )
|
||||
float flNextThink = FLT_MAX;
|
||||
int nScheduledTick = 0;
|
||||
|
||||
for ( int i = m_ScriptThinkFuncs.Count(); i--; )
|
||||
{
|
||||
if ( m_hfnThink )
|
||||
scriptthinkfunc_t *cur = &m_ScriptThinkFuncs[i];
|
||||
|
||||
if ( cur->m_nNextThinkTick == TICK_NEVER_THINK )
|
||||
continue;
|
||||
|
||||
if ( cur->m_nNextThinkTick > gpGlobals->tickcount )
|
||||
{
|
||||
// release old func
|
||||
ScriptStopThink();
|
||||
// There is more to execute, don't stop thinking if the rest are done.
|
||||
|
||||
// also find the shortest schedule
|
||||
if ( !nScheduledTick || nScheduledTick > cur->m_nNextThinkTick )
|
||||
{
|
||||
nScheduledTick = cur->m_nNextThinkTick;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// no type check here, print error on call instead
|
||||
m_hfnThink = hFunc;
|
||||
ScriptVariant_t varReturn;
|
||||
|
||||
flTime = max( 0, flTime );
|
||||
SetContextThink( &CBaseEntity::ScriptThinkH, gpGlobals->curtime + flTime, "ScriptThinkH" );
|
||||
if ( cur->m_bNoParam )
|
||||
{
|
||||
if ( g_pScriptVM->Call( cur->m_hfnThink, NULL, true, &varReturn ) == SCRIPT_ERROR )
|
||||
{
|
||||
ScriptStopContextThink(cur);
|
||||
m_ScriptThinkFuncs.Remove(i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( g_pScriptVM->Call( cur->m_hfnThink, NULL, true, &varReturn, m_hScriptInstance ) == SCRIPT_ERROR )
|
||||
{
|
||||
ScriptStopContextThink(cur);
|
||||
m_ScriptThinkFuncs.Remove(i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
float flReturn;
|
||||
if ( !varReturn.AssignTo( &flReturn ) )
|
||||
{
|
||||
ScriptStopContextThink(cur);
|
||||
m_ScriptThinkFuncs.Remove(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( flReturn < 0.0f )
|
||||
{
|
||||
ScriptStopContextThink(cur);
|
||||
m_ScriptThinkFuncs.Remove(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
// find the shortest delay
|
||||
if ( flReturn < flNextThink )
|
||||
{
|
||||
flNextThink = flReturn;
|
||||
}
|
||||
|
||||
cur->m_nNextThinkTick = TIME_TO_TICKS( gpGlobals->curtime + flReturn );
|
||||
}
|
||||
|
||||
if ( flNextThink < FLT_MAX )
|
||||
{
|
||||
SetNextThink( gpGlobals->curtime + flNextThink, "ScriptContextThink" );
|
||||
}
|
||||
else if ( nScheduledTick )
|
||||
{
|
||||
SetNextThink( TICKS_TO_TIME( nScheduledTick ), "ScriptContextThink" );
|
||||
}
|
||||
else
|
||||
{
|
||||
ScriptStopThink();
|
||||
SetNextThink( TICK_NEVER_THINK, "ScriptContextThink" );
|
||||
}
|
||||
}
|
||||
|
||||
// see ScriptSetThink
|
||||
static bool s_bScriptContextThinkNoParam = false;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseEntity::ScriptSetContextThink( const char* szContext, HSCRIPT hFunc, float flTime )
|
||||
{
|
||||
scriptthinkfunc_t th;
|
||||
V_memset( &th, 0x0, sizeof(scriptthinkfunc_t) );
|
||||
unsigned short hash = ( szContext && *szContext ) ? HashString( szContext ) : 0;
|
||||
bool bFound = false;
|
||||
|
||||
FOR_EACH_VEC( m_ScriptThinkFuncs, i )
|
||||
{
|
||||
scriptthinkfunc_t f = m_ScriptThinkFuncs[i];
|
||||
if ( hash == f.m_iContextHash )
|
||||
{
|
||||
th = f;
|
||||
m_ScriptThinkFuncs.Remove(i); // reorder
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( hFunc )
|
||||
{
|
||||
float nextthink = gpGlobals->curtime + flTime;
|
||||
|
||||
th.m_bNoParam = s_bScriptContextThinkNoParam;
|
||||
th.m_hfnThink = hFunc;
|
||||
th.m_iContextHash = hash;
|
||||
th.m_nNextThinkTick = TIME_TO_TICKS( nextthink );
|
||||
|
||||
m_ScriptThinkFuncs.AddToHead( th );
|
||||
|
||||
int nexttick = GetNextThinkTick( RegisterThinkContext( "ScriptContextThink" ) );
|
||||
|
||||
// sooner than next think
|
||||
if ( nexttick <= 0 || nexttick > th.m_nNextThinkTick )
|
||||
{
|
||||
SetContextThink( &CBaseEntity::ScriptContextThink, nextthink, "ScriptContextThink" );
|
||||
}
|
||||
}
|
||||
// null func input, think exists
|
||||
else if ( bFound )
|
||||
{
|
||||
ScriptStopContextThink( &th );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// m_bNoParam and s_bScriptContextThinkNoParam exist only to keep backwards compatibility
|
||||
// and are an alternative to this script closure:
|
||||
//
|
||||
// function CBaseEntity::SetThink( func, time )
|
||||
// {
|
||||
// SetContextThink( "", function(_){ return func() }, time )
|
||||
// }
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseEntity::ScriptSetThink( HSCRIPT hFunc, float time )
|
||||
{
|
||||
s_bScriptContextThinkNoParam = true;
|
||||
ScriptSetContextThink( NULL, hFunc, time );
|
||||
s_bScriptContextThinkNoParam = false;
|
||||
}
|
||||
|
||||
void CBaseEntity::ScriptStopThink()
|
||||
{
|
||||
if (m_hfnThink)
|
||||
{
|
||||
g_pScriptVM->ReleaseScript(m_hfnThink);
|
||||
m_hfnThink = NULL;
|
||||
}
|
||||
SetContextThink( NULL, TICK_NEVER_THINK, "ScriptThinkH" );
|
||||
ScriptSetContextThink( NULL, NULL, 0.0f );
|
||||
}
|
||||
|
||||
#endif // MAPBASE_VSCRIPT
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -338,6 +338,16 @@ struct thinkfunc_t
|
||||
DECLARE_SIMPLE_DATADESC();
|
||||
};
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
struct scriptthinkfunc_t
|
||||
{
|
||||
HSCRIPT m_hfnThink;
|
||||
unsigned short m_iContextHash;
|
||||
int m_nNextThinkTick;
|
||||
bool m_bNoParam;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct EmitSound_t;
|
||||
struct rotatingpushmove_t;
|
||||
|
||||
@ -1988,11 +1998,12 @@ public:
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
void ScriptSetThinkFunction(const char *szFunc, float time);
|
||||
void ScriptStopThinkFunction();
|
||||
void ScriptSetThink(HSCRIPT hFunc, float time);
|
||||
void ScriptSetContextThink( const char* szContext, HSCRIPT hFunc, float time );
|
||||
void ScriptSetThink( HSCRIPT hFunc, float time );
|
||||
void ScriptStopThink();
|
||||
void ScriptThinkH();
|
||||
void ScriptContextThink();
|
||||
private:
|
||||
HSCRIPT m_hfnThink;
|
||||
CUtlVector< scriptthinkfunc_t > m_ScriptThinkFuncs;
|
||||
public:
|
||||
#endif
|
||||
const char* GetScriptId();
|
||||
|
@ -906,7 +906,7 @@ CEventQueue::AddEvent( CBaseEntity *target, const char *targetInput, variant_t V
|
||||
AddEvent( newEvent );
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
return reinterpret_cast<intptr_t>(newEvent);
|
||||
return reinterpret_cast<intptr_t>(newEvent); // POINTER_TO_INT
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1257,7 +1257,10 @@ void ServiceEventQueue( void )
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
//-----------------------------------------------------------------------------
|
||||
// Remove events on entity by input.
|
||||
// Remove pending events on entity by input.
|
||||
//
|
||||
// Also removes events that were targeted with their debug name (classname when unnamed).
|
||||
// E.g. CancelEventsByInput( pRelay, "Trigger" ) removes all pending logic_relay "Trigger" events.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEventQueue::CancelEventsByInput( CBaseEntity *pTarget, const char *szInput )
|
||||
{
|
||||
@ -1292,9 +1295,6 @@ void CEventQueue::CancelEventsByInput( CBaseEntity *pTarget, const char *szInput
|
||||
|
||||
bool CEventQueue::RemoveEvent( intptr_t event )
|
||||
{
|
||||
if ( !event )
|
||||
return false;
|
||||
|
||||
EventQueuePrioritizedEvent_t *pe = reinterpret_cast<EventQueuePrioritizedEvent_t*>(event); // INT_TO_POINTER
|
||||
|
||||
for ( EventQueuePrioritizedEvent_t *pCur = m_Events.m_pNext; pCur; pCur = pCur->m_pNext )
|
||||
@ -1312,9 +1312,6 @@ bool CEventQueue::RemoveEvent( intptr_t event )
|
||||
|
||||
float CEventQueue::GetTimeLeft( intptr_t event )
|
||||
{
|
||||
if ( !event )
|
||||
return 0.f;
|
||||
|
||||
EventQueuePrioritizedEvent_t *pe = reinterpret_cast<EventQueuePrioritizedEvent_t*>(event); // INT_TO_POINTER
|
||||
|
||||
for ( EventQueuePrioritizedEvent_t *pCur = m_Events.m_pNext; pCur; pCur = pCur->m_pNext )
|
||||
|
@ -3196,7 +3196,11 @@ float CServerGameClients::ProcessUsercmds( edict_t *player, bf_read *buf, int nu
|
||||
for ( i = totalcmds - 1; i >= 0; i-- )
|
||||
{
|
||||
to = &cmds[ i ];
|
||||
#if defined( MAPBASE_VSCRIPT )
|
||||
ReadUsercmd( buf, to, from, pPlayer ); // Tell whose UserCmd it is
|
||||
#else
|
||||
ReadUsercmd( buf, to, from );
|
||||
#endif
|
||||
from = to;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "vscript_server.nut"
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
#include "world.h"
|
||||
#include "mapbase/vscript_singletons.h"
|
||||
#endif
|
||||
|
||||
extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * );
|
||||
@ -246,451 +247,6 @@ CScriptKeyValues::~CScriptKeyValues( )
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
#define RETURN_IF_CANNOT_DRAW_OVERLAY\
|
||||
if (engine->IsPaused())\
|
||||
{\
|
||||
CGWarning( 1, CON_GROUP_VSCRIPT, "debugoverlay: cannot draw while the game is paused!\n");\
|
||||
return;\
|
||||
}
|
||||
class CDebugOverlayScriptHelper
|
||||
{
|
||||
public:
|
||||
|
||||
void Box(const Vector &origin, const Vector &mins, const Vector &maxs, int r, int g, int b, int a, float flDuration)
|
||||
{
|
||||
RETURN_IF_CANNOT_DRAW_OVERLAY
|
||||
|
||||
if (debugoverlay)
|
||||
{
|
||||
debugoverlay->AddBoxOverlay(origin, mins, maxs, vec3_angle, r, g, b, a, flDuration);
|
||||
}
|
||||
}
|
||||
void BoxDirection(const Vector &origin, const Vector &mins, const Vector &maxs, const Vector &forward, int r, int g, int b, int a, float flDuration)
|
||||
{
|
||||
RETURN_IF_CANNOT_DRAW_OVERLAY
|
||||
|
||||
QAngle f_angles = vec3_angle;
|
||||
f_angles.y = UTIL_VecToYaw(forward);
|
||||
|
||||
if (debugoverlay)
|
||||
{
|
||||
debugoverlay->AddBoxOverlay(origin, mins, maxs, f_angles, r, g, b, a, flDuration);
|
||||
}
|
||||
}
|
||||
void BoxAngles(const Vector &origin, const Vector &mins, const Vector &maxs, const QAngle &angles, int r, int g, int b, int a, float flDuration)
|
||||
{
|
||||
RETURN_IF_CANNOT_DRAW_OVERLAY
|
||||
|
||||
if (debugoverlay)
|
||||
{
|
||||
debugoverlay->AddBoxOverlay(origin, mins, maxs, angles, r, g, b, a, flDuration);
|
||||
}
|
||||
}
|
||||
void SweptBox(const Vector& start, const Vector& end, const Vector& mins, const Vector& maxs, const QAngle & angles, int r, int g, int b, int a, float flDuration)
|
||||
{
|
||||
RETURN_IF_CANNOT_DRAW_OVERLAY
|
||||
|
||||
if (debugoverlay)
|
||||
{
|
||||
debugoverlay->AddSweptBoxOverlay(start, end, mins, maxs, angles, r, g, b, a, flDuration);
|
||||
}
|
||||
}
|
||||
void EntityBounds(HSCRIPT pEntity, int r, int g, int b, int a, float flDuration)
|
||||
{
|
||||
RETURN_IF_CANNOT_DRAW_OVERLAY
|
||||
|
||||
CBaseEntity *pEnt = ToEnt(pEntity);
|
||||
if (!pEnt)
|
||||
return;
|
||||
|
||||
const CCollisionProperty *pCollide = pEnt->CollisionProp();
|
||||
if (debugoverlay)
|
||||
{
|
||||
debugoverlay->AddBoxOverlay(pCollide->GetCollisionOrigin(), pCollide->OBBMins(), pCollide->OBBMaxs(), pCollide->GetCollisionAngles(), r, g, b, a, flDuration);
|
||||
}
|
||||
}
|
||||
void Line(const Vector &origin, const Vector &target, int r, int g, int b, bool noDepthTest, float flDuration)
|
||||
{
|
||||
RETURN_IF_CANNOT_DRAW_OVERLAY
|
||||
|
||||
if (debugoverlay)
|
||||
{
|
||||
debugoverlay->AddLineOverlay(origin, target, r, g, b, noDepthTest, flDuration);
|
||||
}
|
||||
}
|
||||
void Triangle(const Vector &p1, const Vector &p2, const Vector &p3, int r, int g, int b, int a, bool noDepthTest, float duration)
|
||||
{
|
||||
RETURN_IF_CANNOT_DRAW_OVERLAY
|
||||
|
||||
if (debugoverlay)
|
||||
{
|
||||
debugoverlay->AddTriangleOverlay(p1, p2, p3, r, g, b, a, noDepthTest, duration);
|
||||
}
|
||||
}
|
||||
void EntityText(int entityID, int text_offset, const char *text, float flDuration, int r, int g, int b, int a)
|
||||
{
|
||||
RETURN_IF_CANNOT_DRAW_OVERLAY
|
||||
|
||||
if (debugoverlay)
|
||||
{
|
||||
debugoverlay->AddEntityTextOverlay(entityID, text_offset, flDuration,
|
||||
(int)clamp(r * 255.f, 0.f, 255.f), (int)clamp(g * 255.f, 0.f, 255.f), (int)clamp(b * 255.f, 0.f, 255.f),
|
||||
(int)clamp(a * 255.f, 0.f, 255.f), text);
|
||||
}
|
||||
}
|
||||
void EntityTextAtPosition(const Vector &origin, int text_offset, const char *text, float flDuration, int r, int g, int b, int a)
|
||||
{
|
||||
RETURN_IF_CANNOT_DRAW_OVERLAY
|
||||
|
||||
if (debugoverlay)
|
||||
{
|
||||
debugoverlay->AddTextOverlayRGB(origin, text_offset, flDuration, r, g, b, a, "%s", text);
|
||||
}
|
||||
}
|
||||
void Grid(const Vector &vPosition)
|
||||
{
|
||||
RETURN_IF_CANNOT_DRAW_OVERLAY
|
||||
|
||||
if (debugoverlay)
|
||||
{
|
||||
debugoverlay->AddGridOverlay(vPosition);
|
||||
}
|
||||
}
|
||||
void Text(const Vector &origin, const char *text, float flDuration)
|
||||
{
|
||||
RETURN_IF_CANNOT_DRAW_OVERLAY
|
||||
|
||||
if (debugoverlay)
|
||||
{
|
||||
debugoverlay->AddTextOverlay(origin, flDuration, "%s", text);
|
||||
}
|
||||
}
|
||||
void ScreenText(float fXpos, float fYpos, const char *text, int r, int g, int b, int a, float flDuration)
|
||||
{
|
||||
RETURN_IF_CANNOT_DRAW_OVERLAY
|
||||
|
||||
if (debugoverlay)
|
||||
{
|
||||
debugoverlay->AddScreenTextOverlay(fXpos, fYpos, flDuration, r, g, b, a, text);
|
||||
}
|
||||
}
|
||||
void Cross3D(const Vector &position, float size, int r, int g, int b, bool noDepthTest, float flDuration)
|
||||
{
|
||||
RETURN_IF_CANNOT_DRAW_OVERLAY
|
||||
|
||||
Line( position + Vector(size,0,0), position - Vector(size,0,0), r, g, b, noDepthTest, flDuration );
|
||||
Line( position + Vector(0,size,0), position - Vector(0,size,0), r, g, b, noDepthTest, flDuration );
|
||||
Line( position + Vector(0,0,size), position - Vector(0,0,size), r, g, b, noDepthTest, flDuration );
|
||||
}
|
||||
void Cross3DOriented(const Vector &position, const QAngle &angles, float size, int r, int g, int b, bool noDepthTest, float flDuration)
|
||||
{
|
||||
RETURN_IF_CANNOT_DRAW_OVERLAY
|
||||
|
||||
Vector forward, right, up;
|
||||
AngleVectors( angles, &forward, &right, &up );
|
||||
|
||||
forward *= size;
|
||||
right *= size;
|
||||
up *= size;
|
||||
|
||||
Line( position + right, position - right, r, g, b, noDepthTest, flDuration );
|
||||
Line( position + forward, position - forward, r, g, b, noDepthTest, flDuration );
|
||||
Line( position + up, position - up, r, g, b, noDepthTest, flDuration );
|
||||
}
|
||||
void DrawTickMarkedLine(const Vector &startPos, const Vector &endPos, float tickDist, int tickTextDist, int r, int g, int b, bool noDepthTest, float flDuration)
|
||||
{
|
||||
RETURN_IF_CANNOT_DRAW_OVERLAY
|
||||
|
||||
Vector lineDir = (endPos - startPos);
|
||||
float lineDist = VectorNormalize(lineDir);
|
||||
int numTicks = lineDist / tickDist;
|
||||
|
||||
Vector upVec = Vector(0,0,4);
|
||||
Vector sideDir;
|
||||
Vector tickPos = startPos;
|
||||
int tickTextCnt = 0;
|
||||
|
||||
CrossProduct(lineDir, upVec, sideDir);
|
||||
|
||||
Line(startPos, endPos, r, g, b, noDepthTest, flDuration);
|
||||
|
||||
for (int i = 0; i<numTicks + 1; i++)
|
||||
{
|
||||
Vector tickLeft = tickPos - sideDir;
|
||||
Vector tickRight = tickPos + sideDir;
|
||||
|
||||
if (tickTextCnt == tickTextDist)
|
||||
{
|
||||
char text[25];
|
||||
Q_snprintf(text, sizeof(text), "%i", i);
|
||||
Vector textPos = tickLeft + Vector(0, 0, 8);
|
||||
Line(tickLeft, tickRight, 255, 255, 255, noDepthTest, flDuration);
|
||||
Text(textPos, text, flDuration);
|
||||
tickTextCnt = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Line(tickLeft, tickRight, r, g, b, noDepthTest, flDuration);
|
||||
}
|
||||
|
||||
tickTextCnt++;
|
||||
|
||||
tickPos = tickPos + (tickDist * lineDir);
|
||||
}
|
||||
}
|
||||
void HorzArrow(const Vector &startPos, const Vector &endPos, float width, int r, int g, int b, int a, bool noDepthTest, float flDuration)
|
||||
{
|
||||
RETURN_IF_CANNOT_DRAW_OVERLAY
|
||||
|
||||
Vector lineDir = (endPos - startPos);
|
||||
VectorNormalize( lineDir );
|
||||
Vector upVec = Vector( 0, 0, 1 );
|
||||
Vector sideDir;
|
||||
float radius = width / 2.0;
|
||||
|
||||
CrossProduct(lineDir, upVec, sideDir);
|
||||
|
||||
Vector p1 = startPos - sideDir * radius;
|
||||
Vector p2 = endPos - lineDir * width - sideDir * radius;
|
||||
Vector p3 = endPos - lineDir * width - sideDir * width;
|
||||
Vector p4 = endPos;
|
||||
Vector p5 = endPos - lineDir * width + sideDir * width;
|
||||
Vector p6 = endPos - lineDir * width + sideDir * radius;
|
||||
Vector p7 = startPos + sideDir * radius;
|
||||
|
||||
Line(p1, p2, r,g,b,noDepthTest,flDuration);
|
||||
Line(p2, p3, r,g,b,noDepthTest,flDuration);
|
||||
Line(p3, p4, r,g,b,noDepthTest,flDuration);
|
||||
Line(p4, p5, r,g,b,noDepthTest,flDuration);
|
||||
Line(p5, p6, r,g,b,noDepthTest,flDuration);
|
||||
Line(p6, p7, r,g,b,noDepthTest,flDuration);
|
||||
|
||||
if ( a > 0 )
|
||||
{
|
||||
Triangle( p5, p4, p3, r, g, b, a, noDepthTest, flDuration );
|
||||
Triangle( p1, p7, p6, r, g, b, a, noDepthTest, flDuration );
|
||||
Triangle( p6, p2, p1, r, g, b, a, noDepthTest, flDuration );
|
||||
|
||||
Triangle( p3, p4, p5, r, g, b, a, noDepthTest, flDuration );
|
||||
Triangle( p6, p7, p1, r, g, b, a, noDepthTest, flDuration );
|
||||
Triangle( p1, p2, p6, r, g, b, a, noDepthTest, flDuration );
|
||||
}
|
||||
}
|
||||
void YawArrow(const Vector &startPos, float yaw, float length, float width, int r, int g, int b, int a, bool noDepthTest, float flDuration)
|
||||
{
|
||||
RETURN_IF_CANNOT_DRAW_OVERLAY
|
||||
|
||||
Vector forward = UTIL_YawToVector( yaw );
|
||||
HorzArrow( startPos, startPos + forward * length, width, r, g, b, a, noDepthTest, flDuration );
|
||||
}
|
||||
void VertArrow(const Vector &startPos, const Vector &endPos, float width, int r, int g, int b, int a, bool noDepthTest, float flDuration)
|
||||
{
|
||||
RETURN_IF_CANNOT_DRAW_OVERLAY
|
||||
|
||||
Vector lineDir = (endPos - startPos);
|
||||
VectorNormalize( lineDir );
|
||||
Vector upVec;
|
||||
Vector sideDir;
|
||||
float radius = width / 2.0;
|
||||
|
||||
VectorVectors( lineDir, sideDir, upVec );
|
||||
|
||||
Vector p1 = startPos - upVec * radius;
|
||||
Vector p2 = endPos - lineDir * width - upVec * radius;
|
||||
Vector p3 = endPos - lineDir * width - upVec * width;
|
||||
Vector p4 = endPos;
|
||||
Vector p5 = endPos - lineDir * width + upVec * width;
|
||||
Vector p6 = endPos - lineDir * width + upVec * radius;
|
||||
Vector p7 = startPos + upVec * radius;
|
||||
|
||||
Line(p1, p2, r,g,b,noDepthTest,flDuration);
|
||||
Line(p2, p3, r,g,b,noDepthTest,flDuration);
|
||||
Line(p3, p4, r,g,b,noDepthTest,flDuration);
|
||||
Line(p4, p5, r,g,b,noDepthTest,flDuration);
|
||||
Line(p5, p6, r,g,b,noDepthTest,flDuration);
|
||||
Line(p6, p7, r,g,b,noDepthTest,flDuration);
|
||||
|
||||
if ( a > 0 )
|
||||
{
|
||||
Triangle( p5, p4, p3, r, g, b, a, noDepthTest, flDuration );
|
||||
Triangle( p1, p7, p6, r, g, b, a, noDepthTest, flDuration );
|
||||
Triangle( p6, p2, p1, r, g, b, a, noDepthTest, flDuration );
|
||||
|
||||
Triangle( p3, p4, p5, r, g, b, a, noDepthTest, flDuration );
|
||||
Triangle( p6, p7, p1, r, g, b, a, noDepthTest, flDuration );
|
||||
Triangle( p1, p2, p6, r, g, b, a, noDepthTest, flDuration );
|
||||
}
|
||||
}
|
||||
void Axis(const Vector &position, const QAngle &angles, float size, bool noDepthTest, float flDuration)
|
||||
{
|
||||
RETURN_IF_CANNOT_DRAW_OVERLAY
|
||||
|
||||
Vector xvec, yvec, zvec;
|
||||
AngleVectors( angles, &xvec, &yvec, &zvec );
|
||||
|
||||
xvec = position + (size * xvec);
|
||||
yvec = position - (size * yvec);
|
||||
zvec = position + (size * zvec);
|
||||
|
||||
Line( position, xvec, 255, 0, 0, noDepthTest, flDuration );
|
||||
Line( position, yvec, 0, 255, 0, noDepthTest, flDuration );
|
||||
Line( position, zvec, 0, 0, 255, noDepthTest, flDuration );
|
||||
}
|
||||
void Sphere(const Vector ¢er, float radius, int r, int g, int b, bool noDepthTest, float flDuration)
|
||||
{
|
||||
RETURN_IF_CANNOT_DRAW_OVERLAY
|
||||
|
||||
Vector edge, lastEdge;
|
||||
|
||||
float axisSize = radius;
|
||||
Line( center + Vector( 0, 0, -axisSize ), center + Vector( 0, 0, axisSize ), r, g, b, noDepthTest, flDuration );
|
||||
Line( center + Vector( 0, -axisSize, 0 ), center + Vector( 0, axisSize, 0 ), r, g, b, noDepthTest, flDuration );
|
||||
Line( center + Vector( -axisSize, 0, 0 ), center + Vector( axisSize, 0, 0 ), r, g, b, noDepthTest, flDuration );
|
||||
|
||||
lastEdge = Vector( radius + center.x, center.y, center.z );
|
||||
float angle;
|
||||
for( angle=0.0f; angle <= 360.0f; angle += 22.5f )
|
||||
{
|
||||
edge.x = radius * cosf( angle / 180.0f * M_PI ) + center.x;
|
||||
edge.y = center.y;
|
||||
edge.z = radius * sinf( angle / 180.0f * M_PI ) + center.z;
|
||||
|
||||
Line( edge, lastEdge, r, g, b, noDepthTest, flDuration );
|
||||
|
||||
lastEdge = edge;
|
||||
}
|
||||
|
||||
lastEdge = Vector( center.x, radius + center.y, center.z );
|
||||
for( angle=0.0f; angle <= 360.0f; angle += 22.5f )
|
||||
{
|
||||
edge.x = center.x;
|
||||
edge.y = radius * cosf( angle / 180.0f * M_PI ) + center.y;
|
||||
edge.z = radius * sinf( angle / 180.0f * M_PI ) + center.z;
|
||||
|
||||
Line( edge, lastEdge, r, g, b, noDepthTest, flDuration );
|
||||
|
||||
lastEdge = edge;
|
||||
}
|
||||
|
||||
lastEdge = Vector( center.x, radius + center.y, center.z );
|
||||
for( angle=0.0f; angle <= 360.0f; angle += 22.5f )
|
||||
{
|
||||
edge.x = radius * cosf( angle / 180.0f * M_PI ) + center.x;
|
||||
edge.y = radius * sinf( angle / 180.0f * M_PI ) + center.y;
|
||||
edge.z = center.z;
|
||||
|
||||
Line( edge, lastEdge, r, g, b, noDepthTest, flDuration );
|
||||
|
||||
lastEdge = edge;
|
||||
}
|
||||
}
|
||||
void CircleOriented(const Vector &position, const QAngle &angles, float radius, int r, int g, int b, int a, bool bNoDepthTest, float flDuration)
|
||||
{
|
||||
RETURN_IF_CANNOT_DRAW_OVERLAY
|
||||
|
||||
matrix3x4_t xform;
|
||||
AngleMatrix(angles, position, xform);
|
||||
Vector xAxis, yAxis;
|
||||
MatrixGetColumn(xform, 2, xAxis);
|
||||
MatrixGetColumn(xform, 1, yAxis);
|
||||
Circle(position, xAxis, yAxis, radius, r, g, b, a, bNoDepthTest, flDuration);
|
||||
}
|
||||
void Circle(const Vector &position, const Vector &xAxis, const Vector &yAxis, float radius, int r, int g, int b, int a, bool bNoDepthTest, float flDuration)
|
||||
{
|
||||
RETURN_IF_CANNOT_DRAW_OVERLAY
|
||||
|
||||
const unsigned int nSegments = 16;
|
||||
const float flRadStep = (M_PI*2.0f) / (float) nSegments;
|
||||
|
||||
Vector vecLastPosition;
|
||||
Vector vecStart = position + xAxis * radius;
|
||||
Vector vecPosition = vecStart;
|
||||
|
||||
for ( int i = 1; i <= nSegments; i++ )
|
||||
{
|
||||
vecLastPosition = vecPosition;
|
||||
|
||||
float flSin, flCos;
|
||||
SinCos( flRadStep*i, &flSin, &flCos );
|
||||
vecPosition = position + (xAxis * flCos * radius) + (yAxis * flSin * radius);
|
||||
|
||||
Line( vecLastPosition, vecPosition, r, g, b, bNoDepthTest, flDuration );
|
||||
|
||||
if ( a && i > 1 )
|
||||
{
|
||||
debugoverlay->AddTriangleOverlay( vecStart, vecLastPosition, vecPosition, r, g, b, a, bNoDepthTest, flDuration );
|
||||
}
|
||||
}
|
||||
}
|
||||
void SetDebugBits(HSCRIPT hEntity, int bit) // DebugOverlayBits_t
|
||||
{
|
||||
CBaseEntity *pEnt = ToEnt(hEntity);
|
||||
if (!pEnt)
|
||||
return;
|
||||
|
||||
if (pEnt->m_debugOverlays & bit)
|
||||
{
|
||||
pEnt->m_debugOverlays &= ~bit;
|
||||
}
|
||||
else
|
||||
{
|
||||
pEnt->m_debugOverlays |= bit;
|
||||
|
||||
#ifdef AI_MONITOR_FOR_OSCILLATION
|
||||
if (pEnt->IsNPC())
|
||||
{
|
||||
pEnt->MyNPCPointer()->m_ScheduleHistory.RemoveAll();
|
||||
}
|
||||
#endif//AI_MONITOR_FOR_OSCILLATION
|
||||
}
|
||||
}
|
||||
void ClearAllOverlays()
|
||||
{
|
||||
// Clear all entities of their debug overlays
|
||||
for (CBaseEntity *pEntity = gEntList.FirstEnt(); pEntity; pEntity = gEntList.NextEnt(pEntity))
|
||||
{
|
||||
pEntity->m_debugOverlays = 0;
|
||||
}
|
||||
|
||||
if (debugoverlay)
|
||||
{
|
||||
debugoverlay->ClearAllOverlays();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
} g_ScriptDebugOverlay;
|
||||
|
||||
BEGIN_SCRIPTDESC_ROOT(CDebugOverlayScriptHelper, SCRIPT_SINGLETON "CDebugOverlayScriptHelper")
|
||||
DEFINE_SCRIPTFUNC( Box, "Draws a world-space axis-aligned box. Specify bounds in world space." )
|
||||
DEFINE_SCRIPTFUNC( BoxDirection, "Draw box oriented to a Vector direction" )
|
||||
DEFINE_SCRIPTFUNC( BoxAngles, "Draws an oriented box at the origin. Specify bounds in local space." )
|
||||
DEFINE_SCRIPTFUNC( SweptBox, "Draws a swept box. Specify endpoints in world space and the bounds in local space." )
|
||||
DEFINE_SCRIPTFUNC( EntityBounds, "Draws bounds of an entity" )
|
||||
DEFINE_SCRIPTFUNC( Line, "Draws a line between two points" )
|
||||
DEFINE_SCRIPTFUNC( Triangle, "Draws a filled triangle. Specify vertices in world space." )
|
||||
DEFINE_SCRIPTFUNC( EntityText, "Draws text on an entity" )
|
||||
DEFINE_SCRIPTFUNC( EntityTextAtPosition, "Draw entity text overlay at a specific position" )
|
||||
DEFINE_SCRIPTFUNC( Grid, "Add grid overlay" )
|
||||
DEFINE_SCRIPTFUNC( Text, "Draws 2D text. Specify origin in world space." )
|
||||
DEFINE_SCRIPTFUNC( ScreenText, "Draws 2D text. Specify coordinates in screen space." )
|
||||
DEFINE_SCRIPTFUNC( Cross3D, "Draws a world-aligned cross. Specify origin in world space." )
|
||||
DEFINE_SCRIPTFUNC( Cross3DOriented, "Draws an oriented cross. Specify origin in world space." )
|
||||
DEFINE_SCRIPTFUNC( DrawTickMarkedLine, "Draws a dashed line. Specify endpoints in world space." )
|
||||
DEFINE_SCRIPTFUNC( HorzArrow, "Draws a horizontal arrow. Specify endpoints in world space." )
|
||||
DEFINE_SCRIPTFUNC( YawArrow, "Draws a arrow associated with a specific yaw. Specify endpoints in world space." )
|
||||
DEFINE_SCRIPTFUNC( VertArrow, "Draws a vertical arrow. Specify endpoints in world space." )
|
||||
DEFINE_SCRIPTFUNC( Axis, "Draws an axis. Specify origin + orientation in world space." )
|
||||
DEFINE_SCRIPTFUNC( Sphere, "Draws a wireframe sphere. Specify center in world space." )
|
||||
DEFINE_SCRIPTFUNC( CircleOriented, "Draws a circle oriented. Specify center in world space." )
|
||||
DEFINE_SCRIPTFUNC( Circle, "Draws a circle. Specify center in world space." )
|
||||
DEFINE_SCRIPTFUNC( SetDebugBits, "Set debug bits on entity" )
|
||||
DEFINE_SCRIPTFUNC( ClearAllOverlays, "Clear all debug overlays at once" )
|
||||
END_SCRIPTDESC();
|
||||
#endif // MAPBASE_VSCRIPT
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1010,9 +566,7 @@ bool VScriptServerInit()
|
||||
}
|
||||
|
||||
g_pScriptVM->RegisterInstance( &g_ScriptEntityIterator, "Entities" );
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
g_pScriptVM->RegisterInstance( &g_ScriptDebugOverlay, "debugoverlay" );
|
||||
#endif // MAPBASE_VSCRIPT
|
||||
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
g_pScriptVM->RegisterAllClasses();
|
||||
@ -1029,6 +583,7 @@ bool VScriptServerInit()
|
||||
g_pScriptVM->Run( g_Script_vscript_server );
|
||||
}
|
||||
|
||||
VScriptRunScript( "vscript_server", true );
|
||||
VScriptRunScript( "mapspawn", false );
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
@ -1192,6 +747,9 @@ public:
|
||||
|
||||
virtual void LevelShutdownPostEntity( void )
|
||||
{
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
g_ScriptNetMsg->LevelShutdownPreVM();
|
||||
#endif
|
||||
VScriptServerTerm();
|
||||
}
|
||||
|
||||
|
@ -5,13 +5,16 @@ static char g_Script_vscript_server[] = R"vscript(
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
function UniqueString( string = "" )
|
||||
{
|
||||
return ::DoUniqueString( string.tostring() );
|
||||
}
|
||||
|
||||
local DoEntFire = ::DoEntFire
|
||||
local DoEntFireByInstanceHandle = ::DoEntFireByInstanceHandle
|
||||
local DoDispatchParticleEffect = ::DoDispatchParticleEffect
|
||||
local DoUniqueString = ::DoUniqueString
|
||||
local ScriptGetClientConvarValue = ::ScriptGetClientConvarValue
|
||||
|
||||
function UniqueString( string = "" )
|
||||
{
|
||||
return DoUniqueString( string.tostring() );
|
||||
}
|
||||
|
||||
function EntFire( target, action, value = null, delay = 0.0, activator = null, caller = null )
|
||||
{
|
||||
@ -67,10 +70,10 @@ function DispatchParticleEffect( particleName, origin, angles, entity = null )
|
||||
// CConvars is declared within the library
|
||||
function CConvars::GetClientConvarValue(cvar,idx)
|
||||
{
|
||||
return ::ScriptGetClientConvarValue(cvar,idx);
|
||||
return ScriptGetClientConvarValue(cvar,idx);
|
||||
}
|
||||
|
||||
RegisterHelp( "CConvars::GetClientConvarValue", "CConvars::GetClientConvarValue(string, int)", "Returns the convar value for the entindex as a string. Only works with client convars with the FCVAR_USERINFO flag." );
|
||||
__Documentation.RegisterHelp( "CConvars::GetClientConvarValue", "CConvars::GetClientConvarValue(string, int)", "Returns the convar value for the entindex as a string. Only works with client convars with the FCVAR_USERINFO flag." );
|
||||
|
||||
function __ReplaceClosures( script, scope )
|
||||
{
|
||||
|
@ -55,4 +55,8 @@ void RegisterUserMessages( void )
|
||||
// NVNT register haptic user messages
|
||||
RegisterHapticMessages();
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
usermessages->Register( "ScriptMsg", -1 ); // CNetMsgScriptHelper
|
||||
#endif
|
||||
}
|
@ -852,10 +852,4 @@ void RegisterSharedScriptFunctions()
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptIsClient, "IsClient", "Returns true if the script is being run on the client." );
|
||||
|
||||
RegisterScriptSingletons();
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
VScriptRunScript( "vscript_client", true );
|
||||
#else
|
||||
VScriptRunScript( "vscript_server", true );
|
||||
#endif
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -5,12 +5,135 @@
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef VSCRIPT_FUNCS_MATH
|
||||
#define VSCRIPT_FUNCS_MATH
|
||||
#ifndef VSCRIPT_SINGLETONS
|
||||
#define VSCRIPT_SINGLETONS
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
void RegisterScriptSingletons();
|
||||
|
||||
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
// usercmd
|
||||
#define SCRIPT_NETMSG_DATA_SIZE ( ( 1 << 11 ) - 1 )
|
||||
#else
|
||||
// usermsg
|
||||
#define SCRIPT_NETMSG_DATA_SIZE MAX_USER_MSG_DATA
|
||||
#endif
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
class CNetMsgScriptHelper : public CAutoGameSystem
|
||||
#else
|
||||
class CNetMsgScriptHelper
|
||||
#endif
|
||||
{
|
||||
private:
|
||||
#ifdef GAME_DLL
|
||||
CRecipientFilter m_filter;
|
||||
bf_read *m_MsgIn;
|
||||
#else
|
||||
bf_read m_MsgIn;
|
||||
#endif
|
||||
bf_write m_MsgOut;
|
||||
byte m_MsgData[ PAD_NUMBER( SCRIPT_NETMSG_DATA_SIZE, 4 ) ];
|
||||
HSCRIPT m_Hooks;
|
||||
|
||||
public:
|
||||
#ifdef CLIENT_DLL
|
||||
bool m_bWriteReady; // dt ready to send
|
||||
|
||||
CNetMsgScriptHelper() : m_Hooks(NULL), m_bWriteReady(false) {}
|
||||
#else
|
||||
CNetMsgScriptHelper() : m_Hooks(NULL) {}
|
||||
#endif
|
||||
|
||||
public:
|
||||
#ifdef CLIENT_DLL
|
||||
bool Init(); // IGameSystem
|
||||
static void __MsgFunc_ScriptMsg( bf_read &msg );
|
||||
#endif
|
||||
void LevelShutdownPreVM(); // Executed in CVScriptGameSystem
|
||||
void InitPostVM();
|
||||
|
||||
#ifdef GAME_DLL
|
||||
void RecieveMessage( bf_read *msg, CBaseEntity *pPlayer );
|
||||
#else
|
||||
void RecieveMessage( bf_read &msg );
|
||||
#endif
|
||||
void WriteToBuffer( bf_write *bf );
|
||||
|
||||
public:
|
||||
inline void Reset();
|
||||
void Start( const char *msg );
|
||||
#ifdef GAME_DLL
|
||||
void Send( HSCRIPT player, bool bReliable );
|
||||
#else
|
||||
void Send();
|
||||
#endif
|
||||
void Recieve( const char *msg, HSCRIPT func );
|
||||
|
||||
#ifdef GAME_DLL
|
||||
inline void DoSendUserMsg( CRecipientFilter *filter, int type );
|
||||
inline void DoSendEntityMsg( CBaseEntity *entity, bool reliable );
|
||||
|
||||
void SendUserMessage( HSCRIPT hPlayer, const char *msg, bool bReliable );
|
||||
void SendEntityMessage( HSCRIPT hEnt, bool bReliable );
|
||||
#else // CLIENT_DLL
|
||||
void DispatchUserMessage( const char *msg );
|
||||
#endif
|
||||
|
||||
#ifdef GAME_DLL
|
||||
public:
|
||||
void AddRecipient( HSCRIPT player );
|
||||
void AddRecipientsByPVS( const Vector &pos );
|
||||
void AddRecipientsByPAS( const Vector &pos );
|
||||
void AddAllPlayers();
|
||||
#endif // GAME_DLL
|
||||
|
||||
public:
|
||||
void WriteInt( int iValue, int bits );
|
||||
void WriteUInt( int iValue, int bits );
|
||||
void WriteByte( int iValue ); // 8 bit unsigned char
|
||||
void WriteChar( int iValue ); // 8 bit char
|
||||
void WriteShort( int iValue ); // 16 bit short
|
||||
void WriteWord( int iValue ); // 16 bit unsigned short
|
||||
void WriteLong( int iValue ); // 32 bit long
|
||||
void WriteFloat( float flValue );
|
||||
void WriteNormal( float flValue ); // 12 bit
|
||||
void WriteAngle( float flValue ); // 8 bit unsigned char
|
||||
void WriteCoord( float flValue );
|
||||
void WriteVec3Coord( const Vector& rgflValue );
|
||||
void WriteVec3Normal( const Vector& rgflValue ); // 27 bit ( 3 + 2 * (1 + NORMAL_FRACTIONAL_BITS) )
|
||||
void WriteAngles( const QAngle& rgflValue );
|
||||
void WriteString( const char *sz ); // max 512 bytes at once
|
||||
void WriteBool( bool bValue ); // 1 bit
|
||||
void WriteEntity( HSCRIPT hEnt ); // 11 bit (entindex)
|
||||
void WriteEHandle( HSCRIPT hEnt ); // 32 bit long
|
||||
int ReadInt( int bits );
|
||||
int ReadUInt( int bits );
|
||||
int ReadByte();
|
||||
int ReadChar();
|
||||
int ReadShort();
|
||||
int ReadWord();
|
||||
int ReadLong();
|
||||
float ReadFloat();
|
||||
float ReadNormal();
|
||||
float ReadAngle();
|
||||
float ReadCoord();
|
||||
const Vector& ReadVec3Coord();
|
||||
const Vector& ReadVec3Normal();
|
||||
const QAngle& ReadAngles();
|
||||
const char* ReadString();
|
||||
bool ReadBool();
|
||||
HSCRIPT ReadEntity();
|
||||
HSCRIPT ReadEHandle();
|
||||
//int GetNumBitsLeft(); // unreliable on server because of usercmds. so just do away with it
|
||||
int GetNumBitsWritten();
|
||||
|
||||
};
|
||||
|
||||
extern CNetMsgScriptHelper *g_ScriptNetMsg;
|
||||
|
||||
#endif
|
||||
|
@ -10,12 +10,20 @@
|
||||
#include "bitbuf.h"
|
||||
#include "checksum_md5.h"
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
#include "mapbase/vscript_singletons.h"
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
// TF2 specific, need enough space for OBJ_LAST items from tf_shareddefs.h
|
||||
#define WEAPON_SUBTYPE_BITS 6
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
extern CNetMsgScriptHelper *g_ScriptNetMsg;
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Write a delta compressed user command.
|
||||
// Input : *buf -
|
||||
@ -187,6 +195,22 @@ void WriteUsercmd( bf_write *buf, const CUserCmd *to, const CUserCmd *from )
|
||||
buf->WriteOneBit( 0 );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined( MAPBASE_VSCRIPT ) && defined( CLIENT_DLL )
|
||||
Assert( g_ScriptNetMsg );
|
||||
|
||||
if ( g_ScriptNetMsg->m_bWriteReady )
|
||||
{
|
||||
buf->WriteOneBit( 1 );
|
||||
g_ScriptNetMsg->WriteToBuffer( buf );
|
||||
g_ScriptNetMsg->m_bWriteReady = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
buf->WriteOneBit( 0 );
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -196,7 +220,11 @@ void WriteUsercmd( bf_write *buf, const CUserCmd *to, const CUserCmd *from )
|
||||
// *from -
|
||||
// Output : static void ReadUsercmd
|
||||
//-----------------------------------------------------------------------------
|
||||
#if defined( MAPBASE_VSCRIPT ) && defined( GAME_DLL )
|
||||
void ReadUsercmd( bf_read *buf, CUserCmd *move, CUserCmd *from, CBaseEntity *pPlayer )
|
||||
#else
|
||||
void ReadUsercmd( bf_read *buf, CUserCmd *move, CUserCmd *from )
|
||||
#endif
|
||||
{
|
||||
// Assume no change
|
||||
*move = *from;
|
||||
@ -303,4 +331,12 @@ void ReadUsercmd( bf_read *buf, CUserCmd *move, CUserCmd *from )
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined( MAPBASE_VSCRIPT ) && defined( GAME_DLL )
|
||||
if ( buf->ReadOneBit() )
|
||||
{
|
||||
g_ScriptNetMsg->RecieveMessage( buf, pPlayer );
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -198,7 +198,11 @@ public:
|
||||
|
||||
};
|
||||
|
||||
#if defined( MAPBASE_VSCRIPT ) && defined( GAME_DLL )
|
||||
void ReadUsercmd( bf_read *buf, CUserCmd *move, CUserCmd *from, CBaseEntity *pPlayer );
|
||||
#else
|
||||
void ReadUsercmd( bf_read *buf, CUserCmd *move, CUserCmd *from );
|
||||
#endif
|
||||
void WriteUsercmd( bf_write *buf, const CUserCmd *to, const CUserCmd *from );
|
||||
|
||||
#endif // USERCMD_H
|
||||
|
@ -142,6 +142,9 @@ bool VScriptRunScript( const char *pszScriptName, HSCRIPT hScope, bool bWarnMiss
|
||||
bool bSuccess = false;
|
||||
if ( hScript )
|
||||
{
|
||||
// player is not yet spawned, this block is always skipped.
|
||||
// It is registered in CBasePlayer instead.
|
||||
#ifndef MAPBASE
|
||||
#ifdef GAME_DLL
|
||||
if ( gpGlobals->maxClients == 1 )
|
||||
{
|
||||
@ -151,6 +154,7 @@ bool VScriptRunScript( const char *pszScriptName, HSCRIPT hScope, bool bWarnMiss
|
||||
g_pScriptVM->SetValue( "player", pPlayer->GetScriptInstance() );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
bSuccess = ( g_pScriptVM->Run( hScript, hScope ) != SCRIPT_ERROR );
|
||||
if ( !bSuccess )
|
||||
@ -262,7 +266,7 @@ CON_COMMAND_SHARED( script_help, "Output help for script functions, optionally w
|
||||
pszArg1 = args[1];
|
||||
}
|
||||
|
||||
g_pScriptVM->Run( CFmtStr( "PrintHelp( \"%s\" );", pszArg1 ) );
|
||||
g_pScriptVM->Run( CFmtStr( "__Documentation.PrintHelp( \"%s\" );", pszArg1 ) );
|
||||
}
|
||||
|
||||
CON_COMMAND_SHARED( script_dump_all, "Dump the state of the VM to the console" )
|
||||
|
@ -762,6 +762,9 @@ struct ScriptEnumDesc_t
|
||||
|
||||
#define DEFINE_SCRIPTHOOK_PARAM( paramName, type ) pHook->AddParameter( paramName, type );
|
||||
|
||||
// Define actual parameters instead of global variables
|
||||
#define DEFINE_SCRIPTHOOK_REALPARAM( paramName, type )
|
||||
|
||||
#define END_SCRIPTHOOK() \
|
||||
pDesc->m_Hooks.AddToTail(pHook); \
|
||||
}
|
||||
@ -932,6 +935,9 @@ public:
|
||||
virtual bool SetValue( HSCRIPT hScope, const char *pszKey, const char *pszValue ) = 0;
|
||||
virtual bool SetValue( HSCRIPT hScope, const char *pszKey, const ScriptVariant_t &value ) = 0;
|
||||
bool SetValue( const char *pszKey, const ScriptVariant_t &value ) { return SetValue(NULL, pszKey, value ); }
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
virtual bool SetValue( HSCRIPT hScope, const ScriptVariant_t& key, const ScriptVariant_t& val ) = 0;
|
||||
#endif
|
||||
|
||||
virtual void CreateTable( ScriptVariant_t &Table ) = 0;
|
||||
virtual int GetNumTableEntries( HSCRIPT hScope ) = 0;
|
||||
@ -939,10 +945,16 @@ public:
|
||||
|
||||
virtual bool GetValue( HSCRIPT hScope, const char *pszKey, ScriptVariant_t *pValue ) = 0;
|
||||
bool GetValue( const char *pszKey, ScriptVariant_t *pValue ) { return GetValue(NULL, pszKey, pValue ); }
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
virtual bool GetValue( HSCRIPT hScope, ScriptVariant_t key, ScriptVariant_t* pValue ) = 0;
|
||||
#endif
|
||||
virtual void ReleaseValue( ScriptVariant_t &value ) = 0;
|
||||
|
||||
virtual bool ClearValue( HSCRIPT hScope, const char *pszKey ) = 0;
|
||||
bool ClearValue( const char *pszKey) { return ClearValue( NULL, pszKey ); }
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
virtual bool ClearValue( HSCRIPT hScope, ScriptVariant_t pKey ) = 0;
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
// virtual void CreateArray(ScriptVariant_t &arr, int size = 0) = 0;
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include "squirrel/squirrel/sqvm.h"
|
||||
#include "squirrel/squirrel/sqclosure.h"
|
||||
|
||||
#include "color.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "tier1/mapbase_con_groups.h"
|
||||
|
||||
@ -202,15 +201,18 @@ public:
|
||||
|
||||
virtual bool SetValue(HSCRIPT hScope, const char* pszKey, const char* pszValue) override;
|
||||
virtual bool SetValue(HSCRIPT hScope, const char* pszKey, const ScriptVariant_t& value) override;
|
||||
virtual bool SetValue(HSCRIPT hScope, const ScriptVariant_t& key, const ScriptVariant_t& val) override;
|
||||
|
||||
virtual void CreateTable(ScriptVariant_t& Table) override;
|
||||
virtual int GetNumTableEntries(HSCRIPT hScope) override;
|
||||
virtual int GetKeyValue(HSCRIPT hScope, int nIterator, ScriptVariant_t* pKey, ScriptVariant_t* pValue) override;
|
||||
|
||||
virtual bool GetValue(HSCRIPT hScope, const char* pszKey, ScriptVariant_t* pValue) override;
|
||||
virtual bool GetValue(HSCRIPT hScope, ScriptVariant_t key, ScriptVariant_t* pValue) override;
|
||||
virtual void ReleaseValue(ScriptVariant_t& value) override;
|
||||
|
||||
virtual bool ClearValue(HSCRIPT hScope, const char* pszKey) override;
|
||||
virtual bool ClearValue( HSCRIPT hScope, ScriptVariant_t pKey ) override;
|
||||
|
||||
// virtual void CreateArray(ScriptVariant_t &arr, int size = 0) override;
|
||||
virtual bool ArrayAppend(HSCRIPT hArray, const ScriptVariant_t &val) override;
|
||||
@ -1418,6 +1420,19 @@ const char * ScriptDataTypeToName(ScriptDataType_t datatype)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define PushDocumentationRegisterFunction( szName ) \
|
||||
sq_pushroottable(vm); \
|
||||
sq_pushstring(vm, "__Documentation", -1); \
|
||||
sq_get(vm, -2); \
|
||||
sq_pushstring(vm, szName, -1); \
|
||||
sq_get(vm, -2); \
|
||||
sq_push(vm, -2);
|
||||
|
||||
#define CallDocumentationRegisterFunction( paramcount ) \
|
||||
sq_call(vm, paramcount+1, SQFalse, SQFalse); \
|
||||
sq_pop(vm, 3);
|
||||
|
||||
void RegisterDocumentation(HSQUIRRELVM vm, const ScriptFuncDescriptor_t& pFuncDesc, ScriptClassDesc_t* pClassDesc = nullptr)
|
||||
{
|
||||
SquirrelSafeCheck safeCheck(vm);
|
||||
@ -1450,16 +1465,11 @@ void RegisterDocumentation(HSQUIRRELVM vm, const ScriptFuncDescriptor_t& pFuncDe
|
||||
V_strcat_safe(signature, ")");
|
||||
|
||||
// RegisterHelp(name, signature, description)
|
||||
sq_pushroottable(vm);
|
||||
sq_pushstring(vm, "RegisterHelp", -1);
|
||||
sq_get(vm, -2);
|
||||
sq_remove(vm, -2);
|
||||
sq_pushroottable(vm);
|
||||
sq_pushstring(vm, name, -1);
|
||||
sq_pushstring(vm, signature, -1);
|
||||
sq_pushstring(vm, pFuncDesc.m_pszDescription ? pFuncDesc.m_pszDescription : "", -1);
|
||||
sq_call(vm, 4, SQFalse, SQFalse);
|
||||
sq_pop(vm, 1);
|
||||
PushDocumentationRegisterFunction( "RegisterHelp" );
|
||||
sq_pushstring(vm, name, -1);
|
||||
sq_pushstring(vm, signature, -1);
|
||||
sq_pushstring(vm, pFuncDesc.m_pszDescription ? pFuncDesc.m_pszDescription : "", -1);
|
||||
CallDocumentationRegisterFunction( 3 );
|
||||
}
|
||||
|
||||
void RegisterClassDocumentation(HSQUIRRELVM vm, const ScriptClassDesc_t* pClassDesc)
|
||||
@ -1487,16 +1497,11 @@ void RegisterClassDocumentation(HSQUIRRELVM vm, const ScriptClassDesc_t* pClassD
|
||||
}
|
||||
|
||||
// RegisterClassHelp(name, base, description)
|
||||
sq_pushroottable(vm);
|
||||
sq_pushstring(vm, "RegisterClassHelp", -1);
|
||||
sq_get(vm, -2);
|
||||
sq_remove(vm, -2);
|
||||
sq_pushroottable(vm);
|
||||
sq_pushstring(vm, name, -1);
|
||||
sq_pushstring(vm, base, -1);
|
||||
sq_pushstring(vm, description, -1);
|
||||
sq_call(vm, 4, SQFalse, SQFalse);
|
||||
sq_pop(vm, 1);
|
||||
PushDocumentationRegisterFunction( "RegisterClassHelp" );
|
||||
sq_pushstring(vm, name, -1);
|
||||
sq_pushstring(vm, base, -1);
|
||||
sq_pushstring(vm, description, -1);
|
||||
CallDocumentationRegisterFunction( 3 );
|
||||
}
|
||||
|
||||
void RegisterEnumDocumentation(HSQUIRRELVM vm, const ScriptEnumDesc_t* pClassDesc)
|
||||
@ -1509,16 +1514,11 @@ void RegisterEnumDocumentation(HSQUIRRELVM vm, const ScriptEnumDesc_t* pClassDes
|
||||
const char *name = pClassDesc->m_pszScriptName;
|
||||
|
||||
// RegisterEnumHelp(name, description)
|
||||
sq_pushroottable(vm);
|
||||
sq_pushstring(vm, "RegisterEnumHelp", -1);
|
||||
sq_get(vm, -2);
|
||||
sq_remove(vm, -2);
|
||||
sq_pushroottable(vm);
|
||||
sq_pushstring(vm, name, -1);
|
||||
sq_pushinteger(vm, pClassDesc->m_ConstantBindings.Count());
|
||||
sq_pushstring(vm, pClassDesc->m_pszDescription ? pClassDesc->m_pszDescription : "", -1);
|
||||
sq_call(vm, 4, SQFalse, SQFalse);
|
||||
sq_pop(vm, 1);
|
||||
PushDocumentationRegisterFunction( "RegisterEnumHelp" );
|
||||
sq_pushstring(vm, name, -1);
|
||||
sq_pushinteger(vm, pClassDesc->m_ConstantBindings.Count());
|
||||
sq_pushstring(vm, pClassDesc->m_pszDescription ? pClassDesc->m_pszDescription : "", -1);
|
||||
CallDocumentationRegisterFunction( 3 );
|
||||
}
|
||||
|
||||
void RegisterConstantDocumentation( HSQUIRRELVM vm, const ScriptConstantBinding_t* pConstDesc, const char *pszAsString, ScriptEnumDesc_t* pEnumDesc = nullptr )
|
||||
@ -1542,16 +1542,11 @@ void RegisterConstantDocumentation( HSQUIRRELVM vm, const ScriptConstantBinding_
|
||||
V_snprintf(signature, sizeof(signature), "%s (%s)", pszAsString, ScriptDataTypeToName(pConstDesc->m_data.m_type));
|
||||
|
||||
// RegisterConstHelp(name, signature, description)
|
||||
sq_pushroottable(vm);
|
||||
sq_pushstring(vm, "RegisterConstHelp", -1);
|
||||
sq_get(vm, -2);
|
||||
sq_remove(vm, -2);
|
||||
sq_pushroottable(vm);
|
||||
sq_pushstring(vm, name, -1);
|
||||
sq_pushstring(vm, signature, -1);
|
||||
sq_pushstring(vm, pConstDesc->m_pszDescription ? pConstDesc->m_pszDescription : "", -1);
|
||||
sq_call(vm, 4, SQFalse, SQFalse);
|
||||
sq_pop(vm, 1);
|
||||
PushDocumentationRegisterFunction( "RegisterConstHelp" );
|
||||
sq_pushstring(vm, name, -1);
|
||||
sq_pushstring(vm, signature, -1);
|
||||
sq_pushstring(vm, pConstDesc->m_pszDescription ? pConstDesc->m_pszDescription : "", -1);
|
||||
CallDocumentationRegisterFunction( 3 );
|
||||
}
|
||||
|
||||
void RegisterHookDocumentation(HSQUIRRELVM vm, const ScriptHook_t* pHook, const ScriptFuncDescriptor_t& pFuncDesc, ScriptClassDesc_t* pClassDesc = nullptr)
|
||||
@ -1589,16 +1584,11 @@ void RegisterHookDocumentation(HSQUIRRELVM vm, const ScriptHook_t* pHook, const
|
||||
V_strcat_safe(signature, ")");
|
||||
|
||||
// RegisterHookHelp(name, signature, description)
|
||||
sq_pushroottable(vm);
|
||||
sq_pushstring(vm, "RegisterHookHelp", -1);
|
||||
sq_get(vm, -2);
|
||||
sq_remove(vm, -2);
|
||||
sq_pushroottable(vm);
|
||||
sq_pushstring(vm, name, -1);
|
||||
sq_pushstring(vm, signature, -1);
|
||||
sq_pushstring(vm, pFuncDesc.m_pszDescription ? pFuncDesc.m_pszDescription : "", -1);
|
||||
sq_call(vm, 4, SQFalse, SQFalse);
|
||||
sq_pop(vm, 1);
|
||||
PushDocumentationRegisterFunction( "RegisterHookHelp" );
|
||||
sq_pushstring(vm, name, -1);
|
||||
sq_pushstring(vm, signature, -1);
|
||||
sq_pushstring(vm, pFuncDesc.m_pszDescription ? pFuncDesc.m_pszDescription : "", -1);
|
||||
CallDocumentationRegisterFunction( 3 );
|
||||
}
|
||||
|
||||
void RegisterMemberDocumentation(HSQUIRRELVM vm, const ScriptMemberDesc_t& pDesc, ScriptClassDesc_t* pClassDesc = nullptr)
|
||||
@ -1619,21 +1609,15 @@ void RegisterMemberDocumentation(HSQUIRRELVM vm, const ScriptMemberDesc_t& pDesc
|
||||
if (pDesc.m_pszScriptName)
|
||||
V_strcat_safe(name, pDesc.m_pszScriptName);
|
||||
|
||||
|
||||
char signature[256] = "";
|
||||
V_snprintf(signature, sizeof(signature), "%s %s", ScriptDataTypeToName(pDesc.m_ReturnType), name);
|
||||
|
||||
// RegisterHookHelp(name, signature, description)
|
||||
sq_pushroottable(vm);
|
||||
sq_pushstring(vm, "RegisterMemberHelp", -1);
|
||||
sq_get(vm, -2);
|
||||
sq_remove(vm, -2);
|
||||
sq_pushroottable(vm);
|
||||
sq_pushstring(vm, name, -1);
|
||||
sq_pushstring(vm, signature, -1);
|
||||
sq_pushstring(vm, pDesc.m_pszDescription ? pDesc.m_pszDescription : "", -1);
|
||||
sq_call(vm, 4, SQFalse, SQFalse);
|
||||
sq_pop(vm, 1);
|
||||
// RegisterMemberHelp(name, signature, description)
|
||||
PushDocumentationRegisterFunction( "RegisterMemberHelp" );
|
||||
sq_pushstring(vm, name, -1);
|
||||
sq_pushstring(vm, signature, -1);
|
||||
sq_pushstring(vm, pDesc.m_pszDescription ? pDesc.m_pszDescription : "", -1);
|
||||
CallDocumentationRegisterFunction( 3 );
|
||||
}
|
||||
|
||||
|
||||
@ -2449,6 +2433,41 @@ bool SquirrelVM::SetValue(HSCRIPT hScope, const char* pszKey, const ScriptVarian
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SquirrelVM::SetValue( HSCRIPT hScope, const ScriptVariant_t& key, const ScriptVariant_t& val )
|
||||
{
|
||||
SquirrelSafeCheck safeCheck(vm_);
|
||||
HSQOBJECT obj = *(HSQOBJECT*)hScope;
|
||||
if (hScope)
|
||||
{
|
||||
Assert(hScope != INVALID_HSCRIPT);
|
||||
sq_pushobject(vm_, obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
sq_pushroottable(vm_);
|
||||
}
|
||||
|
||||
if ( sq_isarray(obj) )
|
||||
{
|
||||
Assert( key.m_type == FIELD_INTEGER );
|
||||
|
||||
sq_pushinteger(vm_, key.m_int);
|
||||
PushVariant(vm_, val);
|
||||
|
||||
sq_set(vm_, -3);
|
||||
}
|
||||
else
|
||||
{
|
||||
PushVariant(vm_, key);
|
||||
PushVariant(vm_, val);
|
||||
|
||||
sq_newslot(vm_, -3, SQFalse);
|
||||
}
|
||||
|
||||
sq_pop(vm_, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
void SquirrelVM::CreateTable(ScriptVariant_t& Table)
|
||||
{
|
||||
SquirrelSafeCheck safeCheck(vm_);
|
||||
@ -2464,15 +2483,17 @@ void SquirrelVM::CreateTable(ScriptVariant_t& Table)
|
||||
Table = (HSCRIPT)obj;
|
||||
}
|
||||
|
||||
//
|
||||
// input table/array/class/instance/string
|
||||
//
|
||||
int SquirrelVM::GetNumTableEntries(HSCRIPT hScope)
|
||||
{
|
||||
SquirrelSafeCheck safeCheck(vm_);
|
||||
|
||||
if (!hScope)
|
||||
{
|
||||
// TODO: This is called hScope but seems like just a table so
|
||||
// lets not fallback to root table
|
||||
return 0;
|
||||
// sq_getsize returns -1 on invalid input
|
||||
return -1;
|
||||
}
|
||||
|
||||
HSQOBJECT* scope = (HSQOBJECT*)hScope;
|
||||
@ -2565,6 +2586,47 @@ bool SquirrelVM::GetValue(HSCRIPT hScope, const char* pszKey, ScriptVariant_t* p
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SquirrelVM::GetValue( HSCRIPT hScope, ScriptVariant_t key, ScriptVariant_t* pValue )
|
||||
{
|
||||
SquirrelSafeCheck safeCheck(vm_);
|
||||
|
||||
Assert(pValue);
|
||||
if (!pValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hScope)
|
||||
{
|
||||
HSQOBJECT* scope = (HSQOBJECT*)hScope;
|
||||
Assert(hScope != INVALID_HSCRIPT);
|
||||
sq_pushobject(vm_, *scope);
|
||||
}
|
||||
else
|
||||
{
|
||||
sq_pushroottable(vm_);
|
||||
}
|
||||
|
||||
PushVariant(vm_, key);
|
||||
|
||||
if (sq_get(vm_, -2) != SQ_OK)
|
||||
{
|
||||
sq_pop(vm_, 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!getVariant(vm_, -1, *pValue))
|
||||
{
|
||||
sq_pop(vm_, 2);
|
||||
return false;
|
||||
}
|
||||
|
||||
sq_pop(vm_, 2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void SquirrelVM::ReleaseValue(ScriptVariant_t& value)
|
||||
{
|
||||
SquirrelSafeCheck safeCheck(vm_);
|
||||
@ -2609,6 +2671,33 @@ bool SquirrelVM::ClearValue(HSCRIPT hScope, const char* pszKey)
|
||||
sq_pop(vm_, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SquirrelVM::ClearValue(HSCRIPT hScope, ScriptVariant_t pKey)
|
||||
{
|
||||
SquirrelSafeCheck safeCheck(vm_);
|
||||
|
||||
if (hScope)
|
||||
{
|
||||
HSQOBJECT* scope = (HSQOBJECT*)hScope;
|
||||
Assert(hScope != INVALID_HSCRIPT);
|
||||
sq_pushobject(vm_, *scope);
|
||||
}
|
||||
else
|
||||
{
|
||||
sq_pushroottable(vm_);
|
||||
}
|
||||
|
||||
PushVariant(vm_, pKey);
|
||||
if (SQ_FAILED(sq_deleteslot(vm_, -2, SQFalse)))
|
||||
{
|
||||
sq_pop(vm_, 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
sq_pop(vm_, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
void SquirrelVM::CreateArray(ScriptVariant_t &arr, int size)
|
||||
{
|
||||
@ -2629,9 +2718,11 @@ bool SquirrelVM::ArrayAppend(HSCRIPT hArray, const ScriptVariant_t &val)
|
||||
{
|
||||
SquirrelSafeCheck safeCheck(vm_);
|
||||
|
||||
HSQOBJECT *arr = (HSQOBJECT*)hArray;
|
||||
HSQOBJECT arr = *(HSQOBJECT*)hArray;
|
||||
if ( !sq_isarray(arr) )
|
||||
return false;
|
||||
|
||||
sq_pushobject(vm_, *arr);
|
||||
sq_pushobject(vm_, arr);
|
||||
PushVariant(vm_, val);
|
||||
bool ret = sq_arrayappend(vm_, -2) == SQ_OK;
|
||||
sq_pop(vm_, 1);
|
||||
|
@ -106,14 +106,16 @@ class CSimpleCallChainer
|
||||
chain = null;
|
||||
}
|
||||
|
||||
DocumentedFuncs <- {}
|
||||
DocumentedClasses <- {}
|
||||
DocumentedEnums <- {}
|
||||
DocumentedConsts <- {}
|
||||
DocumentedHooks <- {}
|
||||
DocumentedMembers <- {}
|
||||
__Documentation <- {}
|
||||
|
||||
function AddAliasedToTable(name, signature, description, table)
|
||||
local DocumentedFuncs = {}
|
||||
local DocumentedClasses = {}
|
||||
local DocumentedEnums = {}
|
||||
local DocumentedConsts = {}
|
||||
local DocumentedHooks = {}
|
||||
local DocumentedMembers = {}
|
||||
|
||||
local function AddAliasedToTable(name, signature, description, table)
|
||||
{
|
||||
// This is an alias function, could use split() if we could guarantee
|
||||
// that ':' would not occur elsewhere in the description and Squirrel had
|
||||
@ -129,7 +131,7 @@ function AddAliasedToTable(name, signature, description, table)
|
||||
table[name] <- [signature, description];
|
||||
}
|
||||
|
||||
function RegisterHelp(name, signature, description)
|
||||
function __Documentation::RegisterHelp(name, signature, description)
|
||||
{
|
||||
if (description.len() && description[0] == '#')
|
||||
{
|
||||
@ -141,17 +143,17 @@ function RegisterHelp(name, signature, description)
|
||||
}
|
||||
}
|
||||
|
||||
function RegisterClassHelp(name, baseclass, description)
|
||||
function __Documentation::RegisterClassHelp(name, baseclass, description)
|
||||
{
|
||||
DocumentedClasses[name] <- [baseclass, description];
|
||||
}
|
||||
|
||||
function RegisterEnumHelp(name, num_elements, description)
|
||||
function __Documentation::RegisterEnumHelp(name, num_elements, description)
|
||||
{
|
||||
DocumentedEnums[name] <- [num_elements, description];
|
||||
}
|
||||
|
||||
function RegisterConstHelp(name, signature, description)
|
||||
function __Documentation::RegisterConstHelp(name, signature, description)
|
||||
{
|
||||
if (description.len() && description[0] == '#')
|
||||
{
|
||||
@ -163,31 +165,31 @@ function RegisterConstHelp(name, signature, description)
|
||||
}
|
||||
}
|
||||
|
||||
function RegisterHookHelp(name, signature, description)
|
||||
function __Documentation::RegisterHookHelp(name, signature, description)
|
||||
{
|
||||
DocumentedHooks[name] <- [signature, description];
|
||||
}
|
||||
|
||||
function RegisterMemberHelp(name, signature, description)
|
||||
function __Documentation::RegisterMemberHelp(name, signature, description)
|
||||
{
|
||||
DocumentedMembers[name] <- [signature, description];
|
||||
}
|
||||
|
||||
function printdoc( text )
|
||||
local function printdoc( text )
|
||||
{
|
||||
return ::printc(200,224,255,text);
|
||||
}
|
||||
|
||||
function printdocl( text )
|
||||
local function printdocl( text )
|
||||
{
|
||||
return printdoc(text + "\n");
|
||||
}
|
||||
|
||||
function PrintClass(name, doc)
|
||||
local function PrintClass(name, doc)
|
||||
{
|
||||
local text = "=====================================\n";
|
||||
text += ("Class: " + name + "\n");
|
||||
text += ("Base: " + doc[0] + "\n");
|
||||
text += ("Class: " + name + "\n");
|
||||
text += ("Base: " + doc[0] + "\n");
|
||||
if (doc[1].len())
|
||||
text += ("Description: " + doc[1] + "\n");
|
||||
text += "=====================================\n\n";
|
||||
@ -195,7 +197,7 @@ function PrintClass(name, doc)
|
||||
printdoc(text);
|
||||
}
|
||||
|
||||
function PrintFunc(name, doc)
|
||||
local function PrintFunc(name, doc)
|
||||
{
|
||||
local text = "Function: " + name + "\n"
|
||||
|
||||
@ -220,7 +222,7 @@ function PrintFunc(name, doc)
|
||||
printdocl(text);
|
||||
}
|
||||
|
||||
function PrintMember(name, doc)
|
||||
local function PrintMember(name, doc)
|
||||
{
|
||||
local text = ("Member: " + name + "\n");
|
||||
text += ("Signature: " + doc[0] + "\n");
|
||||
@ -229,11 +231,11 @@ function PrintMember(name, doc)
|
||||
printdocl(text);
|
||||
}
|
||||
|
||||
function PrintEnum(name, doc)
|
||||
local function PrintEnum(name, doc)
|
||||
{
|
||||
local text = "=====================================\n";
|
||||
text += ("Enum: " + name + "\n");
|
||||
text += ("Elements: " + doc[0] + "\n");
|
||||
text += ("Enum: " + name + "\n");
|
||||
text += ("Elements: " + doc[0] + "\n");
|
||||
if (doc[1].len())
|
||||
text += ("Description: " + doc[1] + "\n");
|
||||
text += "=====================================\n\n";
|
||||
@ -241,25 +243,25 @@ function PrintEnum(name, doc)
|
||||
printdoc(text);
|
||||
}
|
||||
|
||||
function PrintConst(name, doc)
|
||||
local function PrintConst(name, doc)
|
||||
{
|
||||
local text = ("Constant: " + name + "\n");
|
||||
if (doc[0] == null)
|
||||
{
|
||||
text += ("Value: null\n");
|
||||
text += ("Value: null\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
text += ("Value: " + doc[0] + "\n");
|
||||
text += ("Value: " + doc[0] + "\n");
|
||||
}
|
||||
if (doc[1].len())
|
||||
text += ("Description: " + doc[1] + "\n");
|
||||
printdocl(text);
|
||||
}
|
||||
|
||||
function PrintHook(name, doc)
|
||||
local function PrintHook(name, doc)
|
||||
{
|
||||
local text = ("Hook: " + name + "\n");
|
||||
local text = ("Hook: " + name + "\n");
|
||||
if (doc[0] == null)
|
||||
{
|
||||
// Is an aliased function
|
||||
@ -281,15 +283,15 @@ function PrintHook(name, doc)
|
||||
printdocl(text);
|
||||
}
|
||||
|
||||
function PrintMatchesInDocList(pattern, list, printfunc)
|
||||
local function PrintMatchesInDocList(pattern, list, printfunc)
|
||||
{
|
||||
local foundMatches = false;
|
||||
local foundMatches = 0;
|
||||
|
||||
foreach(name, doc in list)
|
||||
{
|
||||
if (pattern == "*" || name.tolower().find(pattern) != null || (doc[1].len() && doc[1].tolower().find(pattern) != null))
|
||||
{
|
||||
foundMatches = true;
|
||||
foundMatches = 1;
|
||||
printfunc(name, doc)
|
||||
}
|
||||
}
|
||||
@ -297,40 +299,41 @@ function PrintMatchesInDocList(pattern, list, printfunc)
|
||||
return foundMatches;
|
||||
}
|
||||
|
||||
function PrintHelp(pattern = "*")
|
||||
function __Documentation::PrintHelp(pattern = "*")
|
||||
{
|
||||
local foundMatches = false;
|
||||
local patternLower = pattern.tolower();
|
||||
|
||||
// Have a specific order
|
||||
foundMatches = ( PrintMatchesInDocList( patternLower, DocumentedEnums, PrintEnum ) || foundMatches );
|
||||
foundMatches = ( PrintMatchesInDocList( patternLower, DocumentedConsts, PrintConst ) || foundMatches );
|
||||
foundMatches = ( PrintMatchesInDocList( patternLower, DocumentedClasses, PrintClass ) || foundMatches );
|
||||
foundMatches = ( PrintMatchesInDocList( patternLower, DocumentedFuncs, PrintFunc ) || foundMatches );
|
||||
foundMatches = ( PrintMatchesInDocList( patternLower, DocumentedMembers, PrintMember ) || foundMatches );
|
||||
foundMatches = ( PrintMatchesInDocList( patternLower, DocumentedHooks, PrintHook ) || foundMatches );
|
||||
|
||||
if (!foundMatches)
|
||||
if (!(
|
||||
PrintMatchesInDocList( patternLower, DocumentedEnums, PrintEnum ) |
|
||||
PrintMatchesInDocList( patternLower, DocumentedConsts, PrintConst ) |
|
||||
PrintMatchesInDocList( patternLower, DocumentedClasses, PrintClass ) |
|
||||
PrintMatchesInDocList( patternLower, DocumentedFuncs, PrintFunc ) |
|
||||
PrintMatchesInDocList( patternLower, DocumentedMembers, PrintMember ) |
|
||||
PrintMatchesInDocList( patternLower, DocumentedHooks, PrintHook )
|
||||
))
|
||||
{
|
||||
printdocl("Pattern " + pattern + " not found");
|
||||
}
|
||||
}
|
||||
|
||||
// Vector documentation
|
||||
RegisterClassHelp( "Vector", "", "Basic 3-float Vector class." );
|
||||
RegisterHelp( "Vector::Length", "float Vector::Length()", "Return the vector's length." );
|
||||
RegisterHelp( "Vector::LengthSqr", "float Vector::LengthSqr()", "Return the vector's squared length." );
|
||||
RegisterHelp( "Vector::Length2D", "float Vector::Length2D()", "Return the vector's 2D length." );
|
||||
RegisterHelp( "Vector::Length2DSqr", "float Vector::Length2DSqr()", "Return the vector's squared 2D length." );
|
||||
__Documentation.RegisterClassHelp( "Vector", "", "Basic 3-float Vector class." );
|
||||
__Documentation.RegisterHelp( "Vector::Length", "float Vector::Length()", "Return the vector's length." );
|
||||
__Documentation.RegisterHelp( "Vector::LengthSqr", "float Vector::LengthSqr()", "Return the vector's squared length." );
|
||||
__Documentation.RegisterHelp( "Vector::Length2D", "float Vector::Length2D()", "Return the vector's 2D length." );
|
||||
__Documentation.RegisterHelp( "Vector::Length2DSqr", "float Vector::Length2DSqr()", "Return the vector's squared 2D length." );
|
||||
|
||||
RegisterHelp( "Vector::Normalized", "float Vector::Normalized()", "Return a normalized version of the vector." );
|
||||
RegisterHelp( "Vector::Norm", "void Vector::Norm()", "Normalize the vector in place." );
|
||||
RegisterHelp( "Vector::Scale", "vector Vector::Scale(float)", "Scale the vector's magnitude and return the result." );
|
||||
RegisterHelp( "Vector::Dot", "float Vector::Dot(vector)", "Return the dot/scalar product of two vectors." );
|
||||
RegisterHelp( "Vector::Cross", "float Vector::Cross(vector)", "Return the vector product of two vectors." );
|
||||
__Documentation.RegisterHelp( "Vector::Normalized", "float Vector::Normalized()", "Return a normalized version of the vector." );
|
||||
__Documentation.RegisterHelp( "Vector::Norm", "void Vector::Norm()", "Normalize the vector in place." );
|
||||
__Documentation.RegisterHelp( "Vector::Scale", "vector Vector::Scale(float)", "Scale the vector's magnitude and return the result." );
|
||||
__Documentation.RegisterHelp( "Vector::Dot", "float Vector::Dot(vector)", "Return the dot/scalar product of two vectors." );
|
||||
__Documentation.RegisterHelp( "Vector::Cross", "float Vector::Cross(vector)", "Return the vector product of two vectors." );
|
||||
|
||||
RegisterHelp( "Vector::ToKVString", "string Vector::ToKVString()", "Return a vector as a string in KeyValue form, without separation commas." );
|
||||
__Documentation.RegisterHelp( "Vector::ToKVString", "string Vector::ToKVString()", "Return a vector as a string in KeyValue form, without separation commas." );
|
||||
|
||||
RegisterMemberHelp( "Vector.x", "float Vector.x", "The vector's X coordinate on the cartesian X axis." );
|
||||
RegisterMemberHelp( "Vector.y", "float Vector.y", "The vector's Y coordinate on the cartesian Y axis." );
|
||||
RegisterMemberHelp( "Vector.z", "float Vector.z", "The vector's Z coordinate on the cartesian Z axis." );
|
||||
__Documentation.RegisterMemberHelp( "Vector.x", "float Vector.x", "The vector's X coordinate on the cartesian X axis." );
|
||||
__Documentation.RegisterMemberHelp( "Vector.y", "float Vector.y", "The vector's Y coordinate on the cartesian Y axis." );
|
||||
__Documentation.RegisterMemberHelp( "Vector.z", "float Vector.z", "The vector's Z coordinate on the cartesian Z axis." );
|
||||
|
||||
)vscript";
|
Loading…
Reference in New Issue
Block a user