mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2025-01-26 13:47:56 +03:00
Merge branch 'master' of https://github.com/mapbase-source/source-sdk-2013
This commit is contained in:
commit
5b2547a6ff
1
README
1
README
@ -8,6 +8,7 @@ The Alien Swarm-based radial fog and rope code as well as the multiple skybox su
|
||||
The dynamic RTT shadow angles code is from Saul Rennison on the VDC. (https://developer.valvesoftware.com/wiki/Dynamic_RTT_shadow_angles_in_Source_2007)
|
||||
The vortigaunt LOS fix is from Half-Life 2: Community Edition (dky.tehkingd.u in particular). (https://gitlab.com/RaraCerberus/HL2CE)
|
||||
The parallax corrected cubemap code was originally created by Brian Charles. (https://developer.valvesoftware.com/wiki/Parallax_Corrected_Cubemaps)
|
||||
The custom VScript library was created by reductor for Mapbase. (https://github.com/mapbase-source/source-sdk-2013/pull/5)
|
||||
Various other code and contributions were based off of pull requests in the Source 2013 SDK (https://github.com/ValveSoftware/source-sdk-2013/pulls) and snippets on the Valve Developer Community (http://developer.valvesoftware.com/).
|
||||
|
||||
All of the work mentioned above was open source when it was borrowed.
|
||||
|
@ -281,6 +281,11 @@ BEGIN_DATADESC( C_ClientRagdoll )
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
BEGIN_ENT_SCRIPTDESC( C_BaseAnimating, C_BaseEntity, "Animating models client-side" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetPoseParameter, "SetPoseParameter", "Set the specified pose parameter to the specified value" )
|
||||
DEFINE_SCRIPTFUNC( IsSequenceFinished, "Ask whether the main sequence is done playing" )
|
||||
END_SCRIPTDESC();
|
||||
|
||||
C_ClientRagdoll::C_ClientRagdoll( bool bRestoring )
|
||||
{
|
||||
m_iCurrentFriction = 0;
|
||||
@ -1403,6 +1408,15 @@ float C_BaseAnimating::ClampCycle( float flCycle, bool isLooping )
|
||||
return flCycle;
|
||||
}
|
||||
|
||||
void C_BaseAnimating::ScriptSetPoseParameter(const char* szName, float fValue)
|
||||
{
|
||||
CStudioHdr* pHdr = GetModelPtr();
|
||||
if (pHdr == NULL)
|
||||
return;
|
||||
|
||||
int iPoseParam = LookupPoseParameter(pHdr, szName);
|
||||
SetPoseParameter(pHdr, iPoseParam, fValue);
|
||||
}
|
||||
|
||||
void C_BaseAnimating::GetCachedBoneMatrix( int boneIndex, matrix3x4_t &out )
|
||||
{
|
||||
|
@ -95,6 +95,7 @@ public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
DECLARE_INTERPOLATION();
|
||||
DECLARE_ENT_SCRIPTDESC();
|
||||
|
||||
enum
|
||||
{
|
||||
@ -445,6 +446,7 @@ public:
|
||||
|
||||
virtual bool IsViewModel() const;
|
||||
|
||||
void ScriptSetPoseParameter(const char* szName, float fValue);
|
||||
protected:
|
||||
// View models scale their attachment positions to account for FOV. To get the unmodified
|
||||
// attachment position (like if you're rendering something else during the view model's DrawModel call),
|
||||
|
@ -44,6 +44,8 @@
|
||||
#include "viewrender.h"
|
||||
#endif
|
||||
|
||||
#include "gamestringpool.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
@ -423,6 +425,42 @@ BEGIN_RECV_TABLE_NOBASE( C_BaseEntity, DT_AnimTimeMustBeFirst )
|
||||
RecvPropInt( RECVINFO(m_flAnimTime), 0, RecvProxy_AnimTime ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
BEGIN_ENT_SCRIPTDESC_ROOT( C_BaseEntity, "Root class of all client-side entities" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( GetAbsOrigin, "GetOrigin", "" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetForward, "GetForwardVector", "Get the forward vector of the entity" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetLeft, "GetLeftVector", "Get the left vector of the entity" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetUp, "GetUpVector", "Get the up vector of the entity" )
|
||||
DEFINE_SCRIPTFUNC( GetTeamNumber, "Gets this entity's team" )
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DEFINE_SCRIPTFUNC( GetHealth, "" )
|
||||
DEFINE_SCRIPTFUNC( GetMaxHealth, "" )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetModelName, "GetModelName", "Returns the name of the model" )
|
||||
|
||||
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." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetClassname, "" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( GetEntityName, "GetName", "" )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( WorldSpaceCenter, "GetCenter", "Get vector to center of object - absolute coords" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptEyePosition, "EyePosition", "Get vector to eye position - absolute coords" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetAngles, "GetAngles", "Get entity pitch, yaw, roll as a vector" )
|
||||
|
||||
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( ScriptGetMoveParent, "GetMoveParent", "If in hierarchy, retrieves the entity's parent" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetRootMoveParent, "GetRootMoveParent", "If in hierarchy, walks up the hierarchy to find the root parent" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptFirstMoveChild, "FirstMoveChild", "" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptNextMovePeer, "NextMovePeer", "" )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetEffects, "Get effects" )
|
||||
DEFINE_SCRIPTFUNC( IsEffectActive, "Check if an effect is active" )
|
||||
#endif
|
||||
END_SCRIPTDESC();
|
||||
|
||||
#ifndef NO_ENTITY_PREDICTION
|
||||
BEGIN_RECV_TABLE_NOBASE( C_BaseEntity, DT_PredictableId )
|
||||
@ -466,6 +504,8 @@ BEGIN_RECV_TABLE_NOBASE(C_BaseEntity, DT_BaseEntity)
|
||||
RecvPropInt( RECVINFO_NAME(m_hNetworkMoveParent, moveparent), 0, RecvProxy_IntToMoveParent ),
|
||||
RecvPropInt( RECVINFO( m_iParentAttachment ) ),
|
||||
|
||||
RecvPropString(RECVINFO(m_iName)),
|
||||
|
||||
RecvPropInt( "movetype", 0, SIZEOF_IGNORE, 0, RecvProxy_MoveType ),
|
||||
RecvPropInt( "movecollide", 0, SIZEOF_IGNORE, 0, RecvProxy_MoveCollide ),
|
||||
RecvPropDataTable( RECVINFO_DT( m_Collision ), 0, &REFERENCE_RECV_TABLE(DT_CollisionProperty) ),
|
||||
@ -1095,6 +1135,8 @@ bool C_BaseEntity::Init( int entnum, int iSerialNum )
|
||||
|
||||
m_nCreationTick = gpGlobals->tickcount;
|
||||
|
||||
m_hScriptInstance = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1165,6 +1207,7 @@ void C_BaseEntity::Term()
|
||||
g_Predictables.RemoveFromPredictablesList( GetClientHandle() );
|
||||
}
|
||||
|
||||
|
||||
// If it's play simulated, remove from simulation list if the player still exists...
|
||||
if ( IsPlayerSimulated() && C_BasePlayer::GetLocalPlayer() )
|
||||
{
|
||||
@ -1201,6 +1244,12 @@ void C_BaseEntity::Term()
|
||||
RemoveFromLeafSystem();
|
||||
|
||||
RemoveFromAimEntsList();
|
||||
|
||||
if ( m_hScriptInstance )
|
||||
{
|
||||
g_pScriptVM->RemoveInstance( m_hScriptInstance );
|
||||
m_hScriptInstance = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -6442,6 +6491,55 @@ int C_BaseEntity::GetCreationTick() const
|
||||
return m_nCreationTick;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT C_BaseEntity::GetScriptInstance()
|
||||
{
|
||||
if (!m_hScriptInstance)
|
||||
{
|
||||
if (m_iszScriptId == NULL_STRING)
|
||||
{
|
||||
char* szName = (char*)stackalloc(1024);
|
||||
g_pScriptVM->GenerateUniqueKey((m_iName != NULL_STRING) ? STRING(GetEntityName()) : GetClassname(), szName, 1024);
|
||||
m_iszScriptId = AllocPooledString(szName);
|
||||
}
|
||||
|
||||
m_hScriptInstance = g_pScriptVM->RegisterInstance(GetScriptDesc(), this);
|
||||
g_pScriptVM->SetInstanceUniqeId(m_hScriptInstance, STRING(m_iszScriptId));
|
||||
}
|
||||
return m_hScriptInstance;
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT C_BaseEntity::ScriptGetMoveParent( void )
|
||||
{
|
||||
return ToHScript( GetMoveParent() );
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT C_BaseEntity::ScriptGetRootMoveParent()
|
||||
{
|
||||
return ToHScript( GetRootMoveParent() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT C_BaseEntity::ScriptFirstMoveChild( void )
|
||||
{
|
||||
return ToHScript( FirstMoveChild() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT C_BaseEntity::ScriptNextMovePeer( void )
|
||||
{
|
||||
return ToHScript( NextMovePeer() );
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void CC_CL_Find_Ent( const CCommand& args )
|
||||
{
|
||||
|
@ -36,6 +36,9 @@
|
||||
#include "toolframework/itoolentity.h"
|
||||
#include "tier0/threadtools.h"
|
||||
|
||||
#include "vscript/ivscript.h"
|
||||
#include "vscript_shared.h"
|
||||
|
||||
class C_Team;
|
||||
class IPhysicsObject;
|
||||
class IClientVehicle;
|
||||
@ -183,6 +186,8 @@ public:
|
||||
DECLARE_DATADESC();
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
// script description
|
||||
DECLARE_ENT_SCRIPTDESC();
|
||||
|
||||
C_BaseEntity();
|
||||
virtual ~C_BaseEntity();
|
||||
@ -256,6 +261,11 @@ public:
|
||||
|
||||
string_t m_iClassname;
|
||||
|
||||
HSCRIPT GetScriptInstance();
|
||||
|
||||
HSCRIPT m_hScriptInstance;
|
||||
string_t m_iszScriptId;
|
||||
|
||||
// IClientUnknown overrides.
|
||||
public:
|
||||
|
||||
@ -1119,6 +1129,30 @@ public:
|
||||
virtual int GetBody() { return 0; }
|
||||
virtual int GetSkin() { return 0; }
|
||||
|
||||
const Vector& ScriptGetForward(void) { static Vector vecForward; GetVectors(&vecForward, NULL, NULL); return vecForward; }
|
||||
const Vector& ScriptGetLeft(void) { static Vector vecLeft; GetVectors(NULL, &vecLeft, NULL); return vecLeft; }
|
||||
const Vector& ScriptGetUp(void) { static Vector vecUp; GetVectors(NULL, NULL, &vecUp); return vecUp; }
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
const char* ScriptGetModelName( void ) const { return STRING(GetModelName()); }
|
||||
|
||||
void ScriptEmitSound(const char* soundname);
|
||||
float ScriptSoundDuration(const char* soundname, const char* actormodel);
|
||||
|
||||
void VScriptPrecacheScriptSound(const char* soundname);
|
||||
|
||||
const Vector& ScriptEyePosition(void) { static Vector vec; vec = EyePosition(); return vec; }
|
||||
const Vector& ScriptGetAngles(void) { static Vector vec; QAngle qa = GetAbsAngles(); vec.x = qa.x; vec.y = qa.y; vec.z = qa.z; return vec; }
|
||||
|
||||
const Vector& ScriptGetBoundingMins( void ) { return m_Collision.OBBMins(); }
|
||||
const Vector& ScriptGetBoundingMaxs( void ) { return m_Collision.OBBMaxs(); }
|
||||
|
||||
HSCRIPT ScriptGetMoveParent( void );
|
||||
HSCRIPT ScriptGetRootMoveParent();
|
||||
HSCRIPT ScriptFirstMoveChild( void );
|
||||
HSCRIPT ScriptNextMovePeer( void );
|
||||
#endif
|
||||
|
||||
// Stubs on client
|
||||
void NetworkStateManualMode( bool activate ) { }
|
||||
void NetworkStateChanged() { }
|
||||
@ -1266,6 +1300,7 @@ public:
|
||||
void SetRenderMode( RenderMode_t nRenderMode, bool bForceUpdate = false );
|
||||
RenderMode_t GetRenderMode() const;
|
||||
|
||||
const char* GetEntityName();
|
||||
public:
|
||||
|
||||
// Determine what entity this corresponds to
|
||||
@ -1648,6 +1683,8 @@ private:
|
||||
// The owner!
|
||||
EHANDLE m_hOwnerEntity;
|
||||
EHANDLE m_hEffectEntity;
|
||||
|
||||
char m_iName[MAX_PATH];
|
||||
|
||||
// This is a random seed used by the networking code to allow client - side prediction code
|
||||
// randon number generators to spit out the same random numbers on both sides for a particular
|
||||
@ -2203,6 +2240,12 @@ inline bool C_BaseEntity::ShouldRecordInTools() const
|
||||
#endif
|
||||
}
|
||||
|
||||
inline const char *C_BaseEntity::GetEntityName()
|
||||
{
|
||||
return m_iName;
|
||||
}
|
||||
|
||||
|
||||
C_BaseEntity *CreateEntityByName( const char *className );
|
||||
|
||||
#endif // C_BASEENTITY_H
|
||||
|
@ -1480,7 +1480,7 @@ bool C_BaseFlex::ClearSceneEvent( CSceneEventInfo *info, bool fastKill, bool can
|
||||
// expression -
|
||||
// duration -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseFlex::AddSceneEvent( CChoreoScene *scene, CChoreoEvent *event, CBaseEntity *pTarget, bool bClientSide )
|
||||
void C_BaseFlex::AddSceneEvent( CChoreoScene *scene, CChoreoEvent *event, CBaseEntity *pTarget, bool bClientSide, C_SceneEntity* pSceneEntity)
|
||||
{
|
||||
if ( !scene || !event )
|
||||
{
|
||||
@ -1505,6 +1505,7 @@ void C_BaseFlex::AddSceneEvent( CChoreoScene *scene, CChoreoEvent *event, CBaseE
|
||||
info.m_hTarget = pTarget;
|
||||
info.m_bStarted = false;
|
||||
info.m_bClientSide = bClientSide;
|
||||
info.m_hSceneEntity = pSceneEntity;
|
||||
|
||||
if (StartSceneEvent( &info, scene, event, actor, pTarget ))
|
||||
{
|
||||
|
@ -214,7 +214,7 @@ public:
|
||||
virtual bool ClearSceneEvent( CSceneEventInfo *info, bool fastKill, bool canceled );
|
||||
|
||||
// Add the event to the queue for this actor
|
||||
void AddSceneEvent( CChoreoScene *scene, CChoreoEvent *event, C_BaseEntity *pTarget = NULL, bool bClientSide = false );
|
||||
void AddSceneEvent( CChoreoScene *scene, CChoreoEvent *event, C_BaseEntity *pTarget = NULL, bool bClientSide = false, C_SceneEntity* pSceneEntity = NULL);
|
||||
|
||||
// Remove the event from the queue for this actor
|
||||
void RemoveSceneEvent( CChoreoScene *scene, CChoreoEvent *event, bool fastKill );
|
||||
|
@ -480,6 +480,13 @@ C_BasePlayer::~C_BasePlayer()
|
||||
s_pLocalPlayer = NULL;
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
if ( IsLocalPlayer() && g_pScriptVM )
|
||||
{
|
||||
g_pScriptVM->SetValue( "player", SCRIPT_VARIANT_NULL );
|
||||
}
|
||||
#endif
|
||||
|
||||
delete m_pFlashlight;
|
||||
}
|
||||
|
||||
@ -974,6 +981,16 @@ void C_BasePlayer::OnRestore()
|
||||
input->ClearInputButton( IN_ATTACK | IN_ATTACK2 );
|
||||
// GetButtonBits() has to be called for the above to take effect
|
||||
input->GetButtonBits( 0 );
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
// HACK: (03/25/09) Then the player goes across a transition it doesn't spawn and register
|
||||
// it's instance. We're hacking around this for now, but this will go away when we get around to
|
||||
// having entities cross transitions and keep their script state.
|
||||
if ( g_pScriptVM )
|
||||
{
|
||||
g_pScriptVM->SetValue( "player", GetScriptInstance() );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// For ammo history icons to current value so they don't flash on level transtions
|
||||
|
@ -674,7 +674,7 @@ void C_SceneEntity::DispatchStartSpeak( CChoreoScene *scene, C_BaseFlex *actor,
|
||||
es.m_pSoundName = event->GetParameters();
|
||||
|
||||
EmitSound( filter, actor->entindex(), es );
|
||||
actor->AddSceneEvent( scene, event, NULL, IsClientOnly() );
|
||||
actor->AddSceneEvent( scene, event, NULL, IsClientOnly(), this );
|
||||
|
||||
// Close captioning only on master token no matter what...
|
||||
if ( event->GetCloseCaptionType() == CChoreoEvent::CC_MASTER )
|
||||
@ -964,7 +964,7 @@ void C_SceneEntity::UnloadScene( void )
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_SceneEntity::DispatchStartFlexAnimation( CChoreoScene *scene, C_BaseFlex *actor, CChoreoEvent *event )
|
||||
{
|
||||
actor->AddSceneEvent( scene, event, NULL, IsClientOnly() );
|
||||
actor->AddSceneEvent( scene, event, NULL, IsClientOnly(), this );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -984,7 +984,7 @@ void C_SceneEntity::DispatchEndFlexAnimation( CChoreoScene *scene, C_BaseFlex *a
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_SceneEntity::DispatchStartExpression( CChoreoScene *scene, C_BaseFlex *actor, CChoreoEvent *event )
|
||||
{
|
||||
actor->AddSceneEvent( scene, event, NULL, IsClientOnly() );
|
||||
actor->AddSceneEvent( scene, event, NULL, IsClientOnly(), this );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1008,7 +1008,7 @@ void C_SceneEntity::DispatchStartGesture( CChoreoScene *scene, C_BaseFlex *actor
|
||||
if ( !Q_stricmp( event->GetName(), "NULL" ) )
|
||||
return;
|
||||
|
||||
actor->AddSceneEvent( scene, event, NULL, IsClientOnly() );
|
||||
actor->AddSceneEvent( scene, event, NULL, IsClientOnly(), this );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1023,7 +1023,7 @@ void C_SceneEntity::DispatchProcessGesture( CChoreoScene *scene, C_BaseFlex *act
|
||||
return;
|
||||
|
||||
actor->RemoveSceneEvent( scene, event, false );
|
||||
actor->AddSceneEvent( scene, event, NULL, IsClientOnly() );
|
||||
actor->AddSceneEvent( scene, event, NULL, IsClientOnly(), this );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1046,7 +1046,7 @@ void C_SceneEntity::DispatchEndGesture( CChoreoScene *scene, C_BaseFlex *actor,
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_SceneEntity::DispatchStartSequence( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event )
|
||||
{
|
||||
actor->AddSceneEvent( scene, event, NULL, IsClientOnly() );
|
||||
actor->AddSceneEvent( scene, event, NULL, IsClientOnly(), this );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1056,7 +1056,7 @@ void C_SceneEntity::DispatchStartSequence( CChoreoScene *scene, CBaseFlex *actor
|
||||
void C_SceneEntity::DispatchProcessSequence( CChoreoScene *scene, CBaseFlex *actor, CChoreoEvent *event )
|
||||
{
|
||||
actor->RemoveSceneEvent( scene, event, false );
|
||||
actor->AddSceneEvent( scene, event, NULL, IsClientOnly() );
|
||||
actor->AddSceneEvent( scene, event, NULL, IsClientOnly(), this );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -62,6 +62,9 @@ BEGIN_RECV_TABLE( C_World, DT_World )
|
||||
#ifdef MAPBASE
|
||||
RecvPropString(RECVINFO(m_iszChapterTitle)),
|
||||
#endif
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
RecvPropInt(RECVINFO(m_iScriptLanguage)),
|
||||
#endif
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
|
@ -41,6 +41,10 @@ public:
|
||||
float GetWaveHeight() const;
|
||||
const char *GetDetailSpriteMaterial() const;
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
ScriptLanguage_t GetScriptLanguage() { return (ScriptLanguage_t)m_iScriptLanguage; }
|
||||
#endif
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
@ -59,6 +63,9 @@ public:
|
||||
#ifdef MAPBASE
|
||||
char m_iszChapterTitle[64];
|
||||
#endif
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
int m_iScriptLanguage;
|
||||
#endif
|
||||
|
||||
private:
|
||||
void RegisterSharedActivities( void );
|
||||
|
@ -223,6 +223,8 @@ IReplaySystem *g_pReplay = NULL;
|
||||
IVEngineServer *serverengine = NULL;
|
||||
#endif
|
||||
|
||||
IScriptManager *scriptmanager = NULL;
|
||||
|
||||
IHaptics* haptics = NULL;// NVNT haptics system interface singleton
|
||||
|
||||
//=============================================================================
|
||||
@ -964,6 +966,16 @@ int CHLClient::Init( CreateInterfaceFn appSystemFactory, CreateInterfaceFn physi
|
||||
if (!g_pMatSystemSurface)
|
||||
return false;
|
||||
|
||||
if ( !CommandLine()->CheckParm( "-noscripting") )
|
||||
{
|
||||
scriptmanager = (IScriptManager *)appSystemFactory( VSCRIPT_INTERFACE_VERSION, NULL );
|
||||
|
||||
if (scriptmanager == nullptr)
|
||||
{
|
||||
scriptmanager = (IScriptManager*)Sys_GetFactoryThis()(VSCRIPT_INTERFACE_VERSION, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WORKSHOP_IMPORT_ENABLED
|
||||
if ( !ConnectDataModel( appSystemFactory ) )
|
||||
return false;
|
||||
|
@ -493,6 +493,11 @@ $Project
|
||||
$File "viewrender.cpp"
|
||||
$File "$SRCDIR\game\shared\voice_banmgr.cpp"
|
||||
$File "$SRCDIR\game\shared\voice_status.cpp"
|
||||
$File "vscript_client.cpp"
|
||||
$File "vscript_client.h"
|
||||
$File "vscript_client.nut"
|
||||
$File "$SRCDIR\game\shared\vscript_shared.cpp"
|
||||
$File "$SRCDIR\game\shared\vscript_shared.h"
|
||||
$File "warp_overlay.cpp"
|
||||
$File "WaterLODMaterialProxy.cpp"
|
||||
$File "$SRCDIR\game\shared\weapon_parse.cpp"
|
||||
|
@ -31,6 +31,9 @@ $Project
|
||||
$File "$SRCDIR\game\shared\mapbase\MapEdit.h"
|
||||
$File "$SRCDIR\game\shared\mapbase\matchers.cpp"
|
||||
$File "$SRCDIR\game\shared\mapbase\matchers.h"
|
||||
$File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.cpp" [$MAPBASE_VSCRIPT]
|
||||
$File "$SRCDIR\game\shared\mapbase\vscript_funcs_math.cpp" [$MAPBASE_VSCRIPT]
|
||||
$File "$SRCDIR\game\shared\mapbase\vscript_funcs_hl2.cpp" [$MAPBASE_VSCRIPT]
|
||||
|
||||
$File "mapbase\c_func_clientclip.cpp"
|
||||
}
|
||||
@ -51,4 +54,9 @@ $Project
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib "vscript" [$MAPBASE_VSCRIPT]
|
||||
}
|
||||
}
|
||||
|
592
sp/src/game/client/vscript_client.cpp
Normal file
592
sp/src/game/client/vscript_client.cpp
Normal file
@ -0,0 +1,592 @@
|
||||
//========== Copyright © 2008, Valve Corporation, All rights reserved. ========
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "cbase.h"
|
||||
#include "vscript_client.h"
|
||||
#include "icommandline.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "tier1/fmtstr.h"
|
||||
#include "filesystem.h"
|
||||
#include "characterset.h"
|
||||
#include "isaverestore.h"
|
||||
#include "gamerules.h"
|
||||
#include "vscript_client.nut"
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
#include "mapbase/matchers.h"
|
||||
#include "c_world.h"
|
||||
#include "proxyentity.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#endif
|
||||
|
||||
extern IScriptManager *scriptmanager;
|
||||
extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * );
|
||||
|
||||
// #define VMPROFILE 1
|
||||
|
||||
#ifdef VMPROFILE
|
||||
|
||||
#define VMPROF_START float debugStartTime = Plat_FloatTime();
|
||||
#define VMPROF_SHOW( funcname, funcdesc ) DevMsg("***VSCRIPT PROFILE***: %s %s: %6.4f milliseconds\n", (##funcname), (##funcdesc), (Plat_FloatTime() - debugStartTime)*1000.0 );
|
||||
|
||||
#else // !VMPROFILE
|
||||
|
||||
#define VMPROF_START
|
||||
#define VMPROF_SHOW
|
||||
|
||||
#endif // VMPROFILE
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: A clientside variant of CScriptEntityIterator.
|
||||
//-----------------------------------------------------------------------------
|
||||
class CScriptClientEntityIterator
|
||||
{
|
||||
public:
|
||||
HSCRIPT First() { return Next(NULL); }
|
||||
|
||||
HSCRIPT Next( HSCRIPT hStartEntity )
|
||||
{
|
||||
return ToHScript( ClientEntityList().NextBaseEntity( ToEnt( hStartEntity ) ) );
|
||||
}
|
||||
|
||||
HSCRIPT CreateByClassname( const char *className )
|
||||
{
|
||||
return ToHScript( CreateEntityByName( className ) );
|
||||
}
|
||||
|
||||
HSCRIPT FindByClassname( HSCRIPT hStartEntity, const char *szName )
|
||||
{
|
||||
const CEntInfo *pInfo = hStartEntity ? ClientEntityList().GetEntInfoPtr( ToEnt( hStartEntity )->GetRefEHandle() )->m_pNext : ClientEntityList().FirstEntInfo();
|
||||
for ( ;pInfo; pInfo = pInfo->m_pNext )
|
||||
{
|
||||
C_BaseEntity *ent = (C_BaseEntity *)pInfo->m_pEntity;
|
||||
if ( !ent )
|
||||
continue;
|
||||
|
||||
if ( Matcher_Match( szName, ent->GetClassname() ) )
|
||||
return ToHScript( ent );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HSCRIPT FindByName( HSCRIPT hStartEntity, const char *szName )
|
||||
{
|
||||
const CEntInfo *pInfo = hStartEntity ? ClientEntityList().GetEntInfoPtr( ToEnt( hStartEntity )->GetRefEHandle() )->m_pNext : ClientEntityList().FirstEntInfo();
|
||||
for ( ;pInfo; pInfo = pInfo->m_pNext )
|
||||
{
|
||||
C_BaseEntity *ent = (C_BaseEntity *)pInfo->m_pEntity;
|
||||
if ( !ent )
|
||||
continue;
|
||||
|
||||
if ( Matcher_Match( szName, ent->GetEntityName() ) )
|
||||
return ToHScript( ent );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
} g_ScriptEntityIterator;
|
||||
|
||||
BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptClientEntityIterator, "CEntities", SCRIPT_SINGLETON "The global list of entities" )
|
||||
DEFINE_SCRIPTFUNC( First, "Begin an iteration over the list of entities" )
|
||||
DEFINE_SCRIPTFUNC( Next, "Continue an iteration over the list of entities, providing reference to a previously found entity" )
|
||||
DEFINE_SCRIPTFUNC( CreateByClassname, "Creates an entity by classname" )
|
||||
DEFINE_SCRIPTFUNC( FindByClassname, "Find entities by class name. Pass 'null' to start an iteration, or reference to a previously found entity to continue a search" )
|
||||
DEFINE_SCRIPTFUNC( FindByName, "Find entities by name. Pass 'null' to start an iteration, or reference to a previously found entity to continue a search" )
|
||||
END_SCRIPTDESC();
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: A base class for VScript-utilizing clientside classes which can persist
|
||||
// across levels, requiring their scripts to be shut down manually.
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IClientScriptPersistable
|
||||
{
|
||||
public:
|
||||
virtual void TermScript() = 0;
|
||||
};
|
||||
|
||||
CUtlVector<IClientScriptPersistable*> g_ScriptPersistableList;
|
||||
|
||||
#define SCRIPT_MAT_PROXY_MAX_VARS 8
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: A material proxy which runs a VScript and allows it to read/write
|
||||
// to material variables.
|
||||
//-----------------------------------------------------------------------------
|
||||
class CScriptMaterialProxy : public IMaterialProxy, public IClientScriptPersistable
|
||||
{
|
||||
public:
|
||||
CScriptMaterialProxy();
|
||||
virtual ~CScriptMaterialProxy();
|
||||
|
||||
virtual void Release( void );
|
||||
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
virtual void OnBind( void *pRenderable );
|
||||
virtual IMaterial *GetMaterial() { return NULL; }
|
||||
|
||||
// Proxies can persist across levels and aren't bound to a loaded map.
|
||||
// The VM, however, is bound to the loaded map, so the proxy's script variables persisting
|
||||
// causes problems when they're used in a new level with a new VM.
|
||||
// As a result, we call InitScript() and TermScript() during OnBind and when the level is unloaded respectively.
|
||||
bool InitScript();
|
||||
void TermScript();
|
||||
|
||||
bool ValidateIndex(int i)
|
||||
{
|
||||
if (i > SCRIPT_MAT_PROXY_MAX_VARS || i < 0)
|
||||
{
|
||||
Warning("VScriptProxy: %i out of range", i);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *GetVarString( int i );
|
||||
int GetVarInt( int i );
|
||||
float GetVarFloat( int i );
|
||||
const Vector& GetVarVector( int i );
|
||||
|
||||
void SetVarString( int i, const char *value );
|
||||
void SetVarInt( int i, int value );
|
||||
void SetVarFloat( int i, float value );
|
||||
void SetVarVector( int i, const Vector &value );
|
||||
|
||||
private:
|
||||
IMaterialVar *m_MaterialVars[SCRIPT_MAT_PROXY_MAX_VARS];
|
||||
|
||||
// Save the keyvalue string for InitScript()
|
||||
char m_szFilePath[MAX_PATH];
|
||||
|
||||
CScriptScope m_ScriptScope;
|
||||
HSCRIPT m_hScriptInstance;
|
||||
HSCRIPT m_hFuncOnBind;
|
||||
};
|
||||
|
||||
BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptMaterialProxy, "CScriptMaterialProxy", "Material proxy for VScript" )
|
||||
DEFINE_SCRIPTFUNC( GetVarString, "Gets a material var's string value" )
|
||||
DEFINE_SCRIPTFUNC( GetVarInt, "Gets a material var's int value" )
|
||||
DEFINE_SCRIPTFUNC( GetVarFloat, "Gets a material var's float value" )
|
||||
DEFINE_SCRIPTFUNC( GetVarVector, "Gets a material var's vector value" )
|
||||
DEFINE_SCRIPTFUNC( SetVarString, "Sets a material var's string value" )
|
||||
DEFINE_SCRIPTFUNC( SetVarInt, "Sets a material var's int value" )
|
||||
DEFINE_SCRIPTFUNC( SetVarFloat, "Sets a material var's float value" )
|
||||
DEFINE_SCRIPTFUNC( SetVarVector, "Sets a material var's vector value" )
|
||||
END_SCRIPTDESC();
|
||||
|
||||
CScriptMaterialProxy::CScriptMaterialProxy()
|
||||
{
|
||||
m_hScriptInstance = NULL;
|
||||
m_hFuncOnBind = NULL;
|
||||
}
|
||||
|
||||
CScriptMaterialProxy::~CScriptMaterialProxy()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Cleanup
|
||||
//-----------------------------------------------------------------------------
|
||||
void CScriptMaterialProxy::Release( void )
|
||||
{
|
||||
if ( m_hScriptInstance && g_pScriptVM )
|
||||
{
|
||||
g_pScriptVM->RemoveInstance( m_hScriptInstance );
|
||||
m_hScriptInstance = NULL;
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
bool CScriptMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
for (KeyValues *pKey = pKeyValues->GetFirstSubKey(); pKey != NULL; pKey = pKey->GetNextKey())
|
||||
{
|
||||
// Get each variable we're looking for
|
||||
if (Q_strnicmp( pKey->GetName(), "var", 3 ) == 0)
|
||||
{
|
||||
int index = atoi(pKey->GetName() + 3);
|
||||
if (index > SCRIPT_MAT_PROXY_MAX_VARS)
|
||||
{
|
||||
Warning("VScript material proxy only supports 8 vars (not %i)\n", index);
|
||||
continue;
|
||||
}
|
||||
|
||||
bool foundVar;
|
||||
m_MaterialVars[index] = pMaterial->FindVar( pKey->GetString(), &foundVar );
|
||||
|
||||
// Don't init if we didn't find the var
|
||||
if (!foundVar)
|
||||
return false;
|
||||
}
|
||||
else if (FStrEq( pKey->GetName(), "scriptfile" ))
|
||||
{
|
||||
Q_strncpy( m_szFilePath, pKey->GetString(), sizeof( m_szFilePath ) );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CScriptMaterialProxy::InitScript()
|
||||
{
|
||||
if (!m_ScriptScope.IsInitialized())
|
||||
{
|
||||
if (scriptmanager == NULL)
|
||||
{
|
||||
ExecuteOnce(DevMsg("Cannot execute script because scripting is disabled (-scripting)\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (g_pScriptVM == NULL)
|
||||
{
|
||||
ExecuteOnce(DevMsg(" Cannot execute script because there is no available VM\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
char* iszScriptId = (char*)stackalloc( 1024 );
|
||||
g_pScriptVM->GenerateUniqueKey("VScriptProxy", iszScriptId, 1024);
|
||||
|
||||
m_hScriptInstance = g_pScriptVM->RegisterInstance( GetScriptDescForClass( CScriptMaterialProxy ), this );
|
||||
g_pScriptVM->SetInstanceUniqeId( m_hScriptInstance, iszScriptId );
|
||||
|
||||
bool bResult = m_ScriptScope.Init( iszScriptId );
|
||||
|
||||
if (!bResult)
|
||||
{
|
||||
DevMsg("VScriptProxy couldn't create ScriptScope!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
g_pScriptVM->SetValue( m_ScriptScope, "self", m_hScriptInstance );
|
||||
}
|
||||
|
||||
// Don't init if we can't run the script
|
||||
if (!VScriptRunScript( m_szFilePath, m_ScriptScope, true ))
|
||||
return false;
|
||||
|
||||
m_hFuncOnBind = m_ScriptScope.LookupFunction( "OnBind" );
|
||||
|
||||
if (!m_hFuncOnBind)
|
||||
{
|
||||
// Don't init if we can't find our func
|
||||
Warning("VScript material proxy can't find OnBind function\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
g_ScriptPersistableList.AddToTail( this );
|
||||
return true;
|
||||
}
|
||||
|
||||
void CScriptMaterialProxy::TermScript()
|
||||
{
|
||||
if ( m_hScriptInstance )
|
||||
{
|
||||
g_pScriptVM->RemoveInstance( m_hScriptInstance );
|
||||
m_hScriptInstance = NULL;
|
||||
}
|
||||
|
||||
m_hFuncOnBind = NULL;
|
||||
|
||||
m_ScriptScope.Term();
|
||||
}
|
||||
|
||||
void CScriptMaterialProxy::OnBind( void *pRenderable )
|
||||
{
|
||||
if( !pRenderable )
|
||||
return;
|
||||
|
||||
if (m_hFuncOnBind != NULL)
|
||||
{
|
||||
IClientRenderable *pRend = ( IClientRenderable* )pRenderable;
|
||||
C_BaseEntity *pEnt = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||
if ( pEnt )
|
||||
{
|
||||
g_pScriptVM->SetValue( m_ScriptScope, "entity", pEnt->GetScriptInstance() );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Needs to register as a null value so the script doesn't break if it looks for an entity
|
||||
g_pScriptVM->SetValue( m_ScriptScope, "entity", SCRIPT_VARIANT_NULL );
|
||||
}
|
||||
|
||||
m_ScriptScope.Call( m_hFuncOnBind, NULL );
|
||||
|
||||
g_pScriptVM->ClearValue( m_ScriptScope, "entity" );
|
||||
}
|
||||
else
|
||||
{
|
||||
// The VM might not exist if we do it from Init(), so we have to do it here.
|
||||
// TODO: We have no handling for if this fails, how do you cancel a proxy?
|
||||
if (InitScript())
|
||||
OnBind( pRenderable );
|
||||
}
|
||||
}
|
||||
|
||||
const char *CScriptMaterialProxy::GetVarString( int i )
|
||||
{
|
||||
if (!ValidateIndex( i ) || !m_MaterialVars[i])
|
||||
return NULL;
|
||||
|
||||
return m_MaterialVars[i]->GetStringValue();
|
||||
}
|
||||
|
||||
int CScriptMaterialProxy::GetVarInt( int i )
|
||||
{
|
||||
if (!ValidateIndex( i ) || !m_MaterialVars[i])
|
||||
return 0;
|
||||
|
||||
return m_MaterialVars[i]->GetIntValue();
|
||||
}
|
||||
|
||||
float CScriptMaterialProxy::GetVarFloat( int i )
|
||||
{
|
||||
if (!ValidateIndex( i ) || !m_MaterialVars[i])
|
||||
return 0.0f;
|
||||
|
||||
return m_MaterialVars[i]->GetFloatValue();
|
||||
}
|
||||
|
||||
const Vector& CScriptMaterialProxy::GetVarVector( int i )
|
||||
{
|
||||
if (!ValidateIndex( i ) || !m_MaterialVars[i])
|
||||
return vec3_origin;
|
||||
|
||||
if (m_MaterialVars[i]->GetType() != MATERIAL_VAR_TYPE_VECTOR)
|
||||
return vec3_origin;
|
||||
|
||||
// This is really bad. Too bad!
|
||||
return *(reinterpret_cast<const Vector*>(m_MaterialVars[i]->GetVecValue()));
|
||||
}
|
||||
|
||||
void CScriptMaterialProxy::SetVarString( int i, const char *value )
|
||||
{
|
||||
if (!ValidateIndex( i ) || !m_MaterialVars[i])
|
||||
return;
|
||||
|
||||
return m_MaterialVars[i]->SetStringValue( value );
|
||||
}
|
||||
|
||||
void CScriptMaterialProxy::SetVarInt( int i, int value )
|
||||
{
|
||||
if (!ValidateIndex( i ) || !m_MaterialVars[i])
|
||||
return;
|
||||
|
||||
return m_MaterialVars[i]->SetIntValue( value );
|
||||
}
|
||||
|
||||
void CScriptMaterialProxy::SetVarFloat( int i, float value )
|
||||
{
|
||||
if (!ValidateIndex( i ) || !m_MaterialVars[i])
|
||||
return;
|
||||
|
||||
return m_MaterialVars[i]->SetFloatValue( value );
|
||||
}
|
||||
|
||||
void CScriptMaterialProxy::SetVarVector( int i, const Vector &value )
|
||||
{
|
||||
if (!ValidateIndex( i ) || !m_MaterialVars[i])
|
||||
return;
|
||||
|
||||
return m_MaterialVars[i]->SetVecValue( value.Base(), 3 );
|
||||
}
|
||||
|
||||
EXPOSE_INTERFACE( CScriptMaterialProxy, IMaterialProxy, "VScriptProxy" IMATERIAL_PROXY_INTERFACE_VERSION );
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
static float Time()
|
||||
{
|
||||
return gpGlobals->curtime;
|
||||
}
|
||||
|
||||
static const char *GetMapName()
|
||||
{
|
||||
return engine->GetLevelName();
|
||||
}
|
||||
|
||||
static const char *DoUniqueString( const char *pszBase )
|
||||
{
|
||||
static char szBuf[512];
|
||||
g_pScriptVM->GenerateUniqueKey( pszBase, szBuf, ARRAYSIZE(szBuf) );
|
||||
return szBuf;
|
||||
}
|
||||
|
||||
bool DoIncludeScript( const char *pszScript, HSCRIPT hScope )
|
||||
{
|
||||
if ( !VScriptRunScript( pszScript, hScope, true ) )
|
||||
{
|
||||
g_pScriptVM->RaiseException( CFmtStr( "Failed to include script \"%s\"", ( pszScript ) ? pszScript : "unknown" ) );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VScriptClientInit()
|
||||
{
|
||||
VMPROF_START
|
||||
|
||||
if( scriptmanager != NULL )
|
||||
{
|
||||
ScriptLanguage_t scriptLanguage = SL_DEFAULT;
|
||||
|
||||
char const *pszScriptLanguage;
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
if (GetClientWorldEntity()->GetScriptLanguage() != SL_NONE)
|
||||
{
|
||||
// Allow world entity to override script language
|
||||
scriptLanguage = GetClientWorldEntity()->GetScriptLanguage();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if ( CommandLine()->CheckParm( "-scriptlang", &pszScriptLanguage ) )
|
||||
{
|
||||
if( !Q_stricmp(pszScriptLanguage, "gamemonkey") )
|
||||
{
|
||||
scriptLanguage = SL_GAMEMONKEY;
|
||||
}
|
||||
else if( !Q_stricmp(pszScriptLanguage, "squirrel") )
|
||||
{
|
||||
scriptLanguage = SL_SQUIRREL;
|
||||
}
|
||||
else if( !Q_stricmp(pszScriptLanguage, "python") )
|
||||
{
|
||||
scriptLanguage = SL_PYTHON;
|
||||
}
|
||||
else
|
||||
{
|
||||
DevWarning("-scriptlang does not recognize a language named '%s'. virtual machine did NOT start.\n", pszScriptLanguage );
|
||||
scriptLanguage = SL_NONE;
|
||||
}
|
||||
|
||||
}
|
||||
if( scriptLanguage != SL_NONE )
|
||||
{
|
||||
if ( g_pScriptVM == NULL )
|
||||
g_pScriptVM = scriptmanager->CreateVM( scriptLanguage );
|
||||
|
||||
if( g_pScriptVM )
|
||||
{
|
||||
Log( "VSCRIPT: Started VScript virtual machine using script language '%s'\n", g_pScriptVM->GetLanguageName() );
|
||||
ScriptRegisterFunction( g_pScriptVM, GetMapName, "Get the name of the map.");
|
||||
ScriptRegisterFunction( g_pScriptVM, Time, "Get the current server time" );
|
||||
ScriptRegisterFunction( g_pScriptVM, DoIncludeScript, "Execute a script (internal)" );
|
||||
|
||||
if ( GameRules() )
|
||||
{
|
||||
GameRules()->RegisterScriptFunctions();
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
g_pScriptVM->RegisterInstance( &g_ScriptEntityIterator, "Entities" );
|
||||
|
||||
IGameSystem::RegisterVScriptAllSystems();
|
||||
|
||||
RegisterSharedScriptFunctions();
|
||||
#else
|
||||
//g_pScriptVM->RegisterInstance( &g_ScriptEntityIterator, "Entities" );
|
||||
#endif
|
||||
|
||||
if (scriptLanguage == SL_SQUIRREL)
|
||||
{
|
||||
g_pScriptVM->Run( g_Script_vscript_client );
|
||||
}
|
||||
|
||||
VScriptRunScript( "mapspawn", false );
|
||||
|
||||
VMPROF_SHOW( pszScriptLanguage, "virtual machine startup" );
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
DevWarning("VM Did not start!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log( "\nVSCRIPT: Scripting is disabled.\n" );
|
||||
}
|
||||
g_pScriptVM = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
void VScriptClientTerm()
|
||||
{
|
||||
if( g_pScriptVM != NULL )
|
||||
{
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
// Things like proxies can persist across levels, so we have to shut down their scripts manually
|
||||
for (int i = g_ScriptPersistableList.Count()-1; i >= 0; i--)
|
||||
{
|
||||
if (g_ScriptPersistableList[i])
|
||||
{
|
||||
g_ScriptPersistableList[i]->TermScript();
|
||||
g_ScriptPersistableList.FastRemove( i );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if( g_pScriptVM )
|
||||
{
|
||||
scriptmanager->DestroyVM( g_pScriptVM );
|
||||
g_pScriptVM = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class CVScriptGameSystem : public CAutoGameSystemPerFrame
|
||||
{
|
||||
public:
|
||||
// Inherited from IAutoServerSystem
|
||||
virtual void LevelInitPreEntity( void )
|
||||
{
|
||||
m_bAllowEntityCreationInScripts = true;
|
||||
VScriptClientInit();
|
||||
}
|
||||
|
||||
virtual void LevelInitPostEntity( void )
|
||||
{
|
||||
m_bAllowEntityCreationInScripts = false;
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
if (pPlayer)
|
||||
{
|
||||
g_pScriptVM->SetValue( "player", pPlayer->GetScriptInstance() );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual void LevelShutdownPostEntity( void )
|
||||
{
|
||||
VScriptClientTerm();
|
||||
}
|
||||
|
||||
virtual void FrameUpdatePostEntityThink()
|
||||
{
|
||||
if ( g_pScriptVM )
|
||||
g_pScriptVM->Frame( gpGlobals->frametime );
|
||||
}
|
||||
|
||||
bool m_bAllowEntityCreationInScripts;
|
||||
};
|
||||
|
||||
CVScriptGameSystem g_VScriptGameSystem;
|
||||
|
||||
bool IsEntityCreationAllowedInScripts( void )
|
||||
{
|
||||
return g_VScriptGameSystem.m_bAllowEntityCreationInScripts;
|
||||
}
|
||||
|
||||
|
22
sp/src/game/client/vscript_client.h
Normal file
22
sp/src/game/client/vscript_client.h
Normal file
@ -0,0 +1,22 @@
|
||||
//========== Copyright © 2008, Valve Corporation, All rights reserved. ========
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef VSCRIPT_SERVER_H
|
||||
#define VSCRIPT_SERVER_H
|
||||
|
||||
#include "vscript/ivscript.h"
|
||||
#include "vscript_shared.h"
|
||||
|
||||
#if defined( _WIN32 )
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
extern IScriptVM * g_pScriptVM;
|
||||
|
||||
// Only allow scripts to create entities during map initialization
|
||||
bool IsEntityCreationAllowedInScripts( void );
|
||||
|
||||
#endif // VSCRIPT_SERVER_H
|
22
sp/src/game/client/vscript_client.nut
Normal file
22
sp/src/game/client/vscript_client.nut
Normal file
@ -0,0 +1,22 @@
|
||||
static char g_Script_vscript_client[] = R"vscript(
|
||||
//========== Copyright © 2008, Valve Corporation, All rights reserved. ========
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
function UniqueString( string = "" )
|
||||
{
|
||||
return DoUniqueString( string.tostring() );
|
||||
}
|
||||
|
||||
function IncludeScript( name, scope = null )
|
||||
{
|
||||
if ( scope == null )
|
||||
{
|
||||
scope = this;
|
||||
}
|
||||
return ::DoIncludeScript( name, scope );
|
||||
}
|
||||
|
||||
)vscript";
|
@ -98,6 +98,15 @@ BEGIN_DATADESC( CAI_BaseActor )
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
BEGIN_ENT_SCRIPTDESC( CAI_BaseActor, CAI_BaseNPC, "The base class for NPCs which act in complex choreo scenes." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptAddLookTarget, "AddLookTarget", "Add a potential look target for this actor." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptAddLookTargetPos, "AddLookTargetPos", "Add a potential look target position for this actor." )
|
||||
|
||||
END_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
|
||||
BEGIN_SIMPLE_DATADESC( CAI_InterestTarget_t )
|
||||
DEFINE_FIELD( m_eType, FIELD_INTEGER ),
|
||||
|
@ -170,6 +170,15 @@ public:
|
||||
void ClearExpression();
|
||||
const char * GetExpression();
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
//---------------------------------
|
||||
|
||||
void ScriptAddLookTarget( HSCRIPT pTarget, float flImportance, float flDuration, float flRamp = 0.0 ) { AddLookTarget(ToEnt(pTarget), flImportance, flDuration, flRamp); }
|
||||
void ScriptAddLookTargetPos( const Vector &vecPosition, float flImportance, float flDuration, float flRamp = 0.0 ) { AddLookTarget(vecPosition, flImportance, flDuration, flRamp); }
|
||||
|
||||
//---------------------------------
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
SCENE_AI_BLINK = 1,
|
||||
@ -190,6 +199,9 @@ public:
|
||||
|
||||
|
||||
DECLARE_DATADESC();
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DECLARE_ENT_SCRIPTDESC();
|
||||
#endif
|
||||
private:
|
||||
enum
|
||||
{
|
||||
|
@ -689,6 +689,131 @@ void CAI_BaseNPC::InputSetFriendlyFire( inputdata_t &inputdata )
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CAI_BaseNPC::VScriptGetEnemy()
|
||||
{
|
||||
return ToHScript( GetEnemy() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAI_BaseNPC::VScriptSetEnemy( HSCRIPT pEnemy )
|
||||
{
|
||||
SetEnemy( ToEnt( pEnemy ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
Vector CAI_BaseNPC::VScriptGetEnemyLKP()
|
||||
{
|
||||
return GetEnemyLKP();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CAI_BaseNPC::VScriptFindEnemyMemory( HSCRIPT pEnemy )
|
||||
{
|
||||
HSCRIPT hScript = NULL;
|
||||
AI_EnemyInfo_t *info = GetEnemies()->Find( ToEnt(pEnemy) );
|
||||
if (info)
|
||||
{
|
||||
hScript = g_pScriptVM->RegisterInstance( info );
|
||||
}
|
||||
|
||||
return hScript;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
int CAI_BaseNPC::VScriptGetState()
|
||||
{
|
||||
return (int)GetState();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CAI_BaseNPC::VScriptGetHintNode()
|
||||
{
|
||||
return ToHScript( GetHintNode() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CAI_BaseNPC::VScriptGetSchedule()
|
||||
{
|
||||
const char *pName = NULL;
|
||||
pName = GetCurSchedule()->GetName();
|
||||
if (!pName)
|
||||
pName = "Unknown";
|
||||
|
||||
return pName;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
int CAI_BaseNPC::VScriptGetScheduleID()
|
||||
{
|
||||
int iSched = GetCurSchedule()->GetId();
|
||||
|
||||
// Local IDs are needed to correspond with user-friendly enums
|
||||
if ( AI_IdIsGlobal( iSched ) )
|
||||
{
|
||||
iSched = GetClassScheduleIdSpace()->ScheduleGlobalToLocal(iSched);
|
||||
}
|
||||
|
||||
return iSched;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAI_BaseNPC::VScriptSetSchedule( const char *szSchedule )
|
||||
{
|
||||
SetSchedule( GetScheduleID( szSchedule ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CAI_BaseNPC::VScriptGetTask()
|
||||
{
|
||||
const Task_t *pTask = GetTask();
|
||||
const char *pName = NULL;
|
||||
if (pTask)
|
||||
pName = TaskName( pTask->iTask );
|
||||
else
|
||||
pName = "None";
|
||||
|
||||
return pName;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
int CAI_BaseNPC::VScriptGetTaskID()
|
||||
{
|
||||
const Task_t *pTask = GetTask();
|
||||
int iID = -1;
|
||||
if (pTask)
|
||||
iID = GetTaskID( TaskName( pTask->iTask ) );
|
||||
|
||||
return iID;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CAI_BaseNPC::VScriptGetExpresser()
|
||||
{
|
||||
HSCRIPT hScript = NULL;
|
||||
CAI_Expresser *pExpresser = GetExpresser();
|
||||
if (pExpresser)
|
||||
{
|
||||
hScript = g_pScriptVM->RegisterInstance( pExpresser );
|
||||
}
|
||||
|
||||
return hScript;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool CAI_BaseNPC::PassesDamageFilter( const CTakeDamageInfo &info )
|
||||
{
|
||||
if ( ai_block_damage.GetBool() )
|
||||
@ -6403,6 +6528,34 @@ Activity CAI_BaseNPC::NPC_TranslateActivity( Activity eNewActivity )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
if ( m_ScriptScope.IsInitialized() )
|
||||
{
|
||||
g_pScriptVM->SetValue( "activity", GetActivityName(eNewActivity) );
|
||||
g_pScriptVM->SetValue( "activity_id", (int)eNewActivity );
|
||||
|
||||
ScriptVariant_t functionReturn;
|
||||
if( CallScriptFunction( "NPC_TranslateActivity", &functionReturn ) )
|
||||
{
|
||||
if (functionReturn.m_type == FIELD_INTEGER)
|
||||
{
|
||||
Activity activity = (Activity)functionReturn.m_int;
|
||||
if (activity != ACT_INVALID)
|
||||
eNewActivity = (Activity)functionReturn.m_int;
|
||||
}
|
||||
else
|
||||
{
|
||||
Activity activity = (Activity)GetActivityID( functionReturn.m_pszString );
|
||||
if (activity != ACT_INVALID)
|
||||
eNewActivity = activity;
|
||||
}
|
||||
}
|
||||
|
||||
g_pScriptVM->ClearValue( "activity" );
|
||||
g_pScriptVM->ClearValue( "activity_id" );
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
Assert( eNewActivity != ACT_INVALID );
|
||||
|
||||
@ -11758,6 +11911,56 @@ BEGIN_DATADESC( CAI_BaseNPC )
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
BEGIN_ENT_SCRIPTDESC( CAI_BaseNPC, CBaseCombatCharacter, "The base class all NPCs derive from." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( VScriptGetEnemy, "GetEnemy", "Get the NPC's current enemy." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( VScriptSetEnemy, "SetEnemy", "Set the NPC's current enemy." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( VScriptGetEnemyLKP, "GetEnemyLKP", "Get the last known position of the NPC's current enemy." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( VScriptFindEnemyMemory, "FindEnemyMemory", "Get information about the NPC's current enemy." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( VScriptGetState, "GetNPCState", "Get the NPC's current state." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( VScriptGetHintGroup, "GetHintGroup", "Get the name of the NPC's hint group." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( VScriptGetHintNode, "GetHintNode", "Get the NPC's current AI hint." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( CapabilitiesGet, "Get the capabilities the NPC currently possesses." )
|
||||
DEFINE_SCRIPTFUNC( CapabilitiesAdd, "Add capabilities to the NPC." )
|
||||
DEFINE_SCRIPTFUNC( CapabilitiesRemove, "Remove capabilities from the NPC." )
|
||||
DEFINE_SCRIPTFUNC( CapabilitiesClear, "Clear capabilities for the NPC." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetActivity, "GetActivity", "Get the NPC's current activity." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetActivityID, "GetActivityID", "Get the NPC's current activity ID." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetActivity, "SetActivity", "Set the NPC's current activity." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetActivityID, "SetActivityID", "Set the NPC's current activity ID." )
|
||||
DEFINE_SCRIPTFUNC( ResetActivity, "Reset the NPC's current activity." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( VScriptGetSchedule, "GetSchedule", "Get the NPC's current schedule." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( VScriptGetScheduleID, "GetScheduleID", "Get the NPC's current schedule ID." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( VScriptSetSchedule, "SetSchedule", "Set the NPC's current schedule." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( VScriptSetScheduleID, "SetScheduleID", "Set the NPC's current schedule ID." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( VScriptGetTask, "GetTask", "Get the NPC's current task." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( VScriptGetTaskID, "GetTaskID", "Get the NPC's current task ID." )
|
||||
DEFINE_SCRIPTFUNC( ClearSchedule, "Clear the NPC's current schedule for the specified reason." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( VScriptHasCondition, "HasCondition", "Get whether the NPC has a condition." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( VScriptHasConditionID, "HasConditionID", "Get whether the NPC has a condition ID." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( VScriptSetCondition, "SetCondition", "Set a condition on the NPC." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( SetCondition, "SetConditionID", "Set a condition on the NPC by ID." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( VScriptClearCondition, "ClearCondition", "Clear a condition on the NPC." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ClearCondition, "ClearConditionID", "Clear a condition on the NPC by ID." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( IsMoving, "Check if the NPC is moving." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( VScriptGetExpresser, "GetExpresser", "Get a handle for this NPC's expresser." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( IsCommandable, "Check if the NPC is commandable." )
|
||||
DEFINE_SCRIPTFUNC( IsInPlayerSquad, "Check if the NPC is in the player's squad." )
|
||||
|
||||
END_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
BEGIN_SIMPLE_DATADESC( AIScheduleState_t )
|
||||
DEFINE_FIELD( iCurTask, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( fTaskStatus, FIELD_INTEGER ),
|
||||
|
@ -547,6 +547,9 @@ public:
|
||||
|
||||
DECLARE_DATADESC();
|
||||
DECLARE_SERVERCLASS();
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DECLARE_ENT_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
virtual int Save( ISave &save );
|
||||
virtual int Restore( IRestore &restore );
|
||||
@ -1207,6 +1210,40 @@ public:
|
||||
virtual void AddGrenades( int inc, CBaseEntity *pLastGrenade = NULL ) { ; }
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
// VScript stuff uses "VScript" instead of just "Script" to avoid
|
||||
// confusion with NPC_STATE_SCRIPT or StartScripting
|
||||
HSCRIPT VScriptGetEnemy();
|
||||
void VScriptSetEnemy( HSCRIPT pEnemy );
|
||||
Vector VScriptGetEnemyLKP();
|
||||
|
||||
HSCRIPT VScriptFindEnemyMemory( HSCRIPT pEnemy );
|
||||
|
||||
int VScriptGetState();
|
||||
|
||||
const char* VScriptGetHintGroup() { return STRING( GetHintGroup() ); }
|
||||
HSCRIPT VScriptGetHintNode();
|
||||
|
||||
const char* ScriptGetActivity() { return GetActivityName( GetActivity() ); }
|
||||
int ScriptGetActivityID() { return GetActivity(); }
|
||||
void ScriptSetActivity( const char *szActivity ) { SetActivity( (Activity)GetActivityID( szActivity ) ); }
|
||||
void ScriptSetActivityID( int iActivity ) { SetActivity((Activity)iActivity); }
|
||||
|
||||
const char* VScriptGetSchedule();
|
||||
int VScriptGetScheduleID();
|
||||
void VScriptSetSchedule( const char *szSchedule );
|
||||
void VScriptSetScheduleID( int iSched ) { SetSchedule( iSched ); }
|
||||
const char* VScriptGetTask();
|
||||
int VScriptGetTaskID();
|
||||
|
||||
bool VScriptHasCondition( const char *szCondition ) { return HasCondition( GetConditionID( szCondition ) ); }
|
||||
bool VScriptHasConditionID( int iCondition ) { return HasCondition( iCondition ); }
|
||||
void VScriptSetCondition( const char *szCondition ) { SetCondition( GetConditionID( szCondition ) ); }
|
||||
void VScriptClearCondition( const char *szCondition ) { ClearCondition( GetConditionID( szCondition ) ); }
|
||||
|
||||
HSCRIPT VScriptGetExpresser();
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------
|
||||
// Dynamic scripted NPC interactions
|
||||
//-----------------------------------------------------
|
||||
|
@ -386,6 +386,44 @@ CAI_Schedule *CAI_BaseNPC::GetScheduleOfType( int scheduleType )
|
||||
scheduleType = TranslateSchedule( scheduleType );
|
||||
AI_PROFILE_SCOPE_END();
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
if ( m_ScriptScope.IsInitialized() )
|
||||
{
|
||||
// Some of this code should know if there's a function first, so look
|
||||
// up the function beforehand instead of using CallScriptFunction()
|
||||
HSCRIPT hFunc = m_ScriptScope.LookupFunction( "NPC_TranslateSchedule" );
|
||||
if (hFunc)
|
||||
{
|
||||
int newSchedule = scheduleType;
|
||||
if ( AI_IdIsLocal( newSchedule ) )
|
||||
{
|
||||
newSchedule = GetClassScheduleIdSpace()->ScheduleLocalToGlobal(newSchedule);
|
||||
}
|
||||
|
||||
g_pScriptVM->SetValue( "schedule", GetSchedulingSymbols()->ScheduleIdToSymbol( newSchedule ) );
|
||||
g_pScriptVM->SetValue( "schedule_id", scheduleType ); // Use the local ID
|
||||
|
||||
ScriptVariant_t functionReturn;
|
||||
m_ScriptScope.Call( hFunc, &functionReturn );
|
||||
|
||||
if (functionReturn.m_type == FIELD_INTEGER)
|
||||
{
|
||||
newSchedule = functionReturn.m_int;
|
||||
}
|
||||
else
|
||||
{
|
||||
newSchedule = GetScheduleID( functionReturn.m_pszString );
|
||||
}
|
||||
|
||||
if (newSchedule != scheduleType && newSchedule > -1)
|
||||
scheduleType = newSchedule;
|
||||
|
||||
g_pScriptVM->ClearValue( "schedule" );
|
||||
g_pScriptVM->ClearValue( "schedule_id" );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Get a pointer to that schedule
|
||||
CAI_Schedule *schedule = GetSchedule(scheduleType);
|
||||
|
||||
|
@ -38,6 +38,15 @@ BEGIN_DATADESC( CAI_GoalEntity )
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
BEGIN_ENT_SCRIPTDESC( CAI_GoalEntity, CBaseEntity, "The base class for goal entities used to control NPC behavior." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( IsActive, "Check if the goal entity is active." )
|
||||
DEFINE_SCRIPTFUNC( NumActors, "Get the number of actors using this goal entity." )
|
||||
|
||||
END_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
|
@ -27,6 +27,9 @@ class CAI_GoalEntity : public CBaseEntity,
|
||||
public IEntityListener
|
||||
{
|
||||
DECLARE_CLASS( CAI_GoalEntity, CBaseEntity );
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DECLARE_ENT_SCRIPTDESC();
|
||||
#endif
|
||||
public:
|
||||
CAI_GoalEntity()
|
||||
: m_iszActor(NULL_STRING),
|
||||
|
@ -900,6 +900,23 @@ BEGIN_DATADESC( CAI_Hint )
|
||||
|
||||
END_DATADESC( );
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
BEGIN_ENT_SCRIPTDESC( CAI_Hint, CBaseEntity, "An entity which gives contextual pointers for NPCs." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetHintType, "GetHintType", "Get the hint's type ID." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetUser, "GetUser", "Get the hint's current user." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetHintGroup, "GetHintGroup", "Get the name of the hint's group." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetHintActivity, "GetHintActivity", "Get the name of the hint activity." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( IsDisabled, "Check if the hint is disabled." )
|
||||
DEFINE_SCRIPTFUNC( IsLocked, "Check if the hint is locked." )
|
||||
DEFINE_SCRIPTFUNC( GetNodeId, "Get the hint's node ID." )
|
||||
DEFINE_SCRIPTFUNC( Yaw, "Get the hint's yaw." )
|
||||
DEFINE_SCRIPTFUNC( GetDirection, "Get the hint's direction." )
|
||||
|
||||
END_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -312,6 +312,13 @@ public:
|
||||
void NPCHandleStartNav( CAI_BaseNPC *pNPC, bool bDefaultFacing );
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
int ScriptGetHintType() { return (int)HintType(); }
|
||||
HSCRIPT ScriptGetUser() { return ToHScript( User() ); }
|
||||
const char* ScriptGetHintGroup() { return STRING( GetGroup() ); }
|
||||
const char* ScriptGetHintActivity() { return STRING( HintActivityName() ); }
|
||||
#endif
|
||||
|
||||
private:
|
||||
void Spawn( void );
|
||||
virtual void Activate();
|
||||
@ -343,6 +350,9 @@ private:
|
||||
friend class CAI_HintManager;
|
||||
|
||||
DECLARE_DATADESC();
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DECLARE_ENT_SCRIPTDESC();
|
||||
#endif
|
||||
};
|
||||
|
||||
#define SF_ALLOW_JUMP_UP 65536
|
||||
|
@ -146,6 +146,29 @@ BEGIN_SIMPLE_DATADESC( AI_EnemyInfo_t )
|
||||
// NOT SAVED nextEMemory
|
||||
END_DATADESC()
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
#define DEFINE_ENEMY_INFO_SCRIPTFUNCS(name, desc) \
|
||||
DEFINE_SCRIPTFUNC_NAMED( Get##name, #name, "Get " desc ) \
|
||||
DEFINE_SCRIPTFUNC( Set##name, "Set " desc )
|
||||
|
||||
BEGIN_SCRIPTDESC_ROOT( AI_EnemyInfo_t, "Accessor for information about an enemy." )
|
||||
DEFINE_SCRIPTFUNC( Enemy, "Get the enemy." )
|
||||
DEFINE_SCRIPTFUNC( SetEnemy, "Set the enemy." )
|
||||
DEFINE_ENEMY_INFO_SCRIPTFUNCS( LastKnownLocation, "the enemy's last known location." )
|
||||
DEFINE_ENEMY_INFO_SCRIPTFUNCS( LastSeenLocation, "the enemy's last seen location." )
|
||||
DEFINE_ENEMY_INFO_SCRIPTFUNCS( TimeLastSeen, "the last time the enemy was seen." )
|
||||
DEFINE_ENEMY_INFO_SCRIPTFUNCS( TimeFirstSeen, "the first time the enemy was seen." )
|
||||
DEFINE_ENEMY_INFO_SCRIPTFUNCS( TimeLastReacquired, "the last time the enemy was reaquired." )
|
||||
DEFINE_ENEMY_INFO_SCRIPTFUNCS( TimeValidEnemy, "the time at which the enemy can be selected (reaction delay)." )
|
||||
DEFINE_ENEMY_INFO_SCRIPTFUNCS( TimeLastReceivedDamageFrom, "the last time damage was received from this enemy." )
|
||||
DEFINE_ENEMY_INFO_SCRIPTFUNCS( TimeAtFirstHand, "the time at which the enemy was seen firsthand." )
|
||||
DEFINE_ENEMY_INFO_SCRIPTFUNCS( DangerMemory, "the memory of danger position w/o enemy pointer." )
|
||||
DEFINE_ENEMY_INFO_SCRIPTFUNCS( EludedMe, "whether the enemy is not at the last known location." )
|
||||
DEFINE_ENEMY_INFO_SCRIPTFUNCS( Unforgettable, "whether the enemy is unfortgettable." )
|
||||
DEFINE_ENEMY_INFO_SCRIPTFUNCS( MobbedMe, "whether the enemy was part of a mob at some point." )
|
||||
END_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CAI_Enemies::CAI_Enemies(void)
|
||||
|
@ -45,6 +45,29 @@ struct AI_EnemyInfo_t
|
||||
bool bUnforgettable;
|
||||
bool bMobbedMe; // True if enemy was part of a mob at some point
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
// Script functions.
|
||||
#define ENEMY_INFO_SCRIPT_FUNCS(type, name, var) \
|
||||
type Get##name() { return var; } \
|
||||
void Set##name( type v ) { var = v; }
|
||||
|
||||
HSCRIPT Enemy() { return ToHScript(hEnemy); }
|
||||
void SetEnemy( HSCRIPT ent ) { hEnemy = ToEnt(ent); }
|
||||
|
||||
ENEMY_INFO_SCRIPT_FUNCS( Vector, LastKnownLocation, vLastKnownLocation );
|
||||
ENEMY_INFO_SCRIPT_FUNCS( Vector, LastSeenLocation, vLastSeenLocation );
|
||||
ENEMY_INFO_SCRIPT_FUNCS( float, TimeLastSeen, timeLastSeen );
|
||||
ENEMY_INFO_SCRIPT_FUNCS( float, TimeFirstSeen, timeFirstSeen );
|
||||
ENEMY_INFO_SCRIPT_FUNCS( float, TimeLastReacquired, timeLastReacquired );
|
||||
ENEMY_INFO_SCRIPT_FUNCS( float, TimeValidEnemy, timeValidEnemy );
|
||||
ENEMY_INFO_SCRIPT_FUNCS( float, TimeLastReceivedDamageFrom, timeLastReceivedDamageFrom );
|
||||
ENEMY_INFO_SCRIPT_FUNCS( float, TimeAtFirstHand, timeAtFirstHand );
|
||||
ENEMY_INFO_SCRIPT_FUNCS( bool, DangerMemory, bDangerMemory );
|
||||
ENEMY_INFO_SCRIPT_FUNCS( bool, EludedMe, bEludedMe );
|
||||
ENEMY_INFO_SCRIPT_FUNCS( bool, Unforgettable, bUnforgettable );
|
||||
ENEMY_INFO_SCRIPT_FUNCS( bool, MobbedMe, bMobbedMe );
|
||||
#endif
|
||||
|
||||
DECLARE_SIMPLE_DATADESC();
|
||||
};
|
||||
|
||||
|
@ -16,6 +16,9 @@
|
||||
#include "ai_navigator.h"
|
||||
#include "world.h"
|
||||
#include "ai_moveprobe.h"
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
#include "ai_hint.h"
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
@ -31,6 +34,53 @@ extern float MOVE_HEIGHT_EPSILON;
|
||||
// later point we will probabaly have multiple AINetworkds per level
|
||||
CAI_Network* g_pBigAINet;
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
BEGIN_SCRIPTDESC_ROOT( CAI_Network, SCRIPT_SINGLETON "The global list of AI nodes." )
|
||||
DEFINE_SCRIPTFUNC( NumNodes, "Number of nodes in the level" )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetNodePosition, "GetNodePosition", "Get position of node using a generic human hull" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetNodePositionWithHull, "GetNodePositionWithHull", "Get position of node using the specified hull" )
|
||||
DEFINE_SCRIPTFUNC( GetNodeYaw, "Get yaw of node" )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptNearestNodeToPoint, "NearestNodeToPoint", "Get ID of nearest node" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptNearestNodeToPointWithNPC, "NearestNodeToPointForNPC", "Get ID of nearest node using the specified NPC's properties" )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetNodeType, "GetNodeType", "Get a node's type" )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetNodeHint, "GetNodeHint", "Get a node's hint" )
|
||||
END_SCRIPTDESC();
|
||||
|
||||
HSCRIPT CAI_Network::ScriptGetNodeHint( int nodeID )
|
||||
{
|
||||
CAI_Node *pNode = GetNode( nodeID );
|
||||
if (!pNode)
|
||||
return NULL;
|
||||
|
||||
return ToHScript( pNode->GetHint() );
|
||||
}
|
||||
|
||||
int CAI_Network::ScriptGetNodeType( int nodeID )
|
||||
{
|
||||
CAI_Node *pNode = GetNode( nodeID );
|
||||
if (!pNode)
|
||||
return NULL;
|
||||
|
||||
return (int)pNode->GetType();
|
||||
}
|
||||
|
||||
int CAI_Network::ScriptNearestNodeToPointWithNPC( HSCRIPT hNPC, const Vector &vecPosition, bool bCheckVisibility )
|
||||
{
|
||||
CBaseEntity *pEnt = ToEnt( hNPC );
|
||||
if (!pEnt || !pEnt->MyNPCPointer())
|
||||
{
|
||||
Warning("vscript: NearestNodeToPointWithNPC - Invalid NPC\n");
|
||||
return NO_NODE;
|
||||
}
|
||||
|
||||
return NearestNodeToPoint( pEnt->MyNPCPointer(), vecPosition, bCheckVisibility );
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
abstract_class INodeListFilter
|
||||
|
@ -127,6 +127,17 @@ public:
|
||||
}
|
||||
|
||||
CAI_Node** AccessNodes() const { return m_pAInode; }
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
Vector ScriptGetNodePosition( int nodeID ) { return GetNodePosition( HULL_HUMAN, nodeID ); }
|
||||
Vector ScriptGetNodePositionWithHull( int nodeID, int hull ) { return GetNodePosition( (Hull_t)hull, nodeID ); }
|
||||
|
||||
int ScriptNearestNodeToPoint( const Vector &vecPosition, bool bCheckVisibility = true ) { return NearestNodeToPoint( NULL, vecPosition, bCheckVisibility ); }
|
||||
int ScriptNearestNodeToPointWithNPC( HSCRIPT hNPC, const Vector &vecPosition, bool bCheckVisibility = true );
|
||||
|
||||
HSCRIPT ScriptGetNodeHint( int nodeID );
|
||||
int ScriptGetNodeType( int nodeID );
|
||||
#endif
|
||||
|
||||
private:
|
||||
friend class CAI_NetworkManager;
|
||||
|
@ -948,6 +948,13 @@ void CAI_NetworkManager::InitializeAINetworks()
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
if (g_pScriptVM)
|
||||
{
|
||||
g_pScriptVM->RegisterInstance( g_pBigAINet, "AINetwork" );
|
||||
}
|
||||
#endif
|
||||
|
||||
// Reset node counter used during load
|
||||
CNodeEnt::m_nNodeCount = 0;
|
||||
|
||||
|
@ -184,6 +184,20 @@ BEGIN_SIMPLE_DATADESC( CAI_Expresser )
|
||||
DEFINE_FIELD( m_flLastTimeAcceptedSpeak, FIELD_TIME ),
|
||||
END_DATADESC()
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
BEGIN_SCRIPTDESC_ROOT( CAI_Expresser, "Expresser class for complex speech." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( IsSpeaking, "Check if the actor is speaking." )
|
||||
DEFINE_SCRIPTFUNC( CanSpeak, "Check if the actor can speak." )
|
||||
DEFINE_SCRIPTFUNC( BlockSpeechUntil, "Block speech for a certain amount of time. This is stored in curtime." )
|
||||
DEFINE_SCRIPTFUNC( ForceNotSpeaking, "If the actor is speaking, force the system to recognize them as not speaking." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSpeakRawScene, "SpeakRawScene", "Speak a raw, instanced VCD scene as though it were played through the Response System. Return whether the scene successfully plays." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSpeakAutoGeneratedScene, "SpeakAutoGeneratedScene", "Speak an automatically generated, instanced VCD scene for this sound as though it were played through the Response System. Return whether the scene successfully plays." )
|
||||
|
||||
END_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
bool CAI_Expresser::SemaphoreIsAvailable( CBaseEntity *pTalker )
|
||||
|
@ -203,6 +203,12 @@ public:
|
||||
// Force the NPC to release the semaphore & clear next speech time
|
||||
void ForceNotSpeaking( void );
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
bool ScriptSpeakRawScene( char const *soundname, float delay ) { return SpeakRawScene( soundname, delay, NULL ); }
|
||||
bool ScriptSpeakAutoGeneratedScene( char const *soundname, float delay ) { return SpeakAutoGeneratedScene( soundname, delay ); }
|
||||
bool ScriptSpeak( AIConcept_t concept, const char *modifiers ) { return Speak( concept, modifiers ); }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
CAI_TimedSemaphore *GetMySpeechSemaphore( CBaseEntity *pNpc );
|
||||
|
||||
|
@ -282,6 +282,17 @@ IMPLEMENT_SERVERCLASS_ST(CBaseAnimating, DT_BaseAnimating)
|
||||
|
||||
END_SEND_TABLE()
|
||||
|
||||
BEGIN_ENT_SCRIPTDESC( CBaseAnimating, CBaseEntity, "Animating models" )
|
||||
|
||||
DEFINE_SCRIPTFUNC( LookupAttachment, "Get the named attachement id" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetAttachmentOrigin, "GetAttachmentOrigin", "Get the attachement id's origin vector" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetAttachmentAngles, "GetAttachmentAngles", "Get the attachement id's angles as a p,y,r vector" )
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetAttachmentMatrix, "GetAttachmentMatrix", "Get the attachement id's matrix transform" )
|
||||
#endif
|
||||
DEFINE_SCRIPTFUNC( IsSequenceFinished, "Ask whether the main sequence is done playing" )
|
||||
DEFINE_SCRIPTFUNC( SetBodygroup, "Sets a bodygroup")
|
||||
END_SCRIPTDESC();
|
||||
|
||||
CBaseAnimating::CBaseAnimating()
|
||||
{
|
||||
@ -2117,6 +2128,45 @@ bool CBaseAnimating::GetAttachment( int iAttachment, Vector &absOrigin, Vector *
|
||||
return bRet;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns the world location and world angles of an attachment to vscript caller
|
||||
// Input : attachment name
|
||||
// Output : location and angles
|
||||
//-----------------------------------------------------------------------------
|
||||
const Vector& CBaseAnimating::ScriptGetAttachmentOrigin( int iAttachment )
|
||||
{
|
||||
|
||||
static Vector absOrigin;
|
||||
static QAngle qa;
|
||||
|
||||
CBaseAnimating::GetAttachment( iAttachment, absOrigin, qa );
|
||||
|
||||
return absOrigin;
|
||||
}
|
||||
|
||||
const Vector& CBaseAnimating::ScriptGetAttachmentAngles( int iAttachment )
|
||||
{
|
||||
|
||||
static Vector absOrigin;
|
||||
static Vector absAngles;
|
||||
static QAngle qa;
|
||||
|
||||
CBaseAnimating::GetAttachment( iAttachment, absOrigin, qa );
|
||||
absAngles.x = qa.x;
|
||||
absAngles.y = qa.y;
|
||||
absAngles.z = qa.z;
|
||||
return absAngles;
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
HSCRIPT CBaseAnimating::ScriptGetAttachmentMatrix( int iAttachment )
|
||||
{
|
||||
static matrix3x4_t matrix;
|
||||
|
||||
CBaseAnimating::GetAttachment( iAttachment, matrix );
|
||||
return ScriptCreateMatrixInstance( matrix );
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the attachment in local space
|
||||
|
@ -44,6 +44,7 @@ public:
|
||||
|
||||
DECLARE_DATADESC();
|
||||
DECLARE_SERVERCLASS();
|
||||
DECLARE_ENT_SCRIPTDESC();
|
||||
|
||||
virtual void SetModel( const char *szModelName );
|
||||
virtual void Activate();
|
||||
@ -186,6 +187,11 @@ public:
|
||||
bool GetAttachment( int iAttachment, Vector &absOrigin, QAngle &absAngles );
|
||||
int GetAttachmentBone( int iAttachment );
|
||||
virtual bool GetAttachment( int iAttachment, matrix3x4_t &attachmentToWorld );
|
||||
const Vector& ScriptGetAttachmentOrigin(int iAttachment);
|
||||
const Vector& ScriptGetAttachmentAngles(int iAttachment);
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
HSCRIPT ScriptGetAttachmentMatrix(int iAttachment);
|
||||
#endif
|
||||
|
||||
// These return the attachment in the space of the entity
|
||||
bool GetAttachmentLocal( const char *szName, Vector &origin, QAngle &angles );
|
||||
|
@ -150,6 +150,44 @@ BEGIN_DATADESC( CBaseCombatCharacter )
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
BEGIN_ENT_SCRIPTDESC( CBaseCombatCharacter, CBaseFlex, "The base class shared by players and NPCs." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( GetScriptActiveWeapon, "GetActiveWeapon", "Get the character's active weapon entity." )
|
||||
DEFINE_SCRIPTFUNC( WeaponCount, "Get the number of weapons a character possesses." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( GetScriptWeaponIndex, "GetWeapon", "Get a specific weapon in the character's inventory." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( GetScriptWeaponByType, "FindWeapon", "Find a specific weapon in the character's inventory by its classname." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( Weapon_ShootPosition, "ShootPosition", "Get the character's shoot position." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( Weapon_DropAll, "DropAllWeapons", "Make the character drop all of its weapons." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptEquipWeapon, "EquipWeapon", "Make the character equip the specified weapon entity. If they don't already own the weapon, they will acquire it instantly." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetAmmoCount, "GetAmmoCount", "Get the ammo count of the specified ammo type." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetAmmoCount, "SetAmmoCount", "Set the ammo count of the specified ammo type." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptRelationType, "GetRelationship", "Get a character's relationship to a specific entity." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptRelationPriority, "GetRelationPriority", "Get a character's relationship priority for a specific entity." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetRelationship, "SetRelationship", "Set a character's relationship with a specific entity." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( GetScriptVehicleEntity, "GetVehicleEntity", "Get the entity for a character's current vehicle if they're in one." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptInViewCone, "InViewCone", "Check if the specified position is in the character's viewcone." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptEntInViewCone, "EntInViewCone", "Check if the specified entity is in the character's viewcone." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptInAimCone, "InAimCone", "Check if the specified position is in the character's aim cone." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptEntInViewCone, "EntInAimCone", "Check if the specified entity is in the character's aim cone." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptBodyAngles, "BodyAngles", "Get the body's angles." )
|
||||
DEFINE_SCRIPTFUNC( BodyDirection2D, "Get the body's 2D direction." )
|
||||
DEFINE_SCRIPTFUNC( BodyDirection3D, "Get the body's 3D direction." )
|
||||
DEFINE_SCRIPTFUNC( HeadDirection2D, "Get the head's 2D direction." )
|
||||
DEFINE_SCRIPTFUNC( HeadDirection3D, "Get the head's 3D direction." )
|
||||
DEFINE_SCRIPTFUNC( EyeDirection2D, "Get the eyes' 2D direction." )
|
||||
DEFINE_SCRIPTFUNC( EyeDirection3D, "Get the eyes' 3D direction." )
|
||||
|
||||
END_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
|
||||
BEGIN_SIMPLE_DATADESC( Relationship_t )
|
||||
DEFINE_FIELD( entity, FIELD_EHANDLE ),
|
||||
@ -4317,6 +4355,114 @@ void CBaseCombatCharacter::DoMuzzleFlash()
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CBaseCombatCharacter::GetScriptActiveWeapon()
|
||||
{
|
||||
return ToHScript( GetActiveWeapon() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CBaseCombatCharacter::GetScriptWeaponIndex( int i )
|
||||
{
|
||||
return ToHScript( GetWeapon( i ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CBaseCombatCharacter::GetScriptWeaponByType( const char *pszWeapon, int iSubType )
|
||||
{
|
||||
return ToHScript( Weapon_OwnsThisType( pszWeapon, iSubType ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseCombatCharacter::ScriptEquipWeapon( HSCRIPT hWeapon )
|
||||
{
|
||||
CBaseEntity *pEntity = ToEnt( hWeapon );
|
||||
CBaseCombatWeapon *pWeapon = pEntity->MyCombatWeaponPointer();
|
||||
if (!pEntity || !pWeapon)
|
||||
return;
|
||||
|
||||
if (pWeapon->GetOwner() == this)
|
||||
{
|
||||
// Switch to this weapon
|
||||
Weapon_Switch( pWeapon );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CBaseCombatWeapon *pExistingWeapon = Weapon_OwnsThisType( pWeapon->GetClassname() ))
|
||||
{
|
||||
// Drop our existing weapon then!
|
||||
Weapon_Drop( pExistingWeapon );
|
||||
}
|
||||
|
||||
if (IsNPC())
|
||||
{
|
||||
Weapon_Equip( pWeapon );
|
||||
MyNPCPointer()->OnGivenWeapon( pWeapon );
|
||||
}
|
||||
else
|
||||
{
|
||||
Weapon_Equip( pWeapon );
|
||||
}
|
||||
|
||||
pWeapon->OnPickedUp( this );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
int CBaseCombatCharacter::ScriptGetAmmoCount( const char *szName ) const
|
||||
{
|
||||
return GetAmmoCount( GetAmmoDef()->Index(szName) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseCombatCharacter::ScriptSetAmmoCount( const char *szName, int iCount )
|
||||
{
|
||||
int iType = GetAmmoDef()->Index( szName );
|
||||
if (iType == -1)
|
||||
{
|
||||
Warning("\"%s\" is not a valid ammo type\n", szName);
|
||||
return;
|
||||
}
|
||||
|
||||
return SetAmmoCount( iCount, iType );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
int CBaseCombatCharacter::ScriptRelationType( HSCRIPT pTarget )
|
||||
{
|
||||
return (int)IRelationType( ToEnt( pTarget ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
int CBaseCombatCharacter::ScriptRelationPriority( HSCRIPT pTarget )
|
||||
{
|
||||
return IRelationPriority( ToEnt( pTarget ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseCombatCharacter::ScriptSetRelationship( HSCRIPT pTarget, int disposition, int priority )
|
||||
{
|
||||
AddEntityRelationship( ToEnt( pTarget ), (Disposition_t)disposition, priority );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CBaseCombatCharacter::GetScriptVehicleEntity()
|
||||
{
|
||||
return ToHScript( GetVehicleEntity() );
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: return true if given target cant be seen because of fog
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -119,6 +119,9 @@ public:
|
||||
DECLARE_SERVERCLASS();
|
||||
DECLARE_DATADESC();
|
||||
DECLARE_PREDICTABLE();
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DECLARE_ENT_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
@ -407,6 +410,31 @@ public:
|
||||
virtual float GetSpreadBias( CBaseCombatWeapon *pWeapon, CBaseEntity *pTarget );
|
||||
virtual void DoMuzzleFlash();
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT // DO NOT COMMIT; WAIT UNTIL FULL MERGE (5/15/2020)
|
||||
HSCRIPT GetScriptActiveWeapon();
|
||||
HSCRIPT GetScriptWeaponIndex( int i );
|
||||
HSCRIPT GetScriptWeaponByType( const char *pszWeapon, int iSubType = 0 );
|
||||
|
||||
void ScriptEquipWeapon( HSCRIPT hWeapon );
|
||||
|
||||
int ScriptGetAmmoCount( const char *szName ) const;
|
||||
void ScriptSetAmmoCount( const char *szName, int iCount );
|
||||
|
||||
int ScriptRelationType( HSCRIPT pTarget );
|
||||
int ScriptRelationPriority( HSCRIPT pTarget );
|
||||
void ScriptSetRelationship( HSCRIPT pTarget, int disposition, int priority );
|
||||
|
||||
HSCRIPT GetScriptVehicleEntity();
|
||||
|
||||
bool ScriptInViewCone( const Vector &vecSpot ) { return FInViewCone( vecSpot ); }
|
||||
bool ScriptEntInViewCone( HSCRIPT pEntity ) { return FInViewCone( ToEnt( pEntity ) ); }
|
||||
|
||||
bool ScriptInAimCone( const Vector &vecSpot ) { return FInAimCone( vecSpot ); }
|
||||
bool ScriptEntInAimCone( HSCRIPT pEntity ) { return FInAimCone( ToEnt( pEntity ) ); }
|
||||
|
||||
const Vector& ScriptBodyAngles( void ) { static Vector vec; QAngle qa = BodyAngles(); vec.x = qa.x; vec.y = qa.y; vec.z = qa.z; return vec; }
|
||||
#endif
|
||||
|
||||
// Interactions
|
||||
static void InitInteractionSystem();
|
||||
|
||||
|
@ -101,6 +101,9 @@ bool CBaseEntity::s_bAbsQueriesValid = true;
|
||||
|
||||
ConVar sv_netvisdist( "sv_netvisdist", "10000", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY, "Test networking visibility distance" );
|
||||
|
||||
ConVar sv_script_think_interval("sv_script_think_interval", "0.1");
|
||||
|
||||
|
||||
// This table encodes edict data.
|
||||
void SendProxy_AnimTime( const SendProp *pProp, const void *pStruct, const void *pVarData, DVariant *pOut, int iElement, int objectID )
|
||||
{
|
||||
@ -291,6 +294,8 @@ IMPLEMENT_SERVERCLASS_ST_NOBASE( CBaseEntity, DT_BaseEntity )
|
||||
SendPropEHandle (SENDINFO_NAME(m_hMoveParent, moveparent)),
|
||||
SendPropInt (SENDINFO(m_iParentAttachment), NUM_PARENTATTACHMENT_BITS, SPROP_UNSIGNED),
|
||||
|
||||
SendPropStringT( SENDINFO( m_iName ) ),
|
||||
|
||||
SendPropInt (SENDINFO_NAME( m_MoveType, movetype ), MOVETYPE_MAX_BITS, SPROP_UNSIGNED ),
|
||||
SendPropInt (SENDINFO_NAME( m_MoveCollide, movecollide ), MOVECOLLIDE_MAX_BITS, SPROP_UNSIGNED ),
|
||||
#if PREDICTION_ERROR_CHECK_LEVEL > 1
|
||||
@ -1313,6 +1318,19 @@ void CBaseEntity::FireNamedOutput( const char *pszOutput, variant_t variant, CBa
|
||||
if ( pszOutput == NULL )
|
||||
return;
|
||||
|
||||
CBaseEntityOutput *pOutput = FindNamedOutput( pszOutput );
|
||||
if ( pOutput )
|
||||
{
|
||||
pOutput->FireOutput( variant, pActivator, pCaller, flDelay );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CBaseEntityOutput *CBaseEntity::FindNamedOutput( const char *pszOutput )
|
||||
{
|
||||
if ( pszOutput == NULL )
|
||||
return NULL;
|
||||
|
||||
datamap_t *dmap = GetDataDescMap();
|
||||
while ( dmap )
|
||||
{
|
||||
@ -1325,14 +1343,13 @@ void CBaseEntity::FireNamedOutput( const char *pszOutput, variant_t variant, CBa
|
||||
CBaseEntityOutput *pOutput = ( CBaseEntityOutput * )( ( int )this + ( int )dataDesc->fieldOffset[0] );
|
||||
if ( !Q_stricmp( dataDesc->externalName, pszOutput ) )
|
||||
{
|
||||
pOutput->FireOutput( variant, pActivator, pCaller, flDelay );
|
||||
return;
|
||||
return pOutput;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dmap = dmap->baseMap;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CBaseEntity::Activate( void )
|
||||
@ -1822,6 +1839,12 @@ BEGIN_DATADESC_NO_BASE( CBaseEntity )
|
||||
DEFINE_FIELD( m_flSimulationTime, FIELD_TIME ),
|
||||
DEFINE_FIELD( m_nLastThinkTick, FIELD_TICK ),
|
||||
|
||||
DEFINE_FIELD(m_iszScriptId, FIELD_STRING),
|
||||
// m_ScriptScope;
|
||||
// m_hScriptInstance;
|
||||
|
||||
DEFINE_KEYFIELD(m_iszVScripts, FIELD_STRING, "vscripts"),
|
||||
DEFINE_KEYFIELD(m_iszScriptThinkFunction, FIELD_STRING, "thinkfunction"),
|
||||
DEFINE_KEYFIELD( m_nNextThinkTick, FIELD_TICK, "nextthink" ),
|
||||
DEFINE_KEYFIELD( m_fEffects, FIELD_INTEGER, "effects" ),
|
||||
DEFINE_KEYFIELD( m_clrRender, FIELD_COLOR32, "rendercolor" ),
|
||||
@ -2004,6 +2027,14 @@ BEGIN_DATADESC_NO_BASE( CBaseEntity )
|
||||
DEFINE_INPUTFUNC( FIELD_STRING, "FireUser4", InputFireUser4 ),
|
||||
#endif
|
||||
|
||||
DEFINE_INPUTFUNC(FIELD_STRING, "RunScriptFile", InputRunScriptFile),
|
||||
DEFINE_INPUTFUNC(FIELD_STRING, "RunScriptCode", InputRunScript),
|
||||
DEFINE_INPUTFUNC(FIELD_STRING, "CallScriptFunction", InputCallScriptFunction),
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DEFINE_INPUTFUNC(FIELD_STRING, "RunScriptCodeQuotable", InputRunScriptQuotable),
|
||||
DEFINE_INPUTFUNC(FIELD_VOID, "ClearScriptScope", InputClearScriptScope),
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE
|
||||
DEFINE_OUTPUT( m_OutUser1, "OutUser1" ),
|
||||
DEFINE_OUTPUT( m_OutUser2, "OutUser2" ),
|
||||
@ -2081,6 +2112,7 @@ BEGIN_DATADESC_NO_BASE( CBaseEntity )
|
||||
DEFINE_FUNCTION( SUB_Vanish ),
|
||||
DEFINE_FUNCTION( SUB_CallUseToggle ),
|
||||
DEFINE_THINKFUNC( ShadowCastDistThink ),
|
||||
DEFINE_THINKFUNC( ScriptThink ),
|
||||
|
||||
#ifdef MAPBASE
|
||||
DEFINE_FUNCTION( SUB_RemoveWhenNotVisible ),
|
||||
@ -2097,6 +2129,122 @@ BEGIN_DATADESC_NO_BASE( CBaseEntity )
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
|
||||
BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities" )
|
||||
DEFINE_SCRIPT_INSTANCE_HELPER( &g_BaseEntityScriptInstanceHelper )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ConnectOutputToScript, "ConnectOutput", "Adds an I/O connection that will call the named function when the specified output fires" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( DisconnectOutputFromScript, "DisconnectOutput", "Removes a connected script function from an I/O event." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetHealth, "" )
|
||||
DEFINE_SCRIPTFUNC( SetHealth, "" )
|
||||
DEFINE_SCRIPTFUNC( GetMaxHealth, "" )
|
||||
DEFINE_SCRIPTFUNC( SetMaxHealth, "" )
|
||||
|
||||
DEFINE_SCRIPTFUNC( SetModel, "" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetModelName, "GetModelName", "Returns the name of the model" )
|
||||
|
||||
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.")
|
||||
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetClassname, "" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( GetEntityNameAsCStr, "GetName", "" )
|
||||
DEFINE_SCRIPTFUNC( GetPreTemplateName, "Get the entity name stripped of template unique decoration" )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( GetAbsOrigin, "GetOrigin", "" )
|
||||
DEFINE_SCRIPTFUNC( SetAbsOrigin, "SetAbsOrigin" )
|
||||
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetOrigin, "SetOrigin", "" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetForward, "GetForwardVector", "Get the forward vector of the entity" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetLeft, "GetLeftVector", "Get the left vector of the entity" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetUp, "GetUpVector", "Get the up vector of the entity" )
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptEntityToWorldTransform, "EntityToWorldTransform", "Get the entity's transform" )
|
||||
#endif
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetForward, "SetForwardVector", "Set the orientation of the entity to have this forward vector" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( GetAbsVelocity, "GetVelocity", "" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( SetAbsVelocity, "SetVelocity", "" )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetLocalAngularVelocity, "SetAngularVelocity", "Set the local angular velocity - takes float pitch,yaw,roll velocities" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetLocalAngularVelocity, "GetAngularVelocity", "Get the local angular velocity - returns a vector of pitch,yaw,roll" )
|
||||
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( WorldSpaceCenter, "GetCenter", "Get vector to center of object - absolute coords")
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptEyePosition, "EyePosition", "Get vector to eye position - absolute coords")
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptEyeAngles, "EyeAngles", "Get eye pitch, yaw, roll as a vector" )
|
||||
#endif
|
||||
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_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( ScriptSetOwner, "SetOwner", "" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( GetTeamNumber, "GetTeam", "" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ChangeTeam, "SetTeam", "" )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetMoveParent, "GetMoveParent", "If in hierarchy, retrieves the entity's parent" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetRootMoveParent, "GetRootMoveParent", "If in hierarchy, walks up the hierarchy to find the root parent" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptFirstMoveChild, "FirstMoveChild", "" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptNextMovePeer, "NextMovePeer", "" )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( KeyValueFromString, "__KeyValueFromString", SCRIPT_HIDE )
|
||||
DEFINE_SCRIPTFUNC_NAMED( KeyValueFromFloat, "__KeyValueFromFloat", SCRIPT_HIDE )
|
||||
DEFINE_SCRIPTFUNC_NAMED( KeyValueFromInt, "__KeyValueFromInt", SCRIPT_HIDE )
|
||||
DEFINE_SCRIPTFUNC_NAMED( KeyValueFromVector, "__KeyValueFromVector", SCRIPT_HIDE )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetModelKeyValues, "GetModelKeyValues", "Get a KeyValue class instance on this entity's model")
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptIsVisible, "IsVisible", "Check if the specified position can be visible to this entity." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptIsEntVisible, "IsEntVisible", "Check if the specified entity can be visible to this entity." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptIsVisibleWithMask, "IsVisibleWithMask", "Check if the specified position can be visible to this entity with a specific trace mask." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptTakeDamage, "TakeDamage", "Apply damage to this entity with a given info handle" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptFireBullets, "FireBullets", "Fire bullets from entity with a given info handle" )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetContext, "GetContext", "Get a response context value" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptAddContext, "AddContext", "Add a response context value" )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptClassify, "Classify", "Get Class_T class ID" )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetKeyValue, "GetKeyValue", "Get a keyvalue" )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetSpawnFlags, "Get spawnflags" )
|
||||
DEFINE_SCRIPTFUNC( AddSpawnFlags, "Add spawnflag(s)" )
|
||||
DEFINE_SCRIPTFUNC( RemoveSpawnFlags, "Remove spawnflag(s)" )
|
||||
DEFINE_SCRIPTFUNC( ClearSpawnFlags, "Clear spawnflag(s)" )
|
||||
DEFINE_SCRIPTFUNC( HasSpawnFlags, "Check if the entity has specific spawnflag(s) ticked" )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetEffects, "Get effects" )
|
||||
DEFINE_SCRIPTFUNC( AddEffects, "Add effect(s)" )
|
||||
DEFINE_SCRIPTFUNC( RemoveEffects, "Remove effect(s)" )
|
||||
DEFINE_SCRIPTFUNC( ClearEffects, "Clear effect(s)" )
|
||||
DEFINE_SCRIPTFUNC( SetEffects, "Set effect(s)" )
|
||||
DEFINE_SCRIPTFUNC( IsEffectActive, "Check if an effect is active" )
|
||||
|
||||
DEFINE_SCRIPTFUNC( IsPlayer, "Returns true if this entity is a player." )
|
||||
DEFINE_SCRIPTFUNC( IsNPC, "Returns true if this entity is a NPC." )
|
||||
DEFINE_SCRIPTFUNC( IsCombatCharacter, "Returns true if this entity is a combat character (player or NPC)." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( IsBaseCombatWeapon, "IsWeapon", "Returns true if this entity is a weapon." )
|
||||
#endif
|
||||
|
||||
DEFINE_SCRIPTFUNC( ValidateScriptScope, "Ensure that an entity's script scope has been created" )
|
||||
DEFINE_SCRIPTFUNC( GetScriptScope, "Retrieve the script-side data associated with an entity" )
|
||||
DEFINE_SCRIPTFUNC( GetScriptId, "Retrieve the unique identifier used to refer to the entity within the scripting system" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( GetScriptOwnerEntity, "GetOwner", "Gets this entity's owner" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( SetScriptOwnerEntity, "SetOwner", "Sets this entity's owner" )
|
||||
DEFINE_SCRIPTFUNC( entindex, "" )
|
||||
END_SCRIPTDESC();
|
||||
|
||||
|
||||
// For code error checking
|
||||
extern bool g_bReceivedChainedUpdateOnRemove;
|
||||
|
||||
@ -2196,6 +2344,12 @@ void CBaseEntity::UpdateOnRemove( void )
|
||||
modelinfo->ReleaseDynamicModel( m_nModelIndex ); // no-op if not dynamic
|
||||
m_nModelIndex = -1;
|
||||
}
|
||||
|
||||
if ( m_hScriptInstance )
|
||||
{
|
||||
g_pScriptVM->RemoveInstance( m_hScriptInstance );
|
||||
m_hScriptInstance = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -3925,9 +4079,9 @@ const char *CBaseEntity::GetDebugName(void)
|
||||
if ( this == NULL )
|
||||
return "<<null>>";
|
||||
|
||||
if ( m_iName != NULL_STRING )
|
||||
if ( m_iName.Get() != NULL_STRING )
|
||||
{
|
||||
return STRING(m_iName);
|
||||
return STRING(m_iName.Get());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4108,7 +4262,7 @@ bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator,
|
||||
// mapper debug message
|
||||
if (pCaller != NULL)
|
||||
{
|
||||
Q_snprintf( szBuffer, sizeof(szBuffer), "(%0.2f) input %s: %s.%s(%s)\n", gpGlobals->curtime, STRING(pCaller->m_iName), GetDebugName(), szInputName, Value.String() );
|
||||
Q_snprintf( szBuffer, sizeof(szBuffer), "(%0.2f) input %s: %s.%s(%s)\n", gpGlobals->curtime, STRING(pCaller->m_iName.Get()), GetDebugName(), szInputName, Value.String() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4155,7 +4309,7 @@ bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator,
|
||||
Warning( "!! ERROR: bad input/output link:\n!! Unable to convert value \"%s\" from %s (%s) to field type %i\n!! Target Entity: %s (%s), Input: %s\n",
|
||||
Value.GetDebug(),
|
||||
( pCaller != NULL ) ? STRING(pCaller->m_iClassname) : "<null>",
|
||||
( pCaller != NULL ) ? STRING(pCaller->m_iName) : "<null>",
|
||||
( pCaller != NULL ) ? STRING(pCaller->m_iName.Get()) : "<null>",
|
||||
dmap->dataDesc[i].fieldType,
|
||||
STRING(m_iClassname), GetDebugName(), szInputName );
|
||||
return false;
|
||||
@ -4168,7 +4322,7 @@ bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator,
|
||||
Warning( "!! ERROR: bad input/output link:\n!! %s(%s,%s) doesn't match type from %s(%s)\n",
|
||||
STRING(m_iClassname), GetDebugName(), szInputName,
|
||||
( pCaller != NULL ) ? STRING(pCaller->m_iClassname) : "<null>",
|
||||
( pCaller != NULL ) ? STRING(pCaller->m_iName) : "<null>" );
|
||||
( pCaller != NULL ) ? STRING(pCaller->m_iName.Get()) : "<null>" );
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
@ -4187,7 +4341,44 @@ bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator,
|
||||
data.value = Value;
|
||||
data.nOutputID = outputID;
|
||||
|
||||
(this->*pfnInput)( data );
|
||||
|
||||
// Now, see if there's a function named Input<Name of Input> in this entity's script file.
|
||||
// If so, execute it and let it decide whether to allow the default behavior to also execute.
|
||||
bool bCallInputFunc = true; // Always assume default behavior (do call the input function)
|
||||
ScriptVariant_t functionReturn;
|
||||
|
||||
if ( m_ScriptScope.IsInitialized() )
|
||||
{
|
||||
char szScriptFunctionName[255];
|
||||
Q_strcpy( szScriptFunctionName, "Input" );
|
||||
Q_strcat( szScriptFunctionName, szInputName, 255 );
|
||||
|
||||
g_pScriptVM->SetValue( "activator", ( pActivator ) ? ScriptVariant_t( pActivator->GetScriptInstance() ) : SCRIPT_VARIANT_NULL );
|
||||
g_pScriptVM->SetValue( "caller", ( pCaller ) ? ScriptVariant_t( pCaller->GetScriptInstance() ) : SCRIPT_VARIANT_NULL );
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
Value.SetScriptVariant( functionReturn );
|
||||
g_pScriptVM->SetValue( "parameter", functionReturn );
|
||||
#endif
|
||||
|
||||
if( CallScriptFunction( szScriptFunctionName, &functionReturn ) )
|
||||
{
|
||||
bCallInputFunc = functionReturn.m_bool;
|
||||
}
|
||||
}
|
||||
|
||||
if( bCallInputFunc )
|
||||
{
|
||||
(this->*pfnInput)( data );
|
||||
}
|
||||
|
||||
if ( m_ScriptScope.IsInitialized() )
|
||||
{
|
||||
g_pScriptVM->ClearValue( "activator" );
|
||||
g_pScriptVM->ClearValue( "caller" );
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
g_pScriptVM->ClearValue( "parameter" );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if ( dmap->dataDesc[i].flags & FTYPEDESC_KEY )
|
||||
{
|
||||
@ -4210,7 +4401,7 @@ bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator,
|
||||
}
|
||||
}
|
||||
|
||||
DevMsg( 2, "unhandled input: (%s) -> (%s,%s)\n", szInputName, STRING(m_iClassname), GetDebugName()/*,", from (%s,%s)" STRING(pCaller->m_iClassname), STRING(pCaller->m_iName)*/ );
|
||||
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())*/ );
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -5300,6 +5491,36 @@ void CC_Ent_Name( const CCommand& args )
|
||||
}
|
||||
static ConCommand ent_name("ent_name", CC_Ent_Name, 0, FCVAR_CHEAT);
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
void DumpScriptScope(CBasePlayer* pPlayer, const char* name)
|
||||
{
|
||||
CBaseEntity* pEntity = NULL;
|
||||
while ((pEntity = GetNextCommandEntity(pPlayer, name, pEntity)) != NULL)
|
||||
{
|
||||
if (pEntity->m_ScriptScope.IsInitialized())
|
||||
{
|
||||
Msg("----Script Dump for entity %s\n", pEntity->GetDebugName());
|
||||
HSCRIPT hDumpScopeFunc = g_pScriptVM->LookupFunction("__DumpScope");
|
||||
g_pScriptVM->Call(hDumpScopeFunc, NULL, true, NULL, 1, (HSCRIPT)pEntity->m_ScriptScope);
|
||||
Msg("----End Script Dump\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
DevWarning("ent_script_dump: Entity %s has no script scope!\n", pEntity->GetDebugName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void CC_Ent_Script_Dump( const CCommand& args )
|
||||
{
|
||||
DumpScriptScope(UTIL_GetCommandClient(),args[1]);
|
||||
}
|
||||
static ConCommand ent_script_dump("ent_script_dump", CC_Ent_Script_Dump, "Dumps the names and values of this entity's script scope to the console\n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at ", FCVAR_CHEAT);
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#ifdef MAPBASE
|
||||
class CEntTextAutoCompletionFunctor : public ICommandCallback, public ICommandCompletionCallback
|
||||
@ -6978,6 +7199,7 @@ const char *CBaseEntity::GetContextValue( int index ) const
|
||||
}
|
||||
|
||||
return m_ResponseContexts[ index ].m_iszValue.ToCStr();
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -7223,7 +7445,6 @@ void CBaseEntity::InputPassRandomUser( inputdata_t& inputdata )
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef MAPBASE
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sets the entity's targetname.
|
||||
@ -7820,6 +8041,282 @@ void CBaseEntity::InputSetThinkNull( inputdata_t& inputdata )
|
||||
#endif
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Use the string as the filename of a script file
|
||||
// that should be loaded from disk, compiled, and run.
|
||||
//---------------------------------------------------------
|
||||
void CBaseEntity::InputRunScriptFile(inputdata_t& inputdata)
|
||||
{
|
||||
RunScriptFile(inputdata.value.String());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Send the string to the VM as source code and execute it
|
||||
//---------------------------------------------------------
|
||||
void CBaseEntity::InputRunScript(inputdata_t& inputdata)
|
||||
{
|
||||
RunScript(inputdata.value.String(), "InputRunScript");
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Make an explicit function call.
|
||||
//---------------------------------------------------------
|
||||
void CBaseEntity::InputCallScriptFunction(inputdata_t& inputdata)
|
||||
{
|
||||
CallScriptFunction(inputdata.value.String(), NULL);
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
//---------------------------------------------------------
|
||||
// Send the string to the VM as source code and execute it
|
||||
//---------------------------------------------------------
|
||||
void CBaseEntity::InputRunScriptQuotable(inputdata_t& inputdata)
|
||||
{
|
||||
char szQuotableCode[1024];
|
||||
if (V_StrSubst( inputdata.value.String(), "''", "\"", szQuotableCode, sizeof( szQuotableCode ), false ))
|
||||
{
|
||||
RunScript( szQuotableCode, "InputRunScriptQuotable" );
|
||||
}
|
||||
else
|
||||
{
|
||||
RunScript( inputdata.value.String(), "InputRunScriptQuotable" );
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Clear this entity's script scope
|
||||
//---------------------------------------------------------
|
||||
void CBaseEntity::InputClearScriptScope(inputdata_t& inputdata)
|
||||
{
|
||||
m_ScriptScope.Term();
|
||||
}
|
||||
#endif
|
||||
|
||||
// #define VMPROFILE // define to profile vscript calls
|
||||
|
||||
#ifdef VMPROFILE
|
||||
float g_debugCumulativeTime = 0.0;
|
||||
float g_debugCounter = 0;
|
||||
|
||||
#define START_VMPROFILE float debugStartTime = Plat_FloatTime();
|
||||
#define UPDATE_VMPROFILE \
|
||||
g_debugCumulativeTime += Plat_FloatTime() - debugStartTime; \
|
||||
g_debugCounter++; \
|
||||
if ( g_debugCounter >= 500 ) \
|
||||
{ \
|
||||
DevMsg("***VSCRIPT PROFILE***: %s %s: %6.4f milliseconds\n", "500 vscript function calls", "", g_debugCumulativeTime*1000.0 ); \
|
||||
g_debugCounter = 0; \
|
||||
g_debugCumulativeTime = 0.0; \
|
||||
} \
|
||||
|
||||
#else
|
||||
|
||||
#define START_VMPROFILE
|
||||
#define UPDATE_VMPROFILE
|
||||
|
||||
#endif // VMPROFILE
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns true if the function was located and called. false otherwise.
|
||||
// NOTE: Assumes the function takes no parameters at the moment.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBaseEntity::CallScriptFunction(const char* pFunctionName, ScriptVariant_t* pFunctionReturn)
|
||||
{
|
||||
START_VMPROFILE
|
||||
|
||||
if (!ValidateScriptScope())
|
||||
{
|
||||
DevMsg("\n***\nFAILED to create private ScriptScope. ABORTING script\n***\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
HSCRIPT hFunc = m_ScriptScope.LookupFunction(pFunctionName);
|
||||
|
||||
if (hFunc)
|
||||
{
|
||||
m_ScriptScope.Call(hFunc, pFunctionReturn);
|
||||
m_ScriptScope.ReleaseFunction(hFunc);
|
||||
|
||||
UPDATE_VMPROFILE
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseEntity::ConnectOutputToScript(const char* pszOutput, const char* pszScriptFunc)
|
||||
{
|
||||
CBaseEntityOutput* pOutput = FindNamedOutput(pszOutput);
|
||||
if (!pOutput)
|
||||
{
|
||||
DevMsg(2, "Script failed to find output \"%s\"\n", pszOutput);
|
||||
return;
|
||||
}
|
||||
|
||||
string_t iszSelf = AllocPooledString("!self"); // @TODO: cache this [4/25/2008 tom]
|
||||
CEventAction* pAction = pOutput->GetActionList();
|
||||
while (pAction)
|
||||
{
|
||||
if (pAction->m_iTarget == iszSelf &&
|
||||
pAction->m_flDelay == 0 &&
|
||||
pAction->m_nTimesToFire == EVENT_FIRE_ALWAYS &&
|
||||
V_strcmp(STRING(pAction->m_iTargetInput), "CallScriptFunction") == 0 &&
|
||||
V_strcmp(STRING(pAction->m_iParameter), pszScriptFunc) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
pAction = pAction->m_pNext;
|
||||
}
|
||||
|
||||
pAction = new CEventAction(NULL);
|
||||
pAction->m_iTarget = iszSelf;
|
||||
pAction->m_iTargetInput = AllocPooledString("CallScriptFunction");
|
||||
pAction->m_iParameter = AllocPooledString(pszScriptFunc);
|
||||
pOutput->AddEventAction(pAction);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseEntity::DisconnectOutputFromScript(const char* pszOutput, const char* pszScriptFunc)
|
||||
{
|
||||
CBaseEntityOutput* pOutput = FindNamedOutput(pszOutput);
|
||||
if (!pOutput)
|
||||
{
|
||||
DevMsg(2, "Script failed to find output \"%s\"\n", pszOutput);
|
||||
return;
|
||||
}
|
||||
|
||||
string_t iszSelf = AllocPooledString("!self"); // @TODO: cache this [4/25/2008 tom]
|
||||
CEventAction* pAction = pOutput->GetActionList();
|
||||
while (pAction)
|
||||
{
|
||||
if (pAction->m_iTarget == iszSelf &&
|
||||
pAction->m_flDelay == 0 &&
|
||||
pAction->m_nTimesToFire == EVENT_FIRE_ALWAYS &&
|
||||
V_strcmp(STRING(pAction->m_iTargetInput), "CallScriptFunction") == 0 &&
|
||||
V_strcmp(STRING(pAction->m_iParameter), pszScriptFunc) == 0)
|
||||
{
|
||||
pOutput->RemoveEventAction(pAction);
|
||||
delete pAction;
|
||||
return;
|
||||
}
|
||||
pAction = pAction->m_pNext;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseEntity::ScriptThink(void)
|
||||
{
|
||||
ScriptVariant_t varThinkRetVal;
|
||||
if (CallScriptFunction(m_iszScriptThinkFunction.ToCStr(), &varThinkRetVal))
|
||||
{
|
||||
float flThinkFrequency = 0.0f;
|
||||
if (!varThinkRetVal.AssignTo(&flThinkFrequency))
|
||||
{
|
||||
// use default think interval if script think function doesn't provide one
|
||||
flThinkFrequency = sv_script_think_interval.GetFloat();
|
||||
}
|
||||
SetContextThink(&CBaseEntity::ScriptThink,
|
||||
gpGlobals->curtime + flThinkFrequency, "ScriptThink");
|
||||
}
|
||||
else
|
||||
{
|
||||
DevWarning("%s FAILED to call script think function %s!\n", GetDebugName(), STRING(m_iszScriptThinkFunction));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
const char* CBaseEntity::GetScriptId()
|
||||
{
|
||||
return STRING(m_iszScriptThinkFunction);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CBaseEntity::GetScriptScope()
|
||||
{
|
||||
return m_ScriptScope;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CBaseEntity::ScriptGetMoveParent(void)
|
||||
{
|
||||
return ToHScript(GetMoveParent());
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CBaseEntity::ScriptGetRootMoveParent()
|
||||
{
|
||||
return ToHScript(GetRootMoveParent());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CBaseEntity::ScriptFirstMoveChild(void)
|
||||
{
|
||||
return ToHScript(FirstMoveChild());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CBaseEntity::ScriptNextMovePeer(void)
|
||||
{
|
||||
return ToHScript(NextMovePeer());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Load, compile, and run a script file from disk.
|
||||
// Input : *pScriptFile - The filename of the script file.
|
||||
// bUseRootScope - If true, runs this script in the root scope, not
|
||||
// in this entity's private scope.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBaseEntity::RunScriptFile(const char* pScriptFile, bool bUseRootScope)
|
||||
{
|
||||
if (!ValidateScriptScope())
|
||||
{
|
||||
DevMsg("\n***\nFAILED to create private ScriptScope. ABORTING script\n***\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bUseRootScope)
|
||||
{
|
||||
return VScriptRunScript(pScriptFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
return VScriptRunScript(pScriptFile, m_ScriptScope, true);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Compile and execute a discrete string of script source code
|
||||
// Input : *pScriptText - A string containing script code to compile and run
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBaseEntity::RunScript(const char* pScriptText, const char* pDebugFilename)
|
||||
{
|
||||
if (!ValidateScriptScope())
|
||||
{
|
||||
DevMsg("\n***\nFAILED to create private ScriptScope. ABORTING script\n***\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_ScriptScope.Run(pScriptText, pDebugFilename) == SCRIPT_ERROR)
|
||||
{
|
||||
DevWarning(" Entity %s encountered an error in RunScript()\n", GetDebugName());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *contextName -
|
||||
@ -8796,6 +9293,329 @@ void CBaseEntity::SetCollisionBoundsFromModel()
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CBaseEntity::GetScriptInstance()
|
||||
{
|
||||
if (!m_hScriptInstance)
|
||||
{
|
||||
if (m_iszScriptId == NULL_STRING)
|
||||
{
|
||||
char* szName = (char*)stackalloc(1024);
|
||||
g_pScriptVM->GenerateUniqueKey((m_iName.Get() != NULL_STRING) ? STRING(GetEntityName()) : GetClassname(), szName, 1024);
|
||||
m_iszScriptId = AllocPooledString(szName);
|
||||
}
|
||||
|
||||
m_hScriptInstance = g_pScriptVM->RegisterInstance(GetScriptDesc(), this);
|
||||
g_pScriptVM->SetInstanceUniqeId(m_hScriptInstance, STRING(m_iszScriptId));
|
||||
}
|
||||
return m_hScriptInstance;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Using my edict, cook up a unique VScript scope that's private to me, and
|
||||
// persistent.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBaseEntity::ValidateScriptScope()
|
||||
{
|
||||
if (!m_ScriptScope.IsInitialized())
|
||||
{
|
||||
if (scriptmanager == NULL)
|
||||
{
|
||||
ExecuteOnce(DevMsg("Cannot execute script because scripting is disabled (-scripting)\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (g_pScriptVM == NULL)
|
||||
{
|
||||
ExecuteOnce(DevMsg(" Cannot execute script because there is no available VM\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Force instance creation
|
||||
GetScriptInstance();
|
||||
|
||||
EHANDLE hThis;
|
||||
hThis.Set(this);
|
||||
|
||||
bool bResult = m_ScriptScope.Init(STRING(m_iszScriptId));
|
||||
|
||||
if (!bResult)
|
||||
{
|
||||
DevMsg("%s couldn't create ScriptScope!\n", GetDebugName());
|
||||
return false;
|
||||
}
|
||||
g_pScriptVM->SetValue(m_ScriptScope, "self", GetScriptInstance());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Run all of the vscript files that are set in this entity's VSCRIPTS
|
||||
// field in Hammer. The list is space-delimited.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseEntity::RunVScripts()
|
||||
{
|
||||
if (m_iszVScripts == NULL_STRING)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ValidateScriptScope();
|
||||
|
||||
// All functions we want to have call chained instead of overwritten
|
||||
// by other scripts in this entities list.
|
||||
static const char* sCallChainFunctions[] =
|
||||
{
|
||||
"OnPostSpawn",
|
||||
"Precache"
|
||||
};
|
||||
|
||||
ScriptLanguage_t language = g_pScriptVM->GetLanguage();
|
||||
|
||||
// Make a call chainer for each in this entities scope
|
||||
for (int j = 0; j < ARRAYSIZE(sCallChainFunctions); ++j)
|
||||
{
|
||||
|
||||
if (language == SL_PYTHON)
|
||||
{
|
||||
// UNDONE - handle call chaining in python
|
||||
;
|
||||
}
|
||||
else if (language == SL_SQUIRREL)
|
||||
{
|
||||
//TODO: For perf, this should be precompiled and the %s should be passed as a parameter
|
||||
HSCRIPT hCreateChainScript = g_pScriptVM->CompileScript(CFmtStr("%sCallChain <- CSimpleCallChainer(\"%s\", self.GetScriptScope(), true)", sCallChainFunctions[j], sCallChainFunctions[j]));
|
||||
g_pScriptVM->Run(hCreateChainScript, (HSCRIPT)m_ScriptScope);
|
||||
}
|
||||
}
|
||||
|
||||
char szScriptsList[255];
|
||||
Q_strcpy(szScriptsList, STRING(m_iszVScripts));
|
||||
CUtlStringList szScripts;
|
||||
|
||||
V_SplitString(szScriptsList, " ", szScripts);
|
||||
|
||||
for (int i = 0; i < szScripts.Count(); i++)
|
||||
{
|
||||
Log( "%s executing script: %s\n", GetDebugName(), szScripts[i]);
|
||||
|
||||
RunScriptFile(szScripts[i], IsWorld());
|
||||
|
||||
for (int j = 0; j < ARRAYSIZE(sCallChainFunctions); ++j)
|
||||
{
|
||||
if (language == SL_PYTHON)
|
||||
{
|
||||
// UNDONE - handle call chaining in python
|
||||
;
|
||||
}
|
||||
else if (language == SL_SQUIRREL)
|
||||
{
|
||||
//TODO: For perf, this should be precompiled and the %s should be passed as a parameter.
|
||||
HSCRIPT hRunPostScriptExecute = g_pScriptVM->CompileScript(CFmtStr("%sCallChain.PostScriptExecute()", sCallChainFunctions[j]));
|
||||
g_pScriptVM->Run(hRunPostScriptExecute, (HSCRIPT)m_ScriptScope);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_iszScriptThinkFunction != NULL_STRING)
|
||||
{
|
||||
SetContextThink(&CBaseEntity::ScriptThink, gpGlobals->curtime + sv_script_think_interval.GetFloat(), "ScriptThink");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// This is called during entity spawning and after restore to allow scripts to precache any
|
||||
// resources they need.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void CBaseEntity::RunPrecacheScripts(void)
|
||||
{
|
||||
if (m_iszVScripts == NULL_STRING)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HSCRIPT hScriptPrecache = m_ScriptScope.LookupFunction("DispatchPrecache");
|
||||
if (hScriptPrecache)
|
||||
{
|
||||
g_pScriptVM->Call(hScriptPrecache, m_ScriptScope);
|
||||
m_ScriptScope.ReleaseFunction(hScriptPrecache);
|
||||
}
|
||||
}
|
||||
|
||||
void CBaseEntity::RunOnPostSpawnScripts(void)
|
||||
{
|
||||
if (m_iszVScripts == NULL_STRING)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HSCRIPT hFuncConnect = g_pScriptVM->LookupFunction("ConnectOutputs");
|
||||
if (hFuncConnect)
|
||||
{
|
||||
g_pScriptVM->Call(hFuncConnect, NULL, true, NULL, (HSCRIPT)m_ScriptScope);
|
||||
g_pScriptVM->ReleaseFunction(hFuncConnect);
|
||||
}
|
||||
|
||||
HSCRIPT hFuncDisp = m_ScriptScope.LookupFunction("DispatchOnPostSpawn");
|
||||
if (hFuncDisp)
|
||||
{
|
||||
variant_t variant;
|
||||
variant.SetString(MAKE_STRING("DispatchOnPostSpawn"));
|
||||
g_EventQueue.AddEvent(this, "CallScriptFunction", variant, 0, this, this);
|
||||
m_ScriptScope.ReleaseFunction(hFuncDisp);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
HSCRIPT CBaseEntity::GetScriptOwnerEntity()
|
||||
{
|
||||
return ToHScript(GetOwnerEntity());
|
||||
}
|
||||
|
||||
void CBaseEntity::SetScriptOwnerEntity(HSCRIPT pOwner)
|
||||
{
|
||||
SetOwnerEntity(ToEnt(pOwner));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// VScript access to model's key values
|
||||
// for iteration and value access, use:
|
||||
// ScriptFindKey, ScriptGetFirstSubKey, ScriptGetString,
|
||||
// ScriptGetInt, ScriptGetFloat, ScriptGetNextKey
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CBaseEntity::ScriptGetModelKeyValues( void )
|
||||
{
|
||||
KeyValues *pModelKeyValues = new KeyValues("");
|
||||
HSCRIPT hScript = NULL;
|
||||
const char *pszModelName = modelinfo->GetModelName( GetModel() );
|
||||
const char *pBuffer = modelinfo->GetModelKeyValueText( GetModel() ) ;
|
||||
|
||||
if ( pModelKeyValues->LoadFromBuffer( pszModelName, pBuffer ) )
|
||||
{
|
||||
// UNDONE: how does destructor get called on this
|
||||
m_pScriptModelKeyValues = new CScriptKeyValues( pModelKeyValues );
|
||||
|
||||
// UNDONE: who calls ReleaseInstance on this??? Does name need to be unique???
|
||||
|
||||
hScript = g_pScriptVM->RegisterInstance( m_pScriptModelKeyValues );
|
||||
|
||||
/*
|
||||
KeyValues *pParticleEffects = pModelKeyValues->FindKey("Particles");
|
||||
if ( pParticleEffects )
|
||||
{
|
||||
// Start grabbing the sounds and slotting them in
|
||||
for ( KeyValues *pSingleEffect = pParticleEffects->GetFirstSubKey(); pSingleEffect; pSingleEffect = pSingleEffect->GetNextKey() )
|
||||
{
|
||||
const char *pParticleEffectName = pSingleEffect->GetString( "name", "" );
|
||||
PrecacheParticleSystem( pParticleEffectName );
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
return hScript;
|
||||
}
|
||||
|
||||
void CBaseEntity::ScriptSetLocalAngularVelocity(float pitchVel, float yawVel, float rollVel)
|
||||
{
|
||||
QAngle qa;
|
||||
qa.Init(pitchVel, yawVel, rollVel);
|
||||
SetLocalAngularVelocity(qa);
|
||||
}
|
||||
|
||||
const Vector& CBaseEntity::ScriptGetLocalAngularVelocity(void)
|
||||
{
|
||||
QAngle qa = GetLocalAngularVelocity();
|
||||
static Vector v;
|
||||
v.x = qa.x;
|
||||
v.y = qa.y;
|
||||
v.z = qa.z;
|
||||
return v;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Vscript: Gets the min collision bounds, centered on object
|
||||
//-----------------------------------------------------------------------------
|
||||
const Vector& CBaseEntity::ScriptGetBoundingMins(void)
|
||||
{
|
||||
return m_Collision.OBBMins();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Vscript: Gets the max collision bounds, centered on object
|
||||
//-----------------------------------------------------------------------------
|
||||
const Vector& CBaseEntity::ScriptGetBoundingMaxs(void)
|
||||
{
|
||||
return m_Collision.OBBMaxs();
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
int CBaseEntity::ScriptTakeDamage( HSCRIPT pInfo )
|
||||
{
|
||||
if (pInfo)
|
||||
{
|
||||
CTakeDamageInfo *info = HScriptToClass<CTakeDamageInfo>( pInfo ); //ToDamageInfo( pInfo );
|
||||
if (info)
|
||||
{
|
||||
return OnTakeDamage( *info );
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseEntity::ScriptFireBullets( HSCRIPT pInfo )
|
||||
{
|
||||
if (pInfo)
|
||||
{
|
||||
extern FireBulletsInfo_t *GetFireBulletsInfoFromInfo( HSCRIPT hBulletsInfo );
|
||||
FireBulletsInfo_t *info = GetFireBulletsInfoFromInfo( pInfo );
|
||||
if (info)
|
||||
{
|
||||
FireBullets( *info );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseEntity::ScriptAddContext( const char *name, const char *value, float duration )
|
||||
{
|
||||
AddContext( name, value, duration );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CBaseEntity::ScriptGetContext( const char *name )
|
||||
{
|
||||
return GetContextValue( name );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
int CBaseEntity::ScriptClassify( void )
|
||||
{
|
||||
return (int)Classify();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CBaseEntity::ScriptGetKeyValue( const char *pszKeyName )
|
||||
{
|
||||
static char szValue[128];
|
||||
GetKeyValue( pszKeyName, szValue, sizeof(szValue) );
|
||||
return szValue;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef MAPBASE
|
||||
extern int EntityFactory_AutoComplete( const char *cmdname, CUtlVector< CUtlString > &commands, CUtlRBTree< CUtlString > &symbols, char *substring, int checklen = 0 );
|
||||
|
||||
|
@ -21,6 +21,9 @@
|
||||
#include "shareddefs.h"
|
||||
#include "engine/ivmodelinfo.h"
|
||||
|
||||
#include "vscript/ivscript.h"
|
||||
#include "vscript_server.h"
|
||||
|
||||
class CDamageModifier;
|
||||
class CDmgAccumulator;
|
||||
|
||||
@ -311,11 +314,13 @@ a list of all CBaseEntitys is kept in gEntList
|
||||
CBaseEntity *CreateEntityByName( const char *className, int iForceEdictIndex = -1 );
|
||||
CBaseNetworkable *CreateNetworkableByName( const char *className );
|
||||
|
||||
CBaseEntity* ToEnt(HSCRIPT hScript);
|
||||
|
||||
// creates an entity and calls all the necessary spawn functions
|
||||
extern void SpawnEntityByName( const char *className, CEntityMapData *mapData = NULL );
|
||||
|
||||
// calls the spawn functions for an entity
|
||||
extern int DispatchSpawn( CBaseEntity *pEntity );
|
||||
extern int DispatchSpawn( CBaseEntity *pEntity, bool bRunVScripts = true);
|
||||
|
||||
inline CBaseEntity *GetContainingEntity( edict_t *pent );
|
||||
|
||||
@ -379,6 +384,8 @@ public:
|
||||
DECLARE_SERVERCLASS();
|
||||
// data description
|
||||
DECLARE_DATADESC();
|
||||
// script description
|
||||
DECLARE_ENT_SCRIPTDESC();
|
||||
|
||||
// memory handling
|
||||
void *operator new( size_t stAllocateBlock );
|
||||
@ -493,6 +500,8 @@ public:
|
||||
virtual void SetOwnerEntity( CBaseEntity* pOwner );
|
||||
void SetEffectEntity( CBaseEntity *pEffectEnt );
|
||||
CBaseEntity *GetEffectEntity() const;
|
||||
HSCRIPT GetScriptOwnerEntity();
|
||||
virtual void SetScriptOwnerEntity(HSCRIPT pOwner);
|
||||
|
||||
// Only CBaseEntity implements these. CheckTransmit calls the virtual ShouldTransmit to see if the
|
||||
// entity wants to be sent. If so, it calls SetTransmit, which will mark any dependents for transmission too.
|
||||
@ -563,9 +572,14 @@ public:
|
||||
virtual bool KeyValue( const char *szKeyName, float flValue );
|
||||
virtual bool KeyValue( const char *szKeyName, const Vector &vecValue );
|
||||
virtual bool GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen );
|
||||
bool KeyValueFromString( const char *szKeyName, const char *szValue ) { return KeyValue( szKeyName, szValue ); }
|
||||
bool KeyValueFromFloat( const char *szKeyName, float flValue ) { return KeyValue( szKeyName, flValue ); }
|
||||
bool KeyValueFromInt( const char *szKeyName, int nValue ) { return KeyValue( szKeyName, nValue ); }
|
||||
bool KeyValueFromVector( const char *szKeyName, const Vector &vecValue ) { return KeyValue( szKeyName, vecValue ); }
|
||||
|
||||
void ValidateEntityConnections();
|
||||
void FireNamedOutput( const char *pszOutput, variant_t variant, CBaseEntity *pActivator, CBaseEntity *pCaller, float flDelay = 0.0f );
|
||||
CBaseEntityOutput *FindNamedOutput( const char *pszOutput );
|
||||
|
||||
// Activate - called for each entity after each load game and level load
|
||||
virtual void Activate( void );
|
||||
@ -588,6 +602,8 @@ public:
|
||||
int GetParentAttachment();
|
||||
|
||||
string_t GetEntityName();
|
||||
const char* GetEntityNameAsCStr(); // This method is temporary for VSCRIPT functionality until we figure out what to do with string_t (sjb)
|
||||
const char* GetPreTemplateName(); // Not threadsafe. Get the name stripped of template unique decoration
|
||||
|
||||
bool NameMatches( const char *pszNameOrWildcard );
|
||||
bool ClassMatches( const char *pszClassOrWildcard );
|
||||
@ -735,6 +751,18 @@ public:
|
||||
COutputEvent m_OnKilled;
|
||||
#endif
|
||||
|
||||
void InputRunScript(inputdata_t& inputdata);
|
||||
void InputRunScriptFile(inputdata_t& inputdata);
|
||||
void InputCallScriptFunction(inputdata_t& inputdata);
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
void InputRunScriptQuotable(inputdata_t& inputdata);
|
||||
void InputClearScriptScope(inputdata_t& inputdata);
|
||||
#endif
|
||||
|
||||
bool RunScriptFile(const char* pScriptFile, bool bUseRootScope = false);
|
||||
bool RunScript(const char* pScriptText, const char* pDebugFilename = "CBaseEntity::RunScript");
|
||||
|
||||
|
||||
// Returns the origin at which to play an inputted dispatcheffect
|
||||
virtual void GetInputDispatchEffectPosition( const char *sInputString, Vector &pOrigin, QAngle &pAngles );
|
||||
|
||||
@ -1715,7 +1743,7 @@ private:
|
||||
// was pev->flags
|
||||
CNetworkVarForDerived( int, m_fFlags );
|
||||
|
||||
string_t m_iName; // name used to identify this entity
|
||||
CNetworkVar( string_t, m_iName ); // name used to identify this entity
|
||||
|
||||
// Damage modifiers
|
||||
friend class CDamageModifier;
|
||||
@ -1920,6 +1948,85 @@ public:
|
||||
{
|
||||
return s_bAbsQueriesValid;
|
||||
}
|
||||
|
||||
|
||||
// VSCRIPT
|
||||
HSCRIPT GetScriptInstance();
|
||||
bool ValidateScriptScope();
|
||||
virtual void RunVScripts();
|
||||
bool CallScriptFunction(const char* pFunctionName, ScriptVariant_t* pFunctionReturn);
|
||||
void ConnectOutputToScript(const char* pszOutput, const char* pszScriptFunc);
|
||||
void DisconnectOutputFromScript(const char* pszOutput, const char* pszScriptFunc);
|
||||
void ScriptThink();
|
||||
const char* GetScriptId();
|
||||
HSCRIPT GetScriptScope();
|
||||
void RunPrecacheScripts(void);
|
||||
void RunOnPostSpawnScripts(void);
|
||||
|
||||
HSCRIPT ScriptGetMoveParent(void);
|
||||
HSCRIPT ScriptGetRootMoveParent();
|
||||
HSCRIPT ScriptFirstMoveChild(void);
|
||||
HSCRIPT ScriptNextMovePeer(void);
|
||||
|
||||
const Vector& ScriptEyePosition(void) { static Vector vec; vec = EyePosition(); return vec; }
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
const QAngle& ScriptEyeAngles(void) { static QAngle ang; ang = EyeAngles(); return ang; }
|
||||
void ScriptSetAngles(const QAngle angles) { Teleport(NULL, &angles, NULL); }
|
||||
const QAngle& ScriptGetAngles(void) { return GetAbsAngles(); }
|
||||
#else
|
||||
void ScriptSetAngles(float fPitch, float fYaw, float fRoll) { QAngle angles(fPitch, fYaw, fRoll); Teleport(NULL, &angles, NULL); }
|
||||
const Vector& ScriptGetAngles(void) { static Vector vec; QAngle qa = GetAbsAngles(); vec.x = qa.x; vec.y = qa.y; vec.z = qa.z; return vec; }
|
||||
#endif
|
||||
|
||||
void ScriptSetSize(const Vector& mins, const Vector& maxs) { UTIL_SetSize(this, mins, maxs); }
|
||||
void ScriptUtilRemove(void) { UTIL_Remove(this); }
|
||||
void ScriptSetOwner(HSCRIPT hEntity) { SetOwnerEntity(ToEnt(hEntity)); }
|
||||
void ScriptSetOrigin(const Vector& v) { Teleport(&v, NULL, NULL); }
|
||||
void ScriptSetForward(const Vector& v) { QAngle angles; VectorAngles(v, angles); Teleport(NULL, &angles, NULL); }
|
||||
const Vector& ScriptGetForward(void) { static Vector vecForward; GetVectors(&vecForward, NULL, NULL); return vecForward; }
|
||||
const Vector& ScriptGetLeft(void) { static Vector vecLeft; GetVectors(NULL, &vecLeft, NULL); return vecLeft; }
|
||||
const Vector& ScriptGetUp(void) { static Vector vecUp; GetVectors(NULL, NULL, &vecUp); return vecUp; }
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
HSCRIPT ScriptEntityToWorldTransform(void) { return ScriptCreateMatrixInstance( EntityToWorldTransform() ); }
|
||||
#endif
|
||||
|
||||
const char* ScriptGetModelName(void) const;
|
||||
HSCRIPT ScriptGetModelKeyValues(void);
|
||||
|
||||
void ScriptEmitSound(const char* soundname);
|
||||
float ScriptSoundDuration(const char* soundname, const char* actormodel);
|
||||
|
||||
void VScriptPrecacheScriptSound(const char* soundname);
|
||||
|
||||
const Vector& ScriptGetLocalAngularVelocity( void );
|
||||
void ScriptSetLocalAngularVelocity( float pitchVel, float yawVel, float rollVel );
|
||||
|
||||
const Vector& ScriptGetBoundingMins(void);
|
||||
const Vector& ScriptGetBoundingMaxs(void);
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
bool ScriptIsVisible( const Vector &vecSpot ) { return FVisible( vecSpot ); }
|
||||
bool ScriptIsEntVisible( HSCRIPT pEntity ) { return FVisible( ToEnt( pEntity ) ); }
|
||||
bool ScriptIsVisibleWithMask( const Vector &vecSpot, int traceMask ) { return FVisible( vecSpot, traceMask ); }
|
||||
|
||||
int ScriptTakeDamage( HSCRIPT pInfo );
|
||||
void ScriptFireBullets( HSCRIPT pInfo );
|
||||
|
||||
void ScriptAddContext( const char *name, const char *value, float duration = 0.0f );
|
||||
const char *ScriptGetContext( const char *name );
|
||||
|
||||
int ScriptClassify(void);
|
||||
|
||||
const char *ScriptGetKeyValue( const char *pszKeyName );
|
||||
#endif
|
||||
|
||||
string_t m_iszVScripts;
|
||||
string_t m_iszScriptThinkFunction;
|
||||
CScriptScope m_ScriptScope;
|
||||
HSCRIPT m_hScriptInstance;
|
||||
string_t m_iszScriptId;
|
||||
CScriptKeyValues* m_pScriptModelKeyValues;
|
||||
};
|
||||
|
||||
// Send tables exposed in this module.
|
||||
@ -2048,6 +2155,21 @@ inline string_t CBaseEntity::GetEntityName()
|
||||
return m_iName;
|
||||
}
|
||||
|
||||
inline const char *CBaseEntity::GetEntityNameAsCStr()
|
||||
{
|
||||
return STRING(m_iName.Get());
|
||||
}
|
||||
|
||||
inline const char *CBaseEntity::GetPreTemplateName()
|
||||
{
|
||||
const char *pszDelimiter = V_strrchr( STRING(m_iName.Get()), '&' );
|
||||
if ( !pszDelimiter )
|
||||
return STRING( m_iName.Get() );
|
||||
static char szStrippedName[128];
|
||||
V_strncpy( szStrippedName, STRING( m_iName.Get() ), MIN( ARRAYSIZE(szStrippedName), pszDelimiter - STRING( m_iName.Get() ) + 1 ) );
|
||||
return szStrippedName;
|
||||
}
|
||||
|
||||
inline void CBaseEntity::SetName( string_t newName )
|
||||
{
|
||||
m_iName = newName;
|
||||
@ -2726,6 +2848,14 @@ inline void CBaseEntity::FireBullets( int cShots, const Vector &vecSrc,
|
||||
FireBullets( info );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// VScript
|
||||
//-----------------------------------------------------------------------------
|
||||
inline const char* CBaseEntity::ScriptGetModelName(void) const
|
||||
{
|
||||
return STRING(m_ModelName);
|
||||
}
|
||||
|
||||
// Ugly technique to override base member functions
|
||||
// Normally it's illegal to cast a pointer to a member function of a derived class to a pointer to a
|
||||
// member function of a base class. static_cast is a sleezy way around that problem.
|
||||
|
@ -95,6 +95,10 @@ BEGIN_DATADESC( CBaseFlex )
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
BEGIN_ENT_SCRIPTDESC( CBaseFlex, CBaseAnimating, "Animated characters who have vertex flex capability." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetOldestScene, "GetCurrentScene", "Returns the instance of the oldest active scene entity (if any)." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetSceneByIndex, "GetSceneByIndex", "Returns the instance of the scene entity at the specified index." )
|
||||
END_SCRIPTDESC();
|
||||
|
||||
|
||||
LINK_ENTITY_TO_CLASS( funCBaseFlex, CBaseFlex ); // meaningless independant class!!
|
||||
@ -421,7 +425,8 @@ void CBaseFlex::AddSceneEvent( CChoreoScene *scene, CChoreoEvent *event, CBaseEn
|
||||
info.m_pEvent = event;
|
||||
info.m_pScene = scene;
|
||||
info.m_hTarget = pTarget;
|
||||
info.m_bStarted = false;
|
||||
info.m_bStarted = false;
|
||||
info.m_hSceneEntity = pSceneEnt;
|
||||
|
||||
#ifdef MAPBASE
|
||||
if (StartSceneEvent( &info, scene, event, actor, pTarget, pSceneEnt ))
|
||||
@ -2029,6 +2034,37 @@ float CBaseFlex::PlayAutoGeneratedSoundScene( const char *soundname )
|
||||
#endif
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Returns the script instance of the scene entity associated with our oldest ("top level") scene event
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
HSCRIPT CBaseFlex::ScriptGetOldestScene( void )
|
||||
{
|
||||
if ( m_SceneEvents.Count() > 0 )
|
||||
{
|
||||
CSceneEventInfo curScene = m_SceneEvents.Head();
|
||||
return ToHScript( (CBaseEntity*)(curScene.m_hSceneEntity.Get()) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Returns the script instance of the scene at the specified index, or null if index >= count
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
HSCRIPT CBaseFlex::ScriptGetSceneByIndex( int index )
|
||||
{
|
||||
if ( m_SceneEvents.IsValidIndex( index ) )
|
||||
{
|
||||
CSceneEventInfo curScene = m_SceneEvents.Element( index );
|
||||
return ToHScript( (CBaseEntity*)(curScene.m_hSceneEntity.Get()) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// FIXME: move to CBaseActor
|
||||
|
@ -46,6 +46,8 @@ public:
|
||||
DECLARE_SERVERCLASS();
|
||||
DECLARE_DATADESC();
|
||||
DECLARE_PREDICTABLE();
|
||||
// script description
|
||||
DECLARE_ENT_SCRIPTDESC();
|
||||
|
||||
// Construction
|
||||
CBaseFlex( void );
|
||||
@ -130,6 +132,10 @@ public:
|
||||
virtual float PlayAutoGeneratedSoundScene( const char *soundname );
|
||||
#endif
|
||||
|
||||
// Returns the script instance of the scene entity associated with our oldest ("top level") scene event
|
||||
virtual HSCRIPT ScriptGetOldestScene( void );
|
||||
virtual HSCRIPT ScriptGetSceneByIndex( int index );
|
||||
|
||||
virtual int GetSpecialDSP( void ) { return 0; }
|
||||
|
||||
protected:
|
||||
|
@ -396,6 +396,28 @@ void CBaseEntityOutput::AddEventAction( CEventAction *pEventAction )
|
||||
m_ActionList = pEventAction;
|
||||
}
|
||||
|
||||
void CBaseEntityOutput::RemoveEventAction( CEventAction *pEventAction )
|
||||
{
|
||||
CEventAction *pAction = GetActionList();
|
||||
CEventAction *pPrevAction = NULL;
|
||||
while ( pAction )
|
||||
{
|
||||
if ( pAction == pEventAction )
|
||||
{
|
||||
if ( !pPrevAction )
|
||||
{
|
||||
m_ActionList = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pPrevAction->m_pNext = pAction->m_pNext;
|
||||
}
|
||||
return;
|
||||
}
|
||||
pAction = pAction->m_pNext;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// save data description for the event queue
|
||||
BEGIN_SIMPLE_DATADESC( CBaseEntityOutput )
|
||||
|
@ -26,6 +26,7 @@ class IDataCache;
|
||||
class IMDLCache;
|
||||
class IServerEngineTools;
|
||||
class IXboxSystem;
|
||||
class IScriptManager;
|
||||
class CSteamAPIContext;
|
||||
class CSteamGameServerAPIContext;
|
||||
|
||||
@ -43,6 +44,7 @@ extern IDataCache *datacache;
|
||||
extern IMDLCache *mdlcache;
|
||||
extern IServerEngineTools *serverenginetools;
|
||||
extern IXboxSystem *xboxsystem; // 360 only
|
||||
extern IScriptManager *scriptmanager;
|
||||
extern CSteamAPIContext *steamapicontext; // available on game clients
|
||||
extern CSteamGameServerAPIContext *steamgameserverapicontext; //available on game servers
|
||||
|
||||
|
@ -667,7 +667,7 @@ CBaseEntity *CGlobalEntityList::FindEntityByName( CBaseEntity *pStartEntity, con
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !ent->m_iName )
|
||||
if ( !ent->m_iName.Get() )
|
||||
continue;
|
||||
|
||||
if ( ent->NameMatches( szName ) )
|
||||
|
@ -63,6 +63,7 @@ public:
|
||||
|
||||
void ParseEventAction( const char *EventData );
|
||||
void AddEventAction( CEventAction *pEventAction );
|
||||
void RemoveEventAction( CEventAction *pEventAction );
|
||||
|
||||
int Save( ISave &save );
|
||||
int Restore( IRestore &restore, int elementCount );
|
||||
|
@ -30,6 +30,7 @@ class CEnvEntityMaker : public CPointEntity
|
||||
DECLARE_CLASS( CEnvEntityMaker, CPointEntity );
|
||||
public:
|
||||
DECLARE_DATADESC();
|
||||
DECLARE_ENT_SCRIPTDESC();
|
||||
|
||||
virtual void Spawn( void );
|
||||
virtual void Activate( void );
|
||||
@ -43,6 +44,10 @@ public:
|
||||
void InputForceSpawnAtPosition( inputdata_t &inputdata );
|
||||
#endif
|
||||
|
||||
void SpawnEntityFromScript();
|
||||
void SpawnEntityAtEntityOriginFromScript(HSCRIPT hEntity);
|
||||
void SpawnEntityAtNamedEntityOriginFromScript(const char* pszName);
|
||||
void SpawnEntityAtLocationFromScript(const Vector& vecAlternateOrigin, const Vector& vecAlternateAngles);
|
||||
private:
|
||||
|
||||
CPointTemplate *FindTemplate();
|
||||
@ -102,6 +107,13 @@ BEGIN_DATADESC( CEnvEntityMaker )
|
||||
DEFINE_THINKFUNC( CheckSpawnThink ),
|
||||
END_DATADESC()
|
||||
|
||||
BEGIN_ENT_SCRIPTDESC( CEnvEntityMaker, CBaseEntity, "env_entity_maker" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( SpawnEntityFromScript, "SpawnEntity", "Create an entity at the location of the maker" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( SpawnEntityAtEntityOriginFromScript, "SpawnEntityAtEntityOrigin", "Create an entity at the location of a specified entity instance" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( SpawnEntityAtNamedEntityOriginFromScript, "SpawnEntityAtNamedEntityOrigin", "Create an entity at the location of a named entity" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( SpawnEntityAtLocationFromScript, "SpawnEntityAtLocation", "Create an entity at a specified location and orientaton, orientation is Euler angle in degrees (pitch, yaw, roll)" )
|
||||
END_SCRIPTDESC()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( env_entity_maker, CEnvEntityMaker );
|
||||
|
||||
|
||||
@ -266,8 +278,50 @@ void CEnvEntityMaker::SpawnEntity( Vector vecAlternateOrigin, QAngle vecAlternat
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
pTemplate->CreationComplete( hNewEntities );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Spawn an instance of the entity
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEnvEntityMaker::SpawnEntityFromScript()
|
||||
{
|
||||
SpawnEntity();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Spawn an instance of the entity
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEnvEntityMaker::SpawnEntityAtEntityOriginFromScript( HSCRIPT hEntity )
|
||||
{
|
||||
CBaseEntity *pTargetEntity = ToEnt( hEntity );
|
||||
if ( pTargetEntity )
|
||||
{
|
||||
SpawnEntity( pTargetEntity->GetAbsOrigin(), pTargetEntity->GetAbsAngles() );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Spawn an instance of the entity
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEnvEntityMaker::SpawnEntityAtNamedEntityOriginFromScript( const char *pszName )
|
||||
{
|
||||
CBaseEntity *pTargetEntity = gEntList.FindEntityByName( NULL, pszName, this, NULL, NULL );
|
||||
|
||||
if( pTargetEntity )
|
||||
{
|
||||
SpawnEntity( pTargetEntity->GetAbsOrigin(), pTargetEntity->GetAbsAngles() );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Spawn an instance of the entity
|
||||
//-----------------------------------------------------------------------------
|
||||
void CEnvEntityMaker::SpawnEntityAtLocationFromScript( const Vector &vecAlternateOrigin, const Vector &vecAlternateAngles )
|
||||
{
|
||||
SpawnEntity( vecAlternateOrigin, *((QAngle *)&vecAlternateAngles) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns whether or not the template entities can fit if spawned.
|
||||
|
@ -44,6 +44,18 @@ BEGIN_DATADESC( CBaseFilter )
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
BEGIN_ENT_SCRIPTDESC( CBaseFilter, CBaseEntity, "All entities which could be used as filters." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptPassesFilter, "PassesFilter", "Check if the given caller and entity pass the filter." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptPassesDamageFilter, "PassesDamageFilter", "Check if the given caller and damage info pass the damage filter." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptPassesFinalDamageFilter, "PassesFinalDamageFilter", "Used by filter_damage_redirect to distinguish between standalone filter calls and actually damaging an entity. Returns true if there's no unique behavior." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptBloodAllowed, "BloodAllowed", "Check if the given caller and damage info allow for the production of blood." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptDamageMod, "DamageMod", "Mods the damage info with the given caller." )
|
||||
|
||||
END_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool CBaseFilter::PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity )
|
||||
@ -142,6 +154,14 @@ void CBaseFilter::InputSetField( inputdata_t& inputdata )
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
bool CBaseFilter::ScriptPassesFilter( HSCRIPT pCaller, HSCRIPT pEntity ) { return PassesFilter( ToEnt(pCaller), ToEnt(pEntity) ); }
|
||||
bool CBaseFilter::ScriptPassesDamageFilter( HSCRIPT pCaller, HSCRIPT pInfo ) { return (pInfo) ? PassesDamageFilter( ToEnt( pCaller ), *const_cast<const CTakeDamageInfo*>(HScriptToClass<CTakeDamageInfo>( pInfo )) ) : NULL; }
|
||||
bool CBaseFilter::ScriptPassesFinalDamageFilter( HSCRIPT pCaller, HSCRIPT pInfo ) { return (pInfo) ? PassesFinalDamageFilter( ToEnt( pCaller ), *const_cast<const CTakeDamageInfo*>(HScriptToClass<CTakeDamageInfo>( pInfo )) ) : NULL; }
|
||||
bool CBaseFilter::ScriptBloodAllowed( HSCRIPT pCaller, HSCRIPT pInfo ) { return (pInfo) ? BloodAllowed( ToEnt( pCaller ), *const_cast<const CTakeDamageInfo*>(HScriptToClass<CTakeDamageInfo>( pInfo )) ) : NULL; }
|
||||
bool CBaseFilter::ScriptDamageMod( HSCRIPT pCaller, HSCRIPT pInfo ) { return (pInfo) ? DamageMod( ToEnt( pCaller ), *HScriptToClass<CTakeDamageInfo>( pInfo ) ) : NULL; }
|
||||
#endif
|
||||
|
||||
|
||||
// ###################################################################
|
||||
// > FilterMultiple
|
||||
@ -223,6 +243,13 @@ void CFilterMultiple::Activate( void )
|
||||
Warning("filter_multi: Tried to add entity (%s) which is not a filter entity!\n", STRING( m_iFilterName[i] ) );
|
||||
continue;
|
||||
}
|
||||
#ifdef MAPBASE
|
||||
else if ( pFilter == this )
|
||||
{
|
||||
Warning("filter_multi: Tried to add itself!\n");
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Take this entity and increment out array pointer
|
||||
m_hFilter[nNextFilter] = pFilter;
|
||||
@ -2109,3 +2136,152 @@ BEGIN_DATADESC( CFilterDamageLogic )
|
||||
|
||||
END_DATADESC()
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
// ###################################################################
|
||||
// > CFilterScript
|
||||
// ###################################################################
|
||||
class CFilterScript : public CBaseFilter
|
||||
{
|
||||
DECLARE_CLASS( CFilterScript, CBaseFilter );
|
||||
DECLARE_DATADESC();
|
||||
|
||||
public:
|
||||
bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity )
|
||||
{
|
||||
if (m_ScriptScope.IsInitialized())
|
||||
{
|
||||
g_pScriptVM->SetValue( "caller", (pCaller) ? ScriptVariant_t( pCaller->GetScriptInstance() ) : SCRIPT_VARIANT_NULL );
|
||||
g_pScriptVM->SetValue( "activator", (pEntity) ? ScriptVariant_t( pEntity->GetScriptInstance() ) : SCRIPT_VARIANT_NULL );
|
||||
|
||||
ScriptVariant_t functionReturn;
|
||||
if (!CallScriptFunction( "PassesFilter", &functionReturn ))
|
||||
{
|
||||
Warning("%s: No PassesFilter function\n", GetDebugName());
|
||||
}
|
||||
|
||||
g_pScriptVM->ClearValue( "caller" );
|
||||
g_pScriptVM->ClearValue( "activator" );
|
||||
|
||||
return functionReturn.m_bool;
|
||||
}
|
||||
|
||||
Warning("%s: No script scope, cannot filter\n", GetDebugName());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PassesDamageFilterImpl( CBaseEntity *pCaller, const CTakeDamageInfo &info )
|
||||
{
|
||||
if (m_ScriptScope.IsInitialized())
|
||||
{
|
||||
HSCRIPT pInfo = g_pScriptVM->RegisterInstance( const_cast<CTakeDamageInfo*>(&info) );
|
||||
|
||||
g_pScriptVM->SetValue( "info", pInfo );
|
||||
g_pScriptVM->SetValue( "caller", (pCaller) ? ScriptVariant_t( pCaller->GetScriptInstance() ) : SCRIPT_VARIANT_NULL );
|
||||
|
||||
ScriptVariant_t functionReturn;
|
||||
if (!CallScriptFunction( "PassesDamageFilter", &functionReturn ))
|
||||
{
|
||||
// Fall back to main filter function
|
||||
return PassesFilterImpl( pCaller, info.GetAttacker() );
|
||||
}
|
||||
|
||||
g_pScriptVM->RemoveInstance( pInfo );
|
||||
|
||||
g_pScriptVM->ClearValue( "info" );
|
||||
g_pScriptVM->ClearValue( "caller" );
|
||||
|
||||
return functionReturn.m_bool;
|
||||
}
|
||||
|
||||
Warning("%s: No script scope, cannot filter\n", GetDebugName());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PassesFinalDamageFilter( CBaseEntity *pCaller, const CTakeDamageInfo &info )
|
||||
{
|
||||
if (m_ScriptScope.IsInitialized())
|
||||
{
|
||||
HSCRIPT pInfo = g_pScriptVM->RegisterInstance( const_cast<CTakeDamageInfo*>(&info) );
|
||||
|
||||
g_pScriptVM->SetValue( "info", pInfo );
|
||||
g_pScriptVM->SetValue( "caller", (pCaller) ? ScriptVariant_t( pCaller->GetScriptInstance() ) : SCRIPT_VARIANT_NULL );
|
||||
|
||||
ScriptVariant_t functionReturn;
|
||||
if (!CallScriptFunction( "PassesFinalDamageFilter", &functionReturn ))
|
||||
{
|
||||
return BaseClass::PassesFinalDamageFilter( pCaller, info );
|
||||
}
|
||||
|
||||
g_pScriptVM->RemoveInstance( pInfo );
|
||||
|
||||
g_pScriptVM->ClearValue( "info" );
|
||||
g_pScriptVM->ClearValue( "caller" );
|
||||
|
||||
return functionReturn.m_bool;
|
||||
}
|
||||
|
||||
Warning("%s: No script scope, cannot filter\n", GetDebugName());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BloodAllowed( CBaseEntity *pCaller, const CTakeDamageInfo &info )
|
||||
{
|
||||
if (m_ScriptScope.IsInitialized())
|
||||
{
|
||||
HSCRIPT pInfo = g_pScriptVM->RegisterInstance( const_cast<CTakeDamageInfo*>(&info) );
|
||||
|
||||
g_pScriptVM->SetValue( "info", pInfo );
|
||||
g_pScriptVM->SetValue( "caller", (pCaller) ? ScriptVariant_t( pCaller->GetScriptInstance() ) : SCRIPT_VARIANT_NULL );
|
||||
|
||||
ScriptVariant_t functionReturn;
|
||||
if (!CallScriptFunction( "BloodAllowed", &functionReturn ))
|
||||
{
|
||||
return BaseClass::BloodAllowed( pCaller, info );
|
||||
}
|
||||
|
||||
g_pScriptVM->RemoveInstance( pInfo );
|
||||
|
||||
g_pScriptVM->ClearValue( "info" );
|
||||
g_pScriptVM->ClearValue( "caller" );
|
||||
|
||||
return functionReturn.m_bool;
|
||||
}
|
||||
|
||||
Warning("%s: No script scope, cannot filter\n", GetDebugName());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DamageMod( CBaseEntity *pCaller, CTakeDamageInfo &info )
|
||||
{
|
||||
if (m_ScriptScope.IsInitialized())
|
||||
{
|
||||
HSCRIPT pInfo = g_pScriptVM->RegisterInstance( &info );
|
||||
|
||||
g_pScriptVM->SetValue( "info", pInfo );
|
||||
g_pScriptVM->SetValue( "caller", (pCaller) ? ScriptVariant_t( pCaller->GetScriptInstance() ) : SCRIPT_VARIANT_NULL );
|
||||
|
||||
ScriptVariant_t functionReturn;
|
||||
if (!CallScriptFunction( "DamageMod", &functionReturn ))
|
||||
{
|
||||
return BaseClass::DamageMod( pCaller, info );
|
||||
}
|
||||
|
||||
g_pScriptVM->RemoveInstance( pInfo );
|
||||
|
||||
g_pScriptVM->ClearValue( "info" );
|
||||
g_pScriptVM->ClearValue( "caller" );
|
||||
|
||||
return functionReturn.m_bool;
|
||||
}
|
||||
|
||||
Warning("%s: No script scope, cannot filter\n", GetDebugName());
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( filter_script, CFilterScript );
|
||||
|
||||
BEGIN_DATADESC( CFilterScript )
|
||||
END_DATADESC()
|
||||
#endif
|
||||
|
@ -38,6 +38,9 @@ class CBaseFilter : public CLogicalEntity
|
||||
public:
|
||||
|
||||
DECLARE_DATADESC();
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DECLARE_ENT_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
bool PassesFilter( CBaseEntity *pCaller, CBaseEntity *pEntity );
|
||||
#ifdef MAPBASE
|
||||
@ -56,6 +59,14 @@ public:
|
||||
bool PassesDamageFilter( const CTakeDamageInfo &info );
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
bool ScriptPassesFilter( HSCRIPT pCaller, HSCRIPT pEntity );
|
||||
bool ScriptPassesDamageFilter( HSCRIPT pCaller, HSCRIPT pInfo );
|
||||
bool ScriptPassesFinalDamageFilter( HSCRIPT pCaller, HSCRIPT pInfo );
|
||||
bool ScriptBloodAllowed( HSCRIPT pCaller, HSCRIPT pInfo );
|
||||
bool ScriptDamageMod( HSCRIPT pCaller, HSCRIPT pInfo );
|
||||
#endif
|
||||
|
||||
bool m_bNegated;
|
||||
|
||||
// Inputs
|
||||
|
@ -148,6 +148,39 @@ BEGIN_DATADESC_NO_BASE( CFourWheelVehiclePhysics )
|
||||
DEFINE_FIELD( m_bLastSkid, FIELD_BOOLEAN ),
|
||||
END_DATADESC()
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
BEGIN_SCRIPTDESC_ROOT( CFourWheelVehiclePhysics, "Handler for four-wheel vehicle physics." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( SetThrottle, "Sets the throttle." )
|
||||
DEFINE_SCRIPTFUNC( SetMaxThrottle, "Sets the max throttle." )
|
||||
DEFINE_SCRIPTFUNC( SetMaxReverseThrottle, "Sets the max reverse throttle." )
|
||||
DEFINE_SCRIPTFUNC( SetSteering, "Sets the steering." )
|
||||
DEFINE_SCRIPTFUNC( SetSteeringDegrees, "Sets the degrees of steering." )
|
||||
DEFINE_SCRIPTFUNC( SetAction, "Sets the action." )
|
||||
DEFINE_SCRIPTFUNC( SetHandbrake, "Sets the handbrake." )
|
||||
DEFINE_SCRIPTFUNC( SetBoost, "Sets the boost." )
|
||||
DEFINE_SCRIPTFUNC( SetHasBrakePedal, "Sets whether a handbrake pedal exists." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( SetDisableEngine, "Sets whether the engine is disabled." )
|
||||
DEFINE_SCRIPTFUNC( IsEngineDisabled, "Checks whether the engine is disabled." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( EnableMotion, "Enables vehicle motion." )
|
||||
DEFINE_SCRIPTFUNC( DisableMotion, "Disables vehicle motion." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetSpeed, "Gets the speed." )
|
||||
DEFINE_SCRIPTFUNC( GetMaxSpeed, "Gets the max speed." )
|
||||
DEFINE_SCRIPTFUNC( GetRPM, "Gets the RPM." )
|
||||
DEFINE_SCRIPTFUNC( GetThrottle, "Gets the throttle." )
|
||||
DEFINE_SCRIPTFUNC( HasBoost, "Checks if the vehicle has the ability to boost." )
|
||||
DEFINE_SCRIPTFUNC( BoostTimeLeft, "Gets how much time is left in any current boost." )
|
||||
DEFINE_SCRIPTFUNC( IsBoosting, "Checks if the vehicle is boosting." )
|
||||
DEFINE_SCRIPTFUNC( GetHLSpeed, "Gets HL speed." )
|
||||
DEFINE_SCRIPTFUNC( GetSteering, "Gets the steeering." )
|
||||
DEFINE_SCRIPTFUNC( GetSteeringDegrees, "Gets the degrees of steeering." )
|
||||
|
||||
END_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
|
@ -93,6 +93,9 @@
|
||||
#include "world.h"
|
||||
#endif
|
||||
|
||||
#include "vscript/ivscript.h"
|
||||
#include "vscript_server.h"
|
||||
|
||||
|
||||
#ifdef TF_DLL
|
||||
#include "gc_clientsystem.h"
|
||||
@ -185,6 +188,7 @@ IServerEngineTools *serverenginetools = NULL;
|
||||
ISceneFileCache *scenefilecache = NULL;
|
||||
IXboxSystem *xboxsystem = NULL; // Xbox 360 only
|
||||
IMatchmaking *matchmaking = NULL; // Xbox 360 only
|
||||
IScriptManager *scriptmanager = NULL;
|
||||
#if defined( REPLAY_ENABLED )
|
||||
IReplaySystem *g_pReplay = NULL;
|
||||
IServerReplayContext *g_pReplayServerContext = NULL;
|
||||
@ -627,6 +631,16 @@ bool CServerGameDLL::DLLInit( CreateInterfaceFn appSystemFactory,
|
||||
if ( IsX360() && (matchmaking = (IMatchmaking *)appSystemFactory( VENGINE_MATCHMAKING_VERSION, NULL )) == NULL )
|
||||
return false;
|
||||
|
||||
if (!CommandLine()->CheckParm("-noscripting"))
|
||||
{
|
||||
scriptmanager = (IScriptManager*)appSystemFactory(VSCRIPT_INTERFACE_VERSION, NULL);
|
||||
|
||||
if (scriptmanager == nullptr)
|
||||
{
|
||||
scriptmanager = (IScriptManager*)Sys_GetFactoryThis()(VSCRIPT_INTERFACE_VERSION, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// If not running dedicated, grab the engine vgui interface
|
||||
if ( !engine->IsDedicatedServer() )
|
||||
{
|
||||
@ -684,6 +698,7 @@ bool CServerGameDLL::DLLInit( CreateInterfaceFn appSystemFactory,
|
||||
g_pGameSaveRestoreBlockSet->AddBlockHandler( GetCommentarySaveRestoreBlockHandler() );
|
||||
g_pGameSaveRestoreBlockSet->AddBlockHandler( GetEventQueueSaveRestoreBlockHandler() );
|
||||
g_pGameSaveRestoreBlockSet->AddBlockHandler( GetAchievementSaveRestoreBlockHandler() );
|
||||
g_pGameSaveRestoreBlockSet->AddBlockHandler( GetVScriptSaveRestoreBlockHandler() );
|
||||
|
||||
// The string system must init first + shutdown last
|
||||
IGameSystem::Add( GameStringSystem() );
|
||||
@ -762,6 +777,7 @@ void CServerGameDLL::DLLShutdown( void )
|
||||
// Due to dependencies, these are not autogamesystems
|
||||
ModelSoundsCacheShutdown();
|
||||
|
||||
g_pGameSaveRestoreBlockSet->RemoveBlockHandler( GetVScriptSaveRestoreBlockHandler() );
|
||||
g_pGameSaveRestoreBlockSet->RemoveBlockHandler( GetAchievementSaveRestoreBlockHandler() );
|
||||
g_pGameSaveRestoreBlockSet->RemoveBlockHandler( GetCommentarySaveRestoreBlockHandler() );
|
||||
g_pGameSaveRestoreBlockSet->RemoveBlockHandler( GetEventQueueSaveRestoreBlockHandler() );
|
||||
|
@ -143,6 +143,28 @@ public:
|
||||
return m_list.Count();
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
virtual void RegisterVScript()
|
||||
{
|
||||
g_pScriptVM->RegisterInstance( this, "Globals" );
|
||||
}
|
||||
|
||||
int ScriptAddEntity( const char *pGlobalname, const char *pMapName, int state )
|
||||
{
|
||||
return AddEntity( pGlobalname, pMapName, (GLOBALESTATE)state );
|
||||
}
|
||||
|
||||
void ScriptSetState( int globalIndex, int state )
|
||||
{
|
||||
SetState( globalIndex, (GLOBALESTATE)state );
|
||||
}
|
||||
|
||||
int ScriptGetState( int globalIndex )
|
||||
{
|
||||
return (int)GetState( globalIndex );
|
||||
}
|
||||
#endif
|
||||
|
||||
void Reset( void );
|
||||
int Save( ISave &save );
|
||||
int Restore( IRestore &restore );
|
||||
@ -323,3 +345,15 @@ CON_COMMAND(server_game_time, "Gives the game time in seconds (server's curtime)
|
||||
|
||||
ShowServerGameTime();
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
BEGIN_SCRIPTDESC_ROOT( CGlobalState, SCRIPT_SINGLETON "Global state system." )
|
||||
DEFINE_SCRIPTFUNC( GetIndex, "Gets the index of the specified global name. Returns -1 if it does not exist." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptAddEntity, "AddGlobal", "Adds a new global with a specific map name and state. Returns its index." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetState, "GetState", "Gets the state of the specified global." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetState, "SetState", "Sets the state of the specified global." )
|
||||
DEFINE_SCRIPTFUNC( GetCounter, "Gets the counter of the specified global." )
|
||||
DEFINE_SCRIPTFUNC( SetCounter, "Sets the counter of the specified global." )
|
||||
DEFINE_SCRIPTFUNC( AddToCounter, "Adds to the counter of the specified global." )
|
||||
END_SCRIPTDESC();
|
||||
#endif
|
||||
|
@ -2457,6 +2457,16 @@ BEGIN_DATADESC( CAI_ActBusyGoal )
|
||||
DEFINE_OUTPUT( m_OnNPCSeeEnemy, "OnNPCSeeEnemy" ),
|
||||
END_DATADESC()
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
BEGIN_ENT_SCRIPTDESC( CAI_ActBusyGoal, CAI_GoalEntity, "A goal entity which makes NPCs act busy." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptForceBusy, "ForceBusy", "Force a NPC to act busy." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptForceBusyComplex, "ForceBusyComplex", "Force a NPC to act busy with additional parameters." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptStopBusy, "StopBusy", "Force a NPC to stop busying." )
|
||||
|
||||
END_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -2824,6 +2834,46 @@ interval_t &CAI_ActBusyGoal::NextBusySearchInterval()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAI_ActBusyGoal::ScriptForceBusy( HSCRIPT hNPC, HSCRIPT hHint, bool bTeleportOnly )
|
||||
{
|
||||
CAI_ActBusyBehavior *pBehavior = GetBusyBehaviorForNPC( ToEnt( hNPC ), "ForceBusy (vscript)" );
|
||||
if ( !pBehavior )
|
||||
return;
|
||||
|
||||
// Tell the NPC to immediately act busy
|
||||
pBehavior->SetBusySearchRange( m_flBusySearchRange );
|
||||
pBehavior->ForceActBusy( this, dynamic_cast<CAI_Hint*>(ToEnt( hHint )), NO_MAX_TIME, false, bTeleportOnly );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAI_ActBusyGoal::ScriptForceBusyComplex( HSCRIPT hNPC, HSCRIPT hHint, bool bTeleportOnly, bool bVisibleOnly, bool bUseNearestBusy, float flMaxTime, int activity, HSCRIPT pSeeEntity )
|
||||
{
|
||||
CAI_ActBusyBehavior *pBehavior = GetBusyBehaviorForNPC( ToEnt( hNPC ), "ForceBusyComplex (vscript)" );
|
||||
if ( !pBehavior )
|
||||
return;
|
||||
|
||||
// Tell the NPC to immediately act busy
|
||||
pBehavior->SetBusySearchRange( m_flBusySearchRange );
|
||||
pBehavior->ForceActBusy( this, dynamic_cast<CAI_Hint*>(ToEnt( hHint )), flMaxTime, bVisibleOnly, bTeleportOnly, bUseNearestBusy, ToEnt( pSeeEntity ), (Activity)activity );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAI_ActBusyGoal::ScriptStopBusy( HSCRIPT hNPC )
|
||||
{
|
||||
CAI_ActBusyBehavior *pBehavior = GetBusyBehaviorForNPC( ToEnt( hNPC ), "StopBusy (vscript)" );
|
||||
if ( !pBehavior )
|
||||
return;
|
||||
|
||||
// Just stop busying
|
||||
pBehavior->StopBusying();
|
||||
}
|
||||
#endif
|
||||
|
||||
//==========================================================================================================
|
||||
// ACT BUSY QUEUE
|
||||
//==========================================================================================================
|
||||
|
@ -239,6 +239,12 @@ public:
|
||||
interval_t &NextBusySearchInterval();
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
void ScriptForceBusy( HSCRIPT hNPC, HSCRIPT hHint, bool bTeleportOnly );
|
||||
void ScriptForceBusyComplex( HSCRIPT hNPC, HSCRIPT hHint, bool bTeleportOnly, bool bVisibleOnly, bool bUseNearestBusy, float flMaxTime, int activity, HSCRIPT pSeeEntity );
|
||||
void ScriptStopBusy( HSCRIPT hNPC );
|
||||
#endif
|
||||
|
||||
protected:
|
||||
CAI_ActBusyBehavior *GetBusyBehaviorForNPC( const char *pszActorName, CBaseEntity *pActivator, CBaseEntity *pCaller, const char *sInputName );
|
||||
CAI_ActBusyBehavior *GetBusyBehaviorForNPC( CBaseEntity *pEntity, const char *sInputName );
|
||||
@ -257,6 +263,9 @@ protected:
|
||||
#endif
|
||||
|
||||
DECLARE_DATADESC();
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DECLARE_ENT_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
float m_flBusySearchRange;
|
||||
|
@ -593,6 +593,18 @@ BEGIN_DATADESC( CHL2_Player )
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
BEGIN_ENT_SCRIPTDESC( CHL2_Player, CBasePlayer, "The HL2 player entity." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( SuitPower_Drain, "RemoveAuxPower", "Removes from the player's available aux power." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( SuitPower_Charge, "AddAuxPower", "Adds to the player's available aux power." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( SuitPower_SetCharge, "SetAuxPower", "Sets the player's available aux power." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( SuitPower_GetCurrentPercentage, "GetAuxPower", "Gets the player's available aux power." )
|
||||
DEFINE_SCRIPTFUNC( GetFlashlightBattery, "Gets the energy available in the player's flashlight. If the legacy (aux power-based) flashlight is enabled, this returns the aux power." )
|
||||
|
||||
END_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
CHL2_Player::CHL2_Player()
|
||||
{
|
||||
m_nNumMissPositions = 0;
|
||||
@ -4678,7 +4690,7 @@ void CLogicPlayerProxy::InputRequestPlayerFlashBattery( inputdata_t &inputdata )
|
||||
|
||||
// If it's the EP2 flashlight, it returns the flashlight battery. If it's the legacy flashlight, it returns the aux power.
|
||||
// Note that this is on CHL2_Player, not CLogicPlayerProxy.
|
||||
inline float CHL2_Player::GetFlashlightBattery()
|
||||
float CHL2_Player::GetFlashlightBattery()
|
||||
{
|
||||
#ifdef HL2_EPISODIC
|
||||
return Flashlight_UseLegacyVersion() ? SuitPower_GetCurrentPercentage() : m_HL2Local.m_flFlashBattery;
|
||||
|
@ -79,6 +79,9 @@ class CHL2_Player : public CBasePlayer
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CHL2_Player, CBasePlayer );
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DECLARE_ENT_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
CHL2_Player();
|
||||
~CHL2_Player( void );
|
||||
|
@ -27,6 +27,126 @@
|
||||
|
||||
extern CServerGameDLL g_ServerGameDLL;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: An entity that acts as a container for game scripts.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define MAX_SCRIPT_GROUP 16
|
||||
|
||||
class CLogicScript : public CPointEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CLogicScript, CPointEntity );
|
||||
DECLARE_DATADESC();
|
||||
|
||||
void RunVScripts()
|
||||
{
|
||||
/*
|
||||
EntityGroup <- [];
|
||||
function __AppendToScriptGroup( name )
|
||||
{
|
||||
if ( name.len() == 0 )
|
||||
{
|
||||
EntityGroup.append( null );
|
||||
}
|
||||
else
|
||||
{
|
||||
local ent = Entities.FindByName( null, name );
|
||||
EntityGroup.append( ent );
|
||||
if ( ent != null )
|
||||
{
|
||||
ent.ValidateScriptScope();
|
||||
ent.GetScriptScope().EntityGroup <- EntityGroup;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
static const char szAddCode[] =
|
||||
{
|
||||
0x45,0x6e,0x74,0x69,0x74,0x79,0x47,0x72,0x6f,0x75,0x70,0x20,0x3c,0x2d,0x20,0x5b,0x5d,0x3b,0x0d,0x0a,
|
||||
0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x5f,0x5f,0x41,0x70,0x70,0x65,0x6e,0x64,0x54,0x6f,0x53,
|
||||
0x63,0x72,0x69,0x70,0x74,0x47,0x72,0x6f,0x75,0x70,0x28,0x20,0x6e,0x61,0x6d,0x65,0x20,0x29,0x20,0x0d,
|
||||
0x0a,0x7b,0x0d,0x0a,0x09,0x69,0x66,0x20,0x28,0x20,0x6e,0x61,0x6d,0x65,0x2e,0x6c,0x65,0x6e,0x28,0x29,
|
||||
0x20,0x3d,0x3d,0x20,0x30,0x20,0x29,0x20,0x0d,0x0a,0x09,0x7b,0x20,0x0d,0x0a,0x09,0x09,0x45,0x6e,0x74,
|
||||
0x69,0x74,0x79,0x47,0x72,0x6f,0x75,0x70,0x2e,0x61,0x70,0x70,0x65,0x6e,0x64,0x28,0x20,0x6e,0x75,0x6c,
|
||||
0x6c,0x20,0x29,0x3b,0x20,0x0d,0x0a,0x09,0x7d,0x20,0x0d,0x0a,0x09,0x65,0x6c,0x73,0x65,0x0d,0x0a,0x09,
|
||||
0x7b,0x20,0x0d,0x0a,0x09,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x65,0x6e,0x74,0x20,0x3d,0x20,0x45,0x6e,
|
||||
0x74,0x69,0x74,0x69,0x65,0x73,0x2e,0x46,0x69,0x6e,0x64,0x42,0x79,0x4e,0x61,0x6d,0x65,0x28,0x20,0x6e,
|
||||
0x75,0x6c,0x6c,0x2c,0x20,0x6e,0x61,0x6d,0x65,0x20,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x45,0x6e,0x74,0x69,
|
||||
0x74,0x79,0x47,0x72,0x6f,0x75,0x70,0x2e,0x61,0x70,0x70,0x65,0x6e,0x64,0x28,0x20,0x65,0x6e,0x74,0x20,
|
||||
0x29,0x3b,0x0d,0x0a,0x09,0x09,0x69,0x66,0x20,0x28,0x20,0x65,0x6e,0x74,0x20,0x21,0x3d,0x20,0x6e,0x75,
|
||||
0x6c,0x6c,0x20,0x29,0x0d,0x0a,0x09,0x09,0x7b,0x0d,0x0a,0x09,0x09,0x09,0x65,0x6e,0x74,0x2e,0x56,0x61,
|
||||
0x6c,0x69,0x64,0x61,0x74,0x65,0x53,0x63,0x72,0x69,0x70,0x74,0x53,0x63,0x6f,0x70,0x65,0x28,0x29,0x3b,
|
||||
0x0d,0x0a,0x09,0x09,0x09,0x65,0x6e,0x74,0x2e,0x47,0x65,0x74,0x53,0x63,0x72,0x69,0x70,0x74,0x53,0x63,
|
||||
0x6f,0x70,0x65,0x28,0x29,0x2e,0x45,0x6e,0x74,0x69,0x74,0x79,0x47,0x72,0x6f,0x75,0x70,0x20,0x3c,0x2d,
|
||||
0x20,0x45,0x6e,0x74,0x69,0x74,0x79,0x47,0x72,0x6f,0x75,0x70,0x3b,0x0d,0x0a,0x09,0x09,0x7d,0x0d,0x0a,
|
||||
0x09,0x7d,0x0d,0x0a,0x7d,0x0d,0x0a,0x00
|
||||
};
|
||||
|
||||
int iLastMember;
|
||||
for ( iLastMember = MAX_SCRIPT_GROUP - 1; iLastMember >= 0; iLastMember-- )
|
||||
{
|
||||
if ( m_iszGroupMembers[iLastMember] != NULL_STRING )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( iLastMember >= 0 )
|
||||
{
|
||||
HSCRIPT hAddScript = g_pScriptVM->CompileScript( szAddCode );
|
||||
if ( hAddScript )
|
||||
{
|
||||
ValidateScriptScope();
|
||||
m_ScriptScope.Run( hAddScript );
|
||||
HSCRIPT hAddFunc = m_ScriptScope.LookupFunction( "__AppendToScriptGroup" );
|
||||
if ( hAddFunc )
|
||||
{
|
||||
for ( int i = 0; i <= iLastMember; i++ )
|
||||
{
|
||||
m_ScriptScope.Call( hAddFunc, NULL, STRING(m_iszGroupMembers[i]) );
|
||||
}
|
||||
g_pScriptVM->ReleaseFunction( hAddFunc );
|
||||
m_ScriptScope.ClearValue( "__AppendToScriptGroup" );
|
||||
}
|
||||
|
||||
g_pScriptVM->ReleaseScript( hAddScript );
|
||||
}
|
||||
}
|
||||
BaseClass::RunVScripts();
|
||||
}
|
||||
|
||||
string_t m_iszGroupMembers[MAX_SCRIPT_GROUP];
|
||||
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( logic_script, CLogicScript );
|
||||
|
||||
BEGIN_DATADESC( CLogicScript )
|
||||
// Silence, Classcheck!
|
||||
// DEFINE_ARRAY( m_iszGroupMembers, FIELD_STRING, MAX_NUM_TEMPLATES ),
|
||||
|
||||
DEFINE_KEYFIELD( m_iszGroupMembers[0], FIELD_STRING, "Group00"),
|
||||
DEFINE_KEYFIELD( m_iszGroupMembers[1], FIELD_STRING, "Group01"),
|
||||
DEFINE_KEYFIELD( m_iszGroupMembers[2], FIELD_STRING, "Group02"),
|
||||
DEFINE_KEYFIELD( m_iszGroupMembers[3], FIELD_STRING, "Group03"),
|
||||
DEFINE_KEYFIELD( m_iszGroupMembers[4], FIELD_STRING, "Group04"),
|
||||
DEFINE_KEYFIELD( m_iszGroupMembers[5], FIELD_STRING, "Group05"),
|
||||
DEFINE_KEYFIELD( m_iszGroupMembers[6], FIELD_STRING, "Group06"),
|
||||
DEFINE_KEYFIELD( m_iszGroupMembers[7], FIELD_STRING, "Group07"),
|
||||
DEFINE_KEYFIELD( m_iszGroupMembers[8], FIELD_STRING, "Group08"),
|
||||
DEFINE_KEYFIELD( m_iszGroupMembers[9], FIELD_STRING, "Group09"),
|
||||
DEFINE_KEYFIELD( m_iszGroupMembers[10], FIELD_STRING, "Group10"),
|
||||
DEFINE_KEYFIELD( m_iszGroupMembers[11], FIELD_STRING, "Group11"),
|
||||
DEFINE_KEYFIELD( m_iszGroupMembers[12], FIELD_STRING, "Group12"),
|
||||
DEFINE_KEYFIELD( m_iszGroupMembers[13], FIELD_STRING, "Group13"),
|
||||
DEFINE_KEYFIELD( m_iszGroupMembers[14], FIELD_STRING, "Group14"),
|
||||
DEFINE_KEYFIELD( m_iszGroupMembers[15], FIELD_STRING, "Group15"),
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Compares a set of integer inputs to the one main input
|
||||
@ -3679,7 +3799,8 @@ BEGIN_DATADESC( CLogicConsole )
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
ConVar sv_allow_logic_convar("sv_allow_logic_convar", "1");
|
||||
ConVar sv_allow_logic_convar( "sv_allow_logic_convar", "1", FCVAR_NOT_CONNECTED );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Gets console variables for the evil mapper.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -91,8 +91,9 @@ void CV_InitMod()
|
||||
|
||||
void CVEnt_Precache(CMapbaseCVarModEntity *modent)
|
||||
{
|
||||
if (Q_strstr(STRING(modent->m_target), "sv_allow_logic_convar"))
|
||||
return;
|
||||
// Now protected by FCVAR_NOT_CONNECTED
|
||||
//if (Q_strstr(STRING(modent->m_target), "sv_allow_logic_convar"))
|
||||
// return;
|
||||
|
||||
#ifdef MAPBASE_MP
|
||||
if (gpGlobals->maxClients > 1 && !modent->m_bUseServer)
|
||||
|
@ -16,6 +16,9 @@ class CLogicExternalData : public CLogicalEntity
|
||||
{
|
||||
DECLARE_CLASS( CLogicExternalData, CLogicalEntity );
|
||||
DECLARE_DATADESC();
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DECLARE_ENT_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
public:
|
||||
~CLogicExternalData();
|
||||
@ -34,6 +37,16 @@ public:
|
||||
void InputSave( inputdata_t &inputdata );
|
||||
void InputReload( inputdata_t &inputdata );
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
HSCRIPT ScriptGetKeyValues( void );
|
||||
HSCRIPT ScriptGetKeyValueBlock( void );
|
||||
|
||||
void ScriptSetKeyValues( HSCRIPT hKV );
|
||||
void ScriptSetKeyValueBlock( HSCRIPT hKV );
|
||||
|
||||
void ScriptSetBlock( const char *szNewBlock, HSCRIPT hActivator = NULL, HSCRIPT hCaller = NULL );
|
||||
#endif
|
||||
|
||||
char m_iszFile[MAX_PATH];
|
||||
|
||||
// Root file
|
||||
@ -76,6 +89,21 @@ BEGIN_DATADESC( CLogicExternalData )
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
BEGIN_ENT_SCRIPTDESC( CLogicExternalData, CBaseEntity, "An entity which loads keyvalues from an external data file." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetKeyValues, "GetKeyValues", "Gets the external data expressed in CScriptKeyValues." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetKeyValueBlock, "GetKeyValueBlock", "Gets the current external data block expressed in CScriptKeyValues." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetKeyValues, "SetKeyValues", "Sets the external data from a CScriptKeyValues object." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetKeyValueBlock, "SetKeyValues", "Sets the current external data block from a CScriptKeyValues object." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( LoadFile, "Loads external data from the external file." )
|
||||
DEFINE_SCRIPTFUNC( SaveFile, "Saves the external data to the external file." )
|
||||
|
||||
END_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -243,3 +271,95 @@ void CLogicExternalData::InputReload( inputdata_t &inputdata )
|
||||
{
|
||||
LoadFile();
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CLogicExternalData::ScriptGetKeyValues( void )
|
||||
{
|
||||
if (m_bReloadBeforeEachAction)
|
||||
LoadFile();
|
||||
|
||||
HSCRIPT hScript = NULL;
|
||||
if (m_pRoot)
|
||||
{
|
||||
// Does this need to be destructed or freed? m_pScriptModelKeyValues apparently doesn't.
|
||||
CScriptKeyValues *pKV = new CScriptKeyValues( m_pRoot );
|
||||
hScript = g_pScriptVM->RegisterInstance( pKV );
|
||||
}
|
||||
|
||||
return hScript;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CLogicExternalData::ScriptGetKeyValueBlock( void )
|
||||
{
|
||||
if (m_bReloadBeforeEachAction)
|
||||
LoadFile();
|
||||
|
||||
HSCRIPT hScript = NULL;
|
||||
if (m_pBlock)
|
||||
{
|
||||
// Does this need to be destructed or freed? m_pScriptModelKeyValues apparently doesn't.
|
||||
CScriptKeyValues *pKV = new CScriptKeyValues( m_pBlock );
|
||||
hScript = g_pScriptVM->RegisterInstance( pKV );
|
||||
}
|
||||
|
||||
return hScript;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void CLogicExternalData::ScriptSetKeyValues( HSCRIPT hKV )
|
||||
{
|
||||
if (m_pRoot)
|
||||
{
|
||||
m_pRoot->deleteThis();
|
||||
m_pRoot = NULL;
|
||||
}
|
||||
|
||||
CScriptKeyValues *pKV = HScriptToClass<CScriptKeyValues>( hKV );
|
||||
if (pKV)
|
||||
{
|
||||
m_pRoot = pKV->m_pKeyValues;
|
||||
}
|
||||
}
|
||||
|
||||
void CLogicExternalData::ScriptSetKeyValueBlock( HSCRIPT hKV )
|
||||
{
|
||||
if (m_pBlock)
|
||||
{
|
||||
m_pBlock->deleteThis();
|
||||
m_pBlock = NULL;
|
||||
}
|
||||
|
||||
CScriptKeyValues *pKV = HScriptToClass<CScriptKeyValues>( hKV );
|
||||
if (pKV)
|
||||
{
|
||||
m_pBlock = pKV->m_pKeyValues;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLogicExternalData::ScriptSetBlock( const char *szNewBlock, HSCRIPT hActivator, HSCRIPT hCaller )
|
||||
{
|
||||
CBaseEntity *pActivator = ToEnt( hActivator );
|
||||
CBaseEntity *pCaller = ToEnt( hCaller );
|
||||
string_t iszNewTarget = AllocPooledString(szNewBlock);
|
||||
if (STRING(iszNewTarget)[0] == '!')
|
||||
{
|
||||
if (FStrEq(STRING(iszNewTarget), "!self"))
|
||||
iszNewTarget = GetEntityName();
|
||||
else if (pActivator && FStrEq(STRING(iszNewTarget), "!activator"))
|
||||
iszNewTarget = pActivator->GetEntityName();
|
||||
else if (pCaller && FStrEq(STRING(iszNewTarget), "!caller"))
|
||||
iszNewTarget = pCaller->GetEntityName();
|
||||
}
|
||||
|
||||
m_target = iszNewTarget;
|
||||
LoadFile();
|
||||
}
|
||||
#endif
|
||||
|
@ -18,6 +18,8 @@
|
||||
#include "IEffects.h"
|
||||
#include "props.h"
|
||||
|
||||
#include "point_template.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
@ -114,6 +116,8 @@ END_DATADESC()
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseNPCMaker::Spawn( void )
|
||||
{
|
||||
ScriptInstallPreSpawnHook();
|
||||
|
||||
SetSolid( SOLID_NONE );
|
||||
m_nLiveChildren = 0;
|
||||
Precache();
|
||||
@ -830,6 +834,12 @@ void CTemplateNPCMaker::MakeNPC( void )
|
||||
pent->SetAbsAngles( angles );
|
||||
}
|
||||
|
||||
if ( !ScriptPreInstanceSpawn( &m_ScriptScope, pEntity, m_iszTemplateData ) )
|
||||
{
|
||||
UTIL_RemoveImmediate( pEntity );
|
||||
return;
|
||||
}
|
||||
|
||||
m_OnSpawnNPC.Set( pEntity, pEntity, this );
|
||||
|
||||
if ( m_spawnflags & SF_NPCMAKER_FADE )
|
||||
@ -867,6 +877,8 @@ void CTemplateNPCMaker::MakeNPC( void )
|
||||
SetUse( NULL );
|
||||
}
|
||||
}
|
||||
|
||||
ScriptPostSpawn( &m_ScriptScope, &pEntity, 1 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -478,6 +478,33 @@ BEGIN_DATADESC( CBasePlayer )
|
||||
// DEFINE_UTLVECTOR( m_vecPlayerSimInfo ),
|
||||
END_DATADESC()
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
BEGIN_ENT_SCRIPTDESC( CBasePlayer, CBaseCombatCharacter, "The player entity." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptIsPlayerNoclipping, "IsNoclipping", "Returns true if the player is in noclip mode." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( VScriptGetExpresser, "GetExpresser", "Gets a handle for this player's expresser." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( FragCount, "Gets the number of frags (kills) this player has in a multiplayer game." )
|
||||
DEFINE_SCRIPTFUNC( DeathCount, "Gets the number of deaths this player has had in a multiplayer game." )
|
||||
DEFINE_SCRIPTFUNC( IsConnected, "Returns true if this player is connected." )
|
||||
DEFINE_SCRIPTFUNC( IsDisconnecting, "Returns true if this player is disconnecting." )
|
||||
DEFINE_SCRIPTFUNC( IsSuitEquipped, "Returns true if this player had the HEV suit equipped." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ArmorValue, "GetArmor", "Gets the player's armor." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( SetArmorValue, "SetArmor", "Sets the player's armor." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( FlashlightIsOn, "Returns true if the flashlight is on." )
|
||||
DEFINE_SCRIPTFUNC( FlashlightTurnOn, "Turns on the flashlight." )
|
||||
DEFINE_SCRIPTFUNC( FlashlightTurnOff, "Turns off the flashlight." )
|
||||
|
||||
END_SCRIPTDESC();
|
||||
#else
|
||||
BEGIN_ENT_SCRIPTDESC( CBasePlayer, CBaseAnimating, "The player entity." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptIsPlayerNoclipping, "IsNoclipping", "Returns true if the player is in noclip mode." )
|
||||
END_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
int giPrecacheGrunt = 0;
|
||||
|
||||
edict_t *CBasePlayer::s_PlayerEdict = NULL;
|
||||
@ -690,6 +717,11 @@ CBasePlayer::~CBasePlayer( )
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBasePlayer::UpdateOnRemove( void )
|
||||
{
|
||||
if ( !g_pGameRules->IsMultiplayer() && g_pScriptVM )
|
||||
{
|
||||
g_pScriptVM->SetValue( "player", SCRIPT_VARIANT_NULL );
|
||||
}
|
||||
|
||||
VPhysicsDestroyObject();
|
||||
|
||||
// Remove him from his current team
|
||||
@ -5110,6 +5142,11 @@ void CBasePlayer::Spawn( void )
|
||||
UpdateLastKnownArea();
|
||||
|
||||
m_weaponFiredTimer.Invalidate();
|
||||
|
||||
if ( !g_pGameRules->IsMultiplayer() && g_pScriptVM )
|
||||
{
|
||||
g_pScriptVM->SetValue( "player", GetScriptInstance() );
|
||||
}
|
||||
}
|
||||
|
||||
void CBasePlayer::Activate( void )
|
||||
@ -5300,6 +5337,14 @@ void CBasePlayer::OnRestore( void )
|
||||
m_nVehicleViewSavedFrame = 0;
|
||||
|
||||
m_nBodyPitchPoseParam = LookupPoseParameter( "body_pitch" );
|
||||
|
||||
// HACK: (03/25/09) Then the player goes across a transition it doesn't spawn and register
|
||||
// it's instance. We're hacking around this for now, but this will go away when we get around to
|
||||
// having entities cross transitions and keep their script state.
|
||||
if ( !g_pGameRules->IsMultiplayer() && g_pScriptVM && (gpGlobals->eLoadType == MapLoad_Transition) )
|
||||
{
|
||||
g_pScriptVM->SetValue( "player", GetScriptInstance() );
|
||||
}
|
||||
}
|
||||
|
||||
/* void CBasePlayer::SetTeamName( const char *pTeamName )
|
||||
@ -6864,6 +6909,30 @@ void CBasePlayer::ShowCrosshair( bool bShow )
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Used by vscript to determine if the player is noclipping
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBasePlayer::ScriptIsPlayerNoclipping(void)
|
||||
{
|
||||
return (GetMoveType() == MOVETYPE_NOCLIP);
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CBasePlayer::VScriptGetExpresser()
|
||||
{
|
||||
HSCRIPT hScript = NULL;
|
||||
CAI_Expresser *pExpresser = GetExpresser();
|
||||
if (pExpresser)
|
||||
{
|
||||
hScript = g_pScriptVM->RegisterInstance( pExpresser );
|
||||
}
|
||||
|
||||
return hScript;
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -244,6 +244,8 @@ protected:
|
||||
public:
|
||||
DECLARE_DATADESC();
|
||||
DECLARE_SERVERCLASS();
|
||||
// script description
|
||||
DECLARE_ENT_SCRIPTDESC();
|
||||
|
||||
CBasePlayer();
|
||||
~CBasePlayer();
|
||||
@ -386,6 +388,12 @@ public:
|
||||
void ShowViewModel( bool bShow );
|
||||
void ShowCrosshair( bool bShow );
|
||||
|
||||
bool ScriptIsPlayerNoclipping(void);
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
HSCRIPT VScriptGetExpresser();
|
||||
#endif
|
||||
|
||||
// View model prediction setup
|
||||
void CalcView( Vector &eyeOrigin, QAngle &eyeAngles, float &zNear, float &zFar, float &fov );
|
||||
|
||||
|
@ -53,24 +53,6 @@ END_DATADESC()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( point_devshot_camera, CPointDevShotCamera );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Convenience function so we don't have to make this check all over
|
||||
//-----------------------------------------------------------------------------
|
||||
static CBasePlayer * UTIL_GetLocalPlayerOrListenServerHost( void )
|
||||
{
|
||||
if ( gpGlobals->maxClients > 1 )
|
||||
{
|
||||
if ( engine->IsDedicatedServer() )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return UTIL_GetListenServerHost();
|
||||
}
|
||||
|
||||
return UTIL_GetLocalPlayer();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -133,6 +133,8 @@ void PrecachePointTemplates()
|
||||
void CPointTemplate::Spawn( void )
|
||||
{
|
||||
Precache();
|
||||
ScriptInstallPreSpawnHook();
|
||||
ValidateScriptScope();
|
||||
}
|
||||
|
||||
void CPointTemplate::Precache()
|
||||
@ -345,7 +347,7 @@ bool CPointTemplate::CreateInstance( const Vector &vecOrigin, const QAngle &vecA
|
||||
|
||||
// Some templates have Entity I/O connecting the entities within the template.
|
||||
// Unique versions of these templates need to be created whenever they're instanced.
|
||||
if ( AllowNameFixup() && Templates_IndexRequiresEntityIOFixup( iTemplateIndex ) )
|
||||
if ( AllowNameFixup() && ( Templates_IndexRequiresEntityIOFixup( iTemplateIndex ) || m_ScriptScope.IsInitialized() ) )
|
||||
{
|
||||
// This template requires instancing.
|
||||
// Create a new mapdata block and ask the template system to fill it in with
|
||||
@ -381,7 +383,15 @@ bool CPointTemplate::CreateInstance( const Vector &vecOrigin, const QAngle &vecA
|
||||
pEntity->SetAbsOrigin( vecNewOrigin );
|
||||
pEntity->SetAbsAngles( vecNewAngles );
|
||||
|
||||
pSpawnList[i].m_pEntity = pEntity;
|
||||
if (ScriptPreInstanceSpawn(&m_ScriptScope, pEntity, Templates_FindByIndex(iTemplateIndex)))
|
||||
{
|
||||
pSpawnList[i].m_pEntity = pEntity;
|
||||
}
|
||||
else
|
||||
{
|
||||
pSpawnList[i].m_pEntity = NULL;
|
||||
UTIL_RemoveImmediate(pEntity);
|
||||
}
|
||||
pSpawnList[i].m_nDepth = 0;
|
||||
pSpawnList[i].m_pDeferredParent = NULL;
|
||||
}
|
||||
@ -426,7 +436,7 @@ bool CPointTemplate::CreateSpecificInstance( int iTemplate, const Vector &vecOri
|
||||
|
||||
// Some templates have Entity I/O connecting the entities within the template.
|
||||
// Unique versions of these templates need to be created whenever they're instanced.
|
||||
if ( AllowNameFixup() && Templates_IndexRequiresEntityIOFixup( iTemplateIndex ) )
|
||||
if ( AllowNameFixup() && ( Templates_IndexRequiresEntityIOFixup( iTemplateIndex ) || m_ScriptScope.IsInitialized() ) )
|
||||
{
|
||||
// This template requires instancing.
|
||||
// Create a new mapdata block and ask the template system to fill it in with
|
||||
@ -474,6 +484,17 @@ bool CPointTemplate::CreateSpecificInstance( int iTemplate, const Vector &vecOri
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPointTemplate::CreationComplete( const CUtlVector<CBaseEntity*> &entities )
|
||||
{
|
||||
if ( !entities.Count() )
|
||||
return;
|
||||
|
||||
ScriptPostSpawn( &m_ScriptScope, (CBaseEntity **)entities.Base(), entities.Count() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : &inputdata -
|
||||
@ -514,3 +535,72 @@ void CPointTemplate::InputForceSpawnRandomTemplate( inputdata_t &inputdata )
|
||||
m_pOutputOutEntity.Set(pEntity, pEntity, this);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void ScriptInstallPreSpawnHook()
|
||||
{
|
||||
#ifdef IS_WINDOWS_PC
|
||||
if ( !g_pScriptVM->ValueExists( "__ExecutePreSpawn " ) )
|
||||
{
|
||||
//g_pScriptVM->Run( g_Script_spawn_helper );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This function is called after a spawner creates its child entity
|
||||
// but before the keyvalues are injected. This gives us an
|
||||
// opportunity to change any keyvalues before the entity is
|
||||
// configured and spawned. In this case, we see if there is a VScript
|
||||
// that wants to change anything about this entity.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ScriptPreInstanceSpawn( CScriptScope *pScriptScope, CBaseEntity *pChild, string_t iszKeyValueData )
|
||||
{
|
||||
if ( !pScriptScope->IsInitialized() )
|
||||
return true;
|
||||
|
||||
ScriptVariant_t result;
|
||||
if ( pScriptScope->Call( "__ExecutePreSpawn", &result, ToHScript( pChild ) ) != SCRIPT_DONE )
|
||||
return true;
|
||||
|
||||
if ( ( result.m_type == FIELD_BOOLEAN && !result.m_bool ) || ( result.m_type == FIELD_INTEGER && !result.m_int ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
void ScriptPostSpawn( CScriptScope *pScriptScope, CBaseEntity **ppEntities, int nEntities )
|
||||
{
|
||||
if ( !pScriptScope->IsInitialized() )
|
||||
return;
|
||||
|
||||
HSCRIPT hPostSpawnFunc = pScriptScope->LookupFunction( "PostSpawn" );
|
||||
|
||||
if ( !hPostSpawnFunc )
|
||||
return;
|
||||
|
||||
ScriptVariant_t varEntityMakerResultTable;
|
||||
if ( !g_pScriptVM->GetValue( *pScriptScope, "__EntityMakerResult", &varEntityMakerResultTable ) )
|
||||
return;
|
||||
|
||||
if ( varEntityMakerResultTable.m_type != FIELD_HSCRIPT )
|
||||
return;
|
||||
|
||||
HSCRIPT hEntityMakerResultTable = varEntityMakerResultTable.m_hScript;
|
||||
char szEntName[256];
|
||||
for ( int i = 0; i < nEntities; i++ )
|
||||
{
|
||||
V_strncpy( szEntName, ppEntities[i]->GetEntityNameAsCStr(), ARRAYSIZE(szEntName) );
|
||||
char *pAmpersand = V_strrchr( szEntName, '&' );
|
||||
if ( pAmpersand )
|
||||
*pAmpersand = 0;
|
||||
g_pScriptVM->SetValue( hEntityMakerResultTable, szEntName, ToHScript( ppEntities[i] ) );
|
||||
}
|
||||
pScriptScope->Call( hPostSpawnFunc, NULL, hEntityMakerResultTable );
|
||||
pScriptScope->Call( "__FinishSpawn" );
|
||||
g_pScriptVM->ReleaseValue( varEntityMakerResultTable );
|
||||
g_pScriptVM->ReleaseFunction( hPostSpawnFunc );
|
||||
}
|
||||
|
@ -20,6 +20,10 @@ struct template_t
|
||||
DECLARE_SIMPLE_DATADESC();
|
||||
};
|
||||
|
||||
void ScriptInstallPreSpawnHook();
|
||||
bool ScriptPreInstanceSpawn( CScriptScope *pScriptScope, CBaseEntity *pChild, string_t iszKeyValueData );
|
||||
void ScriptPostSpawn( CScriptScope *pScriptScope, CBaseEntity **ppEntities, int nEntities );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -52,6 +56,7 @@ public:
|
||||
#ifdef MAPBASE
|
||||
bool CreateSpecificInstance( int iTemplate, const Vector &vecOrigin, const QAngle &vecAngles, CBaseEntity **pOutEntity );
|
||||
#endif
|
||||
void CreationComplete(const CUtlVector<CBaseEntity*>& entities);
|
||||
|
||||
// Inputs
|
||||
void InputForceSpawn( inputdata_t &inputdata );
|
||||
|
@ -33,6 +33,8 @@
|
||||
#include "SceneCache.h"
|
||||
#include "scripted.h"
|
||||
#include "env_debughistory.h"
|
||||
#include "team.h"
|
||||
#include "triggers.h"
|
||||
|
||||
#ifdef HL2_EPISODIC
|
||||
#include "npc_alyx_episodic.h"
|
||||
@ -323,6 +325,8 @@ public:
|
||||
|
||||
DECLARE_CLASS( CSceneEntity, CPointEntity );
|
||||
DECLARE_SERVERCLASS();
|
||||
// script description
|
||||
DECLARE_ENT_SCRIPTDESC();
|
||||
|
||||
CSceneEntity( void );
|
||||
~CSceneEntity( void );
|
||||
@ -470,6 +474,8 @@ public:
|
||||
|
||||
void InputScriptPlayerDeath( inputdata_t &inputdata );
|
||||
|
||||
void AddBroadcastTeamTarget( int nTeamIndex );
|
||||
void RemoveBroadcastTeamTarget( int nTeamIndex );
|
||||
// Data
|
||||
public:
|
||||
string_t m_iszSceneFile;
|
||||
@ -543,6 +549,9 @@ public:
|
||||
virtual CBaseEntity *FindNamedEntity( const char *name, CBaseEntity *pActor = NULL, bool bBaseFlexOnly = false, bool bUseClear = false );
|
||||
CBaseEntity *FindNamedTarget( string_t iszTarget, bool bBaseFlexOnly = false );
|
||||
virtual CBaseEntity *FindNamedEntityClosest( const char *name, CBaseEntity *pActor = NULL, bool bBaseFlexOnly = false, bool bUseClear = false, const char *pszSecondary = NULL );
|
||||
HSCRIPT ScriptFindNamedEntity( const char *name );
|
||||
bool ScriptLoadSceneFromString( const char * pszFilename, const char *pszData );
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@ -764,6 +773,17 @@ BEGIN_DATADESC( CSceneEntity )
|
||||
DEFINE_OUTPUT( m_OnTrigger16, "OnTrigger16"),
|
||||
END_DATADESC()
|
||||
|
||||
|
||||
BEGIN_ENT_SCRIPTDESC( CSceneEntity, CBaseEntity, "Choreographed scene which controls animation and/or dialog on one or more actors." )
|
||||
DEFINE_SCRIPTFUNC( EstimateLength, "Returns length of this scene in seconds." )
|
||||
DEFINE_SCRIPTFUNC( IsPlayingBack, "If this scene is currently playing." )
|
||||
DEFINE_SCRIPTFUNC( IsPaused, "If this scene is currently paused." )
|
||||
DEFINE_SCRIPTFUNC( AddBroadcastTeamTarget, "Adds a team (by index) to the broadcast list" )
|
||||
DEFINE_SCRIPTFUNC( RemoveBroadcastTeamTarget, "Removes a team (by index) from the broadcast list" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptFindNamedEntity, "FindNamedEntity", "given an entity reference, such as !target, get actual entity from scene object" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptLoadSceneFromString, "LoadSceneFromString", "given a dummy scene name and a vcd string, load the scene" )
|
||||
END_SCRIPTDESC();
|
||||
|
||||
const ConVar *CSceneEntity::m_pcvSndMixahead = NULL;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -3066,7 +3086,7 @@ void CSceneEntity::StartEvent( float currenttime, CChoreoScene *scene, CChoreoEv
|
||||
|
||||
CBaseFlex *pActor = NULL;
|
||||
CChoreoActor *actor = event->GetActor();
|
||||
if ( actor )
|
||||
if ( actor && (event->GetType() != CChoreoEvent::SCRIPT) && (event->GetType() != CChoreoEvent::CAMERA) )
|
||||
{
|
||||
pActor = FindNamedActor( actor );
|
||||
if (pActor == NULL)
|
||||
@ -3229,6 +3249,80 @@ void CSceneEntity::StartEvent( float currenttime, CChoreoScene *scene, CChoreoEv
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CChoreoEvent::CAMERA:
|
||||
{
|
||||
// begin the camera shot
|
||||
const char *pszShotType = event->GetParameters();
|
||||
|
||||
CBaseEntity *pActor1 = FindNamedEntity( event->GetParameters2( ), pActor );
|
||||
CBaseEntity *pActor2 = FindNamedEntity( event->GetParameters3( ), pActor );
|
||||
float duration = event->GetDuration();
|
||||
|
||||
// grab any camera we find in the map
|
||||
// TODO: find camera that is nearest this scene entity?
|
||||
CTriggerCamera *pCamera = (CTriggerCamera *)gEntList.FindEntityByClassname( NULL, "point_viewcontrol" );
|
||||
|
||||
if ( !pCamera )
|
||||
{
|
||||
Warning( "CSceneEntity %s unable to find a camera (point_viewcontrol) in this map!\n", STRING(GetEntityName()) );
|
||||
}
|
||||
else
|
||||
{
|
||||
pCamera->StartCameraShot( pszShotType, this, pActor1, pActor2, duration );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CChoreoEvent::SCRIPT:
|
||||
{
|
||||
// NOTE: this is only used by auto-generated vcds to embed script commands to map entities.
|
||||
|
||||
// vscript call - param1 is entity name, param2 is function name, param3 is function parameter string
|
||||
// calls a vscript function defined on the scope of the named CBaseEntity object/actor.
|
||||
// script call is of the format FunctionName(pActor, pThisSceneEntity, pszScriptParameters, duration)
|
||||
const char *pszActorName = event->GetParameters();
|
||||
const char *pszFunctionName = event->GetParameters2();
|
||||
const char *pszScriptParameters = event->GetParameters3();
|
||||
|
||||
float duration = event->GetDuration();
|
||||
|
||||
// TODO: should be new method CBaseEntity::CallScriptFunctionParams()
|
||||
CBaseEntity *pEntity = (CBaseEntity *)gEntList.FindEntityByName( NULL, pszActorName );
|
||||
|
||||
//START_VMPROFILE
|
||||
if ( !pEntity )
|
||||
{
|
||||
Warning( "CSceneEntity::SCRIPT event - unable to find entity named '%s' in this map!\n", pszActorName );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if( !pEntity->ValidateScriptScope() )
|
||||
{
|
||||
DevMsg("\n***\nCChoreoEvent::SCRIPT - FAILED to create private ScriptScope. ABORTING script call\n***\n");
|
||||
break;
|
||||
}
|
||||
|
||||
HSCRIPT hFunc = pEntity->m_ScriptScope.LookupFunction( pszFunctionName );
|
||||
|
||||
if( hFunc )
|
||||
{
|
||||
pEntity->m_ScriptScope.Call( hFunc, NULL, ToHScript(this), pszScriptParameters, duration );
|
||||
pEntity->m_ScriptScope.ReleaseFunction( hFunc );
|
||||
|
||||
//UPDATE_VMPROFILE
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning("CSceneEntity::SCRIPT event - '%s' entity has no script function '%s' defined!\n", pszActorName,pszFunctionName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case CChoreoEvent::FIRETRIGGER:
|
||||
{
|
||||
if ( IsMultiplayer() )
|
||||
@ -3437,6 +3531,19 @@ void CSceneEntity::EndEvent( float currenttime, CChoreoScene *scene, CChoreoEven
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CChoreoEvent::CAMERA:
|
||||
{
|
||||
// call the end of camera or call a dispatch function
|
||||
}
|
||||
break;
|
||||
|
||||
case CChoreoEvent::SCRIPT:
|
||||
{
|
||||
// call the end of script or call a dispatch function
|
||||
}
|
||||
break;
|
||||
|
||||
case CChoreoEvent::SEQUENCE:
|
||||
{
|
||||
if ( pActor )
|
||||
@ -4268,6 +4375,53 @@ CBaseEntity *CSceneEntity::FindNamedEntityClosest( const char *name, CBaseEntity
|
||||
}
|
||||
|
||||
|
||||
HSCRIPT CSceneEntity::ScriptFindNamedEntity(const char* name)
|
||||
{
|
||||
return ToHScript(FindNamedEntity(name, NULL, false, false));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: vscript - create a scene directly from a buffer containing
|
||||
// a vcd description, and load it into the scene entity.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSceneEntity::ScriptLoadSceneFromString(const char* pszFilename, const char* pszData)
|
||||
{
|
||||
CChoreoScene* pScene = new CChoreoScene(NULL);
|
||||
|
||||
// CSceneTokenProcessor SceneTokenProcessor;
|
||||
// SceneTokenProcessor.SetBuffer( pszData );
|
||||
g_TokenProcessor.SetBuffer((char*)pszData);
|
||||
|
||||
if (!pScene->ParseFromBuffer(pszFilename, &g_TokenProcessor)) //&SceneTokenProcessor ) )
|
||||
{
|
||||
Warning("CSceneEntity::LoadSceneFromString: Unable to parse scene data '%s'\n", pszFilename);
|
||||
delete pScene;
|
||||
pScene = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pScene->SetPrintFunc(LocalScene_Printf);
|
||||
pScene->SetEventCallbackInterface(this);
|
||||
|
||||
|
||||
// precache all sounds for the newly constructed scene
|
||||
PrecacheScene(pScene);
|
||||
}
|
||||
|
||||
if (pScene != NULL)
|
||||
{
|
||||
// release prior scene if present
|
||||
UnloadScene();
|
||||
m_pScene = pScene;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Remove all "scene" expressions from all actors in this scene
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -4691,6 +4845,44 @@ void CSceneEntity::SetRecipientFilter( IRecipientFilter *filter )
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Adds a player (by index) to the recipient filter
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSceneEntity::AddBroadcastTeamTarget(int nTeamIndex)
|
||||
{
|
||||
if (m_pRecipientFilter == NULL)
|
||||
{
|
||||
CRecipientFilter filter;
|
||||
SetRecipientFilter(&filter);
|
||||
}
|
||||
|
||||
CTeam* pTeam = GetGlobalTeam(nTeamIndex);
|
||||
Assert(pTeam);
|
||||
if (pTeam == NULL)
|
||||
return;
|
||||
|
||||
m_pRecipientFilter->AddRecipientsByTeam(pTeam);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Removes a player (by index) from the recipient filter
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSceneEntity::RemoveBroadcastTeamTarget(int nTeamIndex)
|
||||
{
|
||||
if (m_pRecipientFilter == NULL)
|
||||
{
|
||||
CRecipientFilter filter;
|
||||
SetRecipientFilter(&filter);
|
||||
}
|
||||
|
||||
CTeam* pTeam = GetGlobalTeam(nTeamIndex);
|
||||
Assert(pTeam);
|
||||
if (pTeam == NULL)
|
||||
return;
|
||||
|
||||
m_pRecipientFilter->RemoveRecipientsByTeam(pTeam);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
@ -4986,6 +5178,26 @@ int GetSceneSpeechCount( char const *pszScene )
|
||||
return 0;
|
||||
}
|
||||
|
||||
HSCRIPT ScriptCreateSceneEntity( const char* pszScene )
|
||||
{
|
||||
if ( IsEntityCreationAllowedInScripts() == false )
|
||||
{
|
||||
Warning( "VScript error: A script attempted to create a scene entity mid-game. Entity creation from scripts is only allowed during map init.\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_pScriptVM->RegisterClass( GetScriptDescForClass( CSceneEntity ) );
|
||||
CSceneEntity *pScene = (CSceneEntity *)CBaseEntity::CreateNoSpawn( "logic_choreographed_scene", vec3_origin, vec3_angle );
|
||||
|
||||
if ( pScene )
|
||||
{
|
||||
pScene->m_iszSceneFile = AllocPooledString( pszScene );
|
||||
DispatchSpawn( pScene );
|
||||
}
|
||||
|
||||
return ToHScript( pScene );
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
CON_COMMAND(mapbase_scene_precache, "Just work")
|
||||
{
|
||||
|
@ -48,6 +48,7 @@ int GetSceneSpeechCount( char const *pszScene );
|
||||
bool IsInInterruptableScenes( CBaseFlex *pActor );
|
||||
|
||||
void PrecacheInstancedScene( char const *pszScene );
|
||||
HSCRIPT ScriptCreateSceneEntity( char const *pszScene );
|
||||
|
||||
char const *GetSceneFilename( CBaseEntity *ent );
|
||||
void ReloadSceneFromDisk( CBaseEntity *ent );
|
||||
|
@ -648,6 +648,11 @@ $Project
|
||||
$File "$SRCDIR\game\shared\voice_common.h"
|
||||
$File "$SRCDIR\game\shared\voice_gamemgr.cpp"
|
||||
$File "$SRCDIR\game\shared\voice_gamemgr.h"
|
||||
$File "vscript_server.cpp"
|
||||
$File "vscript_server.h"
|
||||
$File "vscript_server.nut"
|
||||
$File "$SRCDIR\game\shared\vscript_shared.cpp"
|
||||
$File "$SRCDIR\game\shared\vscript_shared.h"
|
||||
$File "waterbullet.cpp"
|
||||
$File "waterbullet.h"
|
||||
$File "WaterLODControl.cpp"
|
||||
|
@ -31,6 +31,9 @@ $Project
|
||||
$File "$SRCDIR\game\shared\mapbase\MapEdit.h"
|
||||
$File "$SRCDIR\game\shared\mapbase\matchers.cpp"
|
||||
$File "$SRCDIR\game\shared\mapbase\matchers.h"
|
||||
$File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.cpp" [$MAPBASE_VSCRIPT]
|
||||
$File "$SRCDIR\game\shared\mapbase\vscript_funcs_math.cpp" [$MAPBASE_VSCRIPT]
|
||||
$File "$SRCDIR\game\shared\mapbase\vscript_funcs_hl2.cpp" [$MAPBASE_VSCRIPT]
|
||||
|
||||
$File "mapbase\ai_grenade.cpp"
|
||||
$File "mapbase\ai_grenade.h"
|
||||
@ -81,4 +84,9 @@ $Project
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib "vscript" [$MAPBASE_VSCRIPT]
|
||||
}
|
||||
}
|
||||
|
@ -2978,94 +2978,6 @@ void CAI_ChangeHintGroup::InputActivate( inputdata_t &inputdata )
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class CTriggerCamera : public CBaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CTriggerCamera, CBaseEntity );
|
||||
|
||||
#ifdef MAPBASE
|
||||
CTriggerCamera();
|
||||
|
||||
void UpdateOnRemove();
|
||||
#endif
|
||||
|
||||
void Spawn( void );
|
||||
bool KeyValue( const char *szKeyName, const char *szValue );
|
||||
void Enable( void );
|
||||
void Disable( void );
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
void FollowTarget( void );
|
||||
#ifdef MAPBASE
|
||||
void MoveThink( void );
|
||||
#endif
|
||||
void Move(void);
|
||||
|
||||
// Always transmit to clients so they know where to move the view to
|
||||
virtual int UpdateTransmitState();
|
||||
|
||||
DECLARE_DATADESC();
|
||||
|
||||
// Input handlers
|
||||
void InputEnable( inputdata_t &inputdata );
|
||||
void InputDisable( inputdata_t &inputdata );
|
||||
|
||||
#ifdef MAPBASE
|
||||
void InputSetFOV( inputdata_t &inputdata );
|
||||
void InputSetFOVRate( inputdata_t &inputdata );
|
||||
#endif
|
||||
|
||||
private:
|
||||
EHANDLE m_hPlayer;
|
||||
EHANDLE m_hTarget;
|
||||
|
||||
// used for moving the camera along a path (rail rides)
|
||||
CBaseEntity *m_pPath;
|
||||
string_t m_sPath;
|
||||
float m_flWait;
|
||||
float m_flReturnTime;
|
||||
float m_flStopTime;
|
||||
float m_moveDistance;
|
||||
float m_targetSpeed;
|
||||
float m_initialSpeed;
|
||||
float m_acceleration;
|
||||
float m_deceleration;
|
||||
int m_state;
|
||||
Vector m_vecMoveDir;
|
||||
|
||||
#ifdef MAPBASE
|
||||
float m_fov;
|
||||
float m_fovSpeed;
|
||||
|
||||
bool m_bDontSetPlayerView;
|
||||
#endif
|
||||
|
||||
string_t m_iszTargetAttachment;
|
||||
int m_iAttachmentIndex;
|
||||
bool m_bSnapToGoal;
|
||||
|
||||
#if HL2_EPISODIC
|
||||
bool m_bInterpolatePosition;
|
||||
|
||||
// these are interpolation vars used for interpolating the camera over time
|
||||
Vector m_vStartPos, m_vEndPos;
|
||||
float m_flInterpStartTime;
|
||||
|
||||
const static float kflPosInterpTime; // seconds
|
||||
#endif
|
||||
|
||||
int m_nPlayerButtons;
|
||||
int m_nOldTakeDamage;
|
||||
|
||||
private:
|
||||
COutputEvent m_OnEndFollow;
|
||||
#ifdef MAPBASE
|
||||
COutputEvent m_OnStartFollow;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if HL2_EPISODIC
|
||||
const float CTriggerCamera::kflPosInterpTime = 2.0f;
|
||||
#endif
|
||||
@ -3127,6 +3039,12 @@ BEGIN_DATADESC( CTriggerCamera )
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
// VScript: publish class and select members to script language
|
||||
BEGIN_ENT_SCRIPTDESC( CTriggerCamera, CBaseEntity, "Server-side camera entity" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetFov, "GetFov", "get camera's current fov setting as integer" )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetFov, "SetFov", "set camera's current fov in integer degrees and fov change rate as float" )
|
||||
END_SCRIPTDESC();
|
||||
|
||||
#ifdef MAPBASE
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
@ -3641,6 +3559,59 @@ void CTriggerCamera::FollowTarget( )
|
||||
Move();
|
||||
}
|
||||
|
||||
void CTriggerCamera::StartCameraShot( const char *pszShotType, CBaseEntity *pSceneEntity, CBaseEntity *pActor1, CBaseEntity *pActor2, float duration )
|
||||
{
|
||||
// called from SceneEntity in response to a CChoreoEvent::CAMERA sent from a VCD.
|
||||
// talk to vscript, start a camera move
|
||||
|
||||
HSCRIPT hStartCameraShot = NULL;
|
||||
|
||||
// switch to this camera
|
||||
// Enable();
|
||||
|
||||
// get script module associated with this ent, lookup function in module
|
||||
if( m_iszVScripts != NULL_STRING )
|
||||
{
|
||||
hStartCameraShot = m_ScriptScope.LookupFunction( "ScriptStartCameraShot" );
|
||||
}
|
||||
|
||||
// call the script function to begin the camera move
|
||||
if ( hStartCameraShot )
|
||||
{
|
||||
g_pScriptVM->Call( hStartCameraShot, m_ScriptScope, true, NULL, pszShotType, ToHScript(pSceneEntity), ToHScript(pActor1), ToHScript(pActor2), duration );
|
||||
g_pScriptVM->ReleaseFunction( hStartCameraShot );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: vscript callback to get the player's fov
|
||||
//-----------------------------------------------------------------------------
|
||||
int CTriggerCamera::ScriptGetFov(void)
|
||||
{
|
||||
if (m_hPlayer)
|
||||
{
|
||||
CBasePlayer* pBasePlayer = (CBasePlayer*)m_hPlayer.Get();
|
||||
int iFOV = pBasePlayer->GetFOV();
|
||||
return iFOV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: vscript callback to slam the player's fov
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTriggerCamera::ScriptSetFov(int iFOV, float fovSpeed)
|
||||
{
|
||||
if (m_hPlayer)
|
||||
{
|
||||
m_fov = iFOV;
|
||||
m_fovSpeed = fovSpeed;
|
||||
|
||||
CBasePlayer* pBasePlayer = (CBasePlayer*)m_hPlayer.Get();
|
||||
pBasePlayer->SetFOV(this, iFOV, fovSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
void CTriggerCamera::MoveThink()
|
||||
{
|
||||
|
@ -244,4 +244,98 @@ public:
|
||||
CUtlVector<EHANDLE> m_hurtEntities;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class CTriggerCamera : public CBaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CTriggerCamera, CBaseEntity );
|
||||
// script description
|
||||
DECLARE_ENT_SCRIPTDESC();
|
||||
|
||||
#ifdef MAPBASE
|
||||
CTriggerCamera();
|
||||
|
||||
void UpdateOnRemove();
|
||||
#endif
|
||||
|
||||
void Spawn( void );
|
||||
bool KeyValue( const char *szKeyName, const char *szValue );
|
||||
void Enable( void );
|
||||
void Disable( void );
|
||||
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
void FollowTarget( void );
|
||||
void StartCameraShot( const char *pszShotType, CBaseEntity *pSceneEntity, CBaseEntity *pActor1, CBaseEntity *pActor2, float duration );
|
||||
int ScriptGetFov(void);
|
||||
void ScriptSetFov(int iFOV, float rate);
|
||||
#ifdef MAPBASE
|
||||
void MoveThink( void );
|
||||
#endif
|
||||
void Move(void);
|
||||
|
||||
// Always transmit to clients so they know where to move the view to
|
||||
virtual int UpdateTransmitState();
|
||||
|
||||
DECLARE_DATADESC();
|
||||
|
||||
// Input handlers
|
||||
void InputEnable( inputdata_t &inputdata );
|
||||
void InputDisable( inputdata_t &inputdata );
|
||||
|
||||
#ifdef MAPBASE
|
||||
void InputSetFOV( inputdata_t &inputdata );
|
||||
void InputSetFOVRate( inputdata_t &inputdata );
|
||||
#endif
|
||||
|
||||
private:
|
||||
EHANDLE m_hPlayer;
|
||||
EHANDLE m_hTarget;
|
||||
|
||||
// used for moving the camera along a path (rail rides)
|
||||
CBaseEntity *m_pPath;
|
||||
string_t m_sPath;
|
||||
float m_flWait;
|
||||
float m_flReturnTime;
|
||||
float m_flStopTime;
|
||||
float m_moveDistance;
|
||||
float m_targetSpeed;
|
||||
float m_initialSpeed;
|
||||
float m_acceleration;
|
||||
float m_deceleration;
|
||||
int m_state;
|
||||
Vector m_vecMoveDir;
|
||||
|
||||
#ifdef MAPBASE
|
||||
float m_fov;
|
||||
float m_fovSpeed;
|
||||
|
||||
bool m_bDontSetPlayerView;
|
||||
#endif
|
||||
|
||||
string_t m_iszTargetAttachment;
|
||||
int m_iAttachmentIndex;
|
||||
bool m_bSnapToGoal;
|
||||
|
||||
#if HL2_EPISODIC
|
||||
bool m_bInterpolatePosition;
|
||||
|
||||
// these are interpolation vars used for interpolating the camera over time
|
||||
Vector m_vStartPos, m_vEndPos;
|
||||
float m_flInterpStartTime;
|
||||
|
||||
const static float kflPosInterpTime; // seconds
|
||||
#endif
|
||||
|
||||
int m_nPlayerButtons;
|
||||
int m_nOldTakeDamage;
|
||||
|
||||
private:
|
||||
COutputEvent m_OnEndFollow;
|
||||
#ifdef MAPBASE
|
||||
COutputEvent m_OnStartFollow;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // TRIGGERS_H
|
||||
|
@ -1959,7 +1959,7 @@ extern "C" void Sys_Error( char *error, ... )
|
||||
// *mapData - pointer a block of entity map data
|
||||
// Output : -1 if the entity was not successfully created; 0 on success
|
||||
//-----------------------------------------------------------------------------
|
||||
int DispatchSpawn( CBaseEntity *pEntity )
|
||||
int DispatchSpawn( CBaseEntity *pEntity, bool bRunVScripts )
|
||||
{
|
||||
if ( pEntity )
|
||||
{
|
||||
@ -1974,6 +1974,12 @@ int DispatchSpawn( CBaseEntity *pEntity )
|
||||
//pEntity->SetAbsMins( pEntity->GetOrigin() - Vector(1,1,1) );
|
||||
//pEntity->SetAbsMaxs( pEntity->GetOrigin() + Vector(1,1,1) );
|
||||
|
||||
if (bRunVScripts)
|
||||
{
|
||||
pEntity->RunVScripts();
|
||||
pEntity->RunPrecacheScripts();
|
||||
}
|
||||
|
||||
#if defined(TRACK_ENTITY_MEMORY) && defined(USE_MEM_DEBUG)
|
||||
const char *pszClassname = NULL;
|
||||
int iClassname = ((CEntityFactoryDictionary*)EntityFactoryDictionary())->m_Factories.Find( pEntity->GetClassname() );
|
||||
@ -2040,6 +2046,11 @@ int DispatchSpawn( CBaseEntity *pEntity )
|
||||
}
|
||||
|
||||
gEntList.NotifySpawn( pEntity );
|
||||
|
||||
if( bRunVScripts )
|
||||
{
|
||||
pEntity->RunOnPostSpawnScripts();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -237,6 +237,24 @@ CBasePlayer* UTIL_GetLocalPlayer( void );
|
||||
// get the local player on a listen server
|
||||
CBasePlayer *UTIL_GetListenServerHost( void );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Convenience function so we don't have to make this check all over
|
||||
//-----------------------------------------------------------------------------
|
||||
static CBasePlayer * UTIL_GetLocalPlayerOrListenServerHost( void )
|
||||
{
|
||||
if ( gpGlobals->maxClients > 1 )
|
||||
{
|
||||
if ( engine->IsDedicatedServer() )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return UTIL_GetListenServerHost();
|
||||
}
|
||||
|
||||
return UTIL_GetLocalPlayer();
|
||||
}
|
||||
|
||||
CBasePlayer* UTIL_PlayerByUserId( int userID );
|
||||
CBasePlayer* UTIL_PlayerByName( const char *name ); // not case sensitive
|
||||
|
||||
|
@ -65,6 +65,22 @@ const char *variant_t::GetDebug()
|
||||
return UTIL_VarArgs("%s (%s)", String(), fieldtype);
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
void variant_t::SetScriptVariant( ScriptVariant_t &var )
|
||||
{
|
||||
switch (FieldType())
|
||||
{
|
||||
case FIELD_INTEGER: var = Int(); break;
|
||||
case FIELD_FLOAT: var = Float(); break;
|
||||
case FIELD_STRING: var = String(); break;
|
||||
case FIELD_POSITION_VECTOR:
|
||||
case FIELD_VECTOR: var = reinterpret_cast<Vector*>(&flVal); break; // HACKHACK
|
||||
case FIELD_BOOLEAN: var = Bool(); break;
|
||||
case FIELD_EHANDLE: var = ToHScript( Entity() ); break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// cmp1 = val1 float
|
||||
// cmp2 = val2 float
|
||||
#define VariantToFloat(val1, val2, lenallowed) \
|
||||
|
@ -17,6 +17,10 @@
|
||||
|
||||
class CBaseEntity;
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
struct ScriptVariant_t;
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// A variant class for passing data in entity input/output connections.
|
||||
@ -80,6 +84,10 @@ public:
|
||||
const char *GetDebug();
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
void SetScriptVariant( ScriptVariant_t &var );
|
||||
#endif
|
||||
|
||||
static typedescription_t m_SaveBool[];
|
||||
static typedescription_t m_SaveInt[];
|
||||
static typedescription_t m_SaveFloat[];
|
||||
|
@ -66,6 +66,15 @@ BEGIN_DATADESC( CPropVehicle )
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
BEGIN_ENT_SCRIPTDESC( CPropVehicle, CBaseAnimating, "The base class for four-wheel physics vehicles." )
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetVehicleType, "GetVehicleType", "Get a vehicle's type." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetPhysics, "GetPhysics", "Get a vehicle's physics." )
|
||||
|
||||
END_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
LINK_ENTITY_TO_CLASS( prop_vehicle, CPropVehicle );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -226,6 +235,23 @@ void CPropVehicle::InputHandBrakeOff( inputdata_t &inputdata )
|
||||
m_VehiclePhysics.ReleaseHandbrake();
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CPropVehicle::ScriptGetPhysics()
|
||||
{
|
||||
HSCRIPT hScript = NULL;
|
||||
CFourWheelVehiclePhysics *pPhysics = GetPhysics();
|
||||
if (pPhysics)
|
||||
{
|
||||
hScript = g_pScriptVM->RegisterInstance( pPhysics );
|
||||
}
|
||||
|
||||
return hScript;
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -379,6 +405,19 @@ BEGIN_DATADESC( CPropVehicleDriveable )
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
BEGIN_ENT_SCRIPTDESC( CPropVehicleDriveable, CPropVehicle, "The base class for driveable vehicles." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( IsOverturned, "Check if the vehicle is overturned." )
|
||||
DEFINE_SCRIPTFUNC( IsVehicleBodyInWater, "Check if the vehicle's body is submerged in water." )
|
||||
DEFINE_SCRIPTFUNC( StartEngine, "Start the engine." )
|
||||
DEFINE_SCRIPTFUNC( StopEngine, "Stop the engine." )
|
||||
DEFINE_SCRIPTFUNC( IsEngineOn, "Check if the engine is on." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetDriver, "GetDriver", "Get a vehicle's driver, which could be either a player or a npc_vehicledriver." )
|
||||
|
||||
END_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
|
||||
LINK_ENTITY_TO_CLASS( prop_vehicle_driveable, CPropVehicleDriveable );
|
||||
|
||||
|
@ -109,6 +109,12 @@ public:
|
||||
void InputHandBrakeOff( inputdata_t &inputdata );
|
||||
|
||||
DECLARE_DATADESC();
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DECLARE_ENT_SCRIPTDESC();
|
||||
|
||||
HSCRIPT ScriptGetPhysics();
|
||||
int ScriptGetVehicleType() { return GetVehicleType(); }
|
||||
#endif
|
||||
|
||||
#ifdef HL2_EPISODIC
|
||||
void AddPhysicsChild( CBaseEntity *pChild );
|
||||
@ -166,6 +172,9 @@ class CPropVehicleDriveable : public CPropVehicle, public IDrivableVehicle, publ
|
||||
DECLARE_CLASS( CPropVehicleDriveable, CPropVehicle );
|
||||
DECLARE_SERVERCLASS();
|
||||
DECLARE_DATADESC();
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DECLARE_ENT_SCRIPTDESC();
|
||||
#endif
|
||||
public:
|
||||
CPropVehicleDriveable( void );
|
||||
~CPropVehicleDriveable( void );
|
||||
@ -238,6 +247,10 @@ public:
|
||||
// If this is a vehicle, returns the vehicle interface
|
||||
virtual IServerVehicle *GetServerVehicle() { return m_pServerVehicle; }
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
HSCRIPT ScriptGetDriver() { return ToHScript( GetDriver() ); }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool ShouldThink() { return ( GetDriver() != NULL ); }
|
||||
|
932
sp/src/game/server/vscript_server.cpp
Normal file
932
sp/src/game/server/vscript_server.cpp
Normal file
@ -0,0 +1,932 @@
|
||||
//========== Copyright © 2008, Valve Corporation, All rights reserved. ========
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "cbase.h"
|
||||
#include "vscript_server.h"
|
||||
#include "icommandline.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "tier1/fmtstr.h"
|
||||
#include "filesystem.h"
|
||||
#include "eventqueue.h"
|
||||
#include "characterset.h"
|
||||
#include "sceneentity.h" // for exposing scene precache function
|
||||
#include "isaverestore.h"
|
||||
#include "gamerules.h"
|
||||
#include "vscript_server.nut"
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
#include "world.h"
|
||||
#endif
|
||||
|
||||
extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * );
|
||||
|
||||
// #define VMPROFILE 1
|
||||
|
||||
#ifdef VMPROFILE
|
||||
|
||||
#define VMPROF_START float debugStartTime = Plat_FloatTime();
|
||||
#define VMPROF_SHOW( funcname, funcdesc ) DevMsg("***VSCRIPT PROFILE***: %s %s: %6.4f milliseconds\n", (##funcname), (##funcdesc), (Plat_FloatTime() - debugStartTime)*1000.0 );
|
||||
|
||||
#else // !VMPROFILE
|
||||
|
||||
#define VMPROF_START
|
||||
#define VMPROF_SHOW
|
||||
|
||||
#endif // VMPROFILE
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
class CScriptEntityIterator
|
||||
{
|
||||
public:
|
||||
HSCRIPT First() { return Next(NULL); }
|
||||
|
||||
HSCRIPT Next( HSCRIPT hStartEntity )
|
||||
{
|
||||
return ToHScript( gEntList.NextEnt( ToEnt( hStartEntity ) ) );
|
||||
}
|
||||
|
||||
HSCRIPT CreateByClassname( const char *className )
|
||||
{
|
||||
return ToHScript( CreateEntityByName( className ) );
|
||||
}
|
||||
|
||||
HSCRIPT FindByClassname( HSCRIPT hStartEntity, const char *szName )
|
||||
{
|
||||
return ToHScript( gEntList.FindEntityByClassname( ToEnt( hStartEntity ), szName ) );
|
||||
}
|
||||
|
||||
HSCRIPT FindByName( HSCRIPT hStartEntity, const char *szName )
|
||||
{
|
||||
return ToHScript( gEntList.FindEntityByName( ToEnt( hStartEntity ), szName ) );
|
||||
}
|
||||
|
||||
HSCRIPT FindInSphere( HSCRIPT hStartEntity, const Vector &vecCenter, float flRadius )
|
||||
{
|
||||
return ToHScript( gEntList.FindEntityInSphere( ToEnt( hStartEntity ), vecCenter, flRadius ) );
|
||||
}
|
||||
|
||||
HSCRIPT FindByTarget( HSCRIPT hStartEntity, const char *szName )
|
||||
{
|
||||
return ToHScript( gEntList.FindEntityByTarget( ToEnt( hStartEntity ), szName ) );
|
||||
}
|
||||
|
||||
HSCRIPT FindByModel( HSCRIPT hStartEntity, const char *szModelName )
|
||||
{
|
||||
return ToHScript( gEntList.FindEntityByModel( ToEnt( hStartEntity ), szModelName ) );
|
||||
}
|
||||
|
||||
HSCRIPT FindByNameNearest( const char *szName, const Vector &vecSrc, float flRadius )
|
||||
{
|
||||
return ToHScript( gEntList.FindEntityByNameNearest( szName, vecSrc, flRadius ) );
|
||||
}
|
||||
|
||||
HSCRIPT FindByNameWithin( HSCRIPT hStartEntity, const char *szName, const Vector &vecSrc, float flRadius )
|
||||
{
|
||||
return ToHScript( gEntList.FindEntityByNameWithin( ToEnt( hStartEntity ), szName, vecSrc, flRadius ) );
|
||||
}
|
||||
|
||||
HSCRIPT FindByClassnameNearest( const char *szName, const Vector &vecSrc, float flRadius )
|
||||
{
|
||||
return ToHScript( gEntList.FindEntityByClassnameNearest( szName, vecSrc, flRadius ) );
|
||||
}
|
||||
|
||||
HSCRIPT FindByClassnameWithin( HSCRIPT hStartEntity , const char *szName, const Vector &vecSrc, float flRadius )
|
||||
{
|
||||
return ToHScript( gEntList.FindEntityByClassnameWithin( ToEnt( hStartEntity ), szName, vecSrc, flRadius ) );
|
||||
}
|
||||
|
||||
private:
|
||||
} g_ScriptEntityIterator;
|
||||
|
||||
BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptEntityIterator, "CEntities", SCRIPT_SINGLETON "The global list of entities" )
|
||||
DEFINE_SCRIPTFUNC( First, "Begin an iteration over the list of entities" )
|
||||
DEFINE_SCRIPTFUNC( Next, "Continue an iteration over the list of entities, providing reference to a previously found entity" )
|
||||
DEFINE_SCRIPTFUNC( CreateByClassname, "Creates an entity by classname" )
|
||||
DEFINE_SCRIPTFUNC( FindByClassname, "Find entities by class name. Pass 'null' to start an iteration, or reference to a previously found entity to continue a search" )
|
||||
DEFINE_SCRIPTFUNC( FindByName, "Find entities by name. Pass 'null' to start an iteration, or reference to a previously found entity to continue a search" )
|
||||
DEFINE_SCRIPTFUNC( FindInSphere, "Find entities within a radius. Pass 'null' to start an iteration, or reference to a previously found entity to continue a search" )
|
||||
DEFINE_SCRIPTFUNC( FindByTarget, "Find entities by targetname. Pass 'null' to start an iteration, or reference to a previously found entity to continue a search" )
|
||||
DEFINE_SCRIPTFUNC( FindByModel, "Find entities by model name. Pass 'null' to start an iteration, or reference to a previously found entity to continue a search" )
|
||||
DEFINE_SCRIPTFUNC( FindByNameNearest, "Find entities by name nearest to a point." )
|
||||
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" )
|
||||
END_SCRIPTDESC();
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// KeyValues access - CBaseEntity::ScriptGetKeyFromModel returns root KeyValues
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
BEGIN_SCRIPTDESC_ROOT( CScriptKeyValues, "Wrapper class over KeyValues instance" )
|
||||
DEFINE_SCRIPT_CONSTRUCTOR()
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptFindKey, "FindKey", "Given a KeyValues object and a key name, find a KeyValues object associated with the key name" );
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetFirstSubKey, "GetFirstSubKey", "Given a KeyValues object, return the first sub key object" );
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetNextKey, "GetNextKey", "Given a KeyValues object, return the next key object in a sub key group" );
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetKeyValueInt, "GetKeyInt", "Given a KeyValues object and a key name, return associated integer value" );
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetKeyValueFloat, "GetKeyFloat", "Given a KeyValues object and a key name, return associated float value" );
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetKeyValueBool, "GetKeyBool", "Given a KeyValues object and a key name, return associated bool value" );
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetKeyValueString, "GetKeyString", "Given a KeyValues object and a key name, return associated string value" );
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptIsKeyValueEmpty, "IsKeyEmpty", "Given a KeyValues object and a key name, return true if key name has no value" );
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptReleaseKeyValues, "ReleaseKeyValues", "Given a root KeyValues object, release its contents" );
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetName, "GetName", "Given a KeyValues object, return its name" );
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetInt, "GetInt", "Given a KeyValues object, return its own associated integer value" );
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetFloat, "GetFloat", "Given a KeyValues object, return its own associated float value" );
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetString, "GetString", "Given a KeyValues object, return its own associated string value" );
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetBool, "GetBool", "Given a KeyValues object, return its own associated bool value" );
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetKeyValueInt, "SetKeyInt", "Given a KeyValues object and a key name, set associated integer value" );
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetKeyValueFloat, "SetKeyFloat", "Given a KeyValues object and a key name, set associated float value" );
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetKeyValueBool, "SetKeyBool", "Given a KeyValues object and a key name, set associated bool value" );
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetKeyValueString, "SetKeyString", "Given a KeyValues object and a key name, set associated string value" );
|
||||
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetName, "SetName", "Given a KeyValues object, set its name" );
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetInt, "SetInt", "Given a KeyValues object, set its own associated integer value" );
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetFloat, "SetFloat", "Given a KeyValues object, set its own associated float value" );
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetBool, "SetBool", "Given a KeyValues object, set its own associated bool value" );
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetString, "SetString", "Given a KeyValues object, set its own associated string value" );
|
||||
#endif
|
||||
END_SCRIPTDESC();
|
||||
|
||||
HSCRIPT CScriptKeyValues::ScriptFindKey( const char *pszName )
|
||||
{
|
||||
KeyValues *pKeyValues = m_pKeyValues->FindKey(pszName);
|
||||
if ( pKeyValues == NULL )
|
||||
return NULL;
|
||||
|
||||
CScriptKeyValues *pScriptKey = new CScriptKeyValues( pKeyValues );
|
||||
|
||||
// UNDONE: who calls ReleaseInstance on this??
|
||||
HSCRIPT hScriptInstance = g_pScriptVM->RegisterInstance( pScriptKey );
|
||||
return hScriptInstance;
|
||||
}
|
||||
|
||||
HSCRIPT CScriptKeyValues::ScriptGetFirstSubKey( void )
|
||||
{
|
||||
KeyValues *pKeyValues = m_pKeyValues->GetFirstSubKey();
|
||||
if ( pKeyValues == NULL )
|
||||
return NULL;
|
||||
|
||||
CScriptKeyValues *pScriptKey = new CScriptKeyValues( pKeyValues );
|
||||
|
||||
// UNDONE: who calls ReleaseInstance on this??
|
||||
HSCRIPT hScriptInstance = g_pScriptVM->RegisterInstance( pScriptKey );
|
||||
return hScriptInstance;
|
||||
}
|
||||
|
||||
HSCRIPT CScriptKeyValues::ScriptGetNextKey( void )
|
||||
{
|
||||
KeyValues *pKeyValues = m_pKeyValues->GetNextKey();
|
||||
if ( pKeyValues == NULL )
|
||||
return NULL;
|
||||
|
||||
CScriptKeyValues *pScriptKey = new CScriptKeyValues( pKeyValues );
|
||||
|
||||
// UNDONE: who calls ReleaseInstance on this??
|
||||
HSCRIPT hScriptInstance = g_pScriptVM->RegisterInstance( pScriptKey );
|
||||
return hScriptInstance;
|
||||
}
|
||||
|
||||
int CScriptKeyValues::ScriptGetKeyValueInt( const char *pszName )
|
||||
{
|
||||
int i = m_pKeyValues->GetInt( pszName );
|
||||
return i;
|
||||
}
|
||||
|
||||
float CScriptKeyValues::ScriptGetKeyValueFloat( const char *pszName )
|
||||
{
|
||||
float f = m_pKeyValues->GetFloat( pszName );
|
||||
return f;
|
||||
}
|
||||
|
||||
const char *CScriptKeyValues::ScriptGetKeyValueString( const char *pszName )
|
||||
{
|
||||
const char *psz = m_pKeyValues->GetString( pszName );
|
||||
return psz;
|
||||
}
|
||||
|
||||
bool CScriptKeyValues::ScriptIsKeyValueEmpty( const char *pszName )
|
||||
{
|
||||
bool b = m_pKeyValues->IsEmpty( pszName );
|
||||
return b;
|
||||
}
|
||||
|
||||
bool CScriptKeyValues::ScriptGetKeyValueBool( const char *pszName )
|
||||
{
|
||||
bool b = m_pKeyValues->GetBool( pszName );
|
||||
return b;
|
||||
}
|
||||
|
||||
void CScriptKeyValues::ScriptReleaseKeyValues( )
|
||||
{
|
||||
m_pKeyValues->deleteThis();
|
||||
m_pKeyValues = NULL;
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
const char *CScriptKeyValues::ScriptGetName()
|
||||
{
|
||||
const char *psz = m_pKeyValues->GetName();
|
||||
return psz;
|
||||
}
|
||||
|
||||
int CScriptKeyValues::ScriptGetInt()
|
||||
{
|
||||
int i = m_pKeyValues->GetInt();
|
||||
return i;
|
||||
}
|
||||
|
||||
float CScriptKeyValues::ScriptGetFloat()
|
||||
{
|
||||
float f = m_pKeyValues->GetFloat();
|
||||
return f;
|
||||
}
|
||||
|
||||
const char *CScriptKeyValues::ScriptGetString()
|
||||
{
|
||||
const char *psz = m_pKeyValues->GetString();
|
||||
return psz;
|
||||
}
|
||||
|
||||
bool CScriptKeyValues::ScriptGetBool()
|
||||
{
|
||||
bool b = m_pKeyValues->GetBool();
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
void CScriptKeyValues::ScriptSetKeyValueInt( const char *pszName, int iValue )
|
||||
{
|
||||
m_pKeyValues->SetInt( pszName, iValue );
|
||||
}
|
||||
|
||||
void CScriptKeyValues::ScriptSetKeyValueFloat( const char *pszName, float flValue )
|
||||
{
|
||||
m_pKeyValues->SetFloat( pszName, flValue );
|
||||
}
|
||||
|
||||
void CScriptKeyValues::ScriptSetKeyValueString( const char *pszName, const char *pszValue )
|
||||
{
|
||||
m_pKeyValues->SetString( pszName, pszValue );
|
||||
}
|
||||
|
||||
void CScriptKeyValues::ScriptSetKeyValueBool( const char *pszName, bool bValue )
|
||||
{
|
||||
m_pKeyValues->SetBool( pszName, bValue );
|
||||
}
|
||||
|
||||
void CScriptKeyValues::ScriptSetName( const char *pszValue )
|
||||
{
|
||||
m_pKeyValues->SetName( pszValue );
|
||||
}
|
||||
|
||||
void CScriptKeyValues::ScriptSetInt( int iValue )
|
||||
{
|
||||
m_pKeyValues->SetInt( NULL, iValue );
|
||||
}
|
||||
|
||||
void CScriptKeyValues::ScriptSetFloat( float flValue )
|
||||
{
|
||||
m_pKeyValues->SetFloat( NULL, flValue );
|
||||
}
|
||||
|
||||
void CScriptKeyValues::ScriptSetString( const char *pszValue )
|
||||
{
|
||||
m_pKeyValues->SetString( NULL, pszValue );
|
||||
}
|
||||
|
||||
void CScriptKeyValues::ScriptSetBool( bool bValue )
|
||||
{
|
||||
m_pKeyValues->SetBool( NULL, bValue );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// constructors
|
||||
CScriptKeyValues::CScriptKeyValues( KeyValues *pKeyValues = NULL )
|
||||
{
|
||||
m_pKeyValues = pKeyValues;
|
||||
}
|
||||
|
||||
// destructor
|
||||
CScriptKeyValues::~CScriptKeyValues( )
|
||||
{
|
||||
if (m_pKeyValues)
|
||||
{
|
||||
m_pKeyValues->deleteThis();
|
||||
}
|
||||
m_pKeyValues = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
static float Time()
|
||||
{
|
||||
return gpGlobals->curtime;
|
||||
}
|
||||
|
||||
static float FrameTime()
|
||||
{
|
||||
return gpGlobals->frametime;
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
static int MaxPlayers()
|
||||
{
|
||||
return gpGlobals->maxClients;
|
||||
}
|
||||
|
||||
static float IntervalPerTick()
|
||||
{
|
||||
return gpGlobals->interval_per_tick;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void SendToConsole( const char *pszCommand )
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_GetLocalPlayerOrListenServerHost();
|
||||
if ( !pPlayer )
|
||||
{
|
||||
DevMsg ("Cannot execute \"%s\", no player\n", pszCommand );
|
||||
return;
|
||||
}
|
||||
|
||||
engine->ClientCommand( pPlayer->edict(), pszCommand );
|
||||
}
|
||||
|
||||
static const char *GetMapName()
|
||||
{
|
||||
return STRING( gpGlobals->mapname );
|
||||
}
|
||||
|
||||
static const char *DoUniqueString( const char *pszBase )
|
||||
{
|
||||
static char szBuf[512];
|
||||
g_pScriptVM->GenerateUniqueKey( pszBase, szBuf, ARRAYSIZE(szBuf) );
|
||||
return szBuf;
|
||||
}
|
||||
|
||||
static void DoEntFire( const char *pszTarget, const char *pszAction, const char *pszValue, float delay, HSCRIPT hActivator, HSCRIPT hCaller )
|
||||
{
|
||||
const char *target = "", *action = "Use";
|
||||
variant_t value;
|
||||
|
||||
target = STRING( AllocPooledString( pszTarget ) );
|
||||
|
||||
// Don't allow them to run anything on a point_servercommand unless they're the host player. Otherwise they can ent_fire
|
||||
// and run any command on the server. Admittedly, they can only do the ent_fire if sv_cheats is on, but
|
||||
// people complained about users resetting the rcon password if the server briefly turned on cheats like this:
|
||||
// give point_servercommand
|
||||
// ent_fire point_servercommand command "rcon_password mynewpassword"
|
||||
if ( gpGlobals->maxClients > 1 && V_stricmp( target, "point_servercommand" ) == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( *pszAction )
|
||||
{
|
||||
action = STRING( AllocPooledString( pszAction ) );
|
||||
}
|
||||
if ( *pszValue )
|
||||
{
|
||||
value.SetString( AllocPooledString( pszValue ) );
|
||||
}
|
||||
if ( delay < 0 )
|
||||
{
|
||||
delay = 0;
|
||||
}
|
||||
|
||||
g_EventQueue.AddEvent( target, action, value, delay, ToEnt(hActivator), ToEnt(hCaller) );
|
||||
}
|
||||
|
||||
|
||||
bool DoIncludeScript( const char *pszScript, HSCRIPT hScope )
|
||||
{
|
||||
if ( !VScriptRunScript( pszScript, hScope, true ) )
|
||||
{
|
||||
g_pScriptVM->RaiseException( CFmtStr( "Failed to include script \"%s\"", ( pszScript ) ? pszScript : "unknown" ) );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
HSCRIPT CreateProp( const char *pszEntityName, const Vector &vOrigin, const char *pszModelName, int iAnim )
|
||||
{
|
||||
CBaseAnimating *pBaseEntity = (CBaseAnimating *)CreateEntityByName( pszEntityName );
|
||||
pBaseEntity->SetAbsOrigin( vOrigin );
|
||||
pBaseEntity->SetModel( pszModelName );
|
||||
pBaseEntity->SetPlaybackRate( 1.0f );
|
||||
|
||||
int iSequence = pBaseEntity->SelectWeightedSequence( (Activity)iAnim );
|
||||
|
||||
if ( iSequence != -1 )
|
||||
{
|
||||
pBaseEntity->SetSequence( iSequence );
|
||||
}
|
||||
|
||||
return ToHScript( pBaseEntity );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Use an entity's script instance to add an entity IO event (used for firing events on unnamed entities from vscript)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
static void DoEntFireByInstanceHandle( HSCRIPT hTarget, const char *pszAction, const char *pszValue, float delay, HSCRIPT hActivator, HSCRIPT hCaller )
|
||||
{
|
||||
const char *action = "Use";
|
||||
variant_t value;
|
||||
|
||||
if ( *pszAction )
|
||||
{
|
||||
action = STRING( AllocPooledString( pszAction ) );
|
||||
}
|
||||
if ( *pszValue )
|
||||
{
|
||||
value.SetString( AllocPooledString( pszValue ) );
|
||||
}
|
||||
if ( delay < 0 )
|
||||
{
|
||||
delay = 0;
|
||||
}
|
||||
|
||||
CBaseEntity* pTarget = ToEnt(hTarget);
|
||||
|
||||
if ( !pTarget )
|
||||
{
|
||||
Warning( "VScript error: DoEntFire was passed an invalid entity instance.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
g_EventQueue.AddEvent( pTarget, action, value, delay, ToEnt(hActivator), ToEnt(hCaller) );
|
||||
}
|
||||
|
||||
static float ScriptTraceLine( const Vector &vecStart, const Vector &vecEnd, HSCRIPT entIgnore )
|
||||
{
|
||||
// UTIL_TraceLine( vecAbsStart, vecAbsEnd, MASK_BLOCKLOS, pLooker, COLLISION_GROUP_NONE, ptr );
|
||||
trace_t tr;
|
||||
CBaseEntity *pLooker = ToEnt(entIgnore);
|
||||
UTIL_TraceLine( vecStart, vecEnd, MASK_NPCWORLDSTATIC, pLooker, COLLISION_GROUP_NONE, &tr);
|
||||
if (tr.fractionleftsolid && tr.startsolid)
|
||||
{
|
||||
return 1.0 - tr.fractionleftsolid;
|
||||
}
|
||||
else
|
||||
{
|
||||
return tr.fraction;
|
||||
}
|
||||
}
|
||||
|
||||
bool VScriptServerInit()
|
||||
{
|
||||
VMPROF_START
|
||||
|
||||
if( scriptmanager != NULL )
|
||||
{
|
||||
ScriptLanguage_t scriptLanguage = SL_DEFAULT;
|
||||
|
||||
char const *pszScriptLanguage;
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
if (GetWorldEntity()->GetScriptLanguage() != SL_NONE)
|
||||
{
|
||||
// Allow world entity to override script language
|
||||
scriptLanguage = GetWorldEntity()->GetScriptLanguage();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if ( CommandLine()->CheckParm( "-scriptlang", &pszScriptLanguage ) )
|
||||
{
|
||||
if( !Q_stricmp(pszScriptLanguage, "gamemonkey") )
|
||||
{
|
||||
scriptLanguage = SL_GAMEMONKEY;
|
||||
}
|
||||
else if( !Q_stricmp(pszScriptLanguage, "squirrel") )
|
||||
{
|
||||
scriptLanguage = SL_SQUIRREL;
|
||||
}
|
||||
else if( !Q_stricmp(pszScriptLanguage, "python") )
|
||||
{
|
||||
scriptLanguage = SL_PYTHON;
|
||||
}
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
else if( !Q_stricmp(pszScriptLanguage, "lua") )
|
||||
{
|
||||
scriptLanguage = SL_LUA;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
DevWarning("-server_script does not recognize a language named '%s'. virtual machine did NOT start.\n", pszScriptLanguage );
|
||||
scriptLanguage = SL_NONE;
|
||||
}
|
||||
|
||||
}
|
||||
if( scriptLanguage != SL_NONE )
|
||||
{
|
||||
if ( g_pScriptVM == NULL )
|
||||
g_pScriptVM = scriptmanager->CreateVM( scriptLanguage );
|
||||
|
||||
if( g_pScriptVM )
|
||||
{
|
||||
Log( "VSCRIPT: Started VScript virtual machine using script language '%s'\n", g_pScriptVM->GetLanguageName() );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, UTIL_ShowMessageAll, "ShowMessage", "Print a hud message on all clients" );
|
||||
|
||||
ScriptRegisterFunction( g_pScriptVM, SendToConsole, "Send a string to the console as a command" );
|
||||
ScriptRegisterFunction( g_pScriptVM, GetMapName, "Get the name of the map.");
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptTraceLine, "TraceLine", "given 2 points & ent to ignore, return fraction along line that hits world or models" );
|
||||
|
||||
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, 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." ) );
|
||||
#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." );
|
||||
#endif
|
||||
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. Useful for adding data to tables when not sure what keys are already in use in that table." ) );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCreateSceneEntity, "CreateSceneEntity", "Create a scene entity to play the specified scene." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, NDebugOverlay::Box, "DebugDrawBox", "Draw a debug overlay box" );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, NDebugOverlay::Line, "DebugDrawLine", "Draw a debug overlay box" );
|
||||
ScriptRegisterFunction( g_pScriptVM, DoIncludeScript, "Execute a script (internal)" );
|
||||
ScriptRegisterFunction( g_pScriptVM, CreateProp, "Create a physics prop" );
|
||||
|
||||
|
||||
if ( GameRules() )
|
||||
{
|
||||
GameRules()->RegisterScriptFunctions();
|
||||
}
|
||||
|
||||
g_pScriptVM->RegisterInstance( &g_ScriptEntityIterator, "Entities" );
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
IGameSystem::RegisterVScriptAllSystems();
|
||||
|
||||
RegisterSharedScriptFunctions();
|
||||
#endif
|
||||
|
||||
if (scriptLanguage == SL_SQUIRREL)
|
||||
{
|
||||
g_pScriptVM->Run( g_Script_vscript_server );
|
||||
}
|
||||
|
||||
VScriptRunScript( "mapspawn", false );
|
||||
|
||||
VMPROF_SHOW( pszScriptLanguage, "virtual machine startup" );
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
DevWarning("VM Did not start!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log( "\nVSCRIPT: Scripting is disabled.\n" );
|
||||
}
|
||||
g_pScriptVM = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
void VScriptServerTerm()
|
||||
{
|
||||
if( g_pScriptVM != NULL )
|
||||
{
|
||||
if( g_pScriptVM )
|
||||
{
|
||||
scriptmanager->DestroyVM( g_pScriptVM );
|
||||
g_pScriptVM = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool VScriptServerReplaceClosures( const char *pszScriptName, HSCRIPT hScope, bool bWarnMissing )
|
||||
{
|
||||
if ( !g_pScriptVM )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
HSCRIPT hReplaceClosuresFunc = g_pScriptVM->LookupFunction( "__ReplaceClosures" );
|
||||
if ( !hReplaceClosuresFunc )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
HSCRIPT hNewScript = VScriptCompileScript( pszScriptName, bWarnMissing );
|
||||
if ( !hNewScript )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
g_pScriptVM->Call( hReplaceClosuresFunc, NULL, true, NULL, hNewScript, hScope );
|
||||
return true;
|
||||
}
|
||||
|
||||
CON_COMMAND( script_reload_code, "Execute a vscript file, replacing existing functions with the functions in the run script" )
|
||||
{
|
||||
if ( !*args[1] )
|
||||
{
|
||||
Warning( "No script specified\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !g_pScriptVM )
|
||||
{
|
||||
Warning( "Scripting disabled or no server running\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
VScriptServerReplaceClosures( args[1], NULL, true );
|
||||
}
|
||||
|
||||
CON_COMMAND( script_reload_entity_code, "Execute all of this entity's VScripts, replacing existing functions with the functions in the run scripts" )
|
||||
{
|
||||
extern CBaseEntity *GetNextCommandEntity( CBasePlayer *pPlayer, const char *name, CBaseEntity *ent );
|
||||
|
||||
const char *pszTarget = "";
|
||||
if ( *args[1] )
|
||||
{
|
||||
pszTarget = args[1];
|
||||
}
|
||||
|
||||
if ( !g_pScriptVM )
|
||||
{
|
||||
Warning( "Scripting disabled or no server running\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
CBasePlayer *pPlayer = UTIL_GetCommandClient();
|
||||
if ( !pPlayer )
|
||||
return;
|
||||
|
||||
CBaseEntity *pEntity = NULL;
|
||||
while ( (pEntity = GetNextCommandEntity( pPlayer, pszTarget, pEntity )) != NULL )
|
||||
{
|
||||
if ( pEntity->m_ScriptScope.IsInitialized() && pEntity->m_iszVScripts != NULL_STRING )
|
||||
{
|
||||
char szScriptsList[255];
|
||||
Q_strcpy( szScriptsList, STRING(pEntity->m_iszVScripts) );
|
||||
CUtlStringList szScripts;
|
||||
V_SplitString( szScriptsList, " ", szScripts);
|
||||
|
||||
for( int i = 0 ; i < szScripts.Count() ; i++ )
|
||||
{
|
||||
VScriptServerReplaceClosures( szScripts[i], pEntity->m_ScriptScope, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CON_COMMAND( script_reload_think, "Execute an activation script, replacing existing functions with the functions in the run script" )
|
||||
{
|
||||
extern CBaseEntity *GetNextCommandEntity( CBasePlayer *pPlayer, const char *name, CBaseEntity *ent );
|
||||
|
||||
const char *pszTarget = "";
|
||||
if ( *args[1] )
|
||||
{
|
||||
pszTarget = args[1];
|
||||
}
|
||||
|
||||
if ( !g_pScriptVM )
|
||||
{
|
||||
Warning( "Scripting disabled or no server running\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
CBasePlayer *pPlayer = UTIL_GetCommandClient();
|
||||
if ( !pPlayer )
|
||||
return;
|
||||
|
||||
CBaseEntity *pEntity = NULL;
|
||||
while ( (pEntity = GetNextCommandEntity( pPlayer, pszTarget, pEntity )) != NULL )
|
||||
{
|
||||
if ( pEntity->m_ScriptScope.IsInitialized() && pEntity->m_iszScriptThinkFunction != NULL_STRING )
|
||||
{
|
||||
VScriptServerReplaceClosures( STRING(pEntity->m_iszScriptThinkFunction), pEntity->m_ScriptScope, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CVScriptGameSystem : public CAutoGameSystemPerFrame
|
||||
{
|
||||
public:
|
||||
// Inherited from IAutoServerSystem
|
||||
virtual void LevelInitPreEntity( void )
|
||||
{
|
||||
m_bAllowEntityCreationInScripts = true;
|
||||
VScriptServerInit();
|
||||
}
|
||||
|
||||
virtual void LevelInitPostEntity( void )
|
||||
{
|
||||
m_bAllowEntityCreationInScripts = false;
|
||||
}
|
||||
|
||||
virtual void LevelShutdownPostEntity( void )
|
||||
{
|
||||
VScriptServerTerm();
|
||||
}
|
||||
|
||||
virtual void FrameUpdatePostEntityThink()
|
||||
{
|
||||
if ( g_pScriptVM )
|
||||
g_pScriptVM->Frame( gpGlobals->frametime );
|
||||
}
|
||||
|
||||
bool m_bAllowEntityCreationInScripts;
|
||||
};
|
||||
|
||||
CVScriptGameSystem g_VScriptGameSystem;
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
ConVar script_allow_entity_creation_midgame( "script_allow_entity_creation_midgame", "1", FCVAR_NOT_CONNECTED, "Allows VScript files to create entities mid-game, as opposed to only creating entities on startup." );
|
||||
#endif
|
||||
|
||||
bool IsEntityCreationAllowedInScripts( void )
|
||||
{
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
if (script_allow_entity_creation_midgame.GetBool())
|
||||
return true;
|
||||
#endif
|
||||
|
||||
return g_VScriptGameSystem.m_bAllowEntityCreationInScripts;
|
||||
}
|
||||
|
||||
static short VSCRIPT_SERVER_SAVE_RESTORE_VERSION = 2;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class CVScriptSaveRestoreBlockHandler : public CDefSaveRestoreBlockHandler
|
||||
{
|
||||
public:
|
||||
CVScriptSaveRestoreBlockHandler() :
|
||||
m_InstanceMap( DefLessFunc(const char *) )
|
||||
{
|
||||
}
|
||||
const char *GetBlockName()
|
||||
{
|
||||
return "VScriptServer";
|
||||
}
|
||||
|
||||
//---------------------------------
|
||||
|
||||
void Save( ISave *pSave )
|
||||
{
|
||||
pSave->StartBlock();
|
||||
|
||||
int temp = g_pScriptVM != NULL;
|
||||
pSave->WriteInt( &temp );
|
||||
if ( g_pScriptVM )
|
||||
{
|
||||
temp = g_pScriptVM->GetLanguage();
|
||||
pSave->WriteInt( &temp );
|
||||
CUtlBuffer buffer;
|
||||
g_pScriptVM->WriteState( &buffer );
|
||||
temp = buffer.TellPut();
|
||||
pSave->WriteInt( &temp );
|
||||
if ( temp > 0 )
|
||||
{
|
||||
pSave->WriteData( (const char *)buffer.Base(), temp );
|
||||
}
|
||||
}
|
||||
|
||||
pSave->EndBlock();
|
||||
}
|
||||
|
||||
//---------------------------------
|
||||
|
||||
void WriteSaveHeaders( ISave *pSave )
|
||||
{
|
||||
pSave->WriteShort( &VSCRIPT_SERVER_SAVE_RESTORE_VERSION );
|
||||
}
|
||||
|
||||
//---------------------------------
|
||||
|
||||
void ReadRestoreHeaders( IRestore *pRestore )
|
||||
{
|
||||
// No reason why any future version shouldn't try to retain backward compatability. The default here is to not do so.
|
||||
short version;
|
||||
pRestore->ReadShort( &version );
|
||||
m_fDoLoad = ( version == VSCRIPT_SERVER_SAVE_RESTORE_VERSION );
|
||||
}
|
||||
|
||||
//---------------------------------
|
||||
|
||||
void Restore( IRestore *pRestore, bool createPlayers )
|
||||
{
|
||||
if ( !m_fDoLoad && g_pScriptVM )
|
||||
{
|
||||
return;
|
||||
}
|
||||
CBaseEntity *pEnt = gEntList.FirstEnt();
|
||||
while ( pEnt )
|
||||
{
|
||||
if ( pEnt->m_iszScriptId != NULL_STRING )
|
||||
{
|
||||
g_pScriptVM->RegisterClass( pEnt->GetScriptDesc() );
|
||||
m_InstanceMap.Insert( STRING( pEnt->m_iszScriptId ), pEnt );
|
||||
}
|
||||
pEnt = gEntList.NextEnt( pEnt );
|
||||
}
|
||||
|
||||
pRestore->StartBlock();
|
||||
if ( pRestore->ReadInt() && pRestore->ReadInt() == g_pScriptVM->GetLanguage() )
|
||||
{
|
||||
int nBytes = pRestore->ReadInt();
|
||||
if ( nBytes > 0 )
|
||||
{
|
||||
CUtlBuffer buffer;
|
||||
buffer.EnsureCapacity( nBytes );
|
||||
pRestore->ReadData( (char *)buffer.AccessForDirectRead( nBytes ), nBytes, 0 );
|
||||
g_pScriptVM->ReadState( &buffer );
|
||||
}
|
||||
}
|
||||
pRestore->EndBlock();
|
||||
}
|
||||
|
||||
void PostRestore( void )
|
||||
{
|
||||
for ( int i = m_InstanceMap.FirstInorder(); i != m_InstanceMap.InvalidIndex(); i = m_InstanceMap.NextInorder( i ) )
|
||||
{
|
||||
CBaseEntity *pEnt = m_InstanceMap[i];
|
||||
if ( pEnt->m_hScriptInstance )
|
||||
{
|
||||
ScriptVariant_t variant;
|
||||
if ( g_pScriptVM->GetValue( STRING(pEnt->m_iszScriptId), &variant ) && variant.m_type == FIELD_HSCRIPT )
|
||||
{
|
||||
pEnt->m_ScriptScope.Init( variant.m_hScript, false );
|
||||
pEnt->RunPrecacheScripts();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Script system probably has no internal references
|
||||
pEnt->m_iszScriptId = NULL_STRING;
|
||||
}
|
||||
}
|
||||
m_InstanceMap.Purge();
|
||||
}
|
||||
|
||||
|
||||
CUtlMap<const char *, CBaseEntity *> m_InstanceMap;
|
||||
|
||||
private:
|
||||
bool m_fDoLoad;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CVScriptSaveRestoreBlockHandler g_VScriptSaveRestoreBlockHandler;
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
ISaveRestoreBlockHandler *GetVScriptSaveRestoreBlockHandler()
|
||||
{
|
||||
return &g_VScriptSaveRestoreBlockHandler;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool CBaseEntityScriptInstanceHelper::ToString( void *p, char *pBuf, int bufSize )
|
||||
{
|
||||
CBaseEntity *pEntity = (CBaseEntity *)p;
|
||||
if ( pEntity->GetEntityName() != NULL_STRING )
|
||||
{
|
||||
V_snprintf( pBuf, bufSize, "([%d] %s: %s)", pEntity->entindex(), STRING(pEntity->m_iClassname), STRING( pEntity->GetEntityName() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
V_snprintf( pBuf, bufSize, "([%d] %s)", pEntity->entindex(), STRING(pEntity->m_iClassname) );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void *CBaseEntityScriptInstanceHelper::BindOnRead( HSCRIPT hInstance, void *pOld, const char *pszId )
|
||||
{
|
||||
int iEntity = g_VScriptSaveRestoreBlockHandler.m_InstanceMap.Find( pszId );
|
||||
if ( iEntity != g_VScriptSaveRestoreBlockHandler.m_InstanceMap.InvalidIndex() )
|
||||
{
|
||||
CBaseEntity *pEnt = g_VScriptSaveRestoreBlockHandler.m_InstanceMap[iEntity];
|
||||
pEnt->m_hScriptInstance = hInstance;
|
||||
return pEnt;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
CBaseEntityScriptInstanceHelper g_BaseEntityScriptInstanceHelper;
|
||||
|
||||
|
74
sp/src/game/server/vscript_server.h
Normal file
74
sp/src/game/server/vscript_server.h
Normal file
@ -0,0 +1,74 @@
|
||||
//========== Copyright © 2008, Valve Corporation, All rights reserved. ========
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef VSCRIPT_SERVER_H
|
||||
#define VSCRIPT_SERVER_H
|
||||
|
||||
#include "vscript/ivscript.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "vscript_shared.h"
|
||||
|
||||
#if defined( _WIN32 )
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class ISaveRestoreBlockHandler;
|
||||
|
||||
bool VScriptServerReplaceClosures( const char *pszScriptName, HSCRIPT hScope, bool bWarnMissing = false );
|
||||
ISaveRestoreBlockHandler *GetVScriptSaveRestoreBlockHandler();
|
||||
|
||||
|
||||
class CBaseEntityScriptInstanceHelper : public IScriptInstanceHelper
|
||||
{
|
||||
bool ToString( void *p, char *pBuf, int bufSize );
|
||||
void *BindOnRead( HSCRIPT hInstance, void *pOld, const char *pszId );
|
||||
};
|
||||
|
||||
extern CBaseEntityScriptInstanceHelper g_BaseEntityScriptInstanceHelper;
|
||||
|
||||
// Only allow scripts to create entities during map initialization
|
||||
bool IsEntityCreationAllowedInScripts( void );
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// KeyValues access
|
||||
// ----------------------------------------------------------------------------
|
||||
class CScriptKeyValues
|
||||
{
|
||||
public:
|
||||
CScriptKeyValues( KeyValues *pKeyValues );
|
||||
~CScriptKeyValues( );
|
||||
|
||||
HSCRIPT ScriptFindKey( const char *pszName );
|
||||
HSCRIPT ScriptGetFirstSubKey( void );
|
||||
HSCRIPT ScriptGetNextKey( void );
|
||||
int ScriptGetKeyValueInt( const char *pszName );
|
||||
float ScriptGetKeyValueFloat( const char *pszName );
|
||||
const char *ScriptGetKeyValueString( const char *pszName );
|
||||
bool ScriptIsKeyValueEmpty( const char *pszName );
|
||||
bool ScriptGetKeyValueBool( const char *pszName );
|
||||
void ScriptReleaseKeyValues( );
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
const char *ScriptGetName();
|
||||
int ScriptGetInt();
|
||||
float ScriptGetFloat();
|
||||
const char *ScriptGetString();
|
||||
bool ScriptGetBool();
|
||||
|
||||
void ScriptSetKeyValueInt( const char *pszName, int iValue );
|
||||
void ScriptSetKeyValueFloat( const char *pszName, float flValue );
|
||||
void ScriptSetKeyValueString( const char *pszName, const char *pszValue );
|
||||
void ScriptSetKeyValueBool( const char *pszName, bool bValue );
|
||||
void ScriptSetName( const char *pszValue );
|
||||
void ScriptSetInt( int iValue );
|
||||
void ScriptSetFloat( float flValue );
|
||||
void ScriptSetString( const char *pszValue );
|
||||
void ScriptSetBool( bool bValue );
|
||||
#endif
|
||||
|
||||
KeyValues *m_pKeyValues; // actual KeyValue entity
|
||||
};
|
||||
|
||||
#endif // VSCRIPT_SERVER_H
|
155
sp/src/game/server/vscript_server.nut
Normal file
155
sp/src/game/server/vscript_server.nut
Normal file
@ -0,0 +1,155 @@
|
||||
static char g_Script_vscript_server[] = R"vscript(
|
||||
//========== Copyright © 2008, Valve Corporation, All rights reserved. ========
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
function UniqueString( string = "" )
|
||||
{
|
||||
return DoUniqueString( string.tostring() );
|
||||
}
|
||||
|
||||
function EntFire( target, action, value = null, delay = 0.0, activator = null, caller = null )
|
||||
{
|
||||
if ( !value )
|
||||
{
|
||||
value = "";
|
||||
}
|
||||
|
||||
if ( "self" in this )
|
||||
{
|
||||
if ( !caller )
|
||||
{
|
||||
caller = self;
|
||||
}
|
||||
|
||||
if ( !activator )
|
||||
{
|
||||
activator = self;
|
||||
}
|
||||
}
|
||||
|
||||
DoEntFire( target.tostring(), action.tostring(), value.tostring(), delay, activator, caller );
|
||||
}
|
||||
|
||||
function EntFireByHandle( target, action, value = null, delay = 0.0, activator = null, caller = null )
|
||||
{
|
||||
if ( !value )
|
||||
{
|
||||
value = "";
|
||||
}
|
||||
|
||||
if ( "self" in this )
|
||||
{
|
||||
if ( !caller )
|
||||
{
|
||||
caller = self;
|
||||
}
|
||||
|
||||
if ( !activator )
|
||||
{
|
||||
activator = self;
|
||||
}
|
||||
}
|
||||
|
||||
DoEntFireByInstanceHandle( target, action.tostring(), value.tostring(), delay, activator, caller );
|
||||
}
|
||||
|
||||
function __ReplaceClosures( script, scope )
|
||||
{
|
||||
if ( !scope )
|
||||
{
|
||||
scope = getroottable();
|
||||
}
|
||||
|
||||
local tempParent = { getroottable = function() { return null; } };
|
||||
local temp = { runscript = script };
|
||||
temp.set_delegate(tempParent);
|
||||
|
||||
temp.runscript()
|
||||
foreach( key,val in temp )
|
||||
{
|
||||
if ( typeof(val) == "function" && key != "runscript" )
|
||||
{
|
||||
printl( " Replacing " + key );
|
||||
scope[key] <- val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__OutputsPattern <- regexp("^On.*Output$");
|
||||
|
||||
function ConnectOutputs( table )
|
||||
{
|
||||
const nCharsToStrip = 6;
|
||||
foreach( key, val in table )
|
||||
{
|
||||
if ( typeof( val ) == "function" && __OutputsPattern.match( key ) )
|
||||
{
|
||||
//printl(key.slice( 0, nCharsToStrip ) );
|
||||
table.self.ConnectOutput( key.slice( 0, key.len() - nCharsToStrip ), key );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function IncludeScript( name, scope = null )
|
||||
{
|
||||
if ( scope == null )
|
||||
{
|
||||
scope = this;
|
||||
}
|
||||
return ::DoIncludeScript( name, scope );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Text dump this scope's contents to the console.
|
||||
//---------------------------------------------------------
|
||||
function __DumpScope( depth, table )
|
||||
{
|
||||
local indent=function( count )
|
||||
{
|
||||
local i;
|
||||
for( i = 0 ; i < count ; i++ )
|
||||
{
|
||||
print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
foreach(key, value in table)
|
||||
{
|
||||
indent(depth);
|
||||
print( key );
|
||||
switch (type(value))
|
||||
{
|
||||
case "table":
|
||||
print("(TABLE)\n");
|
||||
indent(depth);
|
||||
print("{\n");
|
||||
__DumpScope( depth + 1, value);
|
||||
indent(depth);
|
||||
print("}");
|
||||
break;
|
||||
case "array":
|
||||
print("(ARRAY)\n");
|
||||
indent(depth);
|
||||
print("[\n")
|
||||
__DumpScope( depth + 1, value);
|
||||
indent(depth);
|
||||
print("]");
|
||||
break;
|
||||
case "string":
|
||||
print(" = \"");
|
||||
print(value);
|
||||
print("\"");
|
||||
break;
|
||||
default:
|
||||
print(" = ");
|
||||
print(value);
|
||||
break;
|
||||
}
|
||||
print("\n");
|
||||
}
|
||||
}
|
||||
|
||||
)vscript";
|
@ -393,6 +393,9 @@ BEGIN_DATADESC( CWorld )
|
||||
DEFINE_KEYFIELD( m_flMaxPropScreenSpaceWidth, FIELD_FLOAT, "maxpropscreenwidth" ),
|
||||
DEFINE_KEYFIELD( m_flMinPropScreenSpaceWidth, FIELD_FLOAT, "minpropscreenwidth" ),
|
||||
DEFINE_KEYFIELD( m_iszDetailSpriteMaterial, FIELD_STRING, "detailmaterial" ),
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DEFINE_KEYFIELD( m_iScriptLanguage, FIELD_INTEGER, "vscriptlanguage" ),
|
||||
#endif
|
||||
DEFINE_KEYFIELD( m_bColdWorld, FIELD_BOOLEAN, "coldworld" ),
|
||||
|
||||
#ifdef MAPBASE
|
||||
@ -417,6 +420,9 @@ IMPLEMENT_SERVERCLASS_ST(CWorld, DT_WORLD)
|
||||
#ifdef MAPBASE
|
||||
SendPropStringT (SENDINFO(m_iszChapterTitle) ),
|
||||
#endif
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
SendPropInt (SENDINFO(m_iScriptLanguage), 2, SPROP_UNSIGNED ),
|
||||
#endif
|
||||
END_SEND_TABLE()
|
||||
|
||||
//
|
||||
@ -476,6 +482,10 @@ CWorld::CWorld( )
|
||||
SetSolid( SOLID_BSP );
|
||||
SetMoveType( MOVETYPE_NONE );
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
m_iScriptLanguage = SL_NONE;
|
||||
#endif
|
||||
|
||||
m_bColdWorld = false;
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,10 @@ public:
|
||||
void InputSetChapterTitle( inputdata_t &inputdata );
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
ScriptLanguage_t GetScriptLanguage() { return (ScriptLanguage_t)(m_iScriptLanguage.Get()); }
|
||||
#endif
|
||||
|
||||
private:
|
||||
DECLARE_DATADESC();
|
||||
|
||||
@ -84,6 +88,10 @@ private:
|
||||
CNetworkVar( float, m_flMaxPropScreenSpaceWidth );
|
||||
CNetworkVar( string_t, m_iszDetailSpriteMaterial );
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
CNetworkVar( int, m_iScriptLanguage );
|
||||
#endif
|
||||
|
||||
// start flags
|
||||
CNetworkVar( bool, m_bStartDark );
|
||||
CNetworkVar( bool, m_bColdWorld );
|
||||
|
@ -1217,6 +1217,19 @@ void CBaseEntity::EmitSound( const char *soundname, HSOUNDSCRIPTHANDLE& handle,
|
||||
EmitSound( filter, entindex(), params, handle );
|
||||
}
|
||||
|
||||
#if !defined ( CLIENT_DLL ) || defined( MAPBASE_VSCRIPT )
|
||||
void CBaseEntity::ScriptEmitSound( const char *soundname )
|
||||
{
|
||||
EmitSound( soundname );
|
||||
}
|
||||
|
||||
float CBaseEntity::ScriptSoundDuration( const char *soundname, const char *actormodel )
|
||||
{
|
||||
float duration = CBaseEntity::GetSoundDuration( soundname, actormodel );
|
||||
return duration;
|
||||
}
|
||||
#endif // !CLIENT
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : filter -
|
||||
@ -1486,6 +1499,14 @@ HSOUNDSCRIPTHANDLE CBaseEntity::PrecacheScriptSound( const char *soundname )
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined ( CLIENT_DLL ) || defined( MAPBASE_VSCRIPT )
|
||||
// Same as server version of above, but signiture changed so it can be deduced by the macros
|
||||
void CBaseEntity::VScriptPrecacheScriptSound(const char* soundname)
|
||||
{
|
||||
g_SoundEmitterSystem.PrecacheScriptSound(soundname);
|
||||
}
|
||||
#endif // !CLIENT_DLL
|
||||
|
||||
void CBaseEntity::PrefetchScriptSound( const char *soundname )
|
||||
{
|
||||
g_SoundEmitterSystem.PrefetchScriptSound( soundname );
|
||||
|
@ -1801,6 +1801,22 @@ void CBaseCombatWeapon::InputHideWeapon( inputdata_t &inputdata )
|
||||
SetWeaponVisible( false );
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CBaseCombatWeapon::ScriptGetPrimaryAmmoType()
|
||||
{
|
||||
return GetPrimaryAmmoType() <= GetAmmoDef()->m_nAmmoIndex ? GetAmmoDef()->m_AmmoType[GetPrimaryAmmoType()].pName : NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CBaseCombatWeapon::ScriptGetSecondaryAmmoType()
|
||||
{
|
||||
return GetSecondaryAmmoType() <= GetAmmoDef()->m_nAmmoIndex ? GetAmmoDef()->m_AmmoType[GetSecondaryAmmoType()].pName : NULL;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -2871,6 +2887,48 @@ END_PREDICTION_DATA()
|
||||
// Special hack since we're aliasing the name C_BaseCombatWeapon with a macro on the client
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( BaseCombatWeapon, DT_BaseCombatWeapon )
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
BEGIN_ENT_SCRIPTDESC( CBaseCombatWeapon, CBaseAnimating, "The base class for all equippable weapons." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( Clip1, "Get the weapon's current primary ammo." )
|
||||
DEFINE_SCRIPTFUNC( Clip2, "Get the weapon's current secondary ammo." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetClip1, "SetClip1", "Set the weapon's current primary ammo." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetClip2, "SetClip2", "Set the weapon's current secondary ammo." )
|
||||
DEFINE_SCRIPTFUNC( GetMaxClip1, "Get the weapon's maximum primary ammo." )
|
||||
DEFINE_SCRIPTFUNC( GetMaxClip2, "Get the weapon's maximum secondary ammo." )
|
||||
DEFINE_SCRIPTFUNC( GetDefaultClip1, "Get the weapon's default primary ammo." )
|
||||
DEFINE_SCRIPTFUNC( GetDefaultClip2, "Get the weapon's default secondary ammo." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( HasAnyAmmo, "Check if the weapon currently has ammo or doesn't need ammo." )
|
||||
DEFINE_SCRIPTFUNC( HasPrimaryAmmo, "Check if the weapon currently has ammo or doesn't need primary ammo." )
|
||||
DEFINE_SCRIPTFUNC( HasSecondaryAmmo, "Check if the weapon currently has ammo or doesn't need secondary ammo." )
|
||||
DEFINE_SCRIPTFUNC( UsesPrimaryAmmo, "Check if the weapon uses primary ammo." )
|
||||
DEFINE_SCRIPTFUNC( UsesSecondaryAmmo, "Check if the weapon uses secondary ammo." )
|
||||
DEFINE_SCRIPTFUNC( GiveDefaultAmmo, "Fill the weapon back up to default ammo." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( UsesClipsForAmmo1, "Check if the weapon uses clips for primary ammo." )
|
||||
DEFINE_SCRIPTFUNC( UsesClipsForAmmo2, "Check if the weapon uses clips for secondary ammo." )
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetPrimaryAmmoType, "GetPrimaryAmmoType", "Get the weapon's primary ammo type." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetSecondaryAmmoType, "GetSecondaryAmmoType", "Get the weapon's secondary ammo type." )
|
||||
#endif
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetSubType, "Get the weapon's subtype." )
|
||||
DEFINE_SCRIPTFUNC( SetSubType, "Set the weapon's subtype." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetFireRate, "Get the weapon's firing rate." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetWorldModel, "Get the weapon's world model." )
|
||||
DEFINE_SCRIPTFUNC( GetViewModel, "Get the weapon's view model." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetWeight, "Get the weapon's weight." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( CanBePickedUpByNPCs, "Check if the weapon can be picked up by NPCs." )
|
||||
|
||||
END_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
#if !defined( CLIENT_DLL )
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Save Data for Base Weapon object
|
||||
|
@ -196,6 +196,9 @@ public:
|
||||
DECLARE_CLASS( CBaseCombatWeapon, BASECOMBATWEAPON_DERIVED_FROM );
|
||||
DECLARE_NETWORKCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
DECLARE_ENT_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
CBaseCombatWeapon();
|
||||
virtual ~CBaseCombatWeapon();
|
||||
@ -446,6 +449,12 @@ public:
|
||||
virtual void Activate( void );
|
||||
|
||||
virtual bool ShouldUseLargeViewModelVROverride() { return false; }
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
void ScriptSetClip1( int ammo ) { m_iClip1 = ammo; }
|
||||
void ScriptSetClip2( int ammo ) { m_iClip2 = ammo; }
|
||||
#endif
|
||||
|
||||
public:
|
||||
// Server Only Methods
|
||||
#if !defined( CLIENT_DLL )
|
||||
@ -510,6 +519,11 @@ public:
|
||||
|
||||
virtual CDmgAccumulator *GetDmgAccumulator( void ) { return NULL; }
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
const char* ScriptGetPrimaryAmmoType();
|
||||
const char* ScriptGetSecondaryAmmoType();
|
||||
#endif
|
||||
|
||||
// Client only methods
|
||||
#else
|
||||
|
||||
|
@ -1599,6 +1599,27 @@ typedef CTraceFilterSimpleList CBulletsTraceFilter;
|
||||
|
||||
void CBaseEntity::FireBullets( const FireBulletsInfo_t &info )
|
||||
{
|
||||
#if defined(MAPBASE_VSCRIPT) && defined(GAME_DLL)
|
||||
if (m_ScriptScope.IsInitialized())
|
||||
{
|
||||
CFireBulletsInfoAccessor pInfo( const_cast<FireBulletsInfo_t*>(&info) );
|
||||
HSCRIPT hInfo = g_pScriptVM->RegisterInstance( &pInfo );
|
||||
|
||||
g_pScriptVM->SetValue( "info", hInfo );
|
||||
|
||||
ScriptVariant_t functionReturn;
|
||||
if ( CallScriptFunction( "FireBullets", &functionReturn ) )
|
||||
{
|
||||
if (!functionReturn.m_bool)
|
||||
return;
|
||||
}
|
||||
|
||||
g_pScriptVM->RemoveInstance( hInfo );
|
||||
|
||||
g_pScriptVM->ClearValue( "info" );
|
||||
}
|
||||
#endif
|
||||
|
||||
static int tracerCount;
|
||||
trace_t tr;
|
||||
CAmmoDef* pAmmoDef = GetAmmoDef();
|
||||
|
@ -68,6 +68,9 @@ enum InvalidatePhysicsBits_t
|
||||
|
||||
#endif
|
||||
|
||||
#include "vscript/ivscript.h"
|
||||
#include "vscript_shared.h"
|
||||
|
||||
#if !defined( NO_ENTITY_PREDICTION )
|
||||
// CBaseEntity inlines
|
||||
inline bool CBaseEntity::IsPlayerSimulated( void ) const
|
||||
@ -247,6 +250,17 @@ inline bool CBaseEntity::IsEffectActive( int nEffects ) const
|
||||
return (m_fEffects & nEffects) != 0;
|
||||
}
|
||||
|
||||
inline HSCRIPT ToHScript(CBaseEntity* pEnt)
|
||||
{
|
||||
return (pEnt) ? pEnt->GetScriptInstance() : NULL;
|
||||
}
|
||||
|
||||
template <> ScriptClassDesc_t* GetScriptDesc<CBaseEntity>(CBaseEntity*);
|
||||
inline CBaseEntity* ToEnt(HSCRIPT hScript)
|
||||
{
|
||||
return (hScript) ? (CBaseEntity*)g_pScriptVM->GetInstanceValue(hScript, GetScriptDescForClass(CBaseEntity)) : NULL;
|
||||
}
|
||||
|
||||
// Shared EntityMessage between game and client .dlls
|
||||
#define BASEENTITY_MSG_REMOVE_DECALS 1
|
||||
|
||||
|
@ -2064,6 +2064,8 @@ static EventNameMap_t g_NameMap[] =
|
||||
{ CChoreoEvent::STOPPOINT, "stoppoint" },
|
||||
{ CChoreoEvent::PERMIT_RESPONSES, "permitresponses" },
|
||||
{ CChoreoEvent::GENERIC, "generic" },
|
||||
{ CChoreoEvent::CAMERA, "camera" },
|
||||
{ CChoreoEvent::SCRIPT, "script" },
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -307,6 +307,12 @@ public:
|
||||
// A string passed to the game code for interpretation
|
||||
GENERIC,
|
||||
|
||||
// Camera control
|
||||
CAMERA,
|
||||
|
||||
// Script function call
|
||||
SCRIPT,
|
||||
|
||||
// THIS MUST BE LAST!!!
|
||||
NUM_TYPES,
|
||||
} EVENTTYPE;
|
||||
|
@ -173,6 +173,8 @@ public:
|
||||
|
||||
virtual bool InRoundRestart( void ) { return false; }
|
||||
|
||||
virtual void RegisterScriptFunctions( void ){ };
|
||||
|
||||
//Allow thirdperson camera.
|
||||
virtual bool AllowThirdPersonCamera( void ) { return false; }
|
||||
|
||||
|
@ -79,6 +79,10 @@ public:
|
||||
virtual void LevelInitPreEntity();
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
virtual void RegisterScriptFunctions( void );
|
||||
#endif
|
||||
|
||||
private:
|
||||
// Rules change for the mega physgun
|
||||
CNetworkVar( bool, m_bMegaPhysgun );
|
||||
|
@ -344,6 +344,15 @@ void IGameSystem::PreClientUpdateAllSystems()
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
|
||||
void IGameSystem::RegisterVScriptAllSystems()
|
||||
{
|
||||
InvokeMethod( &IGameSystem::RegisterVScript );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Invokes a method on all installed game systems in proper order
|
||||
|
@ -98,6 +98,13 @@ public:
|
||||
static CBasePlayer *RunCommandPlayer();
|
||||
static CUserCmd *RunCommandUserCmd();
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
// This should be abstract, but there's a lot of systems which derive from
|
||||
// this interface that would need to have this declared
|
||||
virtual void RegisterVScript() { ; }
|
||||
static void RegisterVScriptAllSystems();
|
||||
#endif
|
||||
};
|
||||
|
||||
class IGameSystemPerFrame : public IGameSystem
|
||||
|
@ -244,7 +244,7 @@ public:
|
||||
pKV->deleteThis();
|
||||
}
|
||||
|
||||
void AddManifestFile( const char *file, bool bDontStore = false )
|
||||
void AddManifestFile( const char *file )
|
||||
{
|
||||
KeyValues *pKV = new KeyValues(file);
|
||||
if ( !pKV->LoadFromFile( filesystem, file ) )
|
||||
@ -364,6 +364,24 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
void ScriptAddManifestFile( const char *szScript ) { AddManifestFile( szScript ); }
|
||||
|
||||
void LoadSoundscriptFile( const char *szScript ) { LoadFromValue(szScript, MANIFEST_SOUNDSCRIPTS, false); }
|
||||
#ifndef CLIENT_DLL
|
||||
void LoadTalkerFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_TALKER, false ); }
|
||||
void LoadActbusyFile( const char *szScript ) { LoadFromValue( szScript, MANIFEST_ACTBUSY, false ); }
|
||||
#endif
|
||||
|
||||
const char *GetModName() { return g_iszGameName; }
|
||||
bool IsCoreMapbase() { return g_bMapbaseCore; }
|
||||
|
||||
virtual void RegisterVScript()
|
||||
{
|
||||
g_pScriptVM->RegisterInstance( this, "Mapbase" );
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
CMapbaseSystem g_MapbaseSystem;
|
||||
@ -374,6 +392,19 @@ BEGIN_DATADESC_NO_BASE( CMapbaseSystem )
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
BEGIN_SCRIPTDESC_ROOT( CMapbaseSystem, SCRIPT_SINGLETON "All-purpose Mapbase system primarily used for map-specific files." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptAddManifestFile, "AddManifestFile", "Loads a manifest file." )
|
||||
DEFINE_SCRIPTFUNC( LoadSoundscriptFile, "Loads a custom soundscript file." )
|
||||
#ifndef CLIENT_DLL
|
||||
DEFINE_SCRIPTFUNC( LoadTalkerFile, "Loads a custom talker file." )
|
||||
DEFINE_SCRIPTFUNC( LoadActbusyFile, "Loads a custom actbusy file." )
|
||||
#endif
|
||||
DEFINE_SCRIPTFUNC( GetModName, "Gets the name of the mod. This is the name which shows up on Steam, RPC, etc." )
|
||||
DEFINE_SCRIPTFUNC( IsCoreMapbase, "Indicates whether this is one of the original Mapbase mods or just a separate mod using its code." )
|
||||
END_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
#ifdef GAME_DLL
|
||||
static CUtlVector<MODTITLECOMMENT> g_MapbaseChapterMaps;
|
||||
static CUtlVector<MODCHAPTER> g_MapbaseChapterList;
|
||||
@ -437,7 +468,7 @@ ThreeState_t Flashlight_GetLegacyVersionKey()
|
||||
|
||||
static void CC_Mapbase_LoadManifestFile( const CCommand& args )
|
||||
{
|
||||
g_MapbaseSystem.AddManifestFile(args[1], args[2]);
|
||||
g_MapbaseSystem.AddManifestFile(args[1]);
|
||||
}
|
||||
|
||||
static ConCommand mapbase_loadmanifestfile("mapbase_loadmanifestfile", CC_Mapbase_LoadManifestFile, "Loads a Mapbase manifest file. If you don't want this to be saved and found when reloaded, type a '1' after the file path." );
|
||||
|
68
sp/src/game/shared/mapbase/vscript_funcs_hl2.cpp
Normal file
68
sp/src/game/shared/mapbase/vscript_funcs_hl2.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: VScript functions for Half-Life 2.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
#include "hl2_gamerules.h"
|
||||
#ifndef CLIENT_DLL
|
||||
#include "eventqueue.h"
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
extern CBaseEntity *CreatePlayerLoadSave( Vector vOrigin, float flDuration, float flHoldTime, float flLoadTime );
|
||||
|
||||
HSCRIPT ScriptGameOver( const char *pszMessage, float flDelay, float flFadeTime, float flLoadTime, int r, int g, int b )
|
||||
{
|
||||
CBaseEntity *pPlayer = AI_GetSinglePlayer();
|
||||
if (pPlayer)
|
||||
{
|
||||
UTIL_ShowMessage( pszMessage, ToBasePlayer( pPlayer ) );
|
||||
ToBasePlayer( pPlayer )->NotifySinglePlayerGameEnding();
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: How should MP handle this?
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CBaseEntity *pReload = CreatePlayerLoadSave( vec3_origin, flFadeTime, flLoadTime + 1.0f, flLoadTime );
|
||||
if (pReload)
|
||||
{
|
||||
pReload->SetRenderColor( r, g, b, 255 );
|
||||
g_EventQueue.AddEvent( pReload, "Reload", flDelay, pReload, pReload );
|
||||
}
|
||||
|
||||
return ToHScript( pReload );
|
||||
}
|
||||
|
||||
bool ScriptMegaPhyscannonActive()
|
||||
{
|
||||
return HL2GameRules()->MegaPhyscannonActive();
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns how much damage the given ammo type should do to the victim
|
||||
// when fired by the attacker.
|
||||
// Input : pAttacker - Dude what shot the gun.
|
||||
// pVictim - Dude what done got shot.
|
||||
// nAmmoType - What been shot out.
|
||||
// Output : How much hurt to put on dude what done got shot (pVictim).
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHalfLife2::RegisterScriptFunctions( void )
|
||||
{
|
||||
BaseClass::RegisterScriptFunctions();
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptGameOver, "GameOver", "Ends the game and reloads the last save." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptMegaPhyscannonActive, "MegaPhyscannonActive", "Checks if supercharged gravity gun mode is enabled." );
|
||||
#endif
|
||||
}
|
308
sp/src/game/shared/mapbase/vscript_funcs_math.cpp
Normal file
308
sp/src/game/shared/mapbase/vscript_funcs_math.cpp
Normal file
@ -0,0 +1,308 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Shared VScript math functions.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// matrix3x4_t
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
//
|
||||
// Exposes matrix3x4_t to VScript
|
||||
//
|
||||
class CScriptMatrix3x4
|
||||
{
|
||||
public:
|
||||
CScriptMatrix3x4()
|
||||
{
|
||||
matrix = new matrix3x4_t();
|
||||
m_bFree = true;
|
||||
}
|
||||
|
||||
~CScriptMatrix3x4()
|
||||
{
|
||||
if (m_bFree == true)
|
||||
delete matrix;
|
||||
}
|
||||
|
||||
CScriptMatrix3x4( matrix3x4_t &inmatrix ) { matrix = &inmatrix; }
|
||||
|
||||
matrix3x4_t *GetMatrix() { return matrix; }
|
||||
void SetMatrix( matrix3x4_t &inmatrix ) { matrix = &inmatrix; }
|
||||
|
||||
void Init( const Vector& xAxis, const Vector& yAxis, const Vector& zAxis, const Vector &vecOrigin )
|
||||
{
|
||||
matrix->Init( xAxis, yAxis, zAxis, vecOrigin );
|
||||
}
|
||||
|
||||
private:
|
||||
matrix3x4_t *matrix;
|
||||
bool m_bFree = false;
|
||||
};
|
||||
|
||||
BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptMatrix3x4, "matrix3x4_t", "A 3x4 matrix transform." )
|
||||
|
||||
DEFINE_SCRIPT_CONSTRUCTOR()
|
||||
DEFINE_SCRIPTFUNC( Init, "Creates a matrix where the X axis = forward, the Y axis = left, and the Z axis = up." )
|
||||
|
||||
END_SCRIPTDESC();
|
||||
|
||||
inline matrix3x4_t *ToMatrix3x4( HSCRIPT hMat ) { return HScriptToClass<CScriptMatrix3x4>( hMat )->GetMatrix(); }
|
||||
|
||||
HSCRIPT ScriptCreateMatrixInstance( matrix3x4_t &matrix )
|
||||
{
|
||||
CScriptMatrix3x4 *smatrix = new CScriptMatrix3x4( matrix );
|
||||
|
||||
return g_pScriptVM->RegisterInstance( smatrix );
|
||||
}
|
||||
|
||||
void ScriptFreeMatrixInstance( HSCRIPT hMat )
|
||||
{
|
||||
CScriptMatrix3x4 *smatrix = HScriptToClass<CScriptMatrix3x4>( hMat );
|
||||
if (smatrix)
|
||||
{
|
||||
g_pScriptVM->RemoveInstance( hMat );
|
||||
delete smatrix;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ScriptConcatTransforms( HSCRIPT hMat1, HSCRIPT hMat2, HSCRIPT hOut )
|
||||
{
|
||||
if (!hMat1 || !hMat2 || !hOut)
|
||||
return;
|
||||
|
||||
matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 );
|
||||
matrix3x4_t *pMat2 = ToMatrix3x4( hMat2 );
|
||||
matrix3x4_t *pOut = ToMatrix3x4( hOut );
|
||||
|
||||
ConcatTransforms( *pMat1, *pMat2, *pOut );
|
||||
}
|
||||
|
||||
void ScriptMatrixCopy( HSCRIPT hMat1, HSCRIPT hOut )
|
||||
{
|
||||
if (!hMat1 || !hOut)
|
||||
return;
|
||||
|
||||
matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 );
|
||||
matrix3x4_t *pOut = ToMatrix3x4( hOut );
|
||||
|
||||
MatrixCopy( *pMat1, *pOut );
|
||||
}
|
||||
|
||||
void ScriptMatrixInvert( HSCRIPT hMat1, HSCRIPT hOut )
|
||||
{
|
||||
if (!hMat1 || !hOut)
|
||||
return;
|
||||
|
||||
matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 );
|
||||
matrix3x4_t *pOut = ToMatrix3x4( hOut );
|
||||
|
||||
MatrixInvert( *pMat1, *pOut );
|
||||
}
|
||||
|
||||
void ScriptMatricesAreEqual( HSCRIPT hMat1, HSCRIPT hMat2 )
|
||||
{
|
||||
if (!hMat1 || !hMat2)
|
||||
return;
|
||||
|
||||
matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 );
|
||||
matrix3x4_t *pMat2 = ToMatrix3x4( hMat2 );
|
||||
|
||||
MatricesAreEqual( *pMat1, *pMat2 );
|
||||
}
|
||||
|
||||
const Vector& ScriptMatrixGetColumn( HSCRIPT hMat1, int column )
|
||||
{
|
||||
static Vector outvec;
|
||||
outvec.Zero();
|
||||
if (!hMat1)
|
||||
return outvec;
|
||||
|
||||
matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 );
|
||||
|
||||
MatrixGetColumn( *pMat1, column, outvec );
|
||||
return outvec;
|
||||
}
|
||||
|
||||
void ScriptMatrixSetColumn( const Vector& vecset, int column, HSCRIPT hMat1 )
|
||||
{
|
||||
if (!hMat1)
|
||||
return;
|
||||
|
||||
matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 );
|
||||
|
||||
static Vector outvec;
|
||||
MatrixSetColumn( vecset, column, *pMat1 );
|
||||
}
|
||||
|
||||
void ScriptMatrixAngles( HSCRIPT hMat1, const QAngle& angset, const Vector& vecset )
|
||||
{
|
||||
if (!hMat1)
|
||||
return;
|
||||
|
||||
matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 );
|
||||
|
||||
MatrixAngles( *pMat1, *const_cast<QAngle*>(&angset), *const_cast<Vector*>(&vecset) );
|
||||
}
|
||||
|
||||
void ScriptAngleMatrix( const QAngle& angset, const Vector& vecset, HSCRIPT hMat1 )
|
||||
{
|
||||
if (!hMat1)
|
||||
return;
|
||||
|
||||
matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 );
|
||||
|
||||
AngleMatrix( angset, vecset, *pMat1 );
|
||||
}
|
||||
|
||||
void ScriptAngleIMatrix( const QAngle& angset, const Vector& vecset, HSCRIPT hMat1 )
|
||||
{
|
||||
if (!hMat1)
|
||||
return;
|
||||
|
||||
matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 );
|
||||
|
||||
AngleIMatrix( angset, vecset, *pMat1 );
|
||||
}
|
||||
|
||||
void ScriptSetIdentityMatrix( HSCRIPT hMat1 )
|
||||
{
|
||||
if (!hMat1)
|
||||
return;
|
||||
|
||||
matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 );
|
||||
|
||||
SetIdentityMatrix( *pMat1 );
|
||||
}
|
||||
|
||||
void ScriptSetScaleMatrix( float x, float y, float z, HSCRIPT hMat1 )
|
||||
{
|
||||
if (!hMat1)
|
||||
return;
|
||||
|
||||
matrix3x4_t *pMat1 = ToMatrix3x4( hMat1 );
|
||||
|
||||
SetScaleMatrix( x, y, z, *pMat1 );
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Misc. Vector/QAngle functions
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
const Vector& ScriptAngleVectors( const QAngle &angles )
|
||||
{
|
||||
static Vector forward;
|
||||
AngleVectors( angles, &forward );
|
||||
return forward;
|
||||
}
|
||||
|
||||
const QAngle& ScriptVectorAngles( const Vector &forward )
|
||||
{
|
||||
static QAngle angles;
|
||||
VectorAngles( forward, angles );
|
||||
return angles;
|
||||
}
|
||||
|
||||
const Vector& ScriptCalcClosestPointOnAABB( const Vector &mins, const Vector &maxs, const Vector &point )
|
||||
{
|
||||
static Vector outvec;
|
||||
CalcClosestPointOnAABB( mins, maxs, point, outvec );
|
||||
return outvec;
|
||||
}
|
||||
|
||||
const Vector& ScriptCalcClosestPointOnLine( const Vector &point, const Vector &vLineA, const Vector &vLineB )
|
||||
{
|
||||
static Vector outvec;
|
||||
CalcClosestPointOnLine( point, vLineA, vLineB, outvec );
|
||||
return outvec;
|
||||
}
|
||||
|
||||
float ScriptCalcDistanceToLine( const Vector &point, const Vector &vLineA, const Vector &vLineB )
|
||||
{
|
||||
return CalcDistanceToLine( point, vLineA, vLineB );
|
||||
}
|
||||
|
||||
const Vector& ScriptCalcClosestPointOnLineSegment( const Vector &point, const Vector &vLineA, const Vector &vLineB )
|
||||
{
|
||||
static Vector outvec;
|
||||
CalcClosestPointOnLineSegment( point, vLineA, vLineB, outvec );
|
||||
return outvec;
|
||||
}
|
||||
|
||||
float ScriptCalcDistanceToLineSegment( const Vector &point, const Vector &vLineA, const Vector &vLineB )
|
||||
{
|
||||
return CalcDistanceToLineSegment( point, vLineA, vLineB );
|
||||
}
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
const Vector& ScriptPredictedPosition( HSCRIPT hTarget, float flTimeDelta )
|
||||
{
|
||||
static Vector predicted;
|
||||
UTIL_PredictedPosition( ToEnt(hTarget), flTimeDelta, &predicted );
|
||||
return predicted;
|
||||
}
|
||||
#endif
|
||||
|
||||
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, 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, 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." );
|
||||
|
||||
//
|
||||
// matrix3x4_t
|
||||
//
|
||||
g_pScriptVM->RegisterClass( GetScriptDescForClass( CScriptMatrix3x4 ) );
|
||||
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptFreeMatrixInstance, "FreeMatrixInstance", "Frees an allocated matrix instance." );
|
||||
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptConcatTransforms, "ConcatTransforms", "Concatenates two transformation matrices into another matrix." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptMatrixCopy, "MatrixCopy", "Copies a matrix to another matrix." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptMatrixInvert, "MatrixInvert", "Inverts a matrix and copies the result to another matrix." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptMatricesAreEqual, "MatricesAreEqual", "Checks if two matrices are equal." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptMatrixGetColumn, "MatrixGetColumn", "Gets the column of a matrix." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptMatrixSetColumn, "MatrixSetColumn", "Sets the column of a matrix." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptMatrixAngles, "MatrixAngles", "Gets the angles and position of a matrix." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptAngleMatrix, "AngleMatrix", "Sets the angles and position of a matrix." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptAngleIMatrix, "AngleIMatrix", "Sets the inverted angles and position of a matrix." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptSetIdentityMatrix, "SetIdentityMatrix", "Turns a matrix into an identity matrix." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptSetScaleMatrix, "SetScaleMatrix", "Scales a matrix." );
|
||||
|
||||
//
|
||||
// Misc. Vector/QAngle functions
|
||||
//
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptAngleVectors, "AngleVectors", "Turns an angle into a direction vector." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptVectorAngles, "VectorAngles", "Turns a direction vector into an angle." );
|
||||
|
||||
ScriptRegisterFunction( g_pScriptVM, CalcSqrDistanceToAABB, "Returns the squared distance to a bounding box." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCalcClosestPointOnAABB, "CalcClosestPointOnAABB", "Returns the closest point on a bounding box." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCalcDistanceToLine, "CalcDistanceToLine", "Returns the distance to a line." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCalcClosestPointOnLine, "CalcClosestPointOnLine", "Returns the closest point on a line." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCalcDistanceToLineSegment, "CalcDistanceToLineSegment", "Returns the distance to a line segment." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCalcClosestPointOnLineSegment, "CalcClosestPointOnLineSegment", "Returns the closest point on a line segment." );
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptPredictedPosition, "PredictedPosition", "Predicts what an entity's position will be in a given amount of time." );
|
||||
#endif
|
||||
}
|
857
sp/src/game/shared/mapbase/vscript_funcs_shared.cpp
Normal file
857
sp/src/game/shared/mapbase/vscript_funcs_shared.cpp
Normal file
@ -0,0 +1,857 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Due to this being a custom integration of VScript based on the Alien Swarm SDK, we don't have access to
|
||||
// some of the code normally available in games like L4D2 or Valve's original VScript DLL.
|
||||
// Instead, that code is recreated here, shared between server and client.
|
||||
//
|
||||
// It also contains other functions unique to Mapbase.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "matchers.h"
|
||||
#include "takedamageinfo.h"
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
#include "globalstate.h"
|
||||
#include "vscript_server.h"
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
class CScriptNetPropManager
|
||||
{
|
||||
public:
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
RecvProp *RecurseTable( RecvTable *pTable, const char *pszPropName )
|
||||
#else
|
||||
SendProp *RecurseTable( SendTable *pTable, const char *pszPropName )
|
||||
#endif
|
||||
{
|
||||
#ifdef CLIENT_DLL
|
||||
RecvProp *pProp = NULL;
|
||||
#else
|
||||
SendProp *pProp = NULL;
|
||||
#endif
|
||||
for (int i = 0; i < pTable->GetNumProps(); i++)
|
||||
{
|
||||
pProp = pTable->GetProp( i );
|
||||
if (pProp->GetType() == DPT_DataTable)
|
||||
{
|
||||
pProp = RecurseTable(pProp->GetDataTable(), pszPropName);
|
||||
if (pProp)
|
||||
return pProp;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FStrEq( pProp->GetName(), pszPropName ))
|
||||
return pProp;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
RecvProp *RecurseNetworkClass( ClientClass *pClass, const char *pszPropName )
|
||||
#else
|
||||
SendProp *RecurseNetworkClass( ServerClass *pClass, const char *pszPropName )
|
||||
#endif
|
||||
{
|
||||
#ifdef CLIENT_DLL
|
||||
RecvProp *pProp = RecurseTable( pClass->m_pRecvTable, pszPropName );
|
||||
#else
|
||||
SendProp *pProp = RecurseTable( pClass->m_pTable, pszPropName );
|
||||
#endif
|
||||
if (pProp)
|
||||
return pProp;
|
||||
|
||||
if (pClass->m_pNext)
|
||||
return RecurseNetworkClass( pClass->m_pNext, pszPropName );
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
RecvProp *GetPropByName( CBaseEntity *pEnt, const char *pszPropName )
|
||||
{
|
||||
if (pEnt)
|
||||
{
|
||||
return RecurseNetworkClass( pEnt->GetClientClass(), pszPropName );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
SendProp *GetPropByName( CBaseEntity *pEnt, const char *pszPropName )
|
||||
{
|
||||
if (pEnt)
|
||||
{
|
||||
return RecurseNetworkClass( pEnt->GetServerClass(), pszPropName );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
int GetPropArraySize( HSCRIPT hEnt, const char *pszPropName )
|
||||
{
|
||||
CBaseEntity *pEnt = ToEnt( hEnt );
|
||||
auto *pProp = GetPropByName( pEnt, pszPropName );
|
||||
if (pProp)
|
||||
{
|
||||
// TODO: Is this what this function wants?
|
||||
return pProp->GetNumElements();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define GetPropFunc( name, varType, propType, defaultval ) \
|
||||
varType name( HSCRIPT hEnt, const char *pszPropName ) \
|
||||
{ \
|
||||
CBaseEntity *pEnt = ToEnt( hEnt ); \
|
||||
auto *pProp = GetPropByName( pEnt, pszPropName ); \
|
||||
if (pProp && pProp->GetType() == propType) \
|
||||
{ \
|
||||
return *(varType*)((char *)pEnt + pProp->GetOffset()); \
|
||||
} \
|
||||
return defaultval; \
|
||||
} \
|
||||
|
||||
#define GetPropFuncArray( name, varType, propType, defaultval ) \
|
||||
varType name( HSCRIPT hEnt, const char *pszPropName, int iArrayElement ) \
|
||||
{ \
|
||||
CBaseEntity *pEnt = ToEnt( hEnt ); \
|
||||
auto *pProp = GetPropByName( pEnt, pszPropName ); \
|
||||
if (pProp && pProp->GetType() == propType) \
|
||||
{ \
|
||||
return ((varType*)((char *)pEnt + pProp->GetOffset()))[iArrayElement]; \
|
||||
} \
|
||||
return defaultval; \
|
||||
} \
|
||||
|
||||
GetPropFunc( GetPropFloat, float, DPT_Float, -1 );
|
||||
GetPropFuncArray( GetPropFloatArray, float, DPT_Float, -1 );
|
||||
GetPropFunc( GetPropInt, int, DPT_Int, -1 );
|
||||
GetPropFuncArray( GetPropIntArray, int, DPT_Int, -1 );
|
||||
GetPropFunc( GetPropVector, Vector, DPT_Vector, vec3_invalid );
|
||||
GetPropFuncArray( GetPropVectorArray, Vector, DPT_Vector, vec3_invalid );
|
||||
|
||||
HSCRIPT GetPropEntity( HSCRIPT hEnt, const char *pszPropName )
|
||||
{
|
||||
CBaseEntity *pEnt = ToEnt( hEnt );
|
||||
auto *pProp = GetPropByName( pEnt, pszPropName );
|
||||
if (pProp && pProp->GetType() == DPT_Int)
|
||||
{
|
||||
return ToHScript( *(CHandle<CBaseEntity>*)((char *)pEnt + pProp->GetOffset()) );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HSCRIPT GetPropEntityArray( HSCRIPT hEnt, const char *pszPropName, int iArrayElement )
|
||||
{
|
||||
CBaseEntity *pEnt = ToEnt( hEnt );
|
||||
auto *pProp = GetPropByName( pEnt, pszPropName );
|
||||
if (pProp && pProp->GetType() == DPT_Int)
|
||||
{
|
||||
return ToHScript( ((CHandle<CBaseEntity>*)((char *)pEnt + pProp->GetOffset()))[iArrayElement] );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *GetPropString( HSCRIPT hEnt, const char *pszPropName )
|
||||
{
|
||||
CBaseEntity *pEnt = ToEnt( hEnt );
|
||||
auto *pProp = GetPropByName( pEnt, pszPropName );
|
||||
if (pProp && pProp->GetType() == DPT_Int)
|
||||
{
|
||||
return (const char*)((char *)pEnt + pProp->GetOffset());
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *GetPropStringArray( HSCRIPT hEnt, const char *pszPropName, int iArrayElement )
|
||||
{
|
||||
CBaseEntity *pEnt = ToEnt( hEnt );
|
||||
auto *pProp = GetPropByName( pEnt, pszPropName );
|
||||
if (pProp && pProp->GetType() == DPT_Int)
|
||||
{
|
||||
return ((const char**)((char *)pEnt + pProp->GetOffset()))[iArrayElement];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *GetPropType( HSCRIPT hEnt, const char *pszPropName )
|
||||
{
|
||||
CBaseEntity *pEnt = ToEnt( hEnt );
|
||||
auto *pProp = GetPropByName( pEnt, pszPropName );
|
||||
if (pProp)
|
||||
{
|
||||
switch (pProp->GetType())
|
||||
{
|
||||
case DPT_Int: return "integer";
|
||||
case DPT_Float: return "float";
|
||||
case DPT_Vector: return "vector";
|
||||
case DPT_VectorXY: return "vector2d";
|
||||
case DPT_String: return "string";
|
||||
case DPT_Array: return "array";
|
||||
case DPT_DataTable: return "datatable";
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool HasProp( HSCRIPT hEnt, const char *pszPropName )
|
||||
{
|
||||
CBaseEntity *pEnt = ToEnt( hEnt );
|
||||
return GetPropByName( pEnt, pszPropName ) != NULL;
|
||||
}
|
||||
|
||||
#define SetPropFunc( name, varType, propType ) \
|
||||
void name( HSCRIPT hEnt, const char *pszPropName, varType value ) \
|
||||
{ \
|
||||
CBaseEntity *pEnt = ToEnt( hEnt ); \
|
||||
auto *pProp = GetPropByName( pEnt, pszPropName ); \
|
||||
if (pProp && pProp->GetType() == propType) \
|
||||
{ \
|
||||
*(varType*)((char *)pEnt + pProp->GetOffset()) = value; \
|
||||
} \
|
||||
} \
|
||||
|
||||
#define SetPropFuncArray( name, varType, propType ) \
|
||||
void name( HSCRIPT hEnt, const char *pszPropName, varType value, int iArrayElement ) \
|
||||
{ \
|
||||
CBaseEntity *pEnt = ToEnt( hEnt ); \
|
||||
auto *pProp = GetPropByName( pEnt, pszPropName ); \
|
||||
if (pProp && pProp->GetType() == propType) \
|
||||
{ \
|
||||
((varType*)((char *)pEnt + pProp->GetOffset()))[iArrayElement] = value; \
|
||||
} \
|
||||
} \
|
||||
|
||||
SetPropFunc( SetPropFloat, float, DPT_Float );
|
||||
SetPropFuncArray( SetPropFloatArray, float, DPT_Float );
|
||||
SetPropFunc( SetPropInt, int, DPT_Int );
|
||||
SetPropFuncArray( SetPropIntArray, int, DPT_Int );
|
||||
SetPropFunc( SetPropVector, Vector, DPT_Vector );
|
||||
SetPropFuncArray( SetPropVectorArray, Vector, DPT_Vector );
|
||||
SetPropFunc( SetPropString, const char*, DPT_String );
|
||||
SetPropFuncArray( SetPropStringArray, const char*, DPT_String );
|
||||
|
||||
void SetPropEntity( HSCRIPT hEnt, const char *pszPropName, HSCRIPT value )
|
||||
{
|
||||
CBaseEntity *pEnt = ToEnt( hEnt );
|
||||
auto *pProp = GetPropByName( pEnt, pszPropName );
|
||||
if (pProp && pProp->GetType() == DPT_Int)
|
||||
{
|
||||
*((CHandle<CBaseEntity>*)((char *)pEnt + pProp->GetOffset())) = ToEnt(value);
|
||||
}
|
||||
}
|
||||
|
||||
HSCRIPT SetPropEntityArray( HSCRIPT hEnt, const char *pszPropName, HSCRIPT value, int iArrayElement )
|
||||
{
|
||||
CBaseEntity *pEnt = ToEnt( hEnt );
|
||||
auto *pProp = GetPropByName( pEnt, pszPropName );
|
||||
if (pProp && pProp->GetType() == DPT_Int)
|
||||
{
|
||||
((CHandle<CBaseEntity>*)((char *)pEnt + pProp->GetOffset()))[iArrayElement] = ToEnt(value);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
} g_ScriptNetPropManager;
|
||||
|
||||
BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptNetPropManager, "CNetPropManager", SCRIPT_SINGLETON "Allows reading and updating the network properties of an entity." )
|
||||
DEFINE_SCRIPTFUNC( GetPropArraySize, "Returns the size of an netprop array, or -1." )
|
||||
DEFINE_SCRIPTFUNC( GetPropEntity, "Reads an EHANDLE valued netprop (21 bit integer). Returns the script handle of the entity." )
|
||||
DEFINE_SCRIPTFUNC( GetPropEntityArray, "Reads an EHANDLE valued netprop (21 bit integer) from an array. Returns the script handle of the entity." )
|
||||
DEFINE_SCRIPTFUNC( GetPropFloat, "Reads a float valued netprop." )
|
||||
DEFINE_SCRIPTFUNC( GetPropFloatArray, "Reads a float valued netprop from an array." )
|
||||
DEFINE_SCRIPTFUNC( GetPropInt, "Reads an integer valued netprop." )
|
||||
DEFINE_SCRIPTFUNC( GetPropIntArray, "Reads an integer valued netprop from an array." )
|
||||
DEFINE_SCRIPTFUNC( GetPropString, "Reads a string valued netprop." )
|
||||
DEFINE_SCRIPTFUNC( GetPropStringArray, "Reads a string valued netprop from an array." )
|
||||
DEFINE_SCRIPTFUNC( GetPropVector, "Reads a 3D vector valued netprop." )
|
||||
DEFINE_SCRIPTFUNC( GetPropVectorArray, "Reads a 3D vector valued netprop from an array." )
|
||||
DEFINE_SCRIPTFUNC( GetPropType, "Returns the name of the netprop type as a string." )
|
||||
DEFINE_SCRIPTFUNC( HasProp, "Checks if a netprop exists." )
|
||||
DEFINE_SCRIPTFUNC( SetPropEntity, "Sets an EHANDLE valued netprop (21 bit integer) to reference the specified entity." )
|
||||
DEFINE_SCRIPTFUNC( SetPropEntityArray, "Sets an EHANDLE valued netprop (21 bit integer) from an array to reference the specified entity." )
|
||||
DEFINE_SCRIPTFUNC( SetPropFloat, "Sets a netprop to the specified float." )
|
||||
DEFINE_SCRIPTFUNC( SetPropFloatArray, "Sets a netprop from an array to the specified float." )
|
||||
DEFINE_SCRIPTFUNC( SetPropInt, "Sets a netprop to the specified integer." )
|
||||
DEFINE_SCRIPTFUNC( SetPropIntArray, "Sets a netprop from an array to the specified integer." )
|
||||
DEFINE_SCRIPTFUNC( SetPropString, "Sets a netprop to the specified string." )
|
||||
DEFINE_SCRIPTFUNC( SetPropStringArray, "Sets a netprop from an array to the specified string." )
|
||||
DEFINE_SCRIPTFUNC( SetPropVector, "Sets a netprop to the specified vector." )
|
||||
DEFINE_SCRIPTFUNC( SetPropVectorArray, "Sets a netprop from an array to the specified vector." )
|
||||
END_SCRIPTDESC();
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
class CScriptConvarLookup
|
||||
{
|
||||
public:
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
const char *GetClientConvarValue( const char *pszConVar, int entindex )
|
||||
{
|
||||
return engine->GetClientConVarValue( entindex, pszConVar );
|
||||
}
|
||||
#endif
|
||||
|
||||
const char *GetStr( const char *pszConVar )
|
||||
{
|
||||
ConVarRef cvar( pszConVar );
|
||||
return cvar.GetString();
|
||||
}
|
||||
|
||||
float GetFloat( const char *pszConVar )
|
||||
{
|
||||
ConVarRef cvar( pszConVar );
|
||||
return cvar.GetFloat();
|
||||
}
|
||||
|
||||
void SetValue( const char *pszConVar, const char *pszValue )
|
||||
{
|
||||
ConVarRef cvar( pszConVar );
|
||||
if (!cvar.IsValid())
|
||||
return;
|
||||
|
||||
// FCVAR_NOT_CONNECTED can be used to protect specific convars from nefarious interference
|
||||
if (cvar.IsFlagSet(FCVAR_NOT_CONNECTED))
|
||||
return;
|
||||
|
||||
cvar.SetValue( pszValue );
|
||||
}
|
||||
|
||||
private:
|
||||
} g_ScriptConvarLookup;
|
||||
|
||||
BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptConvarLookup, "CConvars", SCRIPT_SINGLETON "Provides an interface for getting and setting convars." )
|
||||
#ifndef CLIENT_DLL
|
||||
DEFINE_SCRIPTFUNC( GetClientConvarValue, "Returns the convar value for the entindex as a string. Only works with client convars with the FCVAR_USERINFO flag." )
|
||||
#endif
|
||||
DEFINE_SCRIPTFUNC( GetStr, "Returns the convar as a string. May return null if no such convar." )
|
||||
DEFINE_SCRIPTFUNC( GetFloat, "Returns the convar as a float. May return null if no such convar." )
|
||||
DEFINE_SCRIPTFUNC( SetValue, "Sets the value of the convar. Supported types are bool, int, float, string." )
|
||||
END_SCRIPTDESC();
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
void AddThinkToEnt( HSCRIPT entity, const char *pszFuncName )
|
||||
{
|
||||
CBaseEntity *pEntity = ToEnt( entity );
|
||||
if (!pEntity)
|
||||
return;
|
||||
|
||||
if (pszFuncName == NULL || pszFuncName[0] == '\0')
|
||||
pEntity->m_iszScriptThinkFunction = NULL_STRING;
|
||||
else
|
||||
pEntity->m_iszScriptThinkFunction = AllocPooledString(pszFuncName);
|
||||
|
||||
pEntity->SetContextThink( &CBaseEntity::ScriptThink, gpGlobals->curtime, "ScriptThink" );
|
||||
}
|
||||
|
||||
HSCRIPT EntIndexToHScript( int index )
|
||||
{
|
||||
return ToHScript( UTIL_EntityByIndex( index ) );
|
||||
}
|
||||
|
||||
void ParseScriptTableKeyValues( CBaseEntity *pEntity, HSCRIPT hKV )
|
||||
{
|
||||
int nIterator = -1;
|
||||
ScriptVariant_t varKey, varValue;
|
||||
while ((nIterator = g_pScriptVM->GetKeyValue( hKV, nIterator, &varKey, &varValue )) != -1)
|
||||
{
|
||||
switch (varValue.m_type)
|
||||
{
|
||||
case FIELD_CSTRING: pEntity->KeyValue( varKey.m_pszString, varValue.m_pszString ); break;
|
||||
case FIELD_FLOAT: pEntity->KeyValue( varKey.m_pszString, varValue.m_float ); break;
|
||||
case FIELD_VECTOR: pEntity->KeyValue( varKey.m_pszString, *varValue.m_pVector ); break;
|
||||
}
|
||||
|
||||
g_pScriptVM->ReleaseValue( varKey );
|
||||
g_pScriptVM->ReleaseValue( varValue );
|
||||
}
|
||||
}
|
||||
|
||||
void PrecacheEntityFromTable( const char *pszClassname, HSCRIPT hKV )
|
||||
{
|
||||
if ( IsEntityCreationAllowedInScripts() == false )
|
||||
{
|
||||
Warning( "VScript error: A script attempted to create an entity mid-game. Due to the server's settings, entity creation from scripts is only allowed during map init.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// This is similar to UTIL_PrecacheOther(), but we can't check if we can only precache it once.
|
||||
// Probably for the best anyway, as similar classes can still have different precachable properties.
|
||||
CBaseEntity *pEntity = CreateEntityByName( pszClassname );
|
||||
if (!pEntity)
|
||||
{
|
||||
Assert( !"PrecacheEntityFromTable: only works for CBaseEntities" );
|
||||
return;
|
||||
}
|
||||
|
||||
ParseScriptTableKeyValues( pEntity, hKV );
|
||||
|
||||
pEntity->Precache();
|
||||
|
||||
UTIL_RemoveImmediate( pEntity );
|
||||
}
|
||||
|
||||
HSCRIPT SpawnEntityFromTable( const char *pszClassname, HSCRIPT hKV )
|
||||
{
|
||||
if ( IsEntityCreationAllowedInScripts() == false )
|
||||
{
|
||||
Warning( "VScript error: A script attempted to create an entity mid-game. Due to the server's settings, entity creation from scripts is only allowed during map init.\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CBaseEntity *pEntity = CreateEntityByName( pszClassname );
|
||||
if ( !pEntity )
|
||||
{
|
||||
Assert( !"SpawnEntityFromTable: only works for CBaseEntities" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gEntList.NotifyCreateEntity( pEntity );
|
||||
|
||||
ParseScriptTableKeyValues( pEntity, hKV );
|
||||
|
||||
DispatchSpawn( pEntity );
|
||||
pEntity->Activate();
|
||||
|
||||
return ToHScript( pEntity );
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Mapbase-specific functions start here
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void ScriptColorPrint( int r, int g, int b, const char *pszMsg )
|
||||
{
|
||||
const Color clr(r, g, b, 255);
|
||||
ConColorMsg( clr, "%s", pszMsg );
|
||||
}
|
||||
|
||||
static void ScriptColorPrintL( int r, int g, int b, const char *pszMsg )
|
||||
{
|
||||
const Color clr(r, g, b, 255);
|
||||
ConColorMsg( clr, "%s\n", pszMsg );
|
||||
}
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
HSCRIPT SpawnEntityFromKeyValues( const char *pszClassname, HSCRIPT hKV )
|
||||
{
|
||||
if ( IsEntityCreationAllowedInScripts() == false )
|
||||
{
|
||||
Warning( "VScript error: A script attempted to create an entity mid-game. Due to the server's settings, entity creation from scripts is only allowed during map init.\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CBaseEntity *pEntity = CreateEntityByName( pszClassname );
|
||||
if ( !pEntity )
|
||||
{
|
||||
Assert( !"SpawnEntityFromKeyValues: only works for CBaseEntities" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gEntList.NotifyCreateEntity( pEntity );
|
||||
|
||||
CScriptKeyValues *pScriptKV = hKV ? HScriptToClass<CScriptKeyValues>( hKV ) : NULL;
|
||||
if (pScriptKV)
|
||||
{
|
||||
KeyValues *pKV = pScriptKV->m_pKeyValues;
|
||||
for (pKV = pKV->GetFirstSubKey(); pKV != NULL; pKV = pKV->GetNextKey())
|
||||
{
|
||||
pEntity->KeyValue( pKV->GetName(), pKV->GetString() );
|
||||
}
|
||||
}
|
||||
|
||||
DispatchSpawn( pEntity );
|
||||
pEntity->Activate();
|
||||
|
||||
return ToHScript( pEntity );
|
||||
}
|
||||
|
||||
void ScriptDispatchSpawn( HSCRIPT hEntity )
|
||||
{
|
||||
CBaseEntity *pEntity = ToEnt( hEntity );
|
||||
if (pEntity)
|
||||
{
|
||||
DispatchSpawn( pEntity );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
static HSCRIPT CreateDamageInfo( HSCRIPT hInflictor, HSCRIPT hAttacker, const Vector &vecForce, const Vector &vecDamagePos, float flDamage, int iDamageType )
|
||||
{
|
||||
// The script is responsible for deleting this via DestroyDamageInfo().
|
||||
CTakeDamageInfo *damageInfo = new CTakeDamageInfo(ToEnt(hInflictor), ToEnt(hAttacker), flDamage, iDamageType);
|
||||
HSCRIPT hScript = g_pScriptVM->RegisterInstance( damageInfo );
|
||||
|
||||
damageInfo->SetDamagePosition( vecDamagePos );
|
||||
damageInfo->SetDamageForce( vecForce );
|
||||
|
||||
return hScript;
|
||||
}
|
||||
|
||||
static void DestroyDamageInfo( HSCRIPT hDamageInfo )
|
||||
{
|
||||
if (hDamageInfo)
|
||||
{
|
||||
CTakeDamageInfo *pInfo = (CTakeDamageInfo*)g_pScriptVM->GetInstanceValue( hDamageInfo, GetScriptDescForClass( CTakeDamageInfo ) );
|
||||
if (pInfo)
|
||||
{
|
||||
g_pScriptVM->RemoveInstance( hDamageInfo );
|
||||
delete pInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptCalculateExplosiveDamageForce( HSCRIPT info, const Vector &vecDir, const Vector &vecForceOrigin, float flScale ) { CalculateExplosiveDamageForce( HScriptToClass<CTakeDamageInfo>(info), vecDir, vecForceOrigin, flScale ); }
|
||||
void ScriptCalculateBulletDamageForce( HSCRIPT info, int iBulletType, const Vector &vecBulletDir, const Vector &vecForceOrigin, float flScale ) { CalculateBulletDamageForce( HScriptToClass<CTakeDamageInfo>(info), iBulletType, vecBulletDir, vecForceOrigin, flScale ); }
|
||||
void ScriptCalculateMeleeDamageForce( HSCRIPT info, const Vector &vecMeleeDir, const Vector &vecForceOrigin, float flScale ) { CalculateMeleeDamageForce( HScriptToClass<CTakeDamageInfo>( info ), vecMeleeDir, vecForceOrigin, flScale ); }
|
||||
void ScriptGuessDamageForce( HSCRIPT info, const Vector &vecForceDir, const Vector &vecForceOrigin, float flScale ) { GuessDamageForce( HScriptToClass<CTakeDamageInfo>( info ), vecForceDir, vecForceOrigin, flScale ); }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
class CTraceInfoAccessor
|
||||
{
|
||||
public:
|
||||
|
||||
// CGrameTrace stuff
|
||||
bool DidHitWorld() const { return m_tr.DidHitWorld(); }
|
||||
bool DidHitNonWorldEntity() const { return m_tr.DidHitNonWorldEntity(); }
|
||||
int GetEntityIndex() const { return m_tr.GetEntityIndex(); }
|
||||
bool DidHit() const { return m_tr.DidHit(); }
|
||||
|
||||
float FractionLeftSolid() const { return m_tr.fractionleftsolid; }
|
||||
int HitGroup() const { return m_tr.hitgroup; }
|
||||
int PhysicsBone() const { return m_tr.physicsbone; }
|
||||
|
||||
HSCRIPT Entity() const { return ToHScript(m_tr.m_pEnt); }
|
||||
|
||||
int HitBox() const { return m_tr.hitbox; }
|
||||
|
||||
// CBaseTrace stuff
|
||||
bool IsDispSurface() { return m_tr.IsDispSurface(); }
|
||||
bool IsDispSurfaceWalkable() { return m_tr.IsDispSurfaceWalkable(); }
|
||||
bool IsDispSurfaceBuildable() { return m_tr.IsDispSurfaceBuildable(); }
|
||||
bool IsDispSurfaceProp1() { return m_tr.IsDispSurfaceProp1(); }
|
||||
bool IsDispSurfaceProp2() { return m_tr.IsDispSurfaceProp2(); }
|
||||
|
||||
Vector StartPos() const { return m_tr.startpos; }
|
||||
Vector EndPos() const { return m_tr.endpos; }
|
||||
|
||||
float Fraction() const { return m_tr.fraction; }
|
||||
|
||||
int Contents() const { return m_tr.contents; }
|
||||
int DispFlags() const { return m_tr.dispFlags; }
|
||||
|
||||
bool AllSolid() const { return m_tr.allsolid; }
|
||||
bool StartSolid() const { return m_tr.startsolid; }
|
||||
|
||||
trace_t &GetTrace() { return m_tr; }
|
||||
void Destroy() { delete this; }
|
||||
|
||||
private:
|
||||
trace_t m_tr;
|
||||
|
||||
};
|
||||
|
||||
BEGIN_SCRIPTDESC_ROOT_NAMED( CTraceInfoAccessor, "CGameTrace", "Handle for accessing trace_t info." )
|
||||
DEFINE_SCRIPTFUNC( DidHitWorld, "Returns whether the trace hit the world entity or not." )
|
||||
DEFINE_SCRIPTFUNC( DidHitNonWorldEntity, "Returns whether the trace hit something other than the world entity." )
|
||||
DEFINE_SCRIPTFUNC( GetEntityIndex, "Returns the index of whatever entity this trace hit." )
|
||||
DEFINE_SCRIPTFUNC( DidHit, "Returns whether the trace hit anything." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( FractionLeftSolid, "If this trace started within a solid, this is the point in the trace's fraction at which it left that solid." )
|
||||
DEFINE_SCRIPTFUNC( HitGroup, "Returns the specific hit group this trace hit if it hit an entity." )
|
||||
DEFINE_SCRIPTFUNC( PhysicsBone, "Returns the physics bone this trace hit if it hit an entity." )
|
||||
DEFINE_SCRIPTFUNC( Entity, "Returns the entity this trace has hit." )
|
||||
DEFINE_SCRIPTFUNC( HitBox, "Returns the hitbox of the entity this trace has hit. If it hit the world entity, this returns the static prop index." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( IsDispSurface, "Returns whether this trace hit a displacement." )
|
||||
DEFINE_SCRIPTFUNC( IsDispSurfaceWalkable, "Returns whether DISPSURF_FLAG_WALKABLE is ticked on the displacement this trace hit." )
|
||||
DEFINE_SCRIPTFUNC( IsDispSurfaceBuildable, "Returns whether DISPSURF_FLAG_BUILDABLE is ticked on the displacement this trace hit." )
|
||||
DEFINE_SCRIPTFUNC( IsDispSurfaceProp1, "Returns whether DISPSURF_FLAG_SURFPROP1 is ticked on the displacement this trace hit." )
|
||||
DEFINE_SCRIPTFUNC( IsDispSurfaceProp2, "Returns whether DISPSURF_FLAG_SURFPROP2 is ticked on the displacement this trace hit." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( StartPos, "Gets the trace's start position." )
|
||||
DEFINE_SCRIPTFUNC( EndPos, "Gets the trace's end position." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( Fraction, "Gets the fraction of the trace completed. For example, if the trace stopped exactly halfway to the end position, this would be 0.5." )
|
||||
DEFINE_SCRIPTFUNC( Contents, "Gets the contents of the surface the trace has hit." )
|
||||
DEFINE_SCRIPTFUNC( DispFlags, "Gets the displacement flags of the surface the trace has hit." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( AllSolid, "Returns whether the trace is completely within a solid." )
|
||||
DEFINE_SCRIPTFUNC( StartSolid, "Returns whether the trace started within a solid." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( Destroy, "Deletes this instance. Important for preventing memory leaks." )
|
||||
END_SCRIPTDESC();
|
||||
|
||||
static HSCRIPT ScriptTraceLineComplex( const Vector &vecStart, const Vector &vecEnd, HSCRIPT entIgnore, int iMask, int iCollisionGroup )
|
||||
{
|
||||
// The script is responsible for deleting this via Destroy().
|
||||
CTraceInfoAccessor *traceInfo = new CTraceInfoAccessor();
|
||||
HSCRIPT hScript = g_pScriptVM->RegisterInstance( traceInfo );
|
||||
|
||||
CBaseEntity *pLooker = ToEnt(entIgnore);
|
||||
UTIL_TraceLine( vecStart, vecEnd, iMask, pLooker, iCollisionGroup, &traceInfo->GetTrace());
|
||||
return hScript;
|
||||
}
|
||||
|
||||
static HSCRIPT ScriptTraceHullComplex( const Vector &vecStart, const Vector &vecEnd, const Vector &hullMin, const Vector &hullMax,
|
||||
HSCRIPT entIgnore, int iMask, int iCollisionGroup )
|
||||
{
|
||||
// The script is responsible for deleting this via Destroy().
|
||||
CTraceInfoAccessor *traceInfo = new CTraceInfoAccessor();
|
||||
HSCRIPT hScript = g_pScriptVM->RegisterInstance( traceInfo );
|
||||
|
||||
CBaseEntity *pLooker = ToEnt(entIgnore);
|
||||
UTIL_TraceHull( vecStart, vecEnd, hullMin, hullMax, iMask, pLooker, iCollisionGroup, &traceInfo->GetTrace());
|
||||
return hScript;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
BEGIN_SCRIPTDESC_ROOT_NAMED( CFireBulletsInfoAccessor, "FireBulletsInfo_t", "Handle for accessing FireBulletsInfo_t info." )
|
||||
DEFINE_SCRIPTFUNC( GetShots, "Gets the number of shots which should be fired." )
|
||||
DEFINE_SCRIPTFUNC( SetShots, "Sets the number of shots which should be fired." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetSource, "Gets the source of the bullets." )
|
||||
DEFINE_SCRIPTFUNC( SetSource, "Sets the source of the bullets." )
|
||||
DEFINE_SCRIPTFUNC( GetDirShooting, "Gets the direction of the bullets." )
|
||||
DEFINE_SCRIPTFUNC( SetDirShooting, "Sets the direction of the bullets." )
|
||||
DEFINE_SCRIPTFUNC( GetSpread, "Gets the spread of the bullets." )
|
||||
DEFINE_SCRIPTFUNC( SetSpread, "Sets the spread of the bullets." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetDistance, "Gets the distance the bullets should travel." )
|
||||
DEFINE_SCRIPTFUNC( SetDistance, "Sets the distance the bullets should travel." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetAmmoType, "Gets the ammo type the bullets should use." )
|
||||
DEFINE_SCRIPTFUNC( SetAmmoType, "Sets the ammo type the bullets should use." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetTracerFreq, "Gets the tracer frequency." )
|
||||
DEFINE_SCRIPTFUNC( SetTracerFreq, "Sets the tracer frequency." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetDamage, "Gets the damage the bullets should deal. 0 = use ammo type" )
|
||||
DEFINE_SCRIPTFUNC( SetDamage, "Sets the damage the bullets should deal. 0 = use ammo type" )
|
||||
DEFINE_SCRIPTFUNC( GetPlayerDamage, "Gets the damage the bullets should deal when hitting the player. 0 = use regular damage" )
|
||||
DEFINE_SCRIPTFUNC( SetPlayerDamage, "Sets the damage the bullets should deal when hitting the player. 0 = use regular damage" )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetFlags, "Gets the flags the bullets should use." )
|
||||
DEFINE_SCRIPTFUNC( SetFlags, "Sets the flags the bullets should use." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetDamageForceScale, "Gets the scale of the damage force applied by the bullets." )
|
||||
DEFINE_SCRIPTFUNC( SetDamageForceScale, "Sets the scale of the damage force applied by the bullets." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetAttacker, "Gets the entity considered to be the one who fired the bullets." )
|
||||
DEFINE_SCRIPTFUNC( SetAttacker, "Sets the entity considered to be the one who fired the bullets." )
|
||||
DEFINE_SCRIPTFUNC( GetAdditionalIgnoreEnt, "Gets the optional entity which the bullets should ignore." )
|
||||
DEFINE_SCRIPTFUNC( SetAdditionalIgnoreEnt, "Sets the optional entity which the bullets should ignore." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetPrimaryAttack, "Gets whether the bullets came from a primary attack." )
|
||||
DEFINE_SCRIPTFUNC( SetPrimaryAttack, "Sets whether the bullets came from a primary attack." )
|
||||
|
||||
//DEFINE_SCRIPTFUNC( Destroy, "Deletes this instance. Important for preventing memory leaks." )
|
||||
END_SCRIPTDESC();
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CFireBulletsInfoAccessor::GetAttacker()
|
||||
{
|
||||
return ToHScript( m_info->m_pAttacker );
|
||||
}
|
||||
|
||||
void CFireBulletsInfoAccessor::SetAttacker( HSCRIPT value )
|
||||
{
|
||||
m_info->m_pAttacker = ToEnt( value );
|
||||
}
|
||||
|
||||
HSCRIPT CFireBulletsInfoAccessor::GetAdditionalIgnoreEnt()
|
||||
{
|
||||
return ToHScript( m_info->m_pAdditionalIgnoreEnt );
|
||||
}
|
||||
|
||||
void CFireBulletsInfoAccessor::SetAdditionalIgnoreEnt( HSCRIPT value )
|
||||
{
|
||||
m_info->m_pAdditionalIgnoreEnt = ToEnt( value );
|
||||
}
|
||||
|
||||
static HSCRIPT CreateFireBulletsInfo( int cShots, const Vector &vecSrc, const Vector &vecDirShooting,
|
||||
const Vector &vecSpread, float iDamage, HSCRIPT pAttacker )
|
||||
{
|
||||
// The script is responsible for deleting this via DestroyFireBulletsInfo().
|
||||
FireBulletsInfo_t *info = new FireBulletsInfo_t();
|
||||
CFireBulletsInfoAccessor *bulletsInfo = new CFireBulletsInfoAccessor( info );
|
||||
|
||||
HSCRIPT hScript = g_pScriptVM->RegisterInstance( bulletsInfo );
|
||||
|
||||
bulletsInfo->SetShots( cShots );
|
||||
bulletsInfo->SetSource( vecSrc );
|
||||
bulletsInfo->SetDirShooting( vecDirShooting );
|
||||
bulletsInfo->SetSpread( vecSpread );
|
||||
bulletsInfo->SetDamage( iDamage );
|
||||
bulletsInfo->SetAttacker( pAttacker );
|
||||
|
||||
return hScript;
|
||||
}
|
||||
|
||||
static void DestroyFireBulletsInfo( HSCRIPT hBulletsInfo )
|
||||
{
|
||||
if (hBulletsInfo)
|
||||
{
|
||||
CFireBulletsInfoAccessor *pInfo = (CFireBulletsInfoAccessor*)g_pScriptVM->GetInstanceValue( hBulletsInfo, GetScriptDescForClass( CFireBulletsInfoAccessor ) );
|
||||
if (pInfo)
|
||||
{
|
||||
g_pScriptVM->RemoveInstance( hBulletsInfo );
|
||||
pInfo->Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For the function in baseentity.cpp
|
||||
FireBulletsInfo_t *GetFireBulletsInfoFromInfo( HSCRIPT hBulletsInfo )
|
||||
{
|
||||
if (hBulletsInfo)
|
||||
{
|
||||
CFireBulletsInfoAccessor *pInfo = (CFireBulletsInfoAccessor*)g_pScriptVM->GetInstanceValue( hBulletsInfo, GetScriptDescForClass( CFireBulletsInfoAccessor ) );
|
||||
if (pInfo)
|
||||
{
|
||||
return pInfo->GetInfo();
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
|
||||
static void ScriptEntitiesInBox( HSCRIPT hTable, int listMax, const Vector &hullMin, const Vector &hullMax, int iMask )
|
||||
{
|
||||
CBaseEntity *list[1024];
|
||||
int count = UTIL_EntitiesInBox( list, listMax, hullMin, hullMax, iMask );
|
||||
|
||||
for ( int i = 0; i < count; i++ )
|
||||
{
|
||||
g_pScriptVM->SetValue( hTable, STRING(list[i]->GetEntityName()), ToHScript( list[i] ) );
|
||||
}
|
||||
}
|
||||
|
||||
static void ScriptEntitiesAtPoint( HSCRIPT hTable, int listMax, const Vector &point, int iMask )
|
||||
{
|
||||
CBaseEntity *list[1024];
|
||||
int count = UTIL_EntitiesAtPoint( list, listMax, point, iMask );
|
||||
|
||||
for ( int i = 0; i < count; i++ )
|
||||
{
|
||||
g_pScriptVM->SetValue( hTable, STRING(list[i]->GetEntityName()), ToHScript( list[i] ) );
|
||||
}
|
||||
}
|
||||
|
||||
static void ScriptEntitiesInSphere( HSCRIPT hTable, int listMax, const Vector ¢er, float radius, int iMask )
|
||||
{
|
||||
CBaseEntity *list[1024];
|
||||
int count = UTIL_EntitiesInSphere( list, listMax, center, radius, iMask );
|
||||
|
||||
for ( int i = 0; i < count; i++ )
|
||||
{
|
||||
g_pScriptVM->SetValue( hTable, STRING(list[i]->GetEntityName()), ToHScript( list[i] ) );
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
|
||||
bool ScriptMatcherMatch( const char *pszQuery, const char *szValue ) { return Matcher_Match( pszQuery, szValue ); }
|
||||
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
|
||||
extern void RegisterMathScriptFunctions();
|
||||
|
||||
void RegisterSharedScriptFunctions()
|
||||
{
|
||||
//
|
||||
// Due to this being a custom integration of VScript based on the Alien Swarm SDK, we don't have access to
|
||||
// some of the code normally available in games like L4D2 or Valve's original VScript DLL.
|
||||
// Instead, that code is recreated here, shared between server and client.
|
||||
//
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, NDebugOverlay::BoxDirection, "DebugDrawBoxDirection", "Draw a debug forward box" );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, NDebugOverlay::Text, "DebugDrawText", "Draw a debug overlay text" );
|
||||
|
||||
ScriptRegisterFunction( g_pScriptVM, AddThinkToEnt, "This will put a think function onto an entity, or pass null to remove it. This is NOT chained, so be careful." );
|
||||
ScriptRegisterFunction( g_pScriptVM, EntIndexToHScript, "Returns the script handle for the given entity index." );
|
||||
ScriptRegisterFunction( g_pScriptVM, PrecacheEntityFromTable, "Precache an entity from KeyValues in a table." );
|
||||
ScriptRegisterFunction( g_pScriptVM, SpawnEntityFromTable, "Native function for entity spawning." );
|
||||
#endif
|
||||
|
||||
g_pScriptVM->RegisterInstance( &g_ScriptConvarLookup, "Convars" );
|
||||
g_pScriptVM->RegisterInstance( &g_ScriptNetPropManager, "NetProps" );
|
||||
|
||||
// Functions unique to Mapbase
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptColorPrint, "printc", "Version of print() which takes a color before the message." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptColorPrintL, "printcl", "Version of printl() which takes a color before the message." );
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
ScriptRegisterFunction( g_pScriptVM, SpawnEntityFromKeyValues, "Spawns an entity with the keyvalues in a CScriptKeyValues handle." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptDispatchSpawn, "DispatchSpawn", "Spawns an unspawned entity." );
|
||||
#endif
|
||||
|
||||
ScriptRegisterFunction( g_pScriptVM, CreateDamageInfo, "Creates damage info." );
|
||||
ScriptRegisterFunction( g_pScriptVM, DestroyDamageInfo, "Destroys damage info." );
|
||||
ScriptRegisterFunction( g_pScriptVM, ImpulseScale, "Returns an impulse scale required to push an object." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCalculateExplosiveDamageForce, "CalculateExplosiveDamageForce", "Fill out a damage info handle with a damage force for an explosive." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCalculateBulletDamageForce, "CalculateBulletDamageForce", "Fill out a damage info handle with a damage force for a bullet impact." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCalculateMeleeDamageForce, "CalculateMeleeDamageForce", "Fill out a damage info handle with a damage force for a melee impact." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptGuessDamageForce, "GuessDamageForce", "Try and guess the physics force to use." );
|
||||
|
||||
ScriptRegisterFunction( g_pScriptVM, CreateFireBulletsInfo, "Creates FireBullets info." );
|
||||
ScriptRegisterFunction( g_pScriptVM, DestroyFireBulletsInfo, "Destroys FireBullets info." );
|
||||
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptTraceLineComplex, "TraceLineComplex", "Complex version of TraceLine which takes 2 points, an ent to ignore, a trace mask, and a collision group. Returns a handle which can access all trace info." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptTraceHullComplex, "TraceHullComplex", "Takes 2 points, min/max hull bounds, an ent to ignore, a trace mask, and a collision group to trace to a point using a hull. Returns a handle which can access all trace info." );
|
||||
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptEntitiesInBox, "EntitiesInBox", "Gets all entities which are within a worldspace box." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptEntitiesAtPoint, "EntitiesAtPoint", "Gets all entities which are intersecting a point in space." );
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptEntitiesInSphere, "EntitiesInSphere", "Gets all entities which are within a sphere." );
|
||||
|
||||
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptMatcherMatch, "Matcher_Match", "Compares a string to a query using Mapbase's matcher system, supporting wildcards, RS matchers, etc." );
|
||||
ScriptRegisterFunction( g_pScriptVM, Matcher_NamesMatch, "Compares a string to a query using Mapbase's matcher system using wildcards only." );
|
||||
ScriptRegisterFunction( g_pScriptVM, AppearsToBeANumber, "Checks if the given string appears to be a number." );
|
||||
|
||||
RegisterMathScriptFunctions();
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
VScriptRunScript( "vscript_client", true );
|
||||
#else
|
||||
VScriptRunScript( "vscript_server", true );
|
||||
#endif
|
||||
}
|
@ -36,6 +36,7 @@ public:
|
||||
m_pEvent( 0 ),
|
||||
m_pScene( 0 ),
|
||||
m_pActor( 0 ),
|
||||
m_hSceneEntity(0),
|
||||
m_bStarted( false ),
|
||||
m_iLayer( -1 ),
|
||||
m_iPriority( 0 ),
|
||||
@ -63,6 +64,8 @@ public:
|
||||
// Current actor
|
||||
CChoreoActor *m_pActor;
|
||||
|
||||
CHandle< CSceneEntity > m_hSceneEntity;
|
||||
|
||||
// Set after the first time the event has been configured ( allows
|
||||
// bumping markov index only at start of event playback, not every frame )
|
||||
bool m_bStarted;
|
||||
|
@ -31,6 +31,60 @@ BEGIN_SIMPLE_DATADESC( CTakeDamageInfo )
|
||||
DEFINE_FIELD( m_iDamagedOtherPlayers, FIELD_INTEGER),
|
||||
END_DATADESC()
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
BEGIN_SCRIPTDESC_ROOT( CTakeDamageInfo, "Damage information handler." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetInflictor, "GetInflictor", "Gets the inflictor." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetInflictor, "SetInflictor", "Sets the inflictor." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetWeapon, "GetWeapon", "Gets the weapon." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetWeapon, "SetWeapon", "Sets the weapon." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptGetAttacker, "GetAttacker", "Gets the attacker." )
|
||||
DEFINE_SCRIPTFUNC_NAMED( ScriptSetAttacker, "SetAttacker", "Sets the attacker." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetDamage, "Gets the damage." )
|
||||
DEFINE_SCRIPTFUNC( SetDamage, "Sets the damage." )
|
||||
DEFINE_SCRIPTFUNC( GetMaxDamage, "Gets the max damage." )
|
||||
DEFINE_SCRIPTFUNC( SetMaxDamage, "Sets the max damage." )
|
||||
DEFINE_SCRIPTFUNC( ScaleDamage, "Scales the damage." )
|
||||
DEFINE_SCRIPTFUNC( AddDamage, "Adds to the damage." )
|
||||
DEFINE_SCRIPTFUNC( SubtractDamage, "Removes from the damage." )
|
||||
DEFINE_SCRIPTFUNC( GetDamageBonus, "Gets the damage bonus." )
|
||||
DEFINE_SCRIPTFUNC( SetDamageBonus, "Sets the damage bonus." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetBaseDamage, "Gets the base damage." )
|
||||
DEFINE_SCRIPTFUNC( BaseDamageIsValid, "Checks if the base damage is valid." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetDamageForce, "Gets the damage force." )
|
||||
DEFINE_SCRIPTFUNC( SetDamageForce, "Sets the damage force." )
|
||||
DEFINE_SCRIPTFUNC( ScaleDamageForce, "Scales the damage force." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetDamagePosition, "Gets the damage position." )
|
||||
DEFINE_SCRIPTFUNC( SetDamagePosition, "Sets the damage position." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetReportedPosition, "Gets the reported damage position." )
|
||||
DEFINE_SCRIPTFUNC( SetReportedPosition, "Sets the reported damage position." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetDamageType, "Gets the damage type." )
|
||||
DEFINE_SCRIPTFUNC( SetDamageType, "Sets the damage type." )
|
||||
DEFINE_SCRIPTFUNC( AddDamageType, "Adds to the damage type." )
|
||||
DEFINE_SCRIPTFUNC( GetDamageCustom, "Gets the damage custom." )
|
||||
DEFINE_SCRIPTFUNC( SetDamageCustom, "Sets the damage custom." )
|
||||
DEFINE_SCRIPTFUNC( GetDamageStats, "Gets the damage stats." )
|
||||
DEFINE_SCRIPTFUNC( SetDamageStats, "Sets the damage stats." )
|
||||
DEFINE_SCRIPTFUNC( IsForceFriendlyFire, "Gets force friendly fire." )
|
||||
DEFINE_SCRIPTFUNC( SetForceFriendlyFire, "Sets force friendly fire." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetAmmoType, "Gets the ammo type." )
|
||||
DEFINE_SCRIPTFUNC( SetAmmoType, "Sets the ammo type." )
|
||||
DEFINE_SCRIPTFUNC( GetAmmoName, "Gets the ammo type name." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetPlayerPenetrationCount, "Gets the player penetration count." )
|
||||
DEFINE_SCRIPTFUNC( SetPlayerPenetrationCount, "Sets the player penetration count." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetDamagedOtherPlayers, "Gets whether other players have been damaged." )
|
||||
DEFINE_SCRIPTFUNC( SetDamagedOtherPlayers, "Sets whether other players have been damaged." )
|
||||
END_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
void CTakeDamageInfo::Init( CBaseEntity *pInflictor, CBaseEntity *pAttacker, CBaseEntity *pWeapon, const Vector &damageForce, const Vector &damagePosition, const Vector &reportedPosition, float flDamage, int bitsDamageType, int iCustomDamage )
|
||||
{
|
||||
m_hInflictor = pInflictor;
|
||||
@ -166,6 +220,50 @@ const char *CTakeDamageInfo::GetAmmoName() const
|
||||
return pszAmmoType;
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CTakeDamageInfo::ScriptGetInflictor() const
|
||||
{
|
||||
return ToHScript( GetInflictor() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTakeDamageInfo::ScriptSetInflictor( HSCRIPT pInflictor )
|
||||
{
|
||||
SetInflictor( ToEnt( pInflictor ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CTakeDamageInfo::ScriptGetWeapon() const
|
||||
{
|
||||
return ToHScript( GetWeapon() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTakeDamageInfo::ScriptSetWeapon( HSCRIPT pWeapon )
|
||||
{
|
||||
SetWeapon( ToEnt( pWeapon ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
HSCRIPT CTakeDamageInfo::ScriptGetAttacker() const
|
||||
{
|
||||
return ToHScript( GetAttacker() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTakeDamageInfo::ScriptSetAttacker( HSCRIPT pAttacker )
|
||||
{
|
||||
SetAttacker( ToEnt( pAttacker ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
// -------------------------------------------------------------------------------------------------- //
|
||||
// MultiDamage
|
||||
// Collects multiple small damages into a single damage
|
||||
|
@ -14,6 +14,10 @@
|
||||
|
||||
#include "networkvar.h" // todo: change this when DECLARE_CLASS is moved into a better location.
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
#include "vscript/ivscript.h"
|
||||
#endif
|
||||
|
||||
// Used to initialize m_flBaseDamage to something that we know pretty much for sure
|
||||
// hasn't been modified by a user.
|
||||
#define BASEDAMAGE_NOT_SPECIFIED FLT_MAX
|
||||
@ -102,6 +106,15 @@ public:
|
||||
// For designer debug output.
|
||||
static void DebugGetDamageTypeString(unsigned int DamageType, char *outbuf, int outbuflength );
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
HSCRIPT ScriptGetInflictor() const;
|
||||
void ScriptSetInflictor( HSCRIPT pInflictor );
|
||||
HSCRIPT ScriptGetWeapon() const;
|
||||
void ScriptSetWeapon( HSCRIPT pWeapon );
|
||||
HSCRIPT ScriptGetAttacker() const;
|
||||
void ScriptSetAttacker( HSCRIPT pAttacker );
|
||||
#endif
|
||||
|
||||
|
||||
//private:
|
||||
void CopyDamageToBaseDamage();
|
||||
|
276
sp/src/game/shared/vscript_shared.cpp
Normal file
276
sp/src/game/shared/vscript_shared.cpp
Normal file
@ -0,0 +1,276 @@
|
||||
//========== Copyright © 2008, Valve Corporation, All rights reserved. ========
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "cbase.h"
|
||||
#include "vscript_shared.h"
|
||||
#include "icommandline.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "tier1/fmtstr.h"
|
||||
#include "filesystem.h"
|
||||
#include "characterset.h"
|
||||
#include "isaverestore.h"
|
||||
#include "gamerules.h"
|
||||
|
||||
IScriptVM * g_pScriptVM;
|
||||
extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * );
|
||||
|
||||
// #define VMPROFILE 1
|
||||
|
||||
#ifdef VMPROFILE
|
||||
|
||||
#define VMPROF_START float debugStartTime = Plat_FloatTime();
|
||||
#define VMPROF_SHOW( funcname, funcdesc ) DevMsg("***VSCRIPT PROFILE***: %s %s: %6.4f milliseconds\n", (##funcname), (##funcdesc), (Plat_FloatTime() - debugStartTime)*1000.0 );
|
||||
|
||||
#else // !VMPROFILE
|
||||
|
||||
#define VMPROF_START
|
||||
#define VMPROF_SHOW
|
||||
|
||||
#endif // VMPROFILE
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
// This is to ensure a dependency exists between the vscript library and the game DLLs
|
||||
extern int vscript_token;
|
||||
int vscript_token_hack = vscript_token;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
HSCRIPT VScriptCompileScript( const char *pszScriptName, bool bWarnMissing )
|
||||
{
|
||||
if ( !g_pScriptVM )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *pszExtensions[] =
|
||||
{
|
||||
"", // SL_NONE
|
||||
".gm", // SL_GAMEMONKEY
|
||||
".nut", // SL_SQUIRREL
|
||||
".lua", // SL_LUA
|
||||
".py", // SL_PYTHON
|
||||
};
|
||||
|
||||
const char *pszVMExtension = pszExtensions[g_pScriptVM->GetLanguage()];
|
||||
const char *pszIncomingExtension = V_strrchr( pszScriptName , '.' );
|
||||
if ( pszIncomingExtension && V_strcmp( pszIncomingExtension, pszVMExtension ) != 0 )
|
||||
{
|
||||
Warning( "Script file type does not match VM type\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CFmtStr scriptPath;
|
||||
if ( pszIncomingExtension )
|
||||
{
|
||||
scriptPath.sprintf( "scripts/vscripts/%s", pszScriptName );
|
||||
}
|
||||
else
|
||||
{
|
||||
scriptPath.sprintf( "scripts/vscripts/%s%s", pszScriptName, pszVMExtension );
|
||||
}
|
||||
|
||||
const char *pBase;
|
||||
CUtlBuffer bufferScript;
|
||||
|
||||
if ( g_pScriptVM->GetLanguage() == SL_PYTHON )
|
||||
{
|
||||
// python auto-loads raw or precompiled modules - don't load data here
|
||||
pBase = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool bResult = filesystem->ReadFile( scriptPath, "GAME", bufferScript );
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
if ( !bResult && bWarnMissing )
|
||||
#else
|
||||
if( !bResult )
|
||||
#endif
|
||||
{
|
||||
Warning( "Script not found (%s) \n", scriptPath.operator const char *() );
|
||||
Assert( "Error running script" );
|
||||
}
|
||||
|
||||
pBase = (const char *) bufferScript.Base();
|
||||
|
||||
if ( !pBase || !*pBase )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char *pszFilename = V_strrchr( scriptPath, '/' );
|
||||
pszFilename++;
|
||||
HSCRIPT hScript = g_pScriptVM->CompileScript( pBase, pszFilename );
|
||||
if ( !hScript )
|
||||
{
|
||||
Warning( "FAILED to compile and execute script file named %s\n", scriptPath.operator const char *() );
|
||||
Assert( "Error running script" );
|
||||
}
|
||||
return hScript;
|
||||
}
|
||||
|
||||
static int g_ScriptServerRunScriptDepth;
|
||||
|
||||
bool VScriptRunScript( const char *pszScriptName, HSCRIPT hScope, bool bWarnMissing )
|
||||
{
|
||||
if ( !g_pScriptVM )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !pszScriptName || !*pszScriptName )
|
||||
{
|
||||
Warning( "Cannot run script: NULL script name\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prevent infinite recursion in VM
|
||||
if ( g_ScriptServerRunScriptDepth > 16 )
|
||||
{
|
||||
Warning( "IncludeScript stack overflow\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
g_ScriptServerRunScriptDepth++;
|
||||
HSCRIPT hScript = VScriptCompileScript( pszScriptName, bWarnMissing );
|
||||
bool bSuccess = false;
|
||||
if ( hScript )
|
||||
{
|
||||
#ifdef GAME_DLL
|
||||
if ( gpGlobals->maxClients == 1 )
|
||||
{
|
||||
CBaseEntity *pPlayer = UTIL_GetLocalPlayer();
|
||||
if ( pPlayer )
|
||||
{
|
||||
g_pScriptVM->SetValue( "player", pPlayer->GetScriptInstance() );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
bSuccess = ( g_pScriptVM->Run( hScript, hScope ) != SCRIPT_ERROR );
|
||||
if ( !bSuccess )
|
||||
{
|
||||
Warning( "Error running script named %s\n", pszScriptName );
|
||||
Assert( "Error running script" );
|
||||
}
|
||||
}
|
||||
g_ScriptServerRunScriptDepth--;
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
CON_COMMAND( script_client, "Run the text as a script" )
|
||||
#else
|
||||
CON_COMMAND( script, "Run the text as a script" )
|
||||
#endif
|
||||
{
|
||||
if ( !*args[1] )
|
||||
{
|
||||
Warning( "No function name specified\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !g_pScriptVM )
|
||||
{
|
||||
Warning( "Scripting disabled or no server running\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
const char *pszScript = args.GetCommandString();
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
pszScript += 13;
|
||||
#else
|
||||
pszScript += 6;
|
||||
#endif
|
||||
|
||||
while ( *pszScript == ' ' )
|
||||
{
|
||||
pszScript++;
|
||||
}
|
||||
|
||||
if ( !*pszScript )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( *pszScript != '\"' )
|
||||
{
|
||||
g_pScriptVM->Run( pszScript );
|
||||
}
|
||||
else
|
||||
{
|
||||
pszScript++;
|
||||
const char *pszEndQuote = pszScript;
|
||||
while ( *pszEndQuote != '\"' )
|
||||
{
|
||||
pszEndQuote++;
|
||||
}
|
||||
if ( !*pszEndQuote )
|
||||
{
|
||||
return;
|
||||
}
|
||||
*((char *)pszEndQuote) = 0;
|
||||
g_pScriptVM->Run( pszScript );
|
||||
*((char *)pszEndQuote) = '\"';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CON_COMMAND_SHARED( script_execute, "Run a vscript file" )
|
||||
{
|
||||
if ( !*args[1] )
|
||||
{
|
||||
Warning( "No script specified\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !g_pScriptVM )
|
||||
{
|
||||
Warning( "Scripting disabled or no server running\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
VScriptRunScript( args[1], true );
|
||||
}
|
||||
|
||||
CON_COMMAND_SHARED( script_debug, "Connect the vscript VM to the script debugger" )
|
||||
{
|
||||
if ( !g_pScriptVM )
|
||||
{
|
||||
Warning( "Scripting disabled or no server running\n" );
|
||||
return;
|
||||
}
|
||||
g_pScriptVM->ConnectDebugger();
|
||||
}
|
||||
|
||||
CON_COMMAND_SHARED( script_help, "Output help for script functions, optionally with a search string" )
|
||||
{
|
||||
if ( !g_pScriptVM )
|
||||
{
|
||||
Warning( "Scripting disabled or no server running\n" );
|
||||
return;
|
||||
}
|
||||
const char *pszArg1 = "*";
|
||||
if ( *args[1] )
|
||||
{
|
||||
pszArg1 = args[1];
|
||||
}
|
||||
|
||||
g_pScriptVM->Run( CFmtStr( "PrintHelp( \"%s\" );", pszArg1 ) );
|
||||
}
|
||||
|
||||
CON_COMMAND_SHARED( script_dump_all, "Dump the state of the VM to the console" )
|
||||
{
|
||||
if ( !g_pScriptVM )
|
||||
{
|
||||
Warning( "Scripting disabled or no server running\n" );
|
||||
return;
|
||||
}
|
||||
g_pScriptVM->DumpState();
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user