Skip to content

Commit

Permalink
Merge pull request mapbase-source#105 from samisalreadytaken/dev3
Browse files Browse the repository at this point in the history
vscript additions and fixes 3
  • Loading branch information
Blixibon authored Mar 11, 2021
2 parents cc0eaf9 + 8d60db4 commit fc5b292
Show file tree
Hide file tree
Showing 33 changed files with 1,742 additions and 563 deletions.
17 changes: 17 additions & 0 deletions sp/src/game/client/c_baseentity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,7 @@ BEGIN_ENT_SCRIPTDESC_ROOT( C_BaseEntity, "Root class of all client-side entities

DEFINE_SCRIPTFUNC_NAMED( ScriptGetModelName, "GetModelName", "Returns the name of the model" )

DEFINE_SCRIPTFUNC_NAMED( ScriptStopSound, "StopSound", "Stops a sound from this entity." )
DEFINE_SCRIPTFUNC_NAMED( ScriptEmitSound, "EmitSound", "Plays a sound from this entity." )
DEFINE_SCRIPTFUNC_NAMED( VScriptPrecacheScriptSound, "PrecacheSoundScript", "Precache a sound for later playing." )
DEFINE_SCRIPTFUNC_NAMED( ScriptSoundDuration, "GetSoundDuration", "Returns float duration of the sound. Takes soundname and optional actormodelname." )
Expand All @@ -472,6 +473,7 @@ BEGIN_ENT_SCRIPTDESC_ROOT( C_BaseEntity, "Root class of all client-side entities
DEFINE_SCRIPTFUNC_NAMED( GetAbsAngles, "GetAngles", "Get entity pitch, yaw, roll as a vector" )
DEFINE_SCRIPTFUNC_NAMED( SetAbsAngles, "SetAngles", "Set entity pitch, yaw, roll" )

DEFINE_SCRIPTFUNC( SetSize, "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetBoundingMins, "GetBoundingMins", "Get a vector containing min bounds, centered on object" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetBoundingMaxs, "GetBoundingMaxs", "Get a vector containing max bounds, centered on object" )

Expand Down Expand Up @@ -541,7 +543,13 @@ BEGIN_ENT_SCRIPTDESC_ROOT( C_BaseEntity, "Root class of all client-side entities
DEFINE_SCRIPTFUNC_NAMED( IsBaseCombatWeapon, "IsWeapon", "Returns true if this entity is a weapon." )
DEFINE_SCRIPTFUNC( IsWorld, "Returns true if this entity is the world." )

DEFINE_SCRIPTFUNC( SetModel, "Set client-only entity model" )
//DEFINE_SCRIPTFUNC_NAMED( ScriptInitializeAsClientEntity, "InitializeAsClientEntity", "" )
DEFINE_SCRIPTFUNC_NAMED( Remove, "Destroy", "Remove clientside entity" )
DEFINE_SCRIPTFUNC_NAMED( GetEntityIndex, "entindex", "" )

DEFINE_SCRIPTFUNC_NAMED( ScriptSetContextThink, "SetContextThink", "Set a think function on this entity." )

#endif

END_SCRIPTDESC();
Expand Down Expand Up @@ -1334,6 +1342,15 @@ void C_BaseEntity::Term()
{
g_pScriptVM->RemoveInstance( m_hScriptInstance );
m_hScriptInstance = NULL;

#ifdef MAPBASE_VSCRIPT
FOR_EACH_VEC( m_ScriptThinkFuncs, i )
{
HSCRIPT h = m_ScriptThinkFuncs[i]->m_hfnThink;
if ( h ) g_pScriptVM->ReleaseScript( h );
}
m_ScriptThinkFuncs.PurgeAndDeleteElements();
#endif
}
}

Expand Down
20 changes: 20 additions & 0 deletions sp/src/game/client/c_baseentity.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,16 @@ struct thinkfunc_t
int m_nLastThinkTick;
};

#ifdef MAPBASE_VSCRIPT
struct scriptthinkfunc_t
{
int m_nNextThinkTick;
HSCRIPT m_hfnThink;
unsigned short m_iContextHash;
bool m_bNoParam;
};
#endif

#define CREATE_PREDICTED_ENTITY( className ) \
C_BaseEntity::CreatePredictedEntityByName( className, __FILE__, __LINE__ );

Expand Down Expand Up @@ -1173,6 +1183,7 @@ class C_BaseEntity : public IClientEntity
#ifdef MAPBASE_VSCRIPT
const char* ScriptGetModelName( void ) const { return STRING(GetModelName()); }

void ScriptStopSound(const char* soundname);
void ScriptEmitSound(const char* soundname);
float ScriptSoundDuration(const char* soundname, const char* actormodel);

Expand Down Expand Up @@ -1519,6 +1530,15 @@ class C_BaseEntity : public IClientEntity
CUtlVector< thinkfunc_t > m_aThinkFunctions;
int m_iCurrentThinkContext;

#ifdef MAPBASE_VSCRIPT
public:
void ScriptSetContextThink( const char* szContext, HSCRIPT hFunc, float time );
void ScriptContextThink();
private:
CUtlVector< scriptthinkfunc_t* > m_ScriptThinkFuncs;
public:
#endif

// Object eye position
Vector m_vecViewOffset;

Expand Down
2 changes: 2 additions & 0 deletions sp/src/game/client/c_world.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class C_World : public C_BaseEntity
#endif

#ifdef MAPBASE_VSCRIPT
void ClientThink() { ScriptContextThink(); }

// -2 = Use server language
ScriptLanguage_t GetScriptLanguage() { return (ScriptLanguage_t)(m_iScriptLanguageClient != -2 ? m_iScriptLanguageClient : m_iScriptLanguageServer); }
#endif
Expand Down
6 changes: 6 additions & 0 deletions sp/src/game/client/vscript_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,11 @@ bool DoIncludeScript( const char *pszScript, HSCRIPT hScope )
}

#ifdef MAPBASE_VSCRIPT
static float FrameTime()
{
return gpGlobals->frametime;
}

static bool Con_IsVisible()
{
return engine->Con_IsVisible();
Expand Down Expand Up @@ -585,6 +590,7 @@ bool VScriptClientInit()
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, FrameTime, "Get the time spent on the client in the last frame" );
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" );
Expand Down
12 changes: 10 additions & 2 deletions sp/src/game/client/vscript_client.nut
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,26 @@ static char g_Script_vscript_client[] = R"vscript(
//
//=============================================================================
local DoUniqueString = DoUniqueString
local DoDispatchParticleEffect = DoDispatchParticleEffect
function UniqueString( string = "" )
{
return DoUniqueString( string.tostring() );
return DoUniqueString( "" + string );
}
function IncludeScript( name, scope = null )
{
if ( scope == null )
if ( !scope )
{
scope = this;
}
return ::DoIncludeScript( name, scope );
}
function DispatchParticleEffect( particleName, origin, angles, entity = null )
{
DoDispatchParticleEffect( particleName, origin, angles, entity );
}
)vscript";
2 changes: 1 addition & 1 deletion sp/src/game/server/ai_speech.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1210,7 +1210,7 @@ void CAI_Expresser::SpeechMsg( CBaseEntity *pFlex, const char *pszFormat, ... )
}
else
{
CGMsg( 1, CON_GROUP_CHOREO "%s", string );
CGMsg( 1, CON_GROUP_CHOREO, "%s", string );
}
UTIL_LogPrintf( string );
}
Expand Down
176 changes: 5 additions & 171 deletions sp/src/game/server/baseentity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2222,6 +2222,7 @@ BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities"
DEFINE_SCRIPTFUNC( SetModel, "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetModelName, "GetModelName", "Returns the name of the model" )

DEFINE_SCRIPTFUNC_NAMED( ScriptStopSound, "StopSound", "Stops a sound from this entity." )
DEFINE_SCRIPTFUNC_NAMED( ScriptEmitSound, "EmitSound", "Plays a sound from this entity." )
DEFINE_SCRIPTFUNC_NAMED( VScriptPrecacheScriptSound, "PrecacheSoundScript", "Precache a sound for later playing." )
DEFINE_SCRIPTFUNC_NAMED( ScriptSoundDuration, "GetSoundDuration", "Returns float duration of the sound. Takes soundname and optional actormodelname.")
Expand Down Expand Up @@ -2282,11 +2283,11 @@ BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities"
DEFINE_SCRIPTFUNC_NAMED( ScriptSetAngles, "SetAngles", "Set entity pitch, yaw, roll")
DEFINE_SCRIPTFUNC_NAMED( ScriptGetAngles, "GetAngles", "Get entity pitch, yaw, roll as a vector")

DEFINE_SCRIPTFUNC_NAMED( ScriptSetSize, "SetSize", "" )
DEFINE_SCRIPTFUNC( SetSize, "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetBoundingMins, "GetBoundingMins", "Get a vector containing min bounds, centered on object")
DEFINE_SCRIPTFUNC_NAMED( ScriptGetBoundingMaxs, "GetBoundingMaxs", "Get a vector containing max bounds, centered on object")

DEFINE_SCRIPTFUNC_NAMED( ScriptUtilRemove, "Destroy", "" )
DEFINE_SCRIPTFUNC_NAMED( Remove, "Destroy", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptSetOwner, "SetOwner", "" )
DEFINE_SCRIPTFUNC_NAMED( GetTeamNumber, "GetTeam", "" )
DEFINE_SCRIPTFUNC_NAMED( ChangeTeam, "SetTeam", "" )
Expand Down Expand Up @@ -2587,10 +2588,10 @@ void CBaseEntity::UpdateOnRemove( void )
#ifdef MAPBASE_VSCRIPT
FOR_EACH_VEC( m_ScriptThinkFuncs, i )
{
HSCRIPT h = m_ScriptThinkFuncs[i].m_hfnThink;
HSCRIPT h = m_ScriptThinkFuncs[i]->m_hfnThink;
if ( h ) g_pScriptVM->ReleaseScript( h );
}
m_ScriptThinkFuncs.Purge();
m_ScriptThinkFuncs.PurgeAndDeleteElements();
#endif // MAPBASE_VSCRIPT
}
}
Expand Down Expand Up @@ -8664,173 +8665,6 @@ void CBaseEntity::ScriptStopThinkFunction()
m_iszScriptThinkFunction = NULL_STRING;
SetContextThink( NULL, TICK_NEVER_THINK, "ScriptThink" );
}


static inline void ScriptStopContextThink( scriptthinkfunc_t *context )
{
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 = 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.

// also find the shortest schedule
if ( !nScheduledTick || nScheduledTick > cur->m_nNextThinkTick )
{
nScheduledTick = cur->m_nNextThinkTick;
}
continue;
}

ScriptVariant_t varReturn;

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
{
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()
{
ScriptSetContextThink( NULL, NULL, 0.0f );
}

#endif // MAPBASE_VSCRIPT

//-----------------------------------------------------------------------------
Expand Down
Loading

0 comments on commit fc5b292

Please sign in to comment.