Merge pull request #59 from samisalreadytaken/pr18

vscript additions and fixes
This commit is contained in:
Blixibon 2020-10-31 21:01:30 -05:00 committed by GitHub
commit dbd583b07c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 1456 additions and 109 deletions

View File

@ -301,6 +301,7 @@ BEGIN_ENT_SCRIPTDESC( CBaseAnimating, CBaseEntity, "Animating models" )
DEFINE_SCRIPTFUNC( GetSequence, "Gets the current sequence" )
DEFINE_SCRIPTFUNC( SetSequence, "Sets the current sequence" )
DEFINE_SCRIPTFUNC( SequenceLoops, "Loops the current sequence" )
DEFINE_SCRIPTFUNC_NAMED( ScriptSequenceDuration, "SequenceDuration", "Get the specified sequence duration" )
DEFINE_SCRIPTFUNC( LookupSequence, "Gets the index of the specified sequence name" )
DEFINE_SCRIPTFUNC( LookupActivity, "Gets the ID of the specified activity name" )
DEFINE_SCRIPTFUNC_NAMED( HasMovement, "SequenceHasMovement", "Checks if the specified sequence has movement" )
@ -312,6 +313,10 @@ BEGIN_ENT_SCRIPTDESC( CBaseAnimating, CBaseEntity, "Animating models" )
DEFINE_SCRIPTFUNC_NAMED( ScriptSelectWeightedSequence, "SelectWeightedSequence", "Selects a sequence for the specified activity ID" )
DEFINE_SCRIPTFUNC_NAMED( ScriptSelectHeaviestSequence, "SelectHeaviestSequence", "Selects the sequence with the heaviest weight for the specified activity ID" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetSequenceKeyValues, "GetSequenceKeyValues", "Get a KeyValue class instance on the specified sequence. WARNING: This uses the same KeyValue pointer as GetModelKeyValues!" )
DEFINE_SCRIPTFUNC( GetPlaybackRate, "" )
DEFINE_SCRIPTFUNC( SetPlaybackRate, "" )
DEFINE_SCRIPTFUNC( GetCycle, "" )
DEFINE_SCRIPTFUNC( SetCycle, "" )
DEFINE_SCRIPTFUNC( GetSkin, "Gets the model's skin" )
DEFINE_SCRIPTFUNC( SetSkin, "Sets the model's skin" )
#endif

View File

@ -100,6 +100,9 @@ public:
inline float SequenceDuration( void ) { return SequenceDuration( m_nSequence ); }
float SequenceDuration( CStudioHdr *pStudioHdr, int iSequence );
inline float SequenceDuration( int iSequence ) { return SequenceDuration(GetModelPtr(), iSequence); }
#ifdef MAPBASE_VSCRIPT
inline float ScriptSequenceDuration( int iSequence ) { return SequenceDuration(GetModelPtr(), iSequence); }
#endif
float GetSequenceCycleRate( CStudioHdr *pStudioHdr, int iSequence );
inline float GetSequenceCycleRate( int iSequence ) { return GetSequenceCycleRate(GetModelPtr(),iSequence); }
float GetLastVisibleCycle( CStudioHdr *pStudioHdr, int iSequence );

View File

@ -1329,6 +1329,31 @@ void CBaseEntity::FireNamedOutput( const char *pszOutput, variant_t variant, CBa
}
}
#ifdef MAPBASE_VSCRIPT
void CBaseEntity::ScriptFireOutput( const char *pszOutput, HSCRIPT hActivator, HSCRIPT hCaller, const char *szValue, float flDelay )
{
variant_t value;
value.SetString( MAKE_STRING(szValue) );
FireNamedOutput( pszOutput, value, ToEnt(hActivator), ToEnt(hCaller), flDelay );
}
float CBaseEntity::GetMaxOutputDelay( const char *pszOutput )
{
CBaseEntityOutput *pOutput = FindNamedOutput( pszOutput );
if ( pOutput )
{
return pOutput->GetMaxDelay();
}
return 0;
}
void CBaseEntity::CancelEventsByInput( const char *szInput )
{
g_EventQueue.CancelEventsByInput( this, szInput );
}
#endif // MAPBASE_VSCRIPT
CBaseEntityOutput *CBaseEntity::FindNamedOutput( const char *pszOutput )
{
if ( pszOutput == NULL )
@ -2271,6 +2296,11 @@ BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities"
DEFINE_SCRIPTFUNC_NAMED( ScriptClassify, "Classify", "Get Class_T class ID" )
DEFINE_SCRIPTFUNC_NAMED( ScriptAcceptInput, "AcceptInput", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptFireOutput, "FireOutput", "Fire an entity output" )
DEFINE_SCRIPTFUNC( GetMaxOutputDelay, "Get the longest delay for all events attached to an output" )
DEFINE_SCRIPTFUNC( CancelEventsByInput, "Cancel all I/O events for this entity, match input" )
DEFINE_SCRIPTFUNC_NAMED( ScriptAddOutput, "AddOutput", "Add an output" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetKeyValue, "GetKeyValue", "Get a keyvalue" )
@ -2321,6 +2351,9 @@ BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities"
DEFINE_SCRIPTFUNC( AddEFlags, "Add Eflags" )
DEFINE_SCRIPTFUNC( RemoveEFlags, "Remove Eflags" )
DEFINE_SCRIPTFUNC( GetTransmitState, "" )
DEFINE_SCRIPTFUNC( SetTransmitState, "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetMoveType, "GetMoveType", "Get the move type" )
DEFINE_SCRIPTFUNC_NAMED( ScriptSetMoveType, "SetMoveType", "Set the move type" )
@ -2474,9 +2507,18 @@ void CBaseEntity::UpdateOnRemove( void )
{
CallScriptFunctionHandle( hFunc, NULL );
}
#endif
#endif // MAPBASE_VSCRIPT
g_pScriptVM->RemoveInstance( m_hScriptInstance );
m_hScriptInstance = NULL;
#ifdef MAPBASE_VSCRIPT
if ( m_hfnThink )
{
g_pScriptVM->ReleaseScript( m_hfnThink );
m_hfnThink = NULL;
}
#endif // MAPBASE_VSCRIPT
}
}
@ -4411,7 +4453,11 @@ bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator,
// found a match
// mapper debug message
#ifdef MAPBASE
ConColorMsg( 2, Color(CON_COLOR_DEV_VERBOSE), "(%0.2f) input %s: %s.%s(%s)\n", gpGlobals->curtime, pCaller ? STRING(pCaller->m_iName.Get()) : "<NULL>", GetDebugName(), szInputName, Value.String() );
#else
DevMsg( 2, "(%0.2f) input %s: %s.%s(%s)\n", gpGlobals->curtime, pCaller ? STRING(pCaller->m_iName.Get()) : "<NULL>", GetDebugName(), szInputName, Value.String() );
#endif
ADD_DEBUG_HISTORY( HISTORY_ENTITY_IO, szBuffer );
if (m_debugOverlays & OVERLAY_MESSAGE_BIT)
@ -4544,10 +4590,25 @@ bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator,
}
}
#ifdef MAPBASE
ConColorMsg( 2, Color(CON_COLOR_DEV_VERBOSE), "unhandled input: (%s) -> (%s,%s)\n", szInputName, STRING(m_iClassname), GetDebugName() );
#else
DevMsg( 2, "unhandled input: (%s) -> (%s,%s)\n", szInputName, STRING(m_iClassname), GetDebugName()/*,", from (%s,%s)" STRING(pCaller->m_iClassname), STRING(pCaller->m_iName.Get())*/ );
#endif
return false;
}
#ifdef MAPBASE_VSCRIPT
bool CBaseEntity::ScriptAcceptInput( const char *szInputName, const char *szValue, HSCRIPT hActivator, HSCRIPT hCaller )
{
variant_t value;
value.SetString( MAKE_STRING(szValue) );
return AcceptInput( szInputName, ToEnt(hActivator), ToEnt(hCaller), value, 0 );
}
#endif
//-----------------------------------------------------------------------------
// Purpose: Input handler for the entity alpha.
// Input : nAlpha - Alpha value (0 - 255).
@ -4587,6 +4648,17 @@ void CBaseEntity::InputColor( inputdata_t &inputdata )
void CBaseEntity::InputUse( inputdata_t &inputdata )
{
Use( inputdata.pActivator, inputdata.pCaller, (USE_TYPE)inputdata.nOutputID, 0 );
#ifdef MAPBASE
IGameEvent *event = gameeventmanager->CreateEvent( "player_use" );
if ( event )
{
event->SetInt( "userid", inputdata.pActivator && inputdata.pActivator->IsPlayer() ?
((CBasePlayer*)inputdata.pActivator)->GetUserID() : 0 );
event->SetInt( "entity", entindex() );
gameeventmanager->FireEvent( event );
}
#endif // MAPBASE
}
@ -4702,7 +4774,19 @@ void CBaseEntity::InputKill( inputdata_t &inputdata )
m_OnKilled.FireOutput( inputdata.pActivator, this );
#endif
#ifdef MAPBASE
// Kick players
if ( IsPlayer() )
{
engine->ServerCommand( UTIL_VarArgs( "kickid %d CBaseEntity::InputKill()\n", engine->GetPlayerUserId(edict()) ) );
}
else
{
UTIL_Remove( this );
}
#else
UTIL_Remove( this );
#endif
}
void CBaseEntity::InputKillHierarchy( inputdata_t &inputdata )
@ -4724,6 +4808,9 @@ void CBaseEntity::InputKillHierarchy( inputdata_t &inputdata )
#ifdef MAPBASE
m_OnKilled.FireOutput( inputdata.pActivator, this );
// Kicking players in InputKillHierarchy does not exist in future Valve games
// if ( IsPlayer() )
#endif
UTIL_Remove( this );
@ -8410,7 +8497,7 @@ void CBaseEntity::ScriptThink(void)
#ifdef MAPBASE_VSCRIPT
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CBaseEntity::ScriptSetThinkFunction(const char *szFunc, float time)
void CBaseEntity::ScriptSetThinkFunction( const char *szFunc, float flTime )
{
// Empty string stops thinking
if (!szFunc || szFunc[0] == '\0')
@ -8420,7 +8507,8 @@ void CBaseEntity::ScriptSetThinkFunction(const char *szFunc, float time)
else
{
m_iszScriptThinkFunction = AllocPooledString(szFunc);
SetContextThink( &CBaseEntity::ScriptThink, gpGlobals->curtime + time, "ScriptThink" );
flTime = max( 0, flTime );
SetContextThink( &CBaseEntity::ScriptThink, gpGlobals->curtime + flTime, "ScriptThink" );
}
}
@ -8434,37 +8522,30 @@ void CBaseEntity::ScriptStopThinkFunction()
//-----------------------------------------------------------------------------
void CBaseEntity::ScriptThinkH()
{
if (m_hfnThink)
{
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");
}
else
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" );
}
void CBaseEntity::ScriptSetThink(HSCRIPT hFunc, float time)
void CBaseEntity::ScriptSetThink( HSCRIPT hFunc, float flTime )
{
if (hFunc)
if ( hFunc )
{
if (m_hfnThink)
if ( m_hfnThink )
{
// release old func
ScriptStopThink();
@ -8473,7 +8554,8 @@ void CBaseEntity::ScriptSetThink(HSCRIPT hFunc, float time)
// no type check here, print error on call instead
m_hfnThink = hFunc;
SetContextThink( &CBaseEntity::ScriptThinkH, gpGlobals->curtime + time, "ScriptThinkH" );
flTime = max( 0, flTime );
SetContextThink( &CBaseEntity::ScriptThinkH, gpGlobals->curtime + flTime, "ScriptThinkH" );
}
else
{

View File

@ -581,6 +581,12 @@ public:
void ValidateEntityConnections();
void FireNamedOutput( const char *pszOutput, variant_t variant, CBaseEntity *pActivator, CBaseEntity *pCaller, float flDelay = 0.0f );
CBaseEntityOutput *FindNamedOutput( const char *pszOutput );
#ifdef MAPBASE_VSCRIPT
void ScriptFireOutput( const char *pszOutput, HSCRIPT hActivator, HSCRIPT hCaller, const char *szValue, float flDelay );
float GetMaxOutputDelay( const char *pszOutput );
void CancelEventsByInput( const char *szInput );
#endif
// Activate - called for each entity after each load game and level load
virtual void Activate( void );
@ -656,6 +662,9 @@ public:
// handles an input (usually caused by outputs)
// returns true if the the value in the pass in should be set, false if the input is to be ignored
virtual bool AcceptInput( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, int outputID );
#ifdef MAPBASE_VSCRIPT
bool ScriptAcceptInput(const char *szInputName, const char *szValue, HSCRIPT hActivator, HSCRIPT hCaller);
#endif
//
// Input handlers.

View File

@ -302,7 +302,11 @@ void CBaseEntityOutput::FireOutput(variant_t Value, CBaseEntity *pActivator, CBa
ev->m_flDelay,
STRING(ev->m_iParameter) );
#ifdef MAPBASE
ConColorMsg( 2, Color(CON_COLOR_DEV_VERBOSE), "%s", szBuffer );
#else
DevMsg( 2, "%s", szBuffer );
#endif
ADD_DEBUG_HISTORY( HISTORY_ENTITY_IO, szBuffer );
}
else
@ -321,7 +325,11 @@ void CBaseEntityOutput::FireOutput(variant_t Value, CBaseEntity *pActivator, CBa
STRING(ev->m_iTargetInput),
STRING(ev->m_iParameter) );
#ifdef MAPBASE
ConColorMsg( 2, Color(CON_COLOR_DEV_VERBOSE), "%s", szBuffer );
#else
DevMsg( 2, "%s", szBuffer );
#endif
ADD_DEBUG_HISTORY( HISTORY_ENTITY_IO, szBuffer );
}
@ -342,7 +350,12 @@ void CBaseEntityOutput::FireOutput(variant_t Value, CBaseEntity *pActivator, CBa
{
char szBuffer[256];
Q_snprintf( szBuffer, sizeof(szBuffer), "Removing from action list: (%s,%s) -> (%s,%s)\n", pCaller ? STRING(pCaller->m_iClassname) : "NULL", pCaller ? STRING(pCaller->GetEntityName()) : "NULL", STRING(ev->m_iTarget), STRING(ev->m_iTargetInput));
#ifdef MAPBASE
ConColorMsg( 2, Color(CON_COLOR_DEV_VERBOSE), "%s", szBuffer );
#else
DevMsg( 2, "%s", szBuffer );
#endif
ADD_DEBUG_HISTORY( HISTORY_ENTITY_IO, szBuffer );
bRemove = true;
}
@ -836,7 +849,12 @@ void CEventQueue::Dump( void )
//-----------------------------------------------------------------------------
// Purpose: adds the action into the correct spot in the priority queue, targeting entity via string name
//-----------------------------------------------------------------------------
void CEventQueue::AddEvent( const char *target, const char *targetInput, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID )
#ifdef MAPBASE_VSCRIPT
intptr_t
#else
void
#endif
CEventQueue::AddEvent( const char *target, const char *targetInput, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID )
{
// build the new event
EventQueuePrioritizedEvent_t *newEvent = new EventQueuePrioritizedEvent_t;
@ -854,12 +872,21 @@ void CEventQueue::AddEvent( const char *target, const char *targetInput, variant
newEvent->m_iOutputID = outputID;
AddEvent( newEvent );
#ifdef MAPBASE_VSCRIPT
return reinterpret_cast<intptr_t>(newEvent); // POINTER_TO_INT
#endif
}
//-----------------------------------------------------------------------------
// Purpose: adds the action into the correct spot in the priority queue, targeting entity via pointer
//-----------------------------------------------------------------------------
void CEventQueue::AddEvent( CBaseEntity *target, const char *targetInput, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID )
#ifdef MAPBASE_VSCRIPT
intptr_t
#else
void
#endif
CEventQueue::AddEvent( CBaseEntity *target, const char *targetInput, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID )
{
// build the new event
EventQueuePrioritizedEvent_t *newEvent = new EventQueuePrioritizedEvent_t;
@ -877,6 +904,10 @@ void CEventQueue::AddEvent( CBaseEntity *target, const char *targetInput, varian
newEvent->m_iOutputID = outputID;
AddEvent( newEvent );
#ifdef MAPBASE_VSCRIPT
return reinterpret_cast<intptr_t>(newEvent);
#endif
}
void CEventQueue::AddEvent( CBaseEntity *target, const char *action, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID )
@ -1072,7 +1103,11 @@ void CEventQueue::ServiceEvents( void )
char szBuffer[256];
Q_snprintf( szBuffer, sizeof(szBuffer), "unhandled input: (%s) -> (%s), from (%s,%s); target entity not found\n", STRING(pe->m_iTargetInput), STRING(pe->m_iTarget), pClass, pName );
#ifdef MAPBASE
ConColorMsg( 2, Color(CON_COLOR_DEV_VERBOSE), "%s", szBuffer );
#else
DevMsg( 2, "%s", szBuffer );
#endif
ADD_DEBUG_HISTORY( HISTORY_ENTITY_IO, szBuffer );
}
@ -1220,6 +1255,80 @@ void ServiceEventQueue( void )
}
#ifdef MAPBASE_VSCRIPT
//-----------------------------------------------------------------------------
// Remove events on entity by input.
//-----------------------------------------------------------------------------
void CEventQueue::CancelEventsByInput( CBaseEntity *pTarget, const char *szInput )
{
if ( !pTarget )
return;
string_t iszDebugName = MAKE_STRING( pTarget->GetDebugName() );
EventQueuePrioritizedEvent_t *pCur = m_Events.m_pNext;
while ( pCur )
{
bool bRemove = false;
if ( pTarget == pCur->m_pEntTarget || pCur->m_iTarget == iszDebugName )
{
if ( !V_strncmp( STRING(pCur->m_iTargetInput), szInput, strlen(szInput) ) )
{
bRemove = true;
}
}
EventQueuePrioritizedEvent_t *pPrev = pCur;
pCur = pCur->m_pNext;
if ( bRemove )
{
RemoveEvent(pPrev);
delete pPrev;
}
}
}
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 )
{
if ( pCur == pe )
{
RemoveEvent(pCur);
delete pCur;
return true;
}
}
return false;
}
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 )
{
if ( pCur == pe )
{
return (pCur->m_flFireTime - gpGlobals->curtime);
}
}
return 0.f;
}
#endif // MAPBASE_VSCRIPT
// save data description for the event queue
BEGIN_SIMPLE_DATADESC( CEventQueue )

View File

@ -151,4 +151,8 @@ class CSound;
#include "ndebugoverlay.h"
#include "recipientfilter.h"
#ifdef MAPBASE
#define CON_COLOR_DEV_VERBOSE 192,128,192,255
#endif
#endif // CBASE_H

View File

@ -40,9 +40,14 @@ class CEventQueue
{
public:
// pushes an event into the queue, targeting a string name (m_iName), or directly by a pointer
void AddEvent( const char *target, const char *action, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID = 0 );
#ifdef MAPBASE_VSCRIPT
intptr_t AddEvent( const char *target, const char *action, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID = 0 );
intptr_t AddEvent( CBaseEntity *target, const char *action, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID = 0 );
#else
void AddEvent( const char *target, const char *action, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID = 0 );
void AddEvent( CBaseEntity *target, const char *action, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID = 0 );
#endif
void AddEvent( CBaseEntity *target, const char *action, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID = 0 );
void AddEvent( CBaseEntity *target, const char *action, variant_t Value, float fireDelay, CBaseEntity *pActivator, CBaseEntity *pCaller, int outputID = 0 );
void CancelEvents( CBaseEntity *pCaller );
void CancelEventOn( CBaseEntity *pTarget, const char *sInputName );
@ -66,6 +71,12 @@ public:
void Dump( void );
#ifdef MAPBASE_VSCRIPT
void CancelEventsByInput( CBaseEntity *pTarget, const char *szInput );
bool RemoveEvent( intptr_t event );
float GetTimeLeft( intptr_t event );
#endif // MAPBASE_VSCRIPT
private:
void AddEvent( EventQueuePrioritizedEvent_t *event );

View File

@ -110,8 +110,6 @@ bool CLogicEventListener::KeyValue(const char *szKeyName, const char *szValue)
//-----------------------------------------------------------------------------
void CLogicEventListener::FireGameEvent( IGameEvent *event )
{
DevMsg("Heard Event\n");
if (m_bDisabled)
return;

View File

@ -131,6 +131,16 @@ BEGIN_DATADESC( CBaseTrigger )
END_DATADESC()
#ifdef MAPBASE_VSCRIPT
BEGIN_ENT_SCRIPTDESC( CBaseTrigger, CBaseEntity, "Trigger entity" )
DEFINE_SCRIPTFUNC( Enable, "" )
DEFINE_SCRIPTFUNC( Disable, "" )
DEFINE_SCRIPTFUNC( TouchTest, "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptIsTouching, "IsTouching", "Checks whether the passed entity is touching the trigger." )
END_SCRIPTDESC();
#endif // MAPBASE_VSCRIPT
LINK_ENTITY_TO_CLASS( trigger, CBaseTrigger );
@ -560,6 +570,19 @@ bool CBaseTrigger::IsTouching( CBaseEntity *pOther )
return ( m_hTouchingEntities.Find( hOther ) != m_hTouchingEntities.InvalidIndex() );
}
#ifdef MAPBASE_VSCRIPT
bool CBaseTrigger::ScriptIsTouching( HSCRIPT hOther )
{
CBaseEntity *pOther = ToEnt(hOther);
if ( !pOther )
return false;
EHANDLE eOther;
eOther = pOther;
return ( m_hTouchingEntities.Find( eOther ) != m_hTouchingEntities.InvalidIndex() );
}
#endif // MAPBASE_VSCRIPT
//-----------------------------------------------------------------------------
// Purpose: Return a pointer to the first entity of the specified type being touched by this trigger
//-----------------------------------------------------------------------------
@ -3605,10 +3628,18 @@ int CTriggerCamera::ScriptGetFov(void)
//-----------------------------------------------------------------------------
void CTriggerCamera::ScriptSetFov(int iFOV, float fovSpeed)
{
if (m_hPlayer)
#ifdef MAPBASE
m_fov = iFOV;
m_fovSpeed = fovSpeed;
if ( m_state == USE_ON && m_hPlayer )
{
#else
if ( m_hPlayer )
{
m_fov = iFOV;
m_fovSpeed = fovSpeed;
#endif
CBasePlayer* pBasePlayer = (CBasePlayer*)m_hPlayer.Get();
pBasePlayer->SetFOV(this, iFOV, fovSpeed);

View File

@ -82,6 +82,9 @@ public:
virtual void StartTouch(CBaseEntity *pOther);
virtual void EndTouch(CBaseEntity *pOther);
bool IsTouching( CBaseEntity *pOther );
#ifdef MAPBASE_VSCRIPT
bool ScriptIsTouching( HSCRIPT hOther );
#endif
CBaseEntity *GetTouchedEntityOfType( const char *sClassName );
@ -123,6 +126,9 @@ protected:
#endif
DECLARE_DATADESC();
#ifdef MAPBASE_VSCRIPT
DECLARE_ENT_SCRIPTDESC();
#endif
};
//-----------------------------------------------------------------------------

View File

@ -17,7 +17,6 @@
#include "gamerules.h"
#include "vscript_server.nut"
#ifdef MAPBASE_VSCRIPT
#include "particle_parse.h"
#include "world.h"
#endif
@ -106,7 +105,12 @@ public:
{
return ToHScript( gEntList.FindEntityByClassnameWithin( ToEnt( hStartEntity ), szName, vecSrc, flRadius ) );
}
#ifdef MAPBASE_VSCRIPT
HSCRIPT FindByClassnameWithinBox( HSCRIPT hStartEntity , const char *szName, const Vector &vecMins, const Vector &vecMaxs )
{
return ToHScript( gEntList.FindEntityByClassnameWithin( ToEnt( hStartEntity ), szName, vecMins, vecMaxs ) );
}
#endif
private:
} g_ScriptEntityIterator;
@ -126,6 +130,9 @@ BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptEntityIterator, "CEntities", SCRIPT_SINGLETO
DEFINE_SCRIPTFUNC( FindByNameWithin, "Find entities by name within a radius. Pass 'null' to start an iteration, or reference to a previously found entity to continue a search" )
DEFINE_SCRIPTFUNC( FindByClassnameNearest, "Find entities by class name nearest to a point." )
DEFINE_SCRIPTFUNC( FindByClassnameWithin, "Find entities by class name within a radius. Pass 'null' to start an iteration, or reference to a previously found entity to continue a search" )
#ifdef MAPBASE_VSCRIPT
DEFINE_SCRIPTFUNC( FindByClassnameWithinBox, "Find entities by class name within an AABB. Pass 'null' to start an iteration, or reference to a previously found entity to continue a search" )
#endif
END_SCRIPTDESC();
// ----------------------------------------------------------------------------
@ -815,6 +822,12 @@ static void SendToConsole( const char *pszCommand )
engine->ClientCommand( pPlayer->edict(), pszCommand );
}
static void SendToConsoleServer( const char *pszCommand )
{
// TODO: whitelist for multiplayer
engine->ServerCommand( UTIL_VarArgs("%s\n", pszCommand) );
}
static const char *GetMapName()
{
return STRING( gpGlobals->mapname );
@ -827,7 +840,11 @@ static const char *DoUniqueString( const char *pszBase )
return szBuf;
}
#ifdef MAPBASE_VSCRIPT
static int DoEntFire( const char *pszTarget, const char *pszAction, const char *pszValue, float delay, HSCRIPT hActivator, HSCRIPT hCaller )
#else
static void DoEntFire( const char *pszTarget, const char *pszAction, const char *pszValue, float delay, HSCRIPT hActivator, HSCRIPT hCaller )
#endif
{
const char *target = "", *action = "Use";
variant_t value;
@ -841,7 +858,7 @@ static void DoEntFire( const char *pszTarget, const char *pszAction, const char
// ent_fire point_servercommand command "rcon_password mynewpassword"
if ( gpGlobals->maxClients > 1 && V_stricmp( target, "point_servercommand" ) == 0 )
{
return;
return 0;
}
if ( *pszAction )
@ -857,6 +874,9 @@ static void DoEntFire( const char *pszTarget, const char *pszAction, const char
delay = 0;
}
#ifdef MAPBASE_VSCRIPT
return
#endif
g_EventQueue.AddEvent( target, action, value, delay, ToEnt(hActivator), ToEnt(hCaller) );
}
@ -891,7 +911,11 @@ HSCRIPT CreateProp( const char *pszEntityName, const Vector &vOrigin, const char
//--------------------------------------------------------------------------------------------------
// Use an entity's script instance to add an entity IO event (used for firing events on unnamed entities from vscript)
//--------------------------------------------------------------------------------------------------
#ifdef MAPBASE_VSCRIPT
static int DoEntFireByInstanceHandle( HSCRIPT hTarget, const char *pszAction, const char *pszValue, float delay, HSCRIPT hActivator, HSCRIPT hCaller )
#else
static void DoEntFireByInstanceHandle( HSCRIPT hTarget, const char *pszAction, const char *pszValue, float delay, HSCRIPT hActivator, HSCRIPT hCaller )
#endif
{
const char *action = "Use";
variant_t value;
@ -914,9 +938,16 @@ static void DoEntFireByInstanceHandle( HSCRIPT hTarget, const char *pszAction, c
if ( !pTarget )
{
Warning( "VScript error: DoEntFire was passed an invalid entity instance.\n" );
#ifdef MAPBASE_VSCRIPT
return 0;
#else
return;
#endif
}
#ifdef MAPBASE_VSCRIPT
return
#endif
g_EventQueue.AddEvent( pTarget, action, value, delay, ToEnt(hActivator), ToEnt(hCaller) );
}
@ -937,14 +968,16 @@ static float ScriptTraceLine( const Vector &vecStart, const Vector &vecEnd, HSCR
}
#ifdef MAPBASE_VSCRIPT
//-----------------------------------------------------------------------------
// Simple particle effect dispatch
//-----------------------------------------------------------------------------
static void ScriptDispatchParticleEffect(const char *pszParticleName, const Vector &vecOrigin, const QAngle &vecAngles)
static bool CancelEntityIOEvent( int event )
{
DispatchParticleEffect(pszParticleName, vecOrigin, vecAngles);
return g_EventQueue.RemoveEvent(event);
}
#endif
static float GetEntityIOEventTimeLeft( int event )
{
return g_EventQueue.GetTimeLeft(event);
}
#endif // MAPBASE_VSCRIPT
bool VScriptServerInit()
{
@ -1007,7 +1040,17 @@ bool VScriptServerInit()
Log( "VSCRIPT: Started VScript virtual machine using script language '%s'\n", g_pScriptVM->GetLanguageName() );
#endif
#ifdef MAPBASE_VSCRIPT
// MULTIPLAYER
// ScriptRegisterFunctionNamed( g_pScriptVM, UTIL_PlayerByIndex, "GetPlayerByIndex", "PlayerInstanceFromIndex" );
// ScriptRegisterFunctionNamed( g_pScriptVM, UTIL_PlayerByUserId, "GetPlayerByUserId", "GetPlayerFromUserID" );
// ScriptRegisterFunctionNamed( g_pScriptVM, UTIL_PlayerByName, "GetPlayerByName", "" );
// ScriptRegisterFunctionNamed( g_pScriptVM, ScriptGetPlayerByNetworkID, "GetPlayerByNetworkID", "" );
ScriptRegisterFunctionNamed( g_pScriptVM, UTIL_ShowMessageAll, "ShowMessage", "Print a hud message on all clients" );
#else
ScriptRegisterFunctionNamed( g_pScriptVM, UTIL_ShowMessageAll, "ShowMessage", "Print a hud message on all clients" );
#endif
ScriptRegisterFunction( g_pScriptVM, SendToConsole, "Send a string to the console as a command" );
ScriptRegisterFunction( g_pScriptVM, GetMapName, "Get the name of the map.");
@ -1016,11 +1059,15 @@ bool VScriptServerInit()
ScriptRegisterFunction( g_pScriptVM, Time, "Get the current server time" );
ScriptRegisterFunction( g_pScriptVM, FrameTime, "Get the time spent on the server in the last frame" );
#ifdef MAPBASE_VSCRIPT
ScriptRegisterFunction( g_pScriptVM, SendToConsoleServer, "Send a string to the server console as a command" );
ScriptRegisterFunction( g_pScriptVM, MaxPlayers, "Get the maximum number of players allowed on this server" );
ScriptRegisterFunction( g_pScriptVM, IntervalPerTick, "Get the interval used between each tick" );
ScriptRegisterFunction( g_pScriptVM, DoEntFire, SCRIPT_ALIAS( "EntFire", "Generate an entity i/o event" ) );
ScriptRegisterFunction( g_pScriptVM, DoEntFireByInstanceHandle, SCRIPT_ALIAS( "EntFireByHandle", "Generate an entity i/o event. First parameter is an entity instance." ) );
// ScriptRegisterFunction( g_pScriptVM, IsValidEntity, "Returns true if the entity is valid." );
ScriptRegisterFunction( g_pScriptVM, CancelEntityIOEvent, "Remove entity I/O event." );
ScriptRegisterFunction( g_pScriptVM, GetEntityIOEventTimeLeft, "Get time left on entity I/O event." );
#else
ScriptRegisterFunction( g_pScriptVM, DoEntFire, SCRIPT_ALIAS( "EntFire", "Generate and entity i/o event" ) );
ScriptRegisterFunctionNamed( g_pScriptVM, DoEntFireByInstanceHandle, "EntFireByHandle", "Generate and entity i/o event. First parameter is an entity instance." );
@ -1033,10 +1080,7 @@ bool VScriptServerInit()
#endif
ScriptRegisterFunction( g_pScriptVM, DoIncludeScript, "Execute a script (internal)" );
ScriptRegisterFunction( g_pScriptVM, CreateProp, "Create a physics prop" );
#ifdef MAPBASE_VSCRIPT
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptDispatchParticleEffect, "DispatchParticleEffect", "Dispatches a one-off particle system" );
#endif
if ( GameRules() )
{
GameRules()->RegisterScriptFunctions();
@ -1045,7 +1089,7 @@ bool VScriptServerInit()
g_pScriptVM->RegisterInstance( &g_ScriptEntityIterator, "Entities" );
#ifdef MAPBASE_VSCRIPT
g_pScriptVM->RegisterInstance( &g_ScriptDebugOverlay, "debugoverlay" );
#endif
#endif // MAPBASE_VSCRIPT
#ifdef MAPBASE_VSCRIPT
g_pScriptVM->RegisterAllClasses();

View File

@ -7,16 +7,19 @@ static char g_Script_vscript_server[] = R"vscript(
function UniqueString( string = "" )
{
return DoUniqueString( string.tostring() );
return ::DoUniqueString( string.tostring() );
}
local DoEntFire = ::DoEntFire
local DoEntFireByInstanceHandle = ::DoEntFireByInstanceHandle
function EntFire( target, action, value = null, delay = 0.0, activator = null, caller = null )
{
if ( !value )
{
value = "";
}
if ( "self" in this )
{
if ( !caller )
@ -29,8 +32,8 @@ function EntFire( target, action, value = null, delay = 0.0, activator = null, c
activator = self;
}
}
DoEntFire( target.tostring(), action.tostring(), value.tostring(), delay, activator, caller );
return DoEntFire( target.tostring(), action.tostring(), value.tostring(), delay, activator, caller );
}
function EntFireByHandle( target, action, value = null, delay = 0.0, activator = null, caller = null )
@ -39,7 +42,7 @@ function EntFireByHandle( target, action, value = null, delay = 0.0, activator =
{
value = "";
}
if ( "self" in this )
{
if ( !caller )
@ -52,8 +55,8 @@ function EntFireByHandle( target, action, value = null, delay = 0.0, activator =
activator = self;
}
}
DoEntFireByInstanceHandle( target, action.tostring(), value.tostring(), delay, activator, caller );
return DoEntFireByInstanceHandle( target, action.tostring(), value.tostring(), delay, activator, caller );
}
function __ReplaceClosures( script, scope )
@ -62,11 +65,11 @@ function __ReplaceClosures( script, scope )
{
scope = getroottable();
}
local tempParent = { getroottable = function() { return null; } };
local temp = { runscript = script };
temp.set_delegate(tempParent);
temp.runscript()
foreach( key,val in temp )
{
@ -78,11 +81,11 @@ function __ReplaceClosures( script, scope )
}
}
__OutputsPattern <- regexp("^On.*Output$");
local __OutputsPattern = regexp("^On.*Output$");
function ConnectOutputs( table )
{
const nCharsToStrip = 6;
local nCharsToStrip = 6;
foreach( key, val in table )
{
if ( typeof( val ) == "function" && __OutputsPattern.match( key ) )
@ -95,7 +98,7 @@ function ConnectOutputs( table )
function IncludeScript( name, scope = null )
{
if ( scope == null )
if ( !scope )
{
scope = this;
}

View File

@ -55,12 +55,23 @@ public:
void Dump( void )
{
for (UtlHashHandle_t i = m_Strings.FirstHandle(); i != m_Strings.InvalidHandle(); i = m_Strings.NextHandle(i))
CUtlVector<const char*> strings( 0, m_Strings.Count() );
for ( UtlHashHandle_t i = m_Strings.FirstHandle(); i != m_Strings.InvalidHandle(); i = m_Strings.NextHandle(i) )
{
DevMsg(" %d (0x%p) : %s\n", i, m_Strings[i], m_Strings[i]);
strings.AddToTail( m_Strings[i] );
}
DevMsg("\n");
DevMsg("Size: %d items\n", m_Strings.Count());
struct _Local {
static int __cdecl F(const char * const *a, const char * const *b) { return strcmp(*a, *b); }
};
strings.Sort( _Local::F );
for ( int i = 0; i < strings.Count(); ++i )
{
DevMsg( " %d (0x%p) : %s\n", i, strings[i], strings[i] );
}
DevMsg( "\n" );
DevMsg( "Size: %d items\n", strings.Count() );
}
const char *Find(const char *string)

View File

@ -389,10 +389,10 @@ void RegisterMathScriptFunctions()
{
ScriptRegisterFunction( g_pScriptVM, RandomFloat, "Generate a random floating point number within a range, inclusive." );
ScriptRegisterFunction( g_pScriptVM, RandomInt, "Generate a random integer within a range, inclusive." );
ScriptRegisterFunction( g_pScriptVM, Approach, "Returns a value which approaches the target value from the input value with the specified speed." );
//ScriptRegisterFunction( g_pScriptVM, Approach, "Returns a value which approaches the target value from the input value with the specified speed." );
ScriptRegisterFunction( g_pScriptVM, ApproachAngle, "Returns an angle which approaches the target angle from the input angle with the specified speed." );
ScriptRegisterFunction( g_pScriptVM, AngleDiff, "Returns the degrees difference between two yaw angles." );
ScriptRegisterFunction( g_pScriptVM, AngleDistance, "Returns the distance between two angles." );
//ScriptRegisterFunction( g_pScriptVM, AngleDistance, "Returns the distance between two angles." );
ScriptRegisterFunction( g_pScriptVM, AngleNormalize, "Clamps an angle to be in between -360 and 360." );
ScriptRegisterFunction( g_pScriptVM, AngleNormalizePositive, "Clamps an angle to be in between 0 and 360." );
ScriptRegisterFunction( g_pScriptVM, AnglesAreEqual, "Checks if two angles are equal based on a given tolerance value." );

File diff suppressed because it is too large Load Diff

View File

@ -871,6 +871,11 @@ public:
virtual bool ClearValue( HSCRIPT hScope, const char *pszKey ) = 0;
bool ClearValue( const char *pszKey) { return ClearValue( NULL, pszKey ); }
#ifdef MAPBASE_VSCRIPT
// virtual void CreateArray(ScriptVariant_t &arr, int size = 0) = 0;
virtual bool ArrayAppend(HSCRIPT hArray, const ScriptVariant_t &val) = 0;
#endif
//----------------------------------------------------------------------------
virtual void WriteState( CUtlBuffer *pBuffer ) = 0;

View File

@ -31,7 +31,7 @@
#include "squirrel/squirrel/sqvm.h"
#include "squirrel/squirrel/sqclosure.h"
#include "color.h"
#include "tier1/utlbuffer.h"
#include <cstdarg>
@ -199,6 +199,9 @@ public:
virtual bool ClearValue(HSCRIPT hScope, const char* pszKey) override;
// virtual void CreateArray(ScriptVariant_t &arr, int size = 0) override;
virtual bool ArrayAppend(HSCRIPT hArray, const ScriptVariant_t &val) override;
//----------------------------------------------------------------------------
virtual void WriteState(CUtlBuffer* pBuffer) override;
@ -1362,24 +1365,26 @@ struct SquirrelSafeCheck
};
#define CON_COLOR_VSCRIPT 80,186,255,255
void printfunc(HSQUIRRELVM SQ_UNUSED_ARG(v), const SQChar* format, ...)
{
va_list args;
char buffer[2048];
va_start(args, format);
char buffer[256];
vsprintf(buffer, format, args);
Msg("%s", buffer);
V_vsnprintf(buffer, sizeof(buffer), format, args);
va_end(args);
ConColorMsg(Color(CON_COLOR_VSCRIPT), "%s", buffer);
}
void errorfunc(HSQUIRRELVM SQ_UNUSED_ARG(v), const SQChar* format, ...)
{
va_list args;
char buffer[2048];
va_start(args, format);
char buffer[256];
vsprintf(buffer, format, args);
Warning("%s", buffer);
V_vsnprintf(buffer, sizeof(buffer), format, args);
va_end(args);
Warning("%s", buffer);
}
const char * ScriptDataTypeToName(ScriptDataType_t datatype)
@ -1595,20 +1600,8 @@ bool SquirrelVM::Init()
if (Run(
R"script(
Msg <- print;
Warning <- error;
// LocalTime from Source 2
// function LocalTime()
// {
// local date = ::date();
// return {
// Hours = date.hour,
// Minutes = date.min,
// Seconds = date.sec
// }
// }
function clamp(val,min,max)
{
if ( max < min )
@ -1621,15 +1614,9 @@ bool SquirrelVM::Init()
return val;
}
function max(a,b)
{
return a > b ? a : b;
}
function max(a,b) return a > b ? a : b
function min(a,b)
{
return a < b ? a : b;
}
function min(a,b) return a < b ? a : b
function RemapVal(val, A, B, C, D)
{
@ -1643,10 +1630,36 @@ bool SquirrelVM::Init()
if ( A == B )
return val >= B ? D : C;
local cVal = (val - A) / (B - A);
cVal = ::clamp( cVal, 0.0, 1.0 );
cVal = (cVal < 0.0) ? 0.0 : (1.0 < cVal) ? 1.0 : cVal;
return C + (D - C) * cVal;
}
function Approach( target, value, speed )
{
local delta = target - value
if( delta > speed )
value += speed
else if( delta < (-speed) )
value -= speed
else
value = target
return value
}
function AngleDistance( next, cur )
{
local delta = next - cur
if ( delta < (-180.0) )
delta += 360.0
else if ( delta > 180.0 )
delta -= 360.0
return delta
}
function printl( text )
{
return ::print(text + "\n");
@ -2736,6 +2749,35 @@ bool SquirrelVM::ClearValue(HSCRIPT hScope, const char* pszKey)
sq_pop(vm_, 1);
return true;
}
/*
void SquirrelVM::CreateArray(ScriptVariant_t &arr, int size)
{
SquirrelSafeCheck safeCheck(vm_);
HSQOBJECT *obj = new HSQOBJECT;
sq_resetobject(obj);
sq_newarray(vm_,size);
sq_getstackobj(vm_, -1, obj);
sq_addref(vm_, obj);
sq_pop(vm_, 1);
arr = (HSCRIPT)obj;
}
*/
bool SquirrelVM::ArrayAppend(HSCRIPT hArray, const ScriptVariant_t &val)
{
SquirrelSafeCheck safeCheck(vm_);
HSQOBJECT *arr = (HSQOBJECT*)hArray;
sq_pushobject(vm_, *arr);
PushVariant(vm_, val);
bool ret = sq_arrayappend(vm_, -2) == SQ_OK;
sq_pop(vm_, 1);
return ret;
}
enum ClassType
{