mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2024-12-28 15:55:31 +03:00
Fix ScriptContextThink precision errors
This commit is contained in:
parent
6ed8b31091
commit
d7a06e863e
@ -164,10 +164,9 @@ struct thinkfunc_t
|
|||||||
#ifdef MAPBASE_VSCRIPT
|
#ifdef MAPBASE_VSCRIPT
|
||||||
struct scriptthinkfunc_t
|
struct scriptthinkfunc_t
|
||||||
{
|
{
|
||||||
int m_nNextThinkTick;
|
float m_flNextThink;
|
||||||
HSCRIPT m_hfnThink;
|
HSCRIPT m_hfnThink;
|
||||||
unsigned short m_iContextHash;
|
unsigned m_iContextHash;
|
||||||
bool m_bNoParam;
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -295,6 +294,8 @@ public:
|
|||||||
string_t m_iszScriptId;
|
string_t m_iszScriptId;
|
||||||
#ifdef MAPBASE_VSCRIPT
|
#ifdef MAPBASE_VSCRIPT
|
||||||
CScriptScope m_ScriptScope;
|
CScriptScope m_ScriptScope;
|
||||||
|
|
||||||
|
static ScriptHook_t g_Hook_UpdateOnRemove;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// IClientUnknown overrides.
|
// IClientUnknown overrides.
|
||||||
|
@ -341,9 +341,9 @@ struct thinkfunc_t
|
|||||||
#ifdef MAPBASE_VSCRIPT
|
#ifdef MAPBASE_VSCRIPT
|
||||||
struct scriptthinkfunc_t
|
struct scriptthinkfunc_t
|
||||||
{
|
{
|
||||||
int m_nNextThinkTick;
|
float m_flNextThink;
|
||||||
HSCRIPT m_hfnThink;
|
HSCRIPT m_hfnThink;
|
||||||
unsigned short m_iContextHash;
|
unsigned m_iContextHash;
|
||||||
bool m_bNoParam;
|
bool m_bNoParam;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
@ -2115,6 +2115,9 @@ public:
|
|||||||
int ScriptGetMoveType() { return GetMoveType(); }
|
int ScriptGetMoveType() { return GetMoveType(); }
|
||||||
void ScriptSetMoveType( int iMoveType ) { SetMoveType( (MoveType_t)iMoveType ); }
|
void ScriptSetMoveType( int iMoveType ) { SetMoveType( (MoveType_t)iMoveType ); }
|
||||||
|
|
||||||
|
int ScriptGetSolid() { return GetSolid(); }
|
||||||
|
void ScriptSetSolid( int i ) { SetSolid( (SolidType_t)i ); }
|
||||||
|
|
||||||
bool ScriptDispatchInteraction( int interactionType, HSCRIPT data, HSCRIPT sourceEnt );
|
bool ScriptDispatchInteraction( int interactionType, HSCRIPT data, HSCRIPT sourceEnt );
|
||||||
|
|
||||||
int ScriptGetTakeDamage() { return m_takedamage; }
|
int ScriptGetTakeDamage() { return m_takedamage; }
|
||||||
|
@ -2713,13 +2713,20 @@ HSCRIPT CBaseEntity::ScriptGetPhysicsObject( void )
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef GAME_DLL
|
||||||
|
#define SCRIPT_NEVER_THINK TICK_NEVER_THINK
|
||||||
|
#else
|
||||||
|
#define SCRIPT_NEVER_THINK CLIENT_THINK_NEVER
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline void ScriptStopContextThink( scriptthinkfunc_t *context )
|
static inline void ScriptStopContextThink( scriptthinkfunc_t *context )
|
||||||
{
|
{
|
||||||
Assert( context->m_hfnThink );
|
Assert( context->m_hfnThink );
|
||||||
|
Assert( context->m_flNextThink == SCRIPT_NEVER_THINK );
|
||||||
|
|
||||||
g_pScriptVM->ReleaseScript( context->m_hfnThink );
|
g_pScriptVM->ReleaseScript( context->m_hfnThink );
|
||||||
context->m_hfnThink = NULL;
|
context->m_hfnThink = NULL;
|
||||||
//context->m_nNextThinkTick = TICK_NEVER_THINK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -2728,55 +2735,56 @@ static inline void ScriptStopContextThink( scriptthinkfunc_t *context )
|
|||||||
void CBaseEntity::ScriptContextThink()
|
void CBaseEntity::ScriptContextThink()
|
||||||
{
|
{
|
||||||
float flNextThink = FLT_MAX;
|
float flNextThink = FLT_MAX;
|
||||||
int nScheduledTick = 0;
|
float flScheduled = 0.0f;
|
||||||
|
|
||||||
for ( int i = 0; i < m_ScriptThinkFuncs.Count(); ++i )
|
for ( int i = 0; i < m_ScriptThinkFuncs.Count(); ++i )
|
||||||
{
|
{
|
||||||
scriptthinkfunc_t *cur = m_ScriptThinkFuncs[i];
|
scriptthinkfunc_t *cur = m_ScriptThinkFuncs[i];
|
||||||
|
|
||||||
if ( cur->m_nNextThinkTick == TICK_NEVER_THINK )
|
if ( cur->m_flNextThink == SCRIPT_NEVER_THINK )
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( cur->m_nNextThinkTick > gpGlobals->tickcount )
|
if ( cur->m_flNextThink > gpGlobals->curtime )
|
||||||
{
|
{
|
||||||
// There is more to execute, don't stop thinking if the rest are done.
|
if ( ( flScheduled == 0.0f ) || ( flScheduled > cur->m_flNextThink ) )
|
||||||
|
|
||||||
// Find the shortest schedule
|
|
||||||
if ( !nScheduledTick || nScheduledTick > cur->m_nNextThinkTick )
|
|
||||||
{
|
{
|
||||||
nScheduledTick = cur->m_nNextThinkTick;
|
flScheduled = cur->m_flNextThink;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
// going to run the script func
|
// going to run the script func
|
||||||
cur->m_nNextThinkTick = 0;
|
cur->m_flNextThink = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ScriptVariant_t varReturn;
|
ScriptVariant_t varReturn;
|
||||||
|
|
||||||
|
#ifndef CLIENT_DLL
|
||||||
if ( !cur->m_bNoParam )
|
if ( !cur->m_bNoParam )
|
||||||
{
|
{
|
||||||
|
#endif
|
||||||
ScriptVariant_t arg = m_hScriptInstance;
|
ScriptVariant_t arg = m_hScriptInstance;
|
||||||
if ( g_pScriptVM->ExecuteFunction( cur->m_hfnThink, &arg, 1, &varReturn, NULL, true ) == SCRIPT_ERROR )
|
if ( g_pScriptVM->ExecuteFunction( cur->m_hfnThink, &arg, 1, &varReturn, NULL, true ) == SCRIPT_ERROR )
|
||||||
{
|
{
|
||||||
cur->m_nNextThinkTick = TICK_NEVER_THINK;
|
cur->m_flNextThink = SCRIPT_NEVER_THINK;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
#ifndef CLIENT_DLL
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( g_pScriptVM->ExecuteFunction( cur->m_hfnThink, NULL, 0, &varReturn, NULL, true ) == SCRIPT_ERROR )
|
if ( g_pScriptVM->ExecuteFunction( cur->m_hfnThink, NULL, 0, &varReturn, NULL, true ) == SCRIPT_ERROR )
|
||||||
{
|
{
|
||||||
cur->m_nNextThinkTick = TICK_NEVER_THINK;
|
cur->m_flNextThink = SCRIPT_NEVER_THINK;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if ( cur->m_nNextThinkTick == TICK_NEVER_THINK )
|
if ( cur->m_flNextThink == SCRIPT_NEVER_THINK )
|
||||||
{
|
{
|
||||||
// stopped from script while thinking
|
// stopped from script while thinking
|
||||||
continue;
|
continue;
|
||||||
@ -2785,13 +2793,13 @@ void CBaseEntity::ScriptContextThink()
|
|||||||
float flReturn;
|
float flReturn;
|
||||||
if ( !varReturn.AssignTo( &flReturn ) )
|
if ( !varReturn.AssignTo( &flReturn ) )
|
||||||
{
|
{
|
||||||
cur->m_nNextThinkTick = TICK_NEVER_THINK;
|
cur->m_flNextThink = SCRIPT_NEVER_THINK;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( flReturn < 0.0f )
|
if ( flReturn < 0.0f )
|
||||||
{
|
{
|
||||||
cur->m_nNextThinkTick = TICK_NEVER_THINK;
|
cur->m_flNextThink = SCRIPT_NEVER_THINK;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2800,96 +2808,61 @@ void CBaseEntity::ScriptContextThink()
|
|||||||
flNextThink = flReturn;
|
flNextThink = flReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
cur->m_nNextThinkTick = TIME_TO_TICKS( gpGlobals->curtime + flReturn );
|
cur->m_flNextThink = gpGlobals->curtime + flReturn - 0.001;
|
||||||
}
|
}
|
||||||
|
|
||||||
// deferred safe removal
|
// deferred safe removal
|
||||||
for ( int i = 0; i < m_ScriptThinkFuncs.Count(); )
|
for ( int i = 0; i < m_ScriptThinkFuncs.Count(); )
|
||||||
{
|
{
|
||||||
if ( m_ScriptThinkFuncs[i]->m_nNextThinkTick == TICK_NEVER_THINK )
|
scriptthinkfunc_t *cur = m_ScriptThinkFuncs[i];
|
||||||
|
if ( cur->m_flNextThink == SCRIPT_NEVER_THINK )
|
||||||
{
|
{
|
||||||
ScriptStopContextThink( m_ScriptThinkFuncs[i] );
|
ScriptStopContextThink( cur );
|
||||||
delete m_ScriptThinkFuncs[i];
|
delete cur;
|
||||||
m_ScriptThinkFuncs.Remove(i);
|
m_ScriptThinkFuncs.Remove(i);
|
||||||
}
|
}
|
||||||
else ++i;
|
else ++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bNewNext = flNextThink < FLT_MAX;
|
if ( 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 ( flScheduled > 0.0f )
|
||||||
if ( nScheduledTick )
|
|
||||||
{
|
{
|
||||||
float flScheduledTime = TICKS_TO_TIME( nScheduledTick );
|
flNextThink = min( gpGlobals->curtime + flNextThink, flScheduled );
|
||||||
|
|
||||||
if ( bNewNext )
|
|
||||||
{
|
|
||||||
flNextThink = min( gpGlobals->curtime + flNextThink, flScheduledTime );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
flNextThink = flScheduledTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( bNewNext )
|
|
||||||
{
|
{
|
||||||
flNextThink = gpGlobals->curtime + flNextThink;
|
flNextThink = gpGlobals->curtime + flNextThink;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef GAME_DLL
|
if ( flScheduled > 0.0f )
|
||||||
flNextThink = TICK_NEVER_THINK;
|
{
|
||||||
#else
|
flNextThink = flScheduled;
|
||||||
flNextThink = CLIENT_THINK_NEVER;
|
}
|
||||||
#endif
|
else
|
||||||
|
{
|
||||||
|
flNextThink = SCRIPT_NEVER_THINK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
}
|
#ifdef GAME_DLL
|
||||||
else
|
int nNextThinkTick = GetNextThinkTick("ScriptContextThink");
|
||||||
|
float flNextThinkTime = TICKS_TO_TIME(nNextThinkTick);
|
||||||
|
|
||||||
|
// If internal next think tick is earlier than what we have here with flNextThink,
|
||||||
|
// whoever set that think may fail. In worst case scenario the entity may stop thinking.
|
||||||
|
if ( nNextThinkTick > gpGlobals->tickcount )
|
||||||
{
|
{
|
||||||
// Next think was set (from script) to a sooner tick while thinking?
|
if ( flNextThink == SCRIPT_NEVER_THINK )
|
||||||
|
Assert(0);
|
||||||
|
if ( flNextThinkTime < flNextThink )
|
||||||
Assert(0);
|
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
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef GAME_DLL
|
#ifdef GAME_DLL
|
||||||
SetNextThink( flNextThink, "ScriptContextThink" );
|
SetNextThink( flNextThink, "ScriptContextThink" );
|
||||||
@ -2898,8 +2871,10 @@ void CBaseEntity::ScriptContextThink()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CLIENT_DLL
|
||||||
// see ScriptSetThink
|
// see ScriptSetThink
|
||||||
static bool s_bScriptContextThinkNoParam = false;
|
static bool s_bScriptContextThinkNoParam = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
@ -2917,7 +2892,7 @@ void CBaseEntity::ScriptSetContextThink( const char* szContext, HSCRIPT hFunc, f
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
scriptthinkfunc_t *pf = NULL;
|
scriptthinkfunc_t *pf = NULL;
|
||||||
unsigned short hash = ( szContext && *szContext ) ? HashString( szContext ) : 0;
|
unsigned hash = szContext ? HashString( szContext ) : 0;
|
||||||
|
|
||||||
FOR_EACH_VEC( m_ScriptThinkFuncs, i )
|
FOR_EACH_VEC( m_ScriptThinkFuncs, i )
|
||||||
{
|
{
|
||||||
@ -2939,14 +2914,16 @@ void CBaseEntity::ScriptSetContextThink( const char* szContext, HSCRIPT hFunc, f
|
|||||||
m_ScriptThinkFuncs.SetGrowSize(1);
|
m_ScriptThinkFuncs.SetGrowSize(1);
|
||||||
m_ScriptThinkFuncs.AddToTail( pf );
|
m_ScriptThinkFuncs.AddToTail( pf );
|
||||||
|
|
||||||
pf->m_bNoParam = s_bScriptContextThinkNoParam;
|
|
||||||
pf->m_iContextHash = hash;
|
pf->m_iContextHash = hash;
|
||||||
|
#ifndef CLIENT_DLL
|
||||||
|
pf->m_bNoParam = s_bScriptContextThinkNoParam;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
// update existing
|
// update existing
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
if ( pf->m_nNextThinkTick == 0 )
|
if ( pf->m_flNextThink == 0 )
|
||||||
{
|
{
|
||||||
Warning("Script think ('%s') was changed while it was thinking!\n", szContext);
|
Warning("Script think ('%s') was changed while it was thinking!\n", szContext);
|
||||||
}
|
}
|
||||||
@ -2957,31 +2934,29 @@ void CBaseEntity::ScriptSetContextThink( const char* szContext, HSCRIPT hFunc, f
|
|||||||
float nextthink = gpGlobals->curtime + flTime;
|
float nextthink = gpGlobals->curtime + flTime;
|
||||||
|
|
||||||
pf->m_hfnThink = hFunc;
|
pf->m_hfnThink = hFunc;
|
||||||
pf->m_nNextThinkTick = TIME_TO_TICKS( nextthink );
|
pf->m_flNextThink = nextthink;
|
||||||
|
|
||||||
#ifdef GAME_DLL
|
#ifdef GAME_DLL
|
||||||
int nexttick = GetNextThinkTick( RegisterThinkContext( "ScriptContextThink" ) );
|
int nexttick = GetNextThinkTick( RegisterThinkContext( "ScriptContextThink" ) );
|
||||||
#else
|
if ( nexttick <= 0 || TICKS_TO_TIME(nexttick) > nextthink )
|
||||||
int nexttick = GetNextThinkTick();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// sooner than next think
|
|
||||||
if ( nexttick <= 0 || nexttick > pf->m_nNextThinkTick )
|
|
||||||
{
|
{
|
||||||
#ifdef GAME_DLL
|
|
||||||
SetContextThink( &CBaseEntity::ScriptContextThink, nextthink, "ScriptContextThink" );
|
SetContextThink( &CBaseEntity::ScriptContextThink, nextthink, "ScriptContextThink" );
|
||||||
#else
|
|
||||||
SetNextClientThink( nextthink );
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
// let it self adjust
|
||||||
|
SetNextClientThink( gpGlobals->curtime );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
// null func input, think exists
|
// null func input, think exists
|
||||||
else if ( pf )
|
else if ( pf )
|
||||||
{
|
{
|
||||||
pf->m_nNextThinkTick = TICK_NEVER_THINK;
|
pf->m_flNextThink = SCRIPT_NEVER_THINK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CLIENT_DLL
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// m_bNoParam and s_bScriptContextThinkNoParam exist only to keep backwards compatibility
|
// m_bNoParam and s_bScriptContextThinkNoParam exist only to keep backwards compatibility
|
||||||
// and are an alternative to this script closure:
|
// and are an alternative to this script closure:
|
||||||
@ -2991,7 +2966,6 @@ void CBaseEntity::ScriptSetContextThink( const char* szContext, HSCRIPT hFunc, f
|
|||||||
// SetContextThink( "", function(_){ return func() }, time )
|
// SetContextThink( "", function(_){ return func() }, time )
|
||||||
// }
|
// }
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
#ifndef CLIENT_DLL
|
|
||||||
void CBaseEntity::ScriptSetThink( HSCRIPT hFunc, float time )
|
void CBaseEntity::ScriptSetThink( HSCRIPT hFunc, float time )
|
||||||
{
|
{
|
||||||
s_bScriptContextThinkNoParam = true;
|
s_bScriptContextThinkNoParam = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user