aboutsummaryrefslogtreecommitdiff
path: root/sp/src/game/server/entity_tools_server.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sp/src/game/server/entity_tools_server.cpp')
-rw-r--r--sp/src/game/server/entity_tools_server.cpp864
1 files changed, 432 insertions, 432 deletions
diff --git a/sp/src/game/server/entity_tools_server.cpp b/sp/src/game/server/entity_tools_server.cpp
index fd95e0ae..e1888123 100644
--- a/sp/src/game/server/entity_tools_server.cpp
+++ b/sp/src/game/server/entity_tools_server.cpp
@@ -1,432 +1,432 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================
-#include "cbase.h"
-#include "const.h"
-#include "toolframework/itoolentity.h"
-#include "entitylist.h"
-#include "toolframework/itoolsystem.h"
-#include "KeyValues.h"
-#include "icliententity.h"
-#include "iserverentity.h"
-#include "sceneentity.h"
-#include "particles/particles.h"
-
-
-//-----------------------------------------------------------------------------
-// Interface from engine to tools for manipulating entities
-//-----------------------------------------------------------------------------
-class CServerTools : public IServerTools
-{
-public:
- // Inherited from IServerTools
- virtual IServerEntity *GetIServerEntity( IClientEntity *pClientEntity );
- virtual bool GetPlayerPosition( Vector &org, QAngle &ang, IClientEntity *pClientPlayer = NULL );
- virtual bool SnapPlayerToPosition( const Vector &org, const QAngle &ang, IClientEntity *pClientPlayer = NULL );
- virtual int GetPlayerFOV( IClientEntity *pClientPlayer = NULL );
- virtual bool SetPlayerFOV( int fov, IClientEntity *pClientPlayer = NULL );
- virtual bool IsInNoClipMode( IClientEntity *pClientPlayer = NULL );
- virtual CBaseEntity *FirstEntity( void );
- virtual CBaseEntity *NextEntity( CBaseEntity *pEntity );
- virtual CBaseEntity *FindEntityByHammerID( int iHammerID );
- virtual bool GetKeyValue( CBaseEntity *pEntity, const char *szField, char *szValue, int iMaxLen );
- virtual bool SetKeyValue( CBaseEntity *pEntity, const char *szField, const char *szValue );
- virtual bool SetKeyValue( CBaseEntity *pEntity, const char *szField, float flValue );
- virtual bool SetKeyValue( CBaseEntity *pEntity, const char *szField, const Vector &vecValue );
- virtual CBaseEntity *CreateEntityByName( const char *szClassName );
- virtual void DispatchSpawn( CBaseEntity *pEntity );
- virtual void ReloadParticleDefintions( const char *pFileName, const void *pBufData, int nLen );
- virtual void AddOriginToPVS( const Vector &org );
- virtual void MoveEngineViewTo( const Vector &vPos, const QAngle &vAngles );
- virtual bool DestroyEntityByHammerId( int iHammerID );
- virtual CBaseEntity *GetBaseEntityByEntIndex( int iEntIndex );
- virtual void RemoveEntity( CBaseEntity *pEntity );
- virtual void RemoveEntityImmediate( CBaseEntity *pEntity );
- virtual IEntityFactoryDictionary *GetEntityFactoryDictionary( void );
- virtual void SetMoveType( CBaseEntity *pEntity, int val );
- virtual void SetMoveType( CBaseEntity *pEntity, int val, int moveCollide );
- virtual void ResetSequence( CBaseAnimating *pEntity, int nSequence );
- virtual void ResetSequenceInfo( CBaseAnimating *pEntity );
- virtual void ClearMultiDamage( void );
- virtual void ApplyMultiDamage( void );
- virtual void AddMultiDamage( const CTakeDamageInfo &pTakeDamageInfo, CBaseEntity *pEntity );
- virtual void RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrc, float flRadius, int iClassIgnore, CBaseEntity *pEntityIgnore );
- virtual ITempEntsSystem *GetTempEntsSystem( void );
-};
-
-
-//-----------------------------------------------------------------------------
-// Singleton
-//-----------------------------------------------------------------------------
-static CServerTools g_ServerTools;
-
-// VSERVERTOOLS_INTERFACE_VERSION_1 is compatible with the latest since we're only adding things to the end, so expose that as well.
-EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CServerTools, IServerTools001, VSERVERTOOLS_INTERFACE_VERSION_1, g_ServerTools );
-EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CServerTools, IServerTools, VSERVERTOOLS_INTERFACE_VERSION, g_ServerTools );
-
-// When bumping the version to this interface, check that our assumption is still valid and expose the older version in the same way
-COMPILE_TIME_ASSERT( VSERVERTOOLS_INTERFACE_VERSION_INT == 2 );
-
-
-IServerEntity *CServerTools::GetIServerEntity( IClientEntity *pClientEntity )
-{
- if ( pClientEntity == NULL )
- return NULL;
-
- CBaseHandle ehandle = pClientEntity->GetRefEHandle();
- if ( ehandle.GetEntryIndex() >= MAX_EDICTS )
- return NULL; // the first MAX_EDICTS entities are networked, the rest are client or server only
-
-#if 0
- // this fails, since the server entities have extra bits in their serial numbers,
- // since 20 bits are reserved for serial numbers, except for networked entities, which are restricted to 10
-
- // Brian believes that everything should just restrict itself to 10 to make things simpler,
- // so if/when he changes NUM_SERIAL_NUM_BITS to 10, we can switch back to this simpler code
-
- IServerNetworkable *pNet = gEntList.GetServerNetworkable( ehandle );
- if ( pNet == NULL )
- return NULL;
-
- CBaseEntity *pServerEnt = pNet->GetBaseEntity();
- return pServerEnt;
-#else
- IHandleEntity *pEnt = gEntList.LookupEntityByNetworkIndex( ehandle.GetEntryIndex() );
- if ( pEnt == NULL )
- return NULL;
-
- CBaseHandle h = gEntList.GetNetworkableHandle( ehandle.GetEntryIndex() );
- const int mask = ( 1 << NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS ) - 1;
- if ( !h.IsValid() || ( ( h.GetSerialNumber() & mask ) != ( ehandle.GetSerialNumber() & mask ) ) )
- return NULL;
-
- IServerUnknown *pUnk = static_cast< IServerUnknown* >( pEnt );
- return pUnk->GetBaseEntity();
-#endif
-}
-
-bool CServerTools::GetPlayerPosition( Vector &org, QAngle &ang, IClientEntity *pClientPlayer )
-{
- IServerEntity *pServerPlayer = GetIServerEntity( pClientPlayer );
- CBasePlayer *pPlayer = pServerPlayer ? ( CBasePlayer* )pServerPlayer : UTIL_GetLocalPlayer();
- if ( pPlayer == NULL )
- return false;
-
- org = pPlayer->EyePosition();
- ang = pPlayer->EyeAngles();
- return true;
-}
-
-bool CServerTools::SnapPlayerToPosition( const Vector &org, const QAngle &ang, IClientEntity *pClientPlayer )
-{
- IServerEntity *pServerPlayer = GetIServerEntity( pClientPlayer );
- CBasePlayer *pPlayer = pServerPlayer ? ( CBasePlayer* )pServerPlayer : UTIL_GetLocalPlayer();
- if ( pPlayer == NULL )
- return false;
-
- pPlayer->SetAbsOrigin( org - pPlayer->GetViewOffset() );
- pPlayer->SnapEyeAngles( ang );
-
- // Disengage from hierarchy
- pPlayer->SetParent( NULL );
-
- return true;
-}
-
-int CServerTools::GetPlayerFOV( IClientEntity *pClientPlayer )
-{
- IServerEntity *pServerPlayer = GetIServerEntity( pClientPlayer );
- CBasePlayer *pPlayer = pServerPlayer ? ( CBasePlayer* )pServerPlayer : UTIL_GetLocalPlayer();
- if ( pPlayer == NULL )
- return 0;
-
- return pPlayer->GetFOV();
-}
-
-bool CServerTools::SetPlayerFOV( int fov, IClientEntity *pClientPlayer )
-{
- IServerEntity *pServerPlayer = GetIServerEntity( pClientPlayer );
- CBasePlayer *pPlayer = pServerPlayer ? ( CBasePlayer* )pServerPlayer : UTIL_GetLocalPlayer();
- if ( pPlayer == NULL )
- return false;
-
- pPlayer->SetDefaultFOV( fov );
- CBaseEntity *pFOVOwner = pPlayer->GetFOVOwner();
- return pPlayer->SetFOV( pFOVOwner ? pFOVOwner : pPlayer, fov );
-}
-
-bool CServerTools::IsInNoClipMode( IClientEntity *pClientPlayer )
-{
- IServerEntity *pServerPlayer = GetIServerEntity( pClientPlayer );
- CBasePlayer *pPlayer = pServerPlayer ? ( CBasePlayer* )pServerPlayer : UTIL_GetLocalPlayer();
- if ( pPlayer == NULL )
- return true;
-
- return pPlayer->GetMoveType() == MOVETYPE_NOCLIP;
-}
-
-CBaseEntity *CServerTools::FirstEntity( void )
-{
- return gEntList.FirstEnt();
-}
-
-CBaseEntity *CServerTools::NextEntity( CBaseEntity *pEntity )
-{
- CBaseEntity *pEnt;
-
- if ( pEntity == NULL )
- {
- pEnt = gEntList.FirstEnt();
- }
- else
- {
- pEnt = gEntList.NextEnt( (CBaseEntity *)pEntity );
- }
- return pEnt;
-}
-
-CBaseEntity *CServerTools::FindEntityByHammerID( int iHammerID )
-{
- CBaseEntity *pEntity = gEntList.FirstEnt();
-
- while (pEntity)
- {
- if (pEntity->m_iHammerID == iHammerID)
- return pEntity;
- pEntity = gEntList.NextEnt( pEntity );
- }
- return NULL;
-}
-
-bool CServerTools::GetKeyValue( CBaseEntity *pEntity, const char *szField, char *szValue, int iMaxLen )
-{
- return pEntity->GetKeyValue( szField, szValue, iMaxLen );
-}
-
-bool CServerTools::SetKeyValue( CBaseEntity *pEntity, const char *szField, const char *szValue )
-{
- return pEntity->KeyValue( szField, szValue );
-}
-
-bool CServerTools::SetKeyValue( CBaseEntity *pEntity, const char *szField, float flValue )
-{
- return pEntity->KeyValue( szField, flValue );
-}
-
-bool CServerTools::SetKeyValue( CBaseEntity *pEntity, const char *szField, const Vector &vecValue )
-{
- return pEntity->KeyValue( szField, vecValue );
-}
-
-
-//-----------------------------------------------------------------------------
-// entity spawning
-//-----------------------------------------------------------------------------
-CBaseEntity *CServerTools::CreateEntityByName( const char *szClassName )
-{
- return ::CreateEntityByName( szClassName );
-}
-
-void CServerTools::DispatchSpawn( CBaseEntity *pEntity )
-{
- ::DispatchSpawn( pEntity );
-}
-
-
-//-----------------------------------------------------------------------------
-// Reload particle definitions
-//-----------------------------------------------------------------------------
-void CServerTools::ReloadParticleDefintions( const char *pFileName, const void *pBufData, int nLen )
-{
- // FIXME: Use file name to determine if we care about this data
- CUtlBuffer buf( pBufData, nLen, CUtlBuffer::READ_ONLY );
- g_pParticleSystemMgr->ReadParticleConfigFile( buf, true );
-}
-
-void CServerTools::AddOriginToPVS( const Vector &org )
-{
- engine->AddOriginToPVS( org );
-}
-
-void CServerTools::MoveEngineViewTo( const Vector &vPos, const QAngle &vAngles )
-{
- CBasePlayer *pPlayer = UTIL_GetListenServerHost();
- if ( !pPlayer )
- return;
-
- extern void EnableNoClip( CBasePlayer *pPlayer );
- EnableNoClip( pPlayer );
-
- Vector zOffset = pPlayer->EyePosition() - pPlayer->GetAbsOrigin();
-
- pPlayer->SetAbsOrigin( vPos - zOffset );
- pPlayer->SnapEyeAngles( vAngles );
-}
-
-bool CServerTools::DestroyEntityByHammerId( int iHammerID )
-{
- CBaseEntity *pEntity = (CBaseEntity*)FindEntityByHammerID( iHammerID );
- if ( !pEntity )
- return false;
-
- UTIL_Remove( pEntity );
- return true;
-}
-
-void CServerTools::RemoveEntity( CBaseEntity *pEntity )
-{
- UTIL_Remove( pEntity );
-}
-
-void CServerTools::RemoveEntityImmediate( CBaseEntity *pEntity )
-{
- UTIL_RemoveImmediate( pEntity );
-}
-
-CBaseEntity *CServerTools::GetBaseEntityByEntIndex( int iEntIndex )
-{
- edict_t *pEdict = INDEXENT( iEntIndex );
- if ( pEdict )
- return CBaseEntity::Instance( pEdict );
- else
- return NULL;
-}
-
-IEntityFactoryDictionary *CServerTools::GetEntityFactoryDictionary( void )
-{
- return ::EntityFactoryDictionary();
-}
-
-
-void CServerTools::SetMoveType( CBaseEntity *pEntity, int val )
-{
- pEntity->SetMoveType( (MoveType_t)val );
-}
-
-void CServerTools::SetMoveType( CBaseEntity *pEntity, int val, int moveCollide )
-{
- pEntity->SetMoveType( (MoveType_t)val, (MoveCollide_t)moveCollide );
-}
-
-void CServerTools::ResetSequence( CBaseAnimating *pEntity, int nSequence )
-{
- pEntity->ResetSequence( nSequence );
-}
-
-void CServerTools::ResetSequenceInfo( CBaseAnimating *pEntity )
-{
- pEntity->ResetSequenceInfo();
-}
-
-
-void CServerTools::ClearMultiDamage( void )
-{
- ::ClearMultiDamage();
-}
-
-void CServerTools::ApplyMultiDamage( void )
-{
- ::ApplyMultiDamage();
-}
-
-void CServerTools::AddMultiDamage( const CTakeDamageInfo &pTakeDamageInfo, CBaseEntity *pEntity )
-{
- ::AddMultiDamage( pTakeDamageInfo, pEntity );
-}
-
-void CServerTools::RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrc, float flRadius, int iClassIgnore, CBaseEntity *pEntityIgnore )
-{
- ::RadiusDamage( info, vecSrc, flRadius, iClassIgnore, pEntityIgnore );
-}
-
-
-ITempEntsSystem *CServerTools::GetTempEntsSystem( void )
-{
- return (ITempEntsSystem *)te;
-}
-
-
-// Interface from engine to tools for manipulating entities
-class CServerChoreoTools : public IServerChoreoTools
-{
-public:
- // Iterates through ALL entities (separate list for client vs. server)
- virtual EntitySearchResult NextChoreoEntity( EntitySearchResult currentEnt )
- {
- CBaseEntity *ent = reinterpret_cast< CBaseEntity* >( currentEnt );
- ent = gEntList.FindEntityByClassname( ent, "logic_choreographed_scene" );
- return reinterpret_cast< EntitySearchResult >( ent );
- }
-
- virtual const char *GetSceneFile( EntitySearchResult sr )
- {
- CBaseEntity *ent = reinterpret_cast< CBaseEntity* >( sr );
- if ( !sr )
- return "";
-
- if ( Q_stricmp( ent->GetClassname(), "logic_choreographed_scene" ) )
- return "";
-
- return GetSceneFilename( ent );
- }
-
- // For interactive editing
- virtual int GetEntIndex( EntitySearchResult sr )
- {
- CBaseEntity *ent = reinterpret_cast< CBaseEntity* >( sr );
- if ( !ent )
- return -1;
-
- return ent->entindex();
- }
-
- virtual void ReloadSceneFromDisk( int entindex )
- {
- CBaseEntity *ent = CBaseEntity::Instance( entindex );
- if ( !ent )
- return;
-
- ::ReloadSceneFromDisk( ent );
- }
-};
-
-
-static CServerChoreoTools g_ServerChoreoTools;
-EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CServerChoreoTools, IServerChoreoTools, VSERVERCHOREOTOOLS_INTERFACE_VERSION, g_ServerChoreoTools );
-
-
-//------------------------------------------------------------------------------
-// Applies keyvalues to the entity by hammer ID.
-//------------------------------------------------------------------------------
-void CC_Ent_Keyvalue( const CCommand &args )
-{
- // Must have an odd number of arguments.
- if ( ( args.ArgC() < 4 ) || ( args.ArgC() & 1 ) )
- {
- Msg( "Format: ent_keyvalue <entity id> \"key1\" \"value1\" \"key2\" \"value2\" ... \"keyN\" \"valueN\"\n" );
- return;
- }
-
- int nID = atoi( args[1] );
-
- CBaseEntity *pEnt = g_ServerTools.FindEntityByHammerID( nID );
- if ( !pEnt )
- {
- Msg( "Entity ID %d not found.\n", nID );
- return;
- }
-
- int nArg = 2;
- while ( nArg < args.ArgC() )
- {
- const char *pszKey = args[ nArg ];
- const char *pszValue = args[ nArg + 1 ];
- nArg += 2;
-
- g_ServerTools.SetKeyValue( pEnt, pszKey, pszValue );
- }
-}
-
-static ConCommand ent_keyvalue("ent_keyvalue", CC_Ent_Keyvalue, "Applies the comma delimited key=value pairs to the entity with the given Hammer ID.\n\tFormat: ent_keyvalue <entity id> <key1> <value1> <key2> <value2> ... <keyN> <valueN>\n", FCVAR_CHEAT);
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+#include "cbase.h"
+#include "const.h"
+#include "toolframework/itoolentity.h"
+#include "entitylist.h"
+#include "toolframework/itoolsystem.h"
+#include "KeyValues.h"
+#include "icliententity.h"
+#include "iserverentity.h"
+#include "sceneentity.h"
+#include "particles/particles.h"
+
+
+//-----------------------------------------------------------------------------
+// Interface from engine to tools for manipulating entities
+//-----------------------------------------------------------------------------
+class CServerTools : public IServerTools
+{
+public:
+ // Inherited from IServerTools
+ virtual IServerEntity *GetIServerEntity( IClientEntity *pClientEntity );
+ virtual bool GetPlayerPosition( Vector &org, QAngle &ang, IClientEntity *pClientPlayer = NULL );
+ virtual bool SnapPlayerToPosition( const Vector &org, const QAngle &ang, IClientEntity *pClientPlayer = NULL );
+ virtual int GetPlayerFOV( IClientEntity *pClientPlayer = NULL );
+ virtual bool SetPlayerFOV( int fov, IClientEntity *pClientPlayer = NULL );
+ virtual bool IsInNoClipMode( IClientEntity *pClientPlayer = NULL );
+ virtual CBaseEntity *FirstEntity( void );
+ virtual CBaseEntity *NextEntity( CBaseEntity *pEntity );
+ virtual CBaseEntity *FindEntityByHammerID( int iHammerID );
+ virtual bool GetKeyValue( CBaseEntity *pEntity, const char *szField, char *szValue, int iMaxLen );
+ virtual bool SetKeyValue( CBaseEntity *pEntity, const char *szField, const char *szValue );
+ virtual bool SetKeyValue( CBaseEntity *pEntity, const char *szField, float flValue );
+ virtual bool SetKeyValue( CBaseEntity *pEntity, const char *szField, const Vector &vecValue );
+ virtual CBaseEntity *CreateEntityByName( const char *szClassName );
+ virtual void DispatchSpawn( CBaseEntity *pEntity );
+ virtual void ReloadParticleDefintions( const char *pFileName, const void *pBufData, int nLen );
+ virtual void AddOriginToPVS( const Vector &org );
+ virtual void MoveEngineViewTo( const Vector &vPos, const QAngle &vAngles );
+ virtual bool DestroyEntityByHammerId( int iHammerID );
+ virtual CBaseEntity *GetBaseEntityByEntIndex( int iEntIndex );
+ virtual void RemoveEntity( CBaseEntity *pEntity );
+ virtual void RemoveEntityImmediate( CBaseEntity *pEntity );
+ virtual IEntityFactoryDictionary *GetEntityFactoryDictionary( void );
+ virtual void SetMoveType( CBaseEntity *pEntity, int val );
+ virtual void SetMoveType( CBaseEntity *pEntity, int val, int moveCollide );
+ virtual void ResetSequence( CBaseAnimating *pEntity, int nSequence );
+ virtual void ResetSequenceInfo( CBaseAnimating *pEntity );
+ virtual void ClearMultiDamage( void );
+ virtual void ApplyMultiDamage( void );
+ virtual void AddMultiDamage( const CTakeDamageInfo &pTakeDamageInfo, CBaseEntity *pEntity );
+ virtual void RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrc, float flRadius, int iClassIgnore, CBaseEntity *pEntityIgnore );
+ virtual ITempEntsSystem *GetTempEntsSystem( void );
+};
+
+
+//-----------------------------------------------------------------------------
+// Singleton
+//-----------------------------------------------------------------------------
+static CServerTools g_ServerTools;
+
+// VSERVERTOOLS_INTERFACE_VERSION_1 is compatible with the latest since we're only adding things to the end, so expose that as well.
+EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CServerTools, IServerTools001, VSERVERTOOLS_INTERFACE_VERSION_1, g_ServerTools );
+EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CServerTools, IServerTools, VSERVERTOOLS_INTERFACE_VERSION, g_ServerTools );
+
+// When bumping the version to this interface, check that our assumption is still valid and expose the older version in the same way
+COMPILE_TIME_ASSERT( VSERVERTOOLS_INTERFACE_VERSION_INT == 2 );
+
+
+IServerEntity *CServerTools::GetIServerEntity( IClientEntity *pClientEntity )
+{
+ if ( pClientEntity == NULL )
+ return NULL;
+
+ CBaseHandle ehandle = pClientEntity->GetRefEHandle();
+ if ( ehandle.GetEntryIndex() >= MAX_EDICTS )
+ return NULL; // the first MAX_EDICTS entities are networked, the rest are client or server only
+
+#if 0
+ // this fails, since the server entities have extra bits in their serial numbers,
+ // since 20 bits are reserved for serial numbers, except for networked entities, which are restricted to 10
+
+ // Brian believes that everything should just restrict itself to 10 to make things simpler,
+ // so if/when he changes NUM_SERIAL_NUM_BITS to 10, we can switch back to this simpler code
+
+ IServerNetworkable *pNet = gEntList.GetServerNetworkable( ehandle );
+ if ( pNet == NULL )
+ return NULL;
+
+ CBaseEntity *pServerEnt = pNet->GetBaseEntity();
+ return pServerEnt;
+#else
+ IHandleEntity *pEnt = gEntList.LookupEntityByNetworkIndex( ehandle.GetEntryIndex() );
+ if ( pEnt == NULL )
+ return NULL;
+
+ CBaseHandle h = gEntList.GetNetworkableHandle( ehandle.GetEntryIndex() );
+ const int mask = ( 1 << NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS ) - 1;
+ if ( !h.IsValid() || ( ( h.GetSerialNumber() & mask ) != ( ehandle.GetSerialNumber() & mask ) ) )
+ return NULL;
+
+ IServerUnknown *pUnk = static_cast< IServerUnknown* >( pEnt );
+ return pUnk->GetBaseEntity();
+#endif
+}
+
+bool CServerTools::GetPlayerPosition( Vector &org, QAngle &ang, IClientEntity *pClientPlayer )
+{
+ IServerEntity *pServerPlayer = GetIServerEntity( pClientPlayer );
+ CBasePlayer *pPlayer = pServerPlayer ? ( CBasePlayer* )pServerPlayer : UTIL_GetLocalPlayer();
+ if ( pPlayer == NULL )
+ return false;
+
+ org = pPlayer->EyePosition();
+ ang = pPlayer->EyeAngles();
+ return true;
+}
+
+bool CServerTools::SnapPlayerToPosition( const Vector &org, const QAngle &ang, IClientEntity *pClientPlayer )
+{
+ IServerEntity *pServerPlayer = GetIServerEntity( pClientPlayer );
+ CBasePlayer *pPlayer = pServerPlayer ? ( CBasePlayer* )pServerPlayer : UTIL_GetLocalPlayer();
+ if ( pPlayer == NULL )
+ return false;
+
+ pPlayer->SetAbsOrigin( org - pPlayer->GetViewOffset() );
+ pPlayer->SnapEyeAngles( ang );
+
+ // Disengage from hierarchy
+ pPlayer->SetParent( NULL );
+
+ return true;
+}
+
+int CServerTools::GetPlayerFOV( IClientEntity *pClientPlayer )
+{
+ IServerEntity *pServerPlayer = GetIServerEntity( pClientPlayer );
+ CBasePlayer *pPlayer = pServerPlayer ? ( CBasePlayer* )pServerPlayer : UTIL_GetLocalPlayer();
+ if ( pPlayer == NULL )
+ return 0;
+
+ return pPlayer->GetFOV();
+}
+
+bool CServerTools::SetPlayerFOV( int fov, IClientEntity *pClientPlayer )
+{
+ IServerEntity *pServerPlayer = GetIServerEntity( pClientPlayer );
+ CBasePlayer *pPlayer = pServerPlayer ? ( CBasePlayer* )pServerPlayer : UTIL_GetLocalPlayer();
+ if ( pPlayer == NULL )
+ return false;
+
+ pPlayer->SetDefaultFOV( fov );
+ CBaseEntity *pFOVOwner = pPlayer->GetFOVOwner();
+ return pPlayer->SetFOV( pFOVOwner ? pFOVOwner : pPlayer, fov );
+}
+
+bool CServerTools::IsInNoClipMode( IClientEntity *pClientPlayer )
+{
+ IServerEntity *pServerPlayer = GetIServerEntity( pClientPlayer );
+ CBasePlayer *pPlayer = pServerPlayer ? ( CBasePlayer* )pServerPlayer : UTIL_GetLocalPlayer();
+ if ( pPlayer == NULL )
+ return true;
+
+ return pPlayer->GetMoveType() == MOVETYPE_NOCLIP;
+}
+
+CBaseEntity *CServerTools::FirstEntity( void )
+{
+ return gEntList.FirstEnt();
+}
+
+CBaseEntity *CServerTools::NextEntity( CBaseEntity *pEntity )
+{
+ CBaseEntity *pEnt;
+
+ if ( pEntity == NULL )
+ {
+ pEnt = gEntList.FirstEnt();
+ }
+ else
+ {
+ pEnt = gEntList.NextEnt( (CBaseEntity *)pEntity );
+ }
+ return pEnt;
+}
+
+CBaseEntity *CServerTools::FindEntityByHammerID( int iHammerID )
+{
+ CBaseEntity *pEntity = gEntList.FirstEnt();
+
+ while (pEntity)
+ {
+ if (pEntity->m_iHammerID == iHammerID)
+ return pEntity;
+ pEntity = gEntList.NextEnt( pEntity );
+ }
+ return NULL;
+}
+
+bool CServerTools::GetKeyValue( CBaseEntity *pEntity, const char *szField, char *szValue, int iMaxLen )
+{
+ return pEntity->GetKeyValue( szField, szValue, iMaxLen );
+}
+
+bool CServerTools::SetKeyValue( CBaseEntity *pEntity, const char *szField, const char *szValue )
+{
+ return pEntity->KeyValue( szField, szValue );
+}
+
+bool CServerTools::SetKeyValue( CBaseEntity *pEntity, const char *szField, float flValue )
+{
+ return pEntity->KeyValue( szField, flValue );
+}
+
+bool CServerTools::SetKeyValue( CBaseEntity *pEntity, const char *szField, const Vector &vecValue )
+{
+ return pEntity->KeyValue( szField, vecValue );
+}
+
+
+//-----------------------------------------------------------------------------
+// entity spawning
+//-----------------------------------------------------------------------------
+CBaseEntity *CServerTools::CreateEntityByName( const char *szClassName )
+{
+ return ::CreateEntityByName( szClassName );
+}
+
+void CServerTools::DispatchSpawn( CBaseEntity *pEntity )
+{
+ ::DispatchSpawn( pEntity );
+}
+
+
+//-----------------------------------------------------------------------------
+// Reload particle definitions
+//-----------------------------------------------------------------------------
+void CServerTools::ReloadParticleDefintions( const char *pFileName, const void *pBufData, int nLen )
+{
+ // FIXME: Use file name to determine if we care about this data
+ CUtlBuffer buf( pBufData, nLen, CUtlBuffer::READ_ONLY );
+ g_pParticleSystemMgr->ReadParticleConfigFile( buf, true );
+}
+
+void CServerTools::AddOriginToPVS( const Vector &org )
+{
+ engine->AddOriginToPVS( org );
+}
+
+void CServerTools::MoveEngineViewTo( const Vector &vPos, const QAngle &vAngles )
+{
+ CBasePlayer *pPlayer = UTIL_GetListenServerHost();
+ if ( !pPlayer )
+ return;
+
+ extern void EnableNoClip( CBasePlayer *pPlayer );
+ EnableNoClip( pPlayer );
+
+ Vector zOffset = pPlayer->EyePosition() - pPlayer->GetAbsOrigin();
+
+ pPlayer->SetAbsOrigin( vPos - zOffset );
+ pPlayer->SnapEyeAngles( vAngles );
+}
+
+bool CServerTools::DestroyEntityByHammerId( int iHammerID )
+{
+ CBaseEntity *pEntity = (CBaseEntity*)FindEntityByHammerID( iHammerID );
+ if ( !pEntity )
+ return false;
+
+ UTIL_Remove( pEntity );
+ return true;
+}
+
+void CServerTools::RemoveEntity( CBaseEntity *pEntity )
+{
+ UTIL_Remove( pEntity );
+}
+
+void CServerTools::RemoveEntityImmediate( CBaseEntity *pEntity )
+{
+ UTIL_RemoveImmediate( pEntity );
+}
+
+CBaseEntity *CServerTools::GetBaseEntityByEntIndex( int iEntIndex )
+{
+ edict_t *pEdict = INDEXENT( iEntIndex );
+ if ( pEdict )
+ return CBaseEntity::Instance( pEdict );
+ else
+ return NULL;
+}
+
+IEntityFactoryDictionary *CServerTools::GetEntityFactoryDictionary( void )
+{
+ return ::EntityFactoryDictionary();
+}
+
+
+void CServerTools::SetMoveType( CBaseEntity *pEntity, int val )
+{
+ pEntity->SetMoveType( (MoveType_t)val );
+}
+
+void CServerTools::SetMoveType( CBaseEntity *pEntity, int val, int moveCollide )
+{
+ pEntity->SetMoveType( (MoveType_t)val, (MoveCollide_t)moveCollide );
+}
+
+void CServerTools::ResetSequence( CBaseAnimating *pEntity, int nSequence )
+{
+ pEntity->ResetSequence( nSequence );
+}
+
+void CServerTools::ResetSequenceInfo( CBaseAnimating *pEntity )
+{
+ pEntity->ResetSequenceInfo();
+}
+
+
+void CServerTools::ClearMultiDamage( void )
+{
+ ::ClearMultiDamage();
+}
+
+void CServerTools::ApplyMultiDamage( void )
+{
+ ::ApplyMultiDamage();
+}
+
+void CServerTools::AddMultiDamage( const CTakeDamageInfo &pTakeDamageInfo, CBaseEntity *pEntity )
+{
+ ::AddMultiDamage( pTakeDamageInfo, pEntity );
+}
+
+void CServerTools::RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrc, float flRadius, int iClassIgnore, CBaseEntity *pEntityIgnore )
+{
+ ::RadiusDamage( info, vecSrc, flRadius, iClassIgnore, pEntityIgnore );
+}
+
+
+ITempEntsSystem *CServerTools::GetTempEntsSystem( void )
+{
+ return (ITempEntsSystem *)te;
+}
+
+
+// Interface from engine to tools for manipulating entities
+class CServerChoreoTools : public IServerChoreoTools
+{
+public:
+ // Iterates through ALL entities (separate list for client vs. server)
+ virtual EntitySearchResult NextChoreoEntity( EntitySearchResult currentEnt )
+ {
+ CBaseEntity *ent = reinterpret_cast< CBaseEntity* >( currentEnt );
+ ent = gEntList.FindEntityByClassname( ent, "logic_choreographed_scene" );
+ return reinterpret_cast< EntitySearchResult >( ent );
+ }
+
+ virtual const char *GetSceneFile( EntitySearchResult sr )
+ {
+ CBaseEntity *ent = reinterpret_cast< CBaseEntity* >( sr );
+ if ( !sr )
+ return "";
+
+ if ( Q_stricmp( ent->GetClassname(), "logic_choreographed_scene" ) )
+ return "";
+
+ return GetSceneFilename( ent );
+ }
+
+ // For interactive editing
+ virtual int GetEntIndex( EntitySearchResult sr )
+ {
+ CBaseEntity *ent = reinterpret_cast< CBaseEntity* >( sr );
+ if ( !ent )
+ return -1;
+
+ return ent->entindex();
+ }
+
+ virtual void ReloadSceneFromDisk( int entindex )
+ {
+ CBaseEntity *ent = CBaseEntity::Instance( entindex );
+ if ( !ent )
+ return;
+
+ ::ReloadSceneFromDisk( ent );
+ }
+};
+
+
+static CServerChoreoTools g_ServerChoreoTools;
+EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CServerChoreoTools, IServerChoreoTools, VSERVERCHOREOTOOLS_INTERFACE_VERSION, g_ServerChoreoTools );
+
+
+//------------------------------------------------------------------------------
+// Applies keyvalues to the entity by hammer ID.
+//------------------------------------------------------------------------------
+void CC_Ent_Keyvalue( const CCommand &args )
+{
+ // Must have an odd number of arguments.
+ if ( ( args.ArgC() < 4 ) || ( args.ArgC() & 1 ) )
+ {
+ Msg( "Format: ent_keyvalue <entity id> \"key1\" \"value1\" \"key2\" \"value2\" ... \"keyN\" \"valueN\"\n" );
+ return;
+ }
+
+ int nID = atoi( args[1] );
+
+ CBaseEntity *pEnt = g_ServerTools.FindEntityByHammerID( nID );
+ if ( !pEnt )
+ {
+ Msg( "Entity ID %d not found.\n", nID );
+ return;
+ }
+
+ int nArg = 2;
+ while ( nArg < args.ArgC() )
+ {
+ const char *pszKey = args[ nArg ];
+ const char *pszValue = args[ nArg + 1 ];
+ nArg += 2;
+
+ g_ServerTools.SetKeyValue( pEnt, pszKey, pszValue );
+ }
+}
+
+static ConCommand ent_keyvalue("ent_keyvalue", CC_Ent_Keyvalue, "Applies the comma delimited key=value pairs to the entity with the given Hammer ID.\n\tFormat: ent_keyvalue <entity id> <key1> <value1> <key2> <value2> ... <keyN> <valueN>\n", FCVAR_CHEAT);