Skip to content

Commit ef7d9cc

Browse files
vscript additions and fixes:
vscript_client.cpp - Fixed local player script instance registration - Added CEntities::GetLocalPlayer - Added Con_IsVisible - Added IsWindowedMode - Added ScreenWidth - Added ScreenHeight - Added ScreenTransform - Added missing DoUniqueString gameinterface.cpp usercmd.h usercmd.cpp vscript_singletons.cpp - CNetMsgScriptHelper vscript_singletons.cpp - Added hash map for CScriptSaveRestoreUtil - Added hash map for CScriptGameEventListener::s_GameEvents - Changed CScriptGameEventListener string contexts to hashes - Added invalid input condition on CScriptGameEventListener::ListenToGameEvent - Moved CDebugOverlayScriptHelper to shared code ivscript.h vscript_squirrel.cpp - Added IScriptVM::Get/Set/ClearValue (ScriptVariant_t key) baseentity.h baseentity.cpp - Added CBaseEntity::SetContextThink (ScriptSetContextThink) vscript_server.cpp vscript_client.cpp vscript_funcs_shared.cpp - Changed the order user vscript_*.nut files are executed - after internal scripts, before mapspawn vscript_squirrel.cpp vscript_squirrel.nut vscript_server.nut vscript_shared.cpp - Localised all documentation under __Documentation hl2_usermessages.cpp - Added usermessage ScriptMsg c_baseplayer.cpp - Removed redundant check in ~C_BasePlayer
1 parent 6ba3cd4 commit ef7d9cc

18 files changed

+1733
-1008
lines changed

sp/src/game/client/c_baseplayer.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -492,14 +492,14 @@ C_BasePlayer::~C_BasePlayer()
492492
if ( this == s_pLocalPlayer )
493493
{
494494
s_pLocalPlayer = NULL;
495-
}
496495

497496
#ifdef MAPBASE_VSCRIPT
498-
if ( IsLocalPlayer() && g_pScriptVM )
499-
{
500-
g_pScriptVM->SetValue( "player", SCRIPT_VARIANT_NULL );
501-
}
497+
if ( g_pScriptVM )
498+
{
499+
g_pScriptVM->SetValue( "player", SCRIPT_VARIANT_NULL );
500+
}
502501
#endif
502+
}
503503

504504
delete m_pFlashlight;
505505
}

sp/src/game/client/vscript_client.cpp

Lines changed: 62 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "proxyentity.h"
2121
#include "materialsystem/imaterial.h"
2222
#include "materialsystem/imaterialvar.h"
23+
#include "mapbase/vscript_singletons.h"
2324
#endif
2425

2526
extern IScriptManager *scriptmanager;
@@ -46,6 +47,11 @@ extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * );
4647
class CScriptClientEntityIterator
4748
{
4849
public:
50+
HSCRIPT GetLocalPlayer()
51+
{
52+
return ToHScript( C_BasePlayer::GetLocalPlayer() );
53+
}
54+
4955
HSCRIPT First() { return Next(NULL); }
5056

5157
HSCRIPT Next( HSCRIPT hStartEntity )
@@ -94,6 +100,7 @@ class CScriptClientEntityIterator
94100
} g_ScriptEntityIterator;
95101

96102
BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptClientEntityIterator, "CEntities", SCRIPT_SINGLETON "The global list of entities" )
103+
DEFINE_SCRIPTFUNC( GetLocalPlayer, "Get local player" )
97104
DEFINE_SCRIPTFUNC( First, "Begin an iteration over the list of entities" )
98105
DEFINE_SCRIPTFUNC( Next, "Continue an iteration over the list of entities, providing reference to a previously found entity" )
99106
DEFINE_SCRIPTFUNC( CreateByClassname, "Creates an entity by classname" )
@@ -399,7 +406,7 @@ void CScriptMaterialProxy::SetVarVector( int i, const Vector &value )
399406
}
400407

401408
EXPOSE_INTERFACE( CScriptMaterialProxy, IMaterialProxy, "VScriptProxy" IMATERIAL_PROXY_INTERFACE_VERSION );
402-
#endif
409+
#endif // MAPBASE_VSCRIPT
403410

404411
//-----------------------------------------------------------------------------
405412
//
@@ -431,6 +438,39 @@ bool DoIncludeScript( const char *pszScript, HSCRIPT hScope )
431438
return true;
432439
}
433440

441+
#ifdef MAPBASE_VSCRIPT
442+
static bool Con_IsVisible()
443+
{
444+
return engine->Con_IsVisible();
445+
}
446+
447+
static bool IsWindowedMode()
448+
{
449+
return engine->IsWindowedMode();
450+
}
451+
452+
int ScreenTransform( const Vector& point, Vector& screen );
453+
454+
//-----------------------------------------------------------------------------
455+
// Input array [x,y], set normalised screen space pos. Return true if on screen
456+
//-----------------------------------------------------------------------------
457+
static bool ScriptScreenTransform( const Vector &pos, HSCRIPT hArray )
458+
{
459+
if ( g_pScriptVM->GetNumTableEntries(hArray) >= 2 )
460+
{
461+
Vector v;
462+
bool r = ScreenTransform( pos, v );
463+
float x = 0.5f * ( 1.0f + v[0] );
464+
float y = 0.5f * ( 1.0f - v[1] );
465+
466+
g_pScriptVM->SetValue( hArray, ScriptVariant_t(0), x );
467+
g_pScriptVM->SetValue( hArray, 1, y );
468+
return !r;
469+
}
470+
return false;
471+
}
472+
#endif
473+
434474
bool VScriptClientInit()
435475
{
436476
VMPROF_START
@@ -487,14 +527,30 @@ bool VScriptClientInit()
487527
if( g_pScriptVM )
488528
{
489529
#ifdef MAPBASE_VSCRIPT
530+
// Moved here from LevelInitPostEntity, which is executed before local player is spawned.
531+
// This is executed after C_World::OnDataChanged, which is after C_BasePlayer::Spawn
532+
if ( C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer() )
533+
{
534+
g_pScriptVM->SetValue( "player", pPlayer->GetScriptInstance() );
535+
}
536+
490537
CGMsg( 0, CON_GROUP_VSCRIPT, "VSCRIPT CLIENT: Started VScript virtual machine using script language '%s'\n", g_pScriptVM->GetLanguageName() );
491538
#else
492539
Log( "VSCRIPT: Started VScript virtual machine using script language '%s'\n", g_pScriptVM->GetLanguageName() );
493540
#endif
494541
ScriptRegisterFunction( g_pScriptVM, GetMapName, "Get the name of the map.");
495542
ScriptRegisterFunction( g_pScriptVM, Time, "Get the current server time" );
543+
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." ) );
496544
ScriptRegisterFunction( g_pScriptVM, DoIncludeScript, "Execute a script (internal)" );
497-
545+
#ifdef MAPBASE_VSCRIPT
546+
ScriptRegisterFunction( g_pScriptVM, Con_IsVisible, "Returns true if the console is visible" );
547+
ScriptRegisterFunction( g_pScriptVM, ScreenWidth, "Width of the screen in pixels" );
548+
ScriptRegisterFunction( g_pScriptVM, ScreenHeight, "Height of the screen in pixels" );
549+
ScriptRegisterFunction( g_pScriptVM, IsWindowedMode, "" );
550+
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptScreenTransform, "ScreenTransform", "Get the x & y positions of a world position in screen space. Returns true if it's onscreen" );
551+
#endif
552+
553+
498554
if ( GameRules() )
499555
{
500556
GameRules()->RegisterScriptFunctions();
@@ -519,6 +575,7 @@ bool VScriptClientInit()
519575
g_pScriptVM->Run( g_Script_vscript_client );
520576
}
521577

578+
VScriptRunScript( "vscript_client", true );
522579
VScriptRunScript( "mapspawn", false );
523580

524581
VMPROF_SHOW( pszScriptLanguage, "virtual machine startup" );
@@ -579,20 +636,13 @@ class CVScriptGameSystem : public CAutoGameSystemPerFrame
579636
virtual void LevelInitPostEntity( void )
580637
{
581638
m_bAllowEntityCreationInScripts = false;
582-
#ifdef MAPBASE_VSCRIPT
583-
if (g_pScriptVM)
584-
{
585-
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
586-
if (pPlayer)
587-
{
588-
g_pScriptVM->SetValue( "player", pPlayer->GetScriptInstance() );
589-
}
590-
}
591-
#endif
592639
}
593640

594641
virtual void LevelShutdownPostEntity( void )
595642
{
643+
#ifdef MAPBASE_VSCRIPT
644+
g_ScriptNetMsg->LevelShutdownPreVM();
645+
#endif
596646
VScriptClientTerm();
597647
}
598648

sp/src/game/server/baseentity.cpp

Lines changed: 148 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2190,7 +2190,7 @@ BEGIN_DATADESC_NO_BASE( CBaseEntity )
21902190
DEFINE_THINKFUNC( ShadowCastDistThink ),
21912191
DEFINE_THINKFUNC( ScriptThink ),
21922192
#ifdef MAPBASE_VSCRIPT
2193-
DEFINE_THINKFUNC( ScriptThinkH ),
2193+
DEFINE_THINKFUNC( ScriptContextThink ),
21942194
#endif
21952195

21962196
#ifdef MAPBASE
@@ -2442,6 +2442,7 @@ BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities"
24422442
#ifdef MAPBASE_VSCRIPT
24432443
DEFINE_SCRIPTFUNC_NAMED( ScriptSetThinkFunction, "SetThinkFunction", "" )
24442444
DEFINE_SCRIPTFUNC_NAMED( ScriptStopThinkFunction, "StopThinkFunction", "" )
2445+
DEFINE_SCRIPTFUNC_NAMED( ScriptSetContextThink, "SetContextThink", "Set a think function on this entity." )
24452446
DEFINE_SCRIPTFUNC_NAMED( ScriptSetThink, "SetThink", "" )
24462447
DEFINE_SCRIPTFUNC_NAMED( ScriptStopThink, "StopThink", "" )
24472448

@@ -2590,11 +2591,12 @@ void CBaseEntity::UpdateOnRemove( void )
25902591
m_hScriptInstance = NULL;
25912592

25922593
#ifdef MAPBASE_VSCRIPT
2593-
if ( m_hfnThink )
2594+
FOR_EACH_VEC( m_ScriptThinkFuncs, i )
25942595
{
2595-
g_pScriptVM->ReleaseScript( m_hfnThink );
2596-
m_hfnThink = NULL;
2596+
HSCRIPT h = m_ScriptThinkFuncs[i].m_hfnThink;
2597+
if ( h ) g_pScriptVM->ReleaseScript( h );
25972598
}
2599+
m_ScriptThinkFuncs.Purge();
25982600
#endif // MAPBASE_VSCRIPT
25992601
}
26002602
}
@@ -8653,60 +8655,172 @@ void CBaseEntity::ScriptStopThinkFunction()
86538655
SetContextThink( NULL, TICK_NEVER_THINK, "ScriptThink" );
86548656
}
86558657

8658+
8659+
static inline void ScriptStopContextThink( scriptthinkfunc_t *context )
8660+
{
8661+
g_pScriptVM->ReleaseScript( context->m_hfnThink );
8662+
context->m_hfnThink = NULL;
8663+
context->m_nNextThinkTick = TICK_NEVER_THINK;
8664+
}
8665+
86568666
//-----------------------------------------------------------------------------
8667+
//
86578668
//-----------------------------------------------------------------------------
8658-
void CBaseEntity::ScriptThinkH()
8669+
void CBaseEntity::ScriptContextThink()
86598670
{
8660-
ScriptVariant_t varThinkRetVal;
8661-
if ( g_pScriptVM->ExecuteFunction(m_hfnThink, NULL, 0, &varThinkRetVal, NULL, true) == SCRIPT_ERROR )
8671+
float flNextThink = FLT_MAX;
8672+
int nScheduledTick = 0;
8673+
8674+
for ( int i = m_ScriptThinkFuncs.Count(); i--; )
86628675
{
8663-
DevWarning("%s FAILED to call script think function (invalid closure)!\n", GetDebugName());
8664-
ScriptStopThink();
8665-
return;
8676+
scriptthinkfunc_t *cur = &m_ScriptThinkFuncs[i];
8677+
8678+
if ( cur->m_nNextThinkTick == TICK_NEVER_THINK )
8679+
continue;
8680+
8681+
if ( cur->m_nNextThinkTick > gpGlobals->tickcount )
8682+
{
8683+
// There is more to execute, don't stop thinking if the rest are done.
8684+
8685+
// also find the shortest schedule
8686+
if ( !nScheduledTick || nScheduledTick > cur->m_nNextThinkTick )
8687+
{
8688+
nScheduledTick = cur->m_nNextThinkTick;
8689+
}
8690+
continue;
8691+
}
8692+
8693+
ScriptVariant_t varReturn;
8694+
8695+
if ( cur->m_bNoParam )
8696+
{
8697+
if ( g_pScriptVM->Call( cur->m_hfnThink, NULL, true, &varReturn ) == SCRIPT_ERROR )
8698+
{
8699+
ScriptStopContextThink(cur);
8700+
m_ScriptThinkFuncs.Remove(i);
8701+
continue;
8702+
}
8703+
}
8704+
else
8705+
{
8706+
if ( g_pScriptVM->Call( cur->m_hfnThink, NULL, true, &varReturn, m_hScriptInstance ) == SCRIPT_ERROR )
8707+
{
8708+
ScriptStopContextThink(cur);
8709+
m_ScriptThinkFuncs.Remove(i);
8710+
continue;
8711+
}
8712+
}
8713+
8714+
float flReturn;
8715+
if ( !varReturn.AssignTo( &flReturn ) )
8716+
{
8717+
ScriptStopContextThink(cur);
8718+
m_ScriptThinkFuncs.Remove(i);
8719+
continue;
8720+
}
8721+
8722+
if ( flReturn < 0.0f )
8723+
{
8724+
ScriptStopContextThink(cur);
8725+
m_ScriptThinkFuncs.Remove(i);
8726+
continue;
8727+
}
8728+
8729+
// find the shortest delay
8730+
if ( flReturn < flNextThink )
8731+
{
8732+
flNextThink = flReturn;
8733+
}
8734+
8735+
cur->m_nNextThinkTick = TIME_TO_TICKS( gpGlobals->curtime + flReturn );
86668736
}
86678737

8668-
float flThinkFrequency = 0.f;
8669-
if ( !varThinkRetVal.AssignTo(&flThinkFrequency) )
8738+
if ( flNextThink < FLT_MAX )
86708739
{
8671-
// no return value stops thinking
8672-
ScriptStopThink();
8673-
return;
8740+
SetNextThink( gpGlobals->curtime + flNextThink, "ScriptContextThink" );
8741+
}
8742+
else if ( nScheduledTick )
8743+
{
8744+
SetNextThink( TICKS_TO_TIME( nScheduledTick ), "ScriptContextThink" );
8745+
}
8746+
else
8747+
{
8748+
SetNextThink( TICK_NEVER_THINK, "ScriptContextThink" );
86748749
}
8675-
8676-
SetNextThink( gpGlobals->curtime + flThinkFrequency, "ScriptThinkH" );
86778750
}
86788751

8679-
void CBaseEntity::ScriptSetThink( HSCRIPT hFunc, float flTime )
8752+
// see ScriptSetThink
8753+
static bool s_bScriptContextThinkNoParam = false;
8754+
8755+
//-----------------------------------------------------------------------------
8756+
//
8757+
//-----------------------------------------------------------------------------
8758+
void CBaseEntity::ScriptSetContextThink( const char* szContext, HSCRIPT hFunc, float flTime )
86808759
{
8681-
if ( hFunc )
8760+
scriptthinkfunc_t th;
8761+
V_memset( &th, 0x0, sizeof(scriptthinkfunc_t) );
8762+
unsigned short hash = ( szContext && *szContext ) ? HashString( szContext ) : 0;
8763+
bool bFound = false;
8764+
8765+
FOR_EACH_VEC( m_ScriptThinkFuncs, i )
86828766
{
8683-
if ( m_hfnThink )
8767+
scriptthinkfunc_t f = m_ScriptThinkFuncs[i];
8768+
if ( hash == f.m_iContextHash )
86848769
{
8685-
// release old func
8686-
ScriptStopThink();
8770+
th = f;
8771+
m_ScriptThinkFuncs.Remove(i); // reorder
8772+
bFound = true;
8773+
break;
86878774
}
8775+
}
86888776

8689-
// no type check here, print error on call instead
8690-
m_hfnThink = hFunc;
8777+
if ( hFunc )
8778+
{
8779+
float nextthink = gpGlobals->curtime + flTime;
86918780

8692-
flTime = max( 0, flTime );
8693-
SetContextThink( &CBaseEntity::ScriptThinkH, gpGlobals->curtime + flTime, "ScriptThinkH" );
8781+
th.m_bNoParam = s_bScriptContextThinkNoParam;
8782+
th.m_hfnThink = hFunc;
8783+
th.m_iContextHash = hash;
8784+
th.m_nNextThinkTick = TIME_TO_TICKS( nextthink );
8785+
8786+
m_ScriptThinkFuncs.AddToHead( th );
8787+
8788+
int nexttick = GetNextThinkTick( RegisterThinkContext( "ScriptContextThink" ) );
8789+
8790+
// sooner than next think
8791+
if ( nexttick <= 0 || nexttick > th.m_nNextThinkTick )
8792+
{
8793+
SetContextThink( &CBaseEntity::ScriptContextThink, nextthink, "ScriptContextThink" );
8794+
}
86948795
}
8695-
else
8796+
// null func input, think exists
8797+
else if ( bFound )
86968798
{
8697-
ScriptStopThink();
8799+
ScriptStopContextThink( &th );
86988800
}
86998801
}
87008802

8803+
//-----------------------------------------------------------------------------
8804+
// m_bNoParam and s_bScriptContextThinkNoParam exist only to keep backwards compatibility
8805+
// and are an alternative to this script closure:
8806+
//
8807+
// function CBaseEntity::SetThink( func, time )
8808+
// {
8809+
// SetContextThink( "", function(_){ return func() }, time )
8810+
// }
8811+
//-----------------------------------------------------------------------------
8812+
void CBaseEntity::ScriptSetThink( HSCRIPT hFunc, float time )
8813+
{
8814+
s_bScriptContextThinkNoParam = true;
8815+
ScriptSetContextThink( NULL, hFunc, time );
8816+
s_bScriptContextThinkNoParam = false;
8817+
}
8818+
87018819
void CBaseEntity::ScriptStopThink()
87028820
{
8703-
if (m_hfnThink)
8704-
{
8705-
g_pScriptVM->ReleaseScript(m_hfnThink);
8706-
m_hfnThink = NULL;
8707-
}
8708-
SetContextThink( NULL, TICK_NEVER_THINK, "ScriptThinkH" );
8821+
ScriptSetContextThink( NULL, NULL, 0.0f );
87098822
}
8823+
87108824
#endif // MAPBASE_VSCRIPT
87118825

87128826
//-----------------------------------------------------------------------------

0 commit comments

Comments
 (0)