aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/client/entity_client_tools.cpp
diff options
context:
space:
mode:
authorJørgen P. Tjernø <[email protected]>2013-12-02 19:31:46 -0800
committerJørgen P. Tjernø <[email protected]>2013-12-02 19:46:31 -0800
commitf56bb35301836e56582a575a75864392a0177875 (patch)
treede61ddd39de3e7df52759711950b4c288592f0dc /mp/src/game/client/entity_client_tools.cpp
parentMark some more files as text. (diff)
downloadsource-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz
source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/game/client/entity_client_tools.cpp')
-rw-r--r--mp/src/game/client/entity_client_tools.cpp1586
1 files changed, 793 insertions, 793 deletions
diff --git a/mp/src/game/client/entity_client_tools.cpp b/mp/src/game/client/entity_client_tools.cpp
index 32261841..99dc2370 100644
--- a/mp/src/game/client/entity_client_tools.cpp
+++ b/mp/src/game/client/entity_client_tools.cpp
@@ -1,793 +1,793 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================
-#include "cbase.h"
-#include "toolframework/itoolentity.h"
-#include "tier1/KeyValues.h"
-#include "Sprite.h"
-#include "enginesprite.h"
-#include "toolframework_client.h"
-#include "particles/particles.h"
-#include "particle_parse.h"
-#include "rendertexture.h"
-
-#ifdef PORTAL
- #include "PortalRender.h"
-#endif
-
-#pragma warning( disable: 4355 ) // warning C4355: 'this' : used in base member initializer list
-
-class CClientTools;
-
-void DrawSpriteModel( IClientEntity *baseentity, CEngineSprite *psprite,
- const Vector &origin, float fscale, float frame,
- int rendermode, int r, int g, int b, int a,
- const Vector& forward, const Vector& right, const Vector& up, float flHDRColorScale = 1.0f );
-float StandardGlowBlend( const pixelvis_queryparams_t &params, pixelvis_handle_t *queryHandle,
- int rendermode, int renderfx, int alpha, float *pscale );
-
-
-// Interface from engine to tools for manipulating entities
-class CClientTools : public IClientTools, public IClientEntityListener
-{
-public:
- CClientTools();
-
- virtual HTOOLHANDLE AttachToEntity( EntitySearchResult entityToAttach );
- virtual void DetachFromEntity( EntitySearchResult entityToDetach );
- virtual bool IsValidHandle( HTOOLHANDLE handle );
-
- virtual int GetNumRecordables();
- virtual HTOOLHANDLE GetRecordable( int index );
-
- // Iterates through ALL entities (separate list for client vs. server)
- virtual EntitySearchResult NextEntity( EntitySearchResult currentEnt );
-
- // Use this to turn on/off the presence of an underlying game entity
- virtual void SetEnabled( HTOOLHANDLE handle, bool enabled );
-
- virtual void SetRecording( HTOOLHANDLE handle, bool recording );
- virtual bool ShouldRecord( HTOOLHANDLE handle );
-
- virtual int GetModelIndex( HTOOLHANDLE handle );
- virtual const char* GetModelName ( HTOOLHANDLE handle );
- virtual const char* GetClassname ( HTOOLHANDLE handle );
-
- virtual HTOOLHANDLE GetToolHandleForEntityByIndex( int entindex );
-
- virtual void AddClientRenderable( IClientRenderable *pRenderable, int renderGroup );
- virtual void RemoveClientRenderable( IClientRenderable *pRenderable );
- virtual void SetRenderGroup( IClientRenderable *pRenderable, int renderGroup );
- virtual void MarkClientRenderableDirty( IClientRenderable *pRenderable );
-
- virtual bool DrawSprite( IClientRenderable *pRenderable,
- float scale, float frame,
- int rendermode, int renderfx,
- const Color &color, float flProxyRadius, int *pVisHandle );
-
- virtual bool GetLocalPlayerEyePosition( Vector& org, QAngle& ang, float &fov );
- virtual EntitySearchResult GetLocalPlayer();
-
- virtual ClientShadowHandle_t CreateShadow( CBaseHandle h, int nFlags );
- virtual void DestroyShadow( ClientShadowHandle_t h );
- virtual ClientShadowHandle_t CreateFlashlight( const FlashlightState_t &lightState );
- virtual void DestroyFlashlight( ClientShadowHandle_t h );
- virtual void UpdateFlashlightState( ClientShadowHandle_t h, const FlashlightState_t &flashlightState );
- virtual void AddToDirtyShadowList( ClientShadowHandle_t h, bool force = false );
- virtual void MarkRenderToTextureShadowDirty( ClientShadowHandle_t h );
- virtual void UpdateProjectedTexture( ClientShadowHandle_t h, bool bForce );
-
- // Global toggle for recording
- virtual void EnableRecordingMode( bool bEnable );
- virtual bool IsInRecordingMode() const;
-
- // Trigger a temp entity
- virtual void TriggerTempEntity( KeyValues *pKeyValues );
-
- // get owning weapon (for viewmodels)
- virtual int GetOwningWeaponEntIndex( int entindex );
- virtual int GetEntIndex( EntitySearchResult entityToAttach );
-
- virtual int FindGlobalFlexcontroller( char const *name );
- virtual char const *GetGlobalFlexControllerName( int idx );
-
- // helper for traversing ownership hierarchy
- virtual EntitySearchResult GetOwnerEntity( EntitySearchResult currentEnt );
-
- // common and useful types to query for hierarchically
- virtual bool IsPlayer( EntitySearchResult entityToAttach );
- virtual bool IsBaseCombatCharacter( EntitySearchResult entityToAttach );
- virtual bool IsNPC( EntitySearchResult entityToAttach );
-
- virtual Vector GetAbsOrigin( HTOOLHANDLE handle );
- virtual QAngle GetAbsAngles( HTOOLHANDLE handle );
- virtual void ReloadParticleDefintions( const char *pFileName, const void *pBufData, int nLen );
-
- // Sends a mesage from the tool to the client
- virtual void PostToolMessage( KeyValues *pKeyValues );
-
- // Indicates whether the client should render particle systems
- virtual void EnableParticleSystems( bool bEnable );
-
- // Is the game rendering in 3rd person mode?
- virtual bool IsRenderingThirdPerson() const;
-
-public:
- C_BaseEntity *LookupEntity( HTOOLHANDLE handle );
-
- // IClientEntityListener methods
- void OnEntityDeleted( C_BaseEntity *pEntity );
- void OnEntityCreated( C_BaseEntity *pEntity );
-
-private:
- struct HToolEntry_t
- {
- HToolEntry_t() : m_Handle( 0 ) {}
- HToolEntry_t( int handle, C_BaseEntity *pEntity = NULL )
- : m_Handle( handle ), m_hEntity( pEntity )
- {
- if ( pEntity )
- {
- m_hEntity->SetToolHandle( m_Handle );
- }
- }
-
- int m_Handle;
- EHANDLE m_hEntity;
- };
-
- static int s_nNextHandle;
-
- static bool HandleLessFunc( const HToolEntry_t& lhs, const HToolEntry_t& rhs )
- {
- return lhs.m_Handle < rhs.m_Handle;
- }
-
- CUtlRBTree< HToolEntry_t > m_Handles;
- CUtlVector< int > m_ActiveHandles;
- bool m_bInRecordingMode;
-};
-
-
-//-----------------------------------------------------------------------------
-// Statics
-//-----------------------------------------------------------------------------
-int CClientTools::s_nNextHandle = 1;
-
-
-//-----------------------------------------------------------------------------
-// Singleton instance
-//-----------------------------------------------------------------------------
-static CClientTools s_ClientTools;
-IClientTools *clienttools = &s_ClientTools;
-EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CClientTools, IClientTools, VCLIENTTOOLS_INTERFACE_VERSION, s_ClientTools );
-
-
-//-----------------------------------------------------------------------------
-// Constructor
-//-----------------------------------------------------------------------------
-CClientTools::CClientTools() : m_Handles( 0, 0, HandleLessFunc )
-{
- m_bInRecordingMode = false;
- cl_entitylist->AddListenerEntity( this );
-}
-
-
-//-----------------------------------------------------------------------------
-// Global toggle for recording
-//-----------------------------------------------------------------------------
-void CClientTools::EnableRecordingMode( bool bEnable )
-{
- m_bInRecordingMode = bEnable;
-}
-
-bool CClientTools::IsInRecordingMode() const
-{
- return m_bInRecordingMode;
-}
-
-
-//-----------------------------------------------------------------------------
-// Trigger a temp entity
-//-----------------------------------------------------------------------------
-void CClientTools::TriggerTempEntity( KeyValues *pKeyValues )
-{
- te->TriggerTempEntity( pKeyValues );
-}
-
-
-//-----------------------------------------------------------------------------
-// get owning weapon (for viewmodels)
-//-----------------------------------------------------------------------------
-int CClientTools::GetOwningWeaponEntIndex( int entindex )
-{
- C_BaseEntity *pEnt = C_BaseEntity::Instance( entindex );
- C_BaseViewModel *pViewModel = dynamic_cast< C_BaseViewModel* >( pEnt );
- if ( pViewModel )
- {
- C_BaseCombatWeapon *pWeapon = pViewModel->GetOwningWeapon();
- if ( pWeapon )
- {
- return pWeapon->entindex();
- }
- }
-
- return -1;
-}
-
-int CClientTools::GetEntIndex( EntitySearchResult entityToAttach )
-{
- C_BaseEntity *ent = reinterpret_cast< C_BaseEntity * >( entityToAttach );
- return ent ? ent->entindex() : 0;
-}
-
-void CClientTools::AddClientRenderable( IClientRenderable *pRenderable, int renderGroup )
-{
- Assert( pRenderable );
-
- cl_entitylist->AddNonNetworkableEntity( pRenderable->GetIClientUnknown() );
-
- ClientRenderHandle_t handle = pRenderable->RenderHandle();
- if ( INVALID_CLIENT_RENDER_HANDLE == handle )
- {
- // create new renderer handle
- ClientLeafSystem()->AddRenderable( pRenderable, (RenderGroup_t)renderGroup );
- }
- else
- {
- // handle already exists, just update group & origin
- ClientLeafSystem()->SetRenderGroup( pRenderable->RenderHandle(), (RenderGroup_t)renderGroup );
- ClientLeafSystem()->RenderableChanged( pRenderable->RenderHandle() );
- }
-
-}
-
-void CClientTools::RemoveClientRenderable( IClientRenderable *pRenderable )
-{
- ClientRenderHandle_t handle = pRenderable->RenderHandle();
- if( handle != INVALID_CLIENT_RENDER_HANDLE )
- {
- ClientLeafSystem()->RemoveRenderable( handle );
- }
- cl_entitylist->RemoveEntity( pRenderable->GetIClientUnknown()->GetRefEHandle() );
-}
-
-void CClientTools::MarkClientRenderableDirty( IClientRenderable *pRenderable )
-{
- ClientRenderHandle_t handle = pRenderable->RenderHandle();
- if ( INVALID_CLIENT_RENDER_HANDLE != handle )
- {
- // handle already exists, just update group & origin
- ClientLeafSystem()->RenderableChanged( pRenderable->RenderHandle() );
- }
-}
-
-void CClientTools::SetRenderGroup( IClientRenderable *pRenderable, int renderGroup )
-{
- ClientRenderHandle_t handle = pRenderable->RenderHandle();
- if ( INVALID_CLIENT_RENDER_HANDLE == handle )
- {
- // create new renderer handle
- ClientLeafSystem()->AddRenderable( pRenderable, (RenderGroup_t)renderGroup );
- }
- else
- {
- // handle already exists, just update group & origin
- ClientLeafSystem()->SetRenderGroup( pRenderable->RenderHandle(), (RenderGroup_t)renderGroup );
- ClientLeafSystem()->RenderableChanged( pRenderable->RenderHandle() );
- }
-}
-
-bool CClientTools::DrawSprite( IClientRenderable *pRenderable, float scale, float frame, int rendermode, int renderfx, const Color &color, float flProxyRadius, int *pVisHandle )
-{
- Vector origin = pRenderable->GetRenderOrigin();
- QAngle angles = pRenderable->GetRenderAngles();
-
- // Get extra data
- CEngineSprite *psprite = (CEngineSprite *)modelinfo->GetModelExtraData( pRenderable->GetModel() );
- if ( !psprite )
- return false;
-
- // Get orthonormal bases for current view - re-align to current camera (vs. recorded camera)
- Vector forward, right, up;
- C_SpriteRenderer::GetSpriteAxes( ( C_SpriteRenderer::SPRITETYPE )psprite->GetOrientation(), origin, angles, forward, right, up );
-
- int r = color.r();
- int g = color.g();
- int b = color.b();
-
- float oldBlend = render->GetBlend();
- if ( rendermode != kRenderNormal )
- {
- // kRenderGlow and kRenderWorldGlow have a special blending function
- if (( rendermode == kRenderGlow ) || ( rendermode == kRenderWorldGlow ))
- {
- pixelvis_queryparams_t params;
- if ( flProxyRadius != 0.0f )
- {
- params.Init( origin, flProxyRadius );
- params.bSizeInScreenspace = true;
- }
- else
- {
- params.Init( origin );
- }
- float blend = oldBlend * StandardGlowBlend( params, ( pixelvis_handle_t* )pVisHandle, rendermode, renderfx, color.a(), &scale );
-
- if ( blend <= 0.0f )
- return false;
-
- //Fade out the sprite depending on distance from the view origin.
- r *= blend;
- g *= blend;
- b *= blend;
-
- render->SetBlend( blend );
- }
- }
-
- DrawSpriteModel( ( IClientEntity* )pRenderable, psprite, origin, scale, frame, rendermode, r, g, b, color.a(), forward, right, up );
-
- if (( rendermode == kRenderGlow ) || ( rendermode == kRenderWorldGlow ))
- {
- render->SetBlend( oldBlend );
- }
-
- return true;
-}
-
-HTOOLHANDLE CClientTools::AttachToEntity( EntitySearchResult entityToAttach )
-{
- C_BaseEntity *ent = reinterpret_cast< C_BaseEntity * >( entityToAttach );
- Assert( ent );
- if ( !ent )
- return (HTOOLHANDLE)0;
-
- HTOOLHANDLE curHandle = ent->GetToolHandle();
- if ( curHandle != 0 )
- return curHandle; // Already attaached
-
- HToolEntry_t newHandle( s_nNextHandle++, ent );
-
- m_Handles.Insert( newHandle );
- m_ActiveHandles.AddToTail( newHandle.m_Handle );
-
- return (HTOOLHANDLE)newHandle.m_Handle;
-}
-
-void CClientTools::DetachFromEntity( EntitySearchResult entityToDetach )
-{
- C_BaseEntity *ent = reinterpret_cast< C_BaseEntity * >( entityToDetach );
- Assert( ent );
- if ( !ent )
- return;
-
- HTOOLHANDLE handle = ent->GetToolHandle();
- ent->SetToolHandle( (HTOOLHANDLE)0 );
-
- if ( handle == (HTOOLHANDLE)0 )
- {
- Assert( 0 );
- return;
- }
-
- int idx = m_Handles.Find( HToolEntry_t( handle ) );
- if ( idx == m_Handles.InvalidIndex() )
- {
- Assert( 0 );
- return;
- }
-
- m_Handles.RemoveAt( idx );
- m_ActiveHandles.FindAndRemove( handle );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : handle -
-// Output : C_BaseEntity
-//-----------------------------------------------------------------------------
-C_BaseEntity *CClientTools::LookupEntity( HTOOLHANDLE handle )
-{
- int idx = m_Handles.Find( HToolEntry_t( handle ) );
- if ( idx == m_Handles.InvalidIndex() )
- return NULL;
-
- return m_Handles[ idx ].m_hEntity;
-}
-
-int CClientTools::GetNumRecordables()
-{
- return m_ActiveHandles.Count();
-}
-
-HTOOLHANDLE CClientTools::GetRecordable( int index )
-{
- if ( index < 0 || index >= m_ActiveHandles.Count() )
- {
- Assert( 0 );
- return (HTOOLHANDLE)0;
- }
-
- return m_ActiveHandles[ index ];
-}
-
-
-//-----------------------------------------------------------------------------
-// Iterates through ALL entities (separate list for client vs. server)
-//-----------------------------------------------------------------------------
-EntitySearchResult CClientTools::NextEntity( EntitySearchResult currentEnt )
-{
- C_BaseEntity *ent = reinterpret_cast< C_BaseEntity* >( currentEnt );
- if ( ent == NULL )
- {
- ent = cl_entitylist->FirstBaseEntity();
- }
- else
- {
- ent = cl_entitylist->NextBaseEntity( ent );
- }
- return reinterpret_cast< EntitySearchResult >( ent );
-}
-
-
-//-----------------------------------------------------------------------------
-// Use this to turn on/off the presence of an underlying game entity
-//-----------------------------------------------------------------------------
-void CClientTools::SetEnabled( HTOOLHANDLE handle, bool enabled )
-{
- int idx = m_Handles.Find( HToolEntry_t( handle ) );
- if ( idx == m_Handles.InvalidIndex() )
- return;
-
- HToolEntry_t *slot = &m_Handles[ idx ];
- Assert( slot );
- if ( slot == NULL )
- return;
-
- C_BaseEntity *ent = slot->m_hEntity.Get();
- if ( ent == NULL || ent->entindex() == 0 )
- return; // Don't disable/enable the "world"
-
- ent->EnableInToolView( enabled );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CClientTools::SetRecording( HTOOLHANDLE handle, bool recording )
-{
- int idx = m_Handles.Find( HToolEntry_t( handle ) );
- if ( idx == m_Handles.InvalidIndex() )
- return;
-
- HToolEntry_t &entry = m_Handles[ idx ];
- if ( entry.m_hEntity )
- {
- entry.m_hEntity->SetToolRecording( recording );
- }
-}
-
-bool CClientTools::ShouldRecord( HTOOLHANDLE handle )
-{
- int idx = m_Handles.Find( HToolEntry_t( handle ) );
- if ( idx == m_Handles.InvalidIndex() )
- return false;
-
- HToolEntry_t &entry = m_Handles[ idx ];
- return entry.m_hEntity && entry.m_hEntity->ShouldRecordInTools();
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-int CClientTools::GetModelIndex( HTOOLHANDLE handle )
-{
- int idx = m_Handles.Find( HToolEntry_t( handle ) );
- if ( idx == m_Handles.InvalidIndex() )
- return NULL;
-
- HToolEntry_t &entry = m_Handles[ idx ];
- if ( entry.m_hEntity )
- {
- return entry.m_hEntity->GetModelIndex();
- }
- Assert( 0 );
- return 0;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-const char* CClientTools::GetModelName( HTOOLHANDLE handle )
-{
- int idx = m_Handles.Find( HToolEntry_t( handle ) );
- if ( idx == m_Handles.InvalidIndex() )
- return NULL;
-
- HToolEntry_t &entry = m_Handles[ idx ];
- if ( entry.m_hEntity )
- {
- return STRING( entry.m_hEntity->GetModelName() );
- }
- Assert( 0 );
- return NULL;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-const char* CClientTools::GetClassname( HTOOLHANDLE handle )
-{
- int idx = m_Handles.Find( HToolEntry_t( handle ) );
- if ( idx == m_Handles.InvalidIndex() )
- return NULL;
-
- HToolEntry_t &entry = m_Handles[ idx ];
- if ( entry.m_hEntity )
- {
- return STRING( entry.m_hEntity->GetClassname() );
- }
- Assert( 0 );
- return NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : handle -
-//-----------------------------------------------------------------------------
-bool CClientTools::IsValidHandle( HTOOLHANDLE handle )
-{
- return m_Handles.Find( HToolEntry_t( handle ) ) != m_Handles.InvalidIndex();
-}
-
-void CClientTools::OnEntityDeleted( CBaseEntity *pEntity )
-{
- HTOOLHANDLE handle = pEntity ? pEntity->GetToolHandle() : (HTOOLHANDLE)0;
- if ( handle == (HTOOLHANDLE)0 )
- return;
-
- if ( m_bInRecordingMode )
- {
- // Send deletion message to tool interface
- KeyValues *kv = new KeyValues( "deleted" );
- ToolFramework_PostToolMessage( handle, kv );
- kv->deleteThis();
- }
-
- DetachFromEntity( pEntity );
-}
-
-void CClientTools::OnEntityCreated( CBaseEntity *pEntity )
-{
- if ( !m_bInRecordingMode )
- return;
-
- HTOOLHANDLE h = AttachToEntity( pEntity );
-
- // Send deletion message to tool interface
- KeyValues *kv = new KeyValues( "created" );
- ToolFramework_PostToolMessage( h, kv );
- kv->deleteThis();
-}
-
-HTOOLHANDLE CClientTools::GetToolHandleForEntityByIndex( int entindex )
-{
- C_BaseEntity *ent = C_BaseEntity::Instance( entindex );
- if ( !ent )
- return (HTOOLHANDLE)0;
-
- return ent->GetToolHandle();
-}
-
-EntitySearchResult CClientTools::GetLocalPlayer()
-{
- C_BasePlayer *p = C_BasePlayer::GetLocalPlayer();
- return reinterpret_cast< EntitySearchResult >( p );
-}
-
-bool CClientTools::GetLocalPlayerEyePosition( Vector& org, QAngle& ang, float &fov )
-{
- C_BasePlayer *pl = C_BasePlayer::GetLocalPlayer();
- if ( pl == NULL )
- return false;
-
- org = pl->EyePosition();
- ang = pl->EyeAngles();
- fov = pl->GetFOV();
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Create, destroy shadow
-//-----------------------------------------------------------------------------
-ClientShadowHandle_t CClientTools::CreateShadow( CBaseHandle h, int nFlags )
-{
- return g_pClientShadowMgr->CreateShadow( h, nFlags );
-}
-
-void CClientTools::DestroyShadow( ClientShadowHandle_t h )
-{
- g_pClientShadowMgr->DestroyShadow( h );
-}
-
-ClientShadowHandle_t CClientTools::CreateFlashlight( const FlashlightState_t &lightState )
-{
- return g_pClientShadowMgr->CreateFlashlight( lightState );
-}
-
-void CClientTools::DestroyFlashlight( ClientShadowHandle_t h )
-{
- g_pClientShadowMgr->DestroyFlashlight( h );
-}
-
-void CClientTools::UpdateFlashlightState( ClientShadowHandle_t h, const FlashlightState_t &lightState )
-{
- g_pClientShadowMgr->UpdateFlashlightState( h, lightState );
-}
-
-void CClientTools::AddToDirtyShadowList( ClientShadowHandle_t h, bool force )
-{
- g_pClientShadowMgr->AddToDirtyShadowList( h, force );
-}
-
-void CClientTools::MarkRenderToTextureShadowDirty( ClientShadowHandle_t h )
-{
- g_pClientShadowMgr->MarkRenderToTextureShadowDirty( h );
-}
-
-void CClientTools::UpdateProjectedTexture( ClientShadowHandle_t h, bool bForce )
-{
- g_pClientShadowMgr->UpdateProjectedTexture( h, bForce );
-}
-
-int CClientTools::FindGlobalFlexcontroller( char const *name )
-{
- return C_BaseFlex::AddGlobalFlexController( (char *)name );
-}
-
-char const *CClientTools::GetGlobalFlexControllerName( int idx )
-{
- return C_BaseFlex::GetGlobalFlexControllerName( idx );
-}
-
-//-----------------------------------------------------------------------------
-// helper for traversing ownership hierarchy
-//-----------------------------------------------------------------------------
-EntitySearchResult CClientTools::GetOwnerEntity( EntitySearchResult currentEnt )
-{
- C_BaseEntity *ent = reinterpret_cast< C_BaseEntity* >( currentEnt );
- return ent ? ent->GetOwnerEntity() : NULL;
-}
-//-----------------------------------------------------------------------------
-// common and useful types to query for hierarchically
-//-----------------------------------------------------------------------------
-bool CClientTools::IsPlayer( EntitySearchResult currentEnt )
-{
- C_BaseEntity *ent = reinterpret_cast< C_BaseEntity* >( currentEnt );
- return ent ? ent->IsPlayer() : false;
-}
-
-bool CClientTools::IsBaseCombatCharacter( EntitySearchResult currentEnt )
-{
- C_BaseEntity *ent = reinterpret_cast< C_BaseEntity* >( currentEnt );
- return ent ? ent->IsBaseCombatCharacter() : false;
-}
-
-bool CClientTools::IsNPC( EntitySearchResult currentEnt )
-{
- C_BaseEntity *ent = reinterpret_cast< C_BaseEntity* >( currentEnt );
- return ent ? ent->IsNPC() : false;
-}
-
-Vector CClientTools::GetAbsOrigin( HTOOLHANDLE handle )
-{
- int idx = m_Handles.Find( HToolEntry_t( handle ) );
- if ( idx == m_Handles.InvalidIndex() )
- return vec3_origin;
-
- HToolEntry_t &entry = m_Handles[ idx ];
- if ( entry.m_hEntity )
- {
- return entry.m_hEntity->GetAbsOrigin();
- }
- Assert( 0 );
- return vec3_origin;
-}
-
-QAngle CClientTools::GetAbsAngles( HTOOLHANDLE handle )
-{
- int idx = m_Handles.Find( HToolEntry_t( handle ) );
- if ( idx == m_Handles.InvalidIndex() )
- return vec3_angle;
-
- HToolEntry_t &entry = m_Handles[ idx ];
- if ( entry.m_hEntity )
- {
- return entry.m_hEntity->GetAbsAngles();
- }
- Assert( 0 );
- return vec3_angle;
-}
-
-
-//-----------------------------------------------------------------------------
-// Sends a mesage from the tool to the client
-//-----------------------------------------------------------------------------
-void CClientTools::PostToolMessage( KeyValues *pKeyValues )
-{
- if ( !Q_stricmp( pKeyValues->GetName(), "QueryParticleManifest" ) )
- {
- // NOTE: This cannot be done during particle system init because tools aren't set up at that point
- CUtlVector<CUtlString> files;
- GetParticleManifest( files );
- int nCount = files.Count();
- for ( int i = 0; i < nCount; ++i )
- {
- char pTemp[256];
- Q_snprintf( pTemp, sizeof(pTemp), "%d", i );
- KeyValues *pSubKey = pKeyValues->FindKey( pTemp, true );
- pSubKey->SetString( "file", files[i] );
- }
- return;
- }
-
- if ( !Q_stricmp( pKeyValues->GetName(), "QueryMonitorTexture" ) )
- {
- pKeyValues->SetPtr( "texture", GetCameraTexture() );
- return;
- }
-
-#ifdef PORTAL
- if ( !Q_stricmp( pKeyValues->GetName(), "portals" ) )
- {
- g_pPortalRender->HandlePortalPlaybackMessage( pKeyValues );
- return;
- }
-
- if ( !Q_stricmp( pKeyValues->GetName(), "query CPortalRenderer" ) )
- {
- pKeyValues->SetInt( "IsRenderingPortal", g_pPortalRender->IsRenderingPortal() ? 1 : 0 );
- return;
- }
-#endif
-}
-
-
-//-----------------------------------------------------------------------------
-// Indicates whether the client should render particle systems
-//-----------------------------------------------------------------------------
-void CClientTools::EnableParticleSystems( bool bEnable )
-{
- ParticleMgr()->RenderParticleSystems( bEnable );
-}
-
-
-//-----------------------------------------------------------------------------
-// Is the game rendering in 3rd person mode?
-//-----------------------------------------------------------------------------
-bool CClientTools::IsRenderingThirdPerson() const
-{
- return !C_BasePlayer::LocalPlayerInFirstPersonView();
-}
-
-
-//-----------------------------------------------------------------------------
-// Reload particle definitions
-//-----------------------------------------------------------------------------
-void CClientTools::ReloadParticleDefintions( const char *pFileName, const void *pBufData, int nLen )
-{
- // Remove all new effects, because we are going to free internal structures they point to
- ParticleMgr()->RemoveAllNewEffects();
-
- // FIXME: Use file name to determine if we care about this data
- CUtlBuffer buf( pBufData, nLen, CUtlBuffer::READ_ONLY );
- g_pParticleSystemMgr->ReadParticleConfigFile( buf, true );
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+#include "cbase.h"
+#include "toolframework/itoolentity.h"
+#include "tier1/KeyValues.h"
+#include "Sprite.h"
+#include "enginesprite.h"
+#include "toolframework_client.h"
+#include "particles/particles.h"
+#include "particle_parse.h"
+#include "rendertexture.h"
+
+#ifdef PORTAL
+ #include "PortalRender.h"
+#endif
+
+#pragma warning( disable: 4355 ) // warning C4355: 'this' : used in base member initializer list
+
+class CClientTools;
+
+void DrawSpriteModel( IClientEntity *baseentity, CEngineSprite *psprite,
+ const Vector &origin, float fscale, float frame,
+ int rendermode, int r, int g, int b, int a,
+ const Vector& forward, const Vector& right, const Vector& up, float flHDRColorScale = 1.0f );
+float StandardGlowBlend( const pixelvis_queryparams_t &params, pixelvis_handle_t *queryHandle,
+ int rendermode, int renderfx, int alpha, float *pscale );
+
+
+// Interface from engine to tools for manipulating entities
+class CClientTools : public IClientTools, public IClientEntityListener
+{
+public:
+ CClientTools();
+
+ virtual HTOOLHANDLE AttachToEntity( EntitySearchResult entityToAttach );
+ virtual void DetachFromEntity( EntitySearchResult entityToDetach );
+ virtual bool IsValidHandle( HTOOLHANDLE handle );
+
+ virtual int GetNumRecordables();
+ virtual HTOOLHANDLE GetRecordable( int index );
+
+ // Iterates through ALL entities (separate list for client vs. server)
+ virtual EntitySearchResult NextEntity( EntitySearchResult currentEnt );
+
+ // Use this to turn on/off the presence of an underlying game entity
+ virtual void SetEnabled( HTOOLHANDLE handle, bool enabled );
+
+ virtual void SetRecording( HTOOLHANDLE handle, bool recording );
+ virtual bool ShouldRecord( HTOOLHANDLE handle );
+
+ virtual int GetModelIndex( HTOOLHANDLE handle );
+ virtual const char* GetModelName ( HTOOLHANDLE handle );
+ virtual const char* GetClassname ( HTOOLHANDLE handle );
+
+ virtual HTOOLHANDLE GetToolHandleForEntityByIndex( int entindex );
+
+ virtual void AddClientRenderable( IClientRenderable *pRenderable, int renderGroup );
+ virtual void RemoveClientRenderable( IClientRenderable *pRenderable );
+ virtual void SetRenderGroup( IClientRenderable *pRenderable, int renderGroup );
+ virtual void MarkClientRenderableDirty( IClientRenderable *pRenderable );
+
+ virtual bool DrawSprite( IClientRenderable *pRenderable,
+ float scale, float frame,
+ int rendermode, int renderfx,
+ const Color &color, float flProxyRadius, int *pVisHandle );
+
+ virtual bool GetLocalPlayerEyePosition( Vector& org, QAngle& ang, float &fov );
+ virtual EntitySearchResult GetLocalPlayer();
+
+ virtual ClientShadowHandle_t CreateShadow( CBaseHandle h, int nFlags );
+ virtual void DestroyShadow( ClientShadowHandle_t h );
+ virtual ClientShadowHandle_t CreateFlashlight( const FlashlightState_t &lightState );
+ virtual void DestroyFlashlight( ClientShadowHandle_t h );
+ virtual void UpdateFlashlightState( ClientShadowHandle_t h, const FlashlightState_t &flashlightState );
+ virtual void AddToDirtyShadowList( ClientShadowHandle_t h, bool force = false );
+ virtual void MarkRenderToTextureShadowDirty( ClientShadowHandle_t h );
+ virtual void UpdateProjectedTexture( ClientShadowHandle_t h, bool bForce );
+
+ // Global toggle for recording
+ virtual void EnableRecordingMode( bool bEnable );
+ virtual bool IsInRecordingMode() const;
+
+ // Trigger a temp entity
+ virtual void TriggerTempEntity( KeyValues *pKeyValues );
+
+ // get owning weapon (for viewmodels)
+ virtual int GetOwningWeaponEntIndex( int entindex );
+ virtual int GetEntIndex( EntitySearchResult entityToAttach );
+
+ virtual int FindGlobalFlexcontroller( char const *name );
+ virtual char const *GetGlobalFlexControllerName( int idx );
+
+ // helper for traversing ownership hierarchy
+ virtual EntitySearchResult GetOwnerEntity( EntitySearchResult currentEnt );
+
+ // common and useful types to query for hierarchically
+ virtual bool IsPlayer( EntitySearchResult entityToAttach );
+ virtual bool IsBaseCombatCharacter( EntitySearchResult entityToAttach );
+ virtual bool IsNPC( EntitySearchResult entityToAttach );
+
+ virtual Vector GetAbsOrigin( HTOOLHANDLE handle );
+ virtual QAngle GetAbsAngles( HTOOLHANDLE handle );
+ virtual void ReloadParticleDefintions( const char *pFileName, const void *pBufData, int nLen );
+
+ // Sends a mesage from the tool to the client
+ virtual void PostToolMessage( KeyValues *pKeyValues );
+
+ // Indicates whether the client should render particle systems
+ virtual void EnableParticleSystems( bool bEnable );
+
+ // Is the game rendering in 3rd person mode?
+ virtual bool IsRenderingThirdPerson() const;
+
+public:
+ C_BaseEntity *LookupEntity( HTOOLHANDLE handle );
+
+ // IClientEntityListener methods
+ void OnEntityDeleted( C_BaseEntity *pEntity );
+ void OnEntityCreated( C_BaseEntity *pEntity );
+
+private:
+ struct HToolEntry_t
+ {
+ HToolEntry_t() : m_Handle( 0 ) {}
+ HToolEntry_t( int handle, C_BaseEntity *pEntity = NULL )
+ : m_Handle( handle ), m_hEntity( pEntity )
+ {
+ if ( pEntity )
+ {
+ m_hEntity->SetToolHandle( m_Handle );
+ }
+ }
+
+ int m_Handle;
+ EHANDLE m_hEntity;
+ };
+
+ static int s_nNextHandle;
+
+ static bool HandleLessFunc( const HToolEntry_t& lhs, const HToolEntry_t& rhs )
+ {
+ return lhs.m_Handle < rhs.m_Handle;
+ }
+
+ CUtlRBTree< HToolEntry_t > m_Handles;
+ CUtlVector< int > m_ActiveHandles;
+ bool m_bInRecordingMode;
+};
+
+
+//-----------------------------------------------------------------------------
+// Statics
+//-----------------------------------------------------------------------------
+int CClientTools::s_nNextHandle = 1;
+
+
+//-----------------------------------------------------------------------------
+// Singleton instance
+//-----------------------------------------------------------------------------
+static CClientTools s_ClientTools;
+IClientTools *clienttools = &s_ClientTools;
+EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CClientTools, IClientTools, VCLIENTTOOLS_INTERFACE_VERSION, s_ClientTools );
+
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+CClientTools::CClientTools() : m_Handles( 0, 0, HandleLessFunc )
+{
+ m_bInRecordingMode = false;
+ cl_entitylist->AddListenerEntity( this );
+}
+
+
+//-----------------------------------------------------------------------------
+// Global toggle for recording
+//-----------------------------------------------------------------------------
+void CClientTools::EnableRecordingMode( bool bEnable )
+{
+ m_bInRecordingMode = bEnable;
+}
+
+bool CClientTools::IsInRecordingMode() const
+{
+ return m_bInRecordingMode;
+}
+
+
+//-----------------------------------------------------------------------------
+// Trigger a temp entity
+//-----------------------------------------------------------------------------
+void CClientTools::TriggerTempEntity( KeyValues *pKeyValues )
+{
+ te->TriggerTempEntity( pKeyValues );
+}
+
+
+//-----------------------------------------------------------------------------
+// get owning weapon (for viewmodels)
+//-----------------------------------------------------------------------------
+int CClientTools::GetOwningWeaponEntIndex( int entindex )
+{
+ C_BaseEntity *pEnt = C_BaseEntity::Instance( entindex );
+ C_BaseViewModel *pViewModel = dynamic_cast< C_BaseViewModel* >( pEnt );
+ if ( pViewModel )
+ {
+ C_BaseCombatWeapon *pWeapon = pViewModel->GetOwningWeapon();
+ if ( pWeapon )
+ {
+ return pWeapon->entindex();
+ }
+ }
+
+ return -1;
+}
+
+int CClientTools::GetEntIndex( EntitySearchResult entityToAttach )
+{
+ C_BaseEntity *ent = reinterpret_cast< C_BaseEntity * >( entityToAttach );
+ return ent ? ent->entindex() : 0;
+}
+
+void CClientTools::AddClientRenderable( IClientRenderable *pRenderable, int renderGroup )
+{
+ Assert( pRenderable );
+
+ cl_entitylist->AddNonNetworkableEntity( pRenderable->GetIClientUnknown() );
+
+ ClientRenderHandle_t handle = pRenderable->RenderHandle();
+ if ( INVALID_CLIENT_RENDER_HANDLE == handle )
+ {
+ // create new renderer handle
+ ClientLeafSystem()->AddRenderable( pRenderable, (RenderGroup_t)renderGroup );
+ }
+ else
+ {
+ // handle already exists, just update group & origin
+ ClientLeafSystem()->SetRenderGroup( pRenderable->RenderHandle(), (RenderGroup_t)renderGroup );
+ ClientLeafSystem()->RenderableChanged( pRenderable->RenderHandle() );
+ }
+
+}
+
+void CClientTools::RemoveClientRenderable( IClientRenderable *pRenderable )
+{
+ ClientRenderHandle_t handle = pRenderable->RenderHandle();
+ if( handle != INVALID_CLIENT_RENDER_HANDLE )
+ {
+ ClientLeafSystem()->RemoveRenderable( handle );
+ }
+ cl_entitylist->RemoveEntity( pRenderable->GetIClientUnknown()->GetRefEHandle() );
+}
+
+void CClientTools::MarkClientRenderableDirty( IClientRenderable *pRenderable )
+{
+ ClientRenderHandle_t handle = pRenderable->RenderHandle();
+ if ( INVALID_CLIENT_RENDER_HANDLE != handle )
+ {
+ // handle already exists, just update group & origin
+ ClientLeafSystem()->RenderableChanged( pRenderable->RenderHandle() );
+ }
+}
+
+void CClientTools::SetRenderGroup( IClientRenderable *pRenderable, int renderGroup )
+{
+ ClientRenderHandle_t handle = pRenderable->RenderHandle();
+ if ( INVALID_CLIENT_RENDER_HANDLE == handle )
+ {
+ // create new renderer handle
+ ClientLeafSystem()->AddRenderable( pRenderable, (RenderGroup_t)renderGroup );
+ }
+ else
+ {
+ // handle already exists, just update group & origin
+ ClientLeafSystem()->SetRenderGroup( pRenderable->RenderHandle(), (RenderGroup_t)renderGroup );
+ ClientLeafSystem()->RenderableChanged( pRenderable->RenderHandle() );
+ }
+}
+
+bool CClientTools::DrawSprite( IClientRenderable *pRenderable, float scale, float frame, int rendermode, int renderfx, const Color &color, float flProxyRadius, int *pVisHandle )
+{
+ Vector origin = pRenderable->GetRenderOrigin();
+ QAngle angles = pRenderable->GetRenderAngles();
+
+ // Get extra data
+ CEngineSprite *psprite = (CEngineSprite *)modelinfo->GetModelExtraData( pRenderable->GetModel() );
+ if ( !psprite )
+ return false;
+
+ // Get orthonormal bases for current view - re-align to current camera (vs. recorded camera)
+ Vector forward, right, up;
+ C_SpriteRenderer::GetSpriteAxes( ( C_SpriteRenderer::SPRITETYPE )psprite->GetOrientation(), origin, angles, forward, right, up );
+
+ int r = color.r();
+ int g = color.g();
+ int b = color.b();
+
+ float oldBlend = render->GetBlend();
+ if ( rendermode != kRenderNormal )
+ {
+ // kRenderGlow and kRenderWorldGlow have a special blending function
+ if (( rendermode == kRenderGlow ) || ( rendermode == kRenderWorldGlow ))
+ {
+ pixelvis_queryparams_t params;
+ if ( flProxyRadius != 0.0f )
+ {
+ params.Init( origin, flProxyRadius );
+ params.bSizeInScreenspace = true;
+ }
+ else
+ {
+ params.Init( origin );
+ }
+ float blend = oldBlend * StandardGlowBlend( params, ( pixelvis_handle_t* )pVisHandle, rendermode, renderfx, color.a(), &scale );
+
+ if ( blend <= 0.0f )
+ return false;
+
+ //Fade out the sprite depending on distance from the view origin.
+ r *= blend;
+ g *= blend;
+ b *= blend;
+
+ render->SetBlend( blend );
+ }
+ }
+
+ DrawSpriteModel( ( IClientEntity* )pRenderable, psprite, origin, scale, frame, rendermode, r, g, b, color.a(), forward, right, up );
+
+ if (( rendermode == kRenderGlow ) || ( rendermode == kRenderWorldGlow ))
+ {
+ render->SetBlend( oldBlend );
+ }
+
+ return true;
+}
+
+HTOOLHANDLE CClientTools::AttachToEntity( EntitySearchResult entityToAttach )
+{
+ C_BaseEntity *ent = reinterpret_cast< C_BaseEntity * >( entityToAttach );
+ Assert( ent );
+ if ( !ent )
+ return (HTOOLHANDLE)0;
+
+ HTOOLHANDLE curHandle = ent->GetToolHandle();
+ if ( curHandle != 0 )
+ return curHandle; // Already attaached
+
+ HToolEntry_t newHandle( s_nNextHandle++, ent );
+
+ m_Handles.Insert( newHandle );
+ m_ActiveHandles.AddToTail( newHandle.m_Handle );
+
+ return (HTOOLHANDLE)newHandle.m_Handle;
+}
+
+void CClientTools::DetachFromEntity( EntitySearchResult entityToDetach )
+{
+ C_BaseEntity *ent = reinterpret_cast< C_BaseEntity * >( entityToDetach );
+ Assert( ent );
+ if ( !ent )
+ return;
+
+ HTOOLHANDLE handle = ent->GetToolHandle();
+ ent->SetToolHandle( (HTOOLHANDLE)0 );
+
+ if ( handle == (HTOOLHANDLE)0 )
+ {
+ Assert( 0 );
+ return;
+ }
+
+ int idx = m_Handles.Find( HToolEntry_t( handle ) );
+ if ( idx == m_Handles.InvalidIndex() )
+ {
+ Assert( 0 );
+ return;
+ }
+
+ m_Handles.RemoveAt( idx );
+ m_ActiveHandles.FindAndRemove( handle );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : handle -
+// Output : C_BaseEntity
+//-----------------------------------------------------------------------------
+C_BaseEntity *CClientTools::LookupEntity( HTOOLHANDLE handle )
+{
+ int idx = m_Handles.Find( HToolEntry_t( handle ) );
+ if ( idx == m_Handles.InvalidIndex() )
+ return NULL;
+
+ return m_Handles[ idx ].m_hEntity;
+}
+
+int CClientTools::GetNumRecordables()
+{
+ return m_ActiveHandles.Count();
+}
+
+HTOOLHANDLE CClientTools::GetRecordable( int index )
+{
+ if ( index < 0 || index >= m_ActiveHandles.Count() )
+ {
+ Assert( 0 );
+ return (HTOOLHANDLE)0;
+ }
+
+ return m_ActiveHandles[ index ];
+}
+
+
+//-----------------------------------------------------------------------------
+// Iterates through ALL entities (separate list for client vs. server)
+//-----------------------------------------------------------------------------
+EntitySearchResult CClientTools::NextEntity( EntitySearchResult currentEnt )
+{
+ C_BaseEntity *ent = reinterpret_cast< C_BaseEntity* >( currentEnt );
+ if ( ent == NULL )
+ {
+ ent = cl_entitylist->FirstBaseEntity();
+ }
+ else
+ {
+ ent = cl_entitylist->NextBaseEntity( ent );
+ }
+ return reinterpret_cast< EntitySearchResult >( ent );
+}
+
+
+//-----------------------------------------------------------------------------
+// Use this to turn on/off the presence of an underlying game entity
+//-----------------------------------------------------------------------------
+void CClientTools::SetEnabled( HTOOLHANDLE handle, bool enabled )
+{
+ int idx = m_Handles.Find( HToolEntry_t( handle ) );
+ if ( idx == m_Handles.InvalidIndex() )
+ return;
+
+ HToolEntry_t *slot = &m_Handles[ idx ];
+ Assert( slot );
+ if ( slot == NULL )
+ return;
+
+ C_BaseEntity *ent = slot->m_hEntity.Get();
+ if ( ent == NULL || ent->entindex() == 0 )
+ return; // Don't disable/enable the "world"
+
+ ent->EnableInToolView( enabled );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CClientTools::SetRecording( HTOOLHANDLE handle, bool recording )
+{
+ int idx = m_Handles.Find( HToolEntry_t( handle ) );
+ if ( idx == m_Handles.InvalidIndex() )
+ return;
+
+ HToolEntry_t &entry = m_Handles[ idx ];
+ if ( entry.m_hEntity )
+ {
+ entry.m_hEntity->SetToolRecording( recording );
+ }
+}
+
+bool CClientTools::ShouldRecord( HTOOLHANDLE handle )
+{
+ int idx = m_Handles.Find( HToolEntry_t( handle ) );
+ if ( idx == m_Handles.InvalidIndex() )
+ return false;
+
+ HToolEntry_t &entry = m_Handles[ idx ];
+ return entry.m_hEntity && entry.m_hEntity->ShouldRecordInTools();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CClientTools::GetModelIndex( HTOOLHANDLE handle )
+{
+ int idx = m_Handles.Find( HToolEntry_t( handle ) );
+ if ( idx == m_Handles.InvalidIndex() )
+ return NULL;
+
+ HToolEntry_t &entry = m_Handles[ idx ];
+ if ( entry.m_hEntity )
+ {
+ return entry.m_hEntity->GetModelIndex();
+ }
+ Assert( 0 );
+ return 0;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+const char* CClientTools::GetModelName( HTOOLHANDLE handle )
+{
+ int idx = m_Handles.Find( HToolEntry_t( handle ) );
+ if ( idx == m_Handles.InvalidIndex() )
+ return NULL;
+
+ HToolEntry_t &entry = m_Handles[ idx ];
+ if ( entry.m_hEntity )
+ {
+ return STRING( entry.m_hEntity->GetModelName() );
+ }
+ Assert( 0 );
+ return NULL;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+const char* CClientTools::GetClassname( HTOOLHANDLE handle )
+{
+ int idx = m_Handles.Find( HToolEntry_t( handle ) );
+ if ( idx == m_Handles.InvalidIndex() )
+ return NULL;
+
+ HToolEntry_t &entry = m_Handles[ idx ];
+ if ( entry.m_hEntity )
+ {
+ return STRING( entry.m_hEntity->GetClassname() );
+ }
+ Assert( 0 );
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : handle -
+//-----------------------------------------------------------------------------
+bool CClientTools::IsValidHandle( HTOOLHANDLE handle )
+{
+ return m_Handles.Find( HToolEntry_t( handle ) ) != m_Handles.InvalidIndex();
+}
+
+void CClientTools::OnEntityDeleted( CBaseEntity *pEntity )
+{
+ HTOOLHANDLE handle = pEntity ? pEntity->GetToolHandle() : (HTOOLHANDLE)0;
+ if ( handle == (HTOOLHANDLE)0 )
+ return;
+
+ if ( m_bInRecordingMode )
+ {
+ // Send deletion message to tool interface
+ KeyValues *kv = new KeyValues( "deleted" );
+ ToolFramework_PostToolMessage( handle, kv );
+ kv->deleteThis();
+ }
+
+ DetachFromEntity( pEntity );
+}
+
+void CClientTools::OnEntityCreated( CBaseEntity *pEntity )
+{
+ if ( !m_bInRecordingMode )
+ return;
+
+ HTOOLHANDLE h = AttachToEntity( pEntity );
+
+ // Send deletion message to tool interface
+ KeyValues *kv = new KeyValues( "created" );
+ ToolFramework_PostToolMessage( h, kv );
+ kv->deleteThis();
+}
+
+HTOOLHANDLE CClientTools::GetToolHandleForEntityByIndex( int entindex )
+{
+ C_BaseEntity *ent = C_BaseEntity::Instance( entindex );
+ if ( !ent )
+ return (HTOOLHANDLE)0;
+
+ return ent->GetToolHandle();
+}
+
+EntitySearchResult CClientTools::GetLocalPlayer()
+{
+ C_BasePlayer *p = C_BasePlayer::GetLocalPlayer();
+ return reinterpret_cast< EntitySearchResult >( p );
+}
+
+bool CClientTools::GetLocalPlayerEyePosition( Vector& org, QAngle& ang, float &fov )
+{
+ C_BasePlayer *pl = C_BasePlayer::GetLocalPlayer();
+ if ( pl == NULL )
+ return false;
+
+ org = pl->EyePosition();
+ ang = pl->EyeAngles();
+ fov = pl->GetFOV();
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Create, destroy shadow
+//-----------------------------------------------------------------------------
+ClientShadowHandle_t CClientTools::CreateShadow( CBaseHandle h, int nFlags )
+{
+ return g_pClientShadowMgr->CreateShadow( h, nFlags );
+}
+
+void CClientTools::DestroyShadow( ClientShadowHandle_t h )
+{
+ g_pClientShadowMgr->DestroyShadow( h );
+}
+
+ClientShadowHandle_t CClientTools::CreateFlashlight( const FlashlightState_t &lightState )
+{
+ return g_pClientShadowMgr->CreateFlashlight( lightState );
+}
+
+void CClientTools::DestroyFlashlight( ClientShadowHandle_t h )
+{
+ g_pClientShadowMgr->DestroyFlashlight( h );
+}
+
+void CClientTools::UpdateFlashlightState( ClientShadowHandle_t h, const FlashlightState_t &lightState )
+{
+ g_pClientShadowMgr->UpdateFlashlightState( h, lightState );
+}
+
+void CClientTools::AddToDirtyShadowList( ClientShadowHandle_t h, bool force )
+{
+ g_pClientShadowMgr->AddToDirtyShadowList( h, force );
+}
+
+void CClientTools::MarkRenderToTextureShadowDirty( ClientShadowHandle_t h )
+{
+ g_pClientShadowMgr->MarkRenderToTextureShadowDirty( h );
+}
+
+void CClientTools::UpdateProjectedTexture( ClientShadowHandle_t h, bool bForce )
+{
+ g_pClientShadowMgr->UpdateProjectedTexture( h, bForce );
+}
+
+int CClientTools::FindGlobalFlexcontroller( char const *name )
+{
+ return C_BaseFlex::AddGlobalFlexController( (char *)name );
+}
+
+char const *CClientTools::GetGlobalFlexControllerName( int idx )
+{
+ return C_BaseFlex::GetGlobalFlexControllerName( idx );
+}
+
+//-----------------------------------------------------------------------------
+// helper for traversing ownership hierarchy
+//-----------------------------------------------------------------------------
+EntitySearchResult CClientTools::GetOwnerEntity( EntitySearchResult currentEnt )
+{
+ C_BaseEntity *ent = reinterpret_cast< C_BaseEntity* >( currentEnt );
+ return ent ? ent->GetOwnerEntity() : NULL;
+}
+//-----------------------------------------------------------------------------
+// common and useful types to query for hierarchically
+//-----------------------------------------------------------------------------
+bool CClientTools::IsPlayer( EntitySearchResult currentEnt )
+{
+ C_BaseEntity *ent = reinterpret_cast< C_BaseEntity* >( currentEnt );
+ return ent ? ent->IsPlayer() : false;
+}
+
+bool CClientTools::IsBaseCombatCharacter( EntitySearchResult currentEnt )
+{
+ C_BaseEntity *ent = reinterpret_cast< C_BaseEntity* >( currentEnt );
+ return ent ? ent->IsBaseCombatCharacter() : false;
+}
+
+bool CClientTools::IsNPC( EntitySearchResult currentEnt )
+{
+ C_BaseEntity *ent = reinterpret_cast< C_BaseEntity* >( currentEnt );
+ return ent ? ent->IsNPC() : false;
+}
+
+Vector CClientTools::GetAbsOrigin( HTOOLHANDLE handle )
+{
+ int idx = m_Handles.Find( HToolEntry_t( handle ) );
+ if ( idx == m_Handles.InvalidIndex() )
+ return vec3_origin;
+
+ HToolEntry_t &entry = m_Handles[ idx ];
+ if ( entry.m_hEntity )
+ {
+ return entry.m_hEntity->GetAbsOrigin();
+ }
+ Assert( 0 );
+ return vec3_origin;
+}
+
+QAngle CClientTools::GetAbsAngles( HTOOLHANDLE handle )
+{
+ int idx = m_Handles.Find( HToolEntry_t( handle ) );
+ if ( idx == m_Handles.InvalidIndex() )
+ return vec3_angle;
+
+ HToolEntry_t &entry = m_Handles[ idx ];
+ if ( entry.m_hEntity )
+ {
+ return entry.m_hEntity->GetAbsAngles();
+ }
+ Assert( 0 );
+ return vec3_angle;
+}
+
+
+//-----------------------------------------------------------------------------
+// Sends a mesage from the tool to the client
+//-----------------------------------------------------------------------------
+void CClientTools::PostToolMessage( KeyValues *pKeyValues )
+{
+ if ( !Q_stricmp( pKeyValues->GetName(), "QueryParticleManifest" ) )
+ {
+ // NOTE: This cannot be done during particle system init because tools aren't set up at that point
+ CUtlVector<CUtlString> files;
+ GetParticleManifest( files );
+ int nCount = files.Count();
+ for ( int i = 0; i < nCount; ++i )
+ {
+ char pTemp[256];
+ Q_snprintf( pTemp, sizeof(pTemp), "%d", i );
+ KeyValues *pSubKey = pKeyValues->FindKey( pTemp, true );
+ pSubKey->SetString( "file", files[i] );
+ }
+ return;
+ }
+
+ if ( !Q_stricmp( pKeyValues->GetName(), "QueryMonitorTexture" ) )
+ {
+ pKeyValues->SetPtr( "texture", GetCameraTexture() );
+ return;
+ }
+
+#ifdef PORTAL
+ if ( !Q_stricmp( pKeyValues->GetName(), "portals" ) )
+ {
+ g_pPortalRender->HandlePortalPlaybackMessage( pKeyValues );
+ return;
+ }
+
+ if ( !Q_stricmp( pKeyValues->GetName(), "query CPortalRenderer" ) )
+ {
+ pKeyValues->SetInt( "IsRenderingPortal", g_pPortalRender->IsRenderingPortal() ? 1 : 0 );
+ return;
+ }
+#endif
+}
+
+
+//-----------------------------------------------------------------------------
+// Indicates whether the client should render particle systems
+//-----------------------------------------------------------------------------
+void CClientTools::EnableParticleSystems( bool bEnable )
+{
+ ParticleMgr()->RenderParticleSystems( bEnable );
+}
+
+
+//-----------------------------------------------------------------------------
+// Is the game rendering in 3rd person mode?
+//-----------------------------------------------------------------------------
+bool CClientTools::IsRenderingThirdPerson() const
+{
+ return !C_BasePlayer::LocalPlayerInFirstPersonView();
+}
+
+
+//-----------------------------------------------------------------------------
+// Reload particle definitions
+//-----------------------------------------------------------------------------
+void CClientTools::ReloadParticleDefintions( const char *pFileName, const void *pBufData, int nLen )
+{
+ // Remove all new effects, because we are going to free internal structures they point to
+ ParticleMgr()->RemoveAllNewEffects();
+
+ // FIXME: Use file name to determine if we care about this data
+ CUtlBuffer buf( pBufData, nLen, CUtlBuffer::READ_ONLY );
+ g_pParticleSystemMgr->ReadParticleConfigFile( buf, true );
+}