vscript additions and fixes:

baseentity_shared.cpp
baseentity.cpp
c_baseentity.h
c_baseentity.cpp
c_world.h
   - Fixed critical ScriptSetContextThink bugs
   - Added C_BaseEntity::SetContextThink (ScriptSetContextThink)
   - Added C_BaseEntity::SetSize
   - Added C_BaseEntity::SetModel
   - Added C_BaseEntity::Destroy

baseentity.h
baseentity.cpp
   - Removed duplicate functions ScriptSetSize and ScriptUtilRemove

player.cpp
   - Moved player script instance registration before player_spawn event

vscript_server.cpp
   - Added CEntities::FindByClassNearestFacing

vscript_funcs_shared.cpp
   - Added GetFrameCount
   - Added IntervalPerTick

vscript_singletons.cpp
   - Better game event descriptors for CScriptGameEventListener
   - Added ::effects (CEffectsScriptHelper)
   - Added ::Convars (CScriptConvarAccessor)

vscript_shared.cpp
   - Fixed clientside entity printing in script VM

mapbase_con_groups.h
mapbase_con_groups.cpp
   - Improved performance by changing string comparisons to direct array access

vscript_bindings_base.h
vscript_bindings_base.cpp
   - Added CScriptKeyValues::SubKeysToTable

vscript_bindings_math.cpp
   - Added ::SimpleSplineRemapVal
   - Added ::SimpleSplineRemapValClamped
   - Added ::Bias
   - Added ::Gain
   - Added ::SmoothCurve
   - Added ::SmoothCurve_Tweak
   - Added ::ExponentialDecay

vscript_squirrel.nut
   - Added ::Lerp
   - Added ::FLerp
   - Added ::SimpleSpline

vscript_squirrel.cpp
   - Added Vector::_unm
   - Added Vector::Set
   - Added Vector::Add
   - Added Vector::Subtract
   - Added Vector::Multiply
   - Added Vector::Divide
   - Added Vector::DistTo
   - Added Vector::DistToSqr
   - Added Vector::IsEqualTo
   - Added Vector::WithinAABox
   - Added Vector::FromKVString
   - Changed vector print syntax
This commit is contained in:
samisalreadytaken
2021-03-06 01:11:43 +02:00
parent bd3b9c3807
commit bf182e1c5d
33 changed files with 1745 additions and 566 deletions

View File

@@ -2712,4 +2712,296 @@ HSCRIPT CBaseEntity::ScriptGetPhysicsObject( void )
else
return NULL;
}
static inline void ScriptStopContextThink( scriptthinkfunc_t *context )
{
Assert( context->m_hfnThink );
g_pScriptVM->ReleaseScript( context->m_hfnThink );
context->m_hfnThink = NULL;
//context->m_nNextThinkTick = TICK_NEVER_THINK;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CBaseEntity::ScriptContextThink()
{
float flNextThink = FLT_MAX;
int nScheduledTick = 0;
for ( int i = 0; i < m_ScriptThinkFuncs.Count(); ++i )
{
scriptthinkfunc_t *cur = m_ScriptThinkFuncs[i];
if ( cur->m_nNextThinkTick == TICK_NEVER_THINK )
{
continue;
}
if ( cur->m_nNextThinkTick > gpGlobals->tickcount )
{
// There is more to execute, don't stop thinking if the rest are done.
// Find the shortest schedule
if ( !nScheduledTick || nScheduledTick > cur->m_nNextThinkTick )
{
nScheduledTick = cur->m_nNextThinkTick;
}
continue;
}
#ifdef _DEBUG
// going to run the script func
cur->m_nNextThinkTick = 0;
#endif
ScriptVariant_t varReturn;
if ( !cur->m_bNoParam )
{
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;
continue;
}
}
else
{
if ( g_pScriptVM->ExecuteFunction( cur->m_hfnThink, NULL, 0, &varReturn, NULL, true ) == SCRIPT_ERROR )
{
cur->m_nNextThinkTick = TICK_NEVER_THINK;
continue;
}
}
if ( cur->m_nNextThinkTick == TICK_NEVER_THINK )
{
// stopped from script while thinking
continue;
}
float flReturn;
if ( !varReturn.AssignTo( &flReturn ) )
{
cur->m_nNextThinkTick = TICK_NEVER_THINK;
continue;
}
if ( flReturn < 0.0f )
{
cur->m_nNextThinkTick = TICK_NEVER_THINK;
continue;
}
if ( flReturn < flNextThink )
{
flNextThink = flReturn;
}
cur->m_nNextThinkTick = TIME_TO_TICKS( gpGlobals->curtime + flReturn );
}
// deferred safe removal
for ( int i = 0; i < m_ScriptThinkFuncs.Count(); )
{
if ( m_ScriptThinkFuncs[i]->m_nNextThinkTick == TICK_NEVER_THINK )
{
ScriptStopContextThink( m_ScriptThinkFuncs[i] );
delete m_ScriptThinkFuncs[i];
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 ) )
{
#endif
if ( nScheduledTick )
{
float flScheduledTime = TICKS_TO_TIME( nScheduledTick );
if ( bNewNext )
{
flNextThink = min( gpGlobals->curtime + flNextThink, flScheduledTime );
}
else
{
flNextThink = flScheduledTime;
}
}
else
{
if ( bNewNext )
{
flNextThink = gpGlobals->curtime + flNextThink;
}
else
{
#ifdef GAME_DLL
flNextThink = TICK_NEVER_THINK;
#else
flNextThink = CLIENT_THINK_NEVER;
#endif
}
}
#ifdef _DEBUG
}
else
{
// Next think was set (from script) to a sooner tick while thinking?
Assert(0);
if ( nScheduledTick )
{
int nNextSchedule = min( nScheduledTick, nNextThinkTick );
float flNextSchedule = TICKS_TO_TIME( nNextSchedule );
if ( bNewNext )
{
flNextThink = min( gpGlobals->curtime + flNextThink, flNextSchedule );
}
else
{
flNextThink = flNextSchedule;
}
}
else
{
float nextthink = TICKS_TO_TIME( nNextThinkTick );
if ( bNewNext )
{
flNextThink = min( gpGlobals->curtime + flNextThink, nextthink );
}
else
{
flNextThink = nextthink;
}
}
}
#endif
#ifdef GAME_DLL
SetNextThink( flNextThink, "ScriptContextThink" );
#else
SetNextClientThink( flNextThink );
#endif
}
// see ScriptSetThink
static bool s_bScriptContextThinkNoParam = false;
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CBaseEntity::ScriptSetContextThink( const char* szContext, HSCRIPT hFunc, float flTime )
{
#ifdef CLIENT_DLL
// Context thinking is not yet supported on client, entities can only have 1 think function.
// C_World does not have one by default, so it is safe to set its.
if ( !IsWorld() )
{
g_pScriptVM->RaiseException("SetContextThink is only supported on C_World");
return;
}
#endif
scriptthinkfunc_t *pf = NULL;
unsigned short hash = ( szContext && *szContext ) ? HashString( szContext ) : 0;
FOR_EACH_VEC( m_ScriptThinkFuncs, i )
{
scriptthinkfunc_t *f = m_ScriptThinkFuncs[i];
if ( hash == f->m_iContextHash )
{
pf = f;
break;
}
}
if ( hFunc )
{
// add new
if ( !pf )
{
pf = new scriptthinkfunc_t;
m_ScriptThinkFuncs.SetGrowSize(1);
m_ScriptThinkFuncs.AddToTail( pf );
pf->m_bNoParam = s_bScriptContextThinkNoParam;
pf->m_iContextHash = hash;
}
// update existing
else
{
#ifdef _DEBUG
if ( pf->m_nNextThinkTick == 0 )
{
Warning("Script think ('%s') was changed while it was thinking!\n", szContext);
}
#endif
g_pScriptVM->ReleaseScript( pf->m_hfnThink );
}
float nextthink = gpGlobals->curtime + flTime;
pf->m_hfnThink = hFunc;
pf->m_nNextThinkTick = TIME_TO_TICKS( 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 )
{
#ifdef GAME_DLL
SetContextThink( &CBaseEntity::ScriptContextThink, nextthink, "ScriptContextThink" );
#else
SetNextClientThink( nextthink );
#endif
}
}
// null func input, think exists
else if ( pf )
{
pf->m_nNextThinkTick = TICK_NEVER_THINK;
}
}
//-----------------------------------------------------------------------------
// 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 )
// }
//-----------------------------------------------------------------------------
#ifndef CLIENT_DLL
void CBaseEntity::ScriptSetThink( HSCRIPT hFunc, float time )
{
s_bScriptContextThinkNoParam = true;
ScriptSetContextThink( NULL, hFunc, time );
s_bScriptContextThinkNoParam = false;
}
void CBaseEntity::ScriptStopThink()
{
ScriptSetContextThink( NULL, NULL, 0.0f );
}
#endif
#endif