mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2025-09-20 04:26:03 +08:00
Added original SDK code for Alien Swarm.
This commit is contained in:
951
game/client/entity_client_tools.cpp
Normal file
951
game/client/entity_client_tools.cpp
Normal file
@ -0,0 +1,951 @@
|
||||
//====== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "cbase.h"
|
||||
#include "toolframework/itoolentity.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "sprite.h"
|
||||
#include "enginesprite.h"
|
||||
#include "beamdraw.h"
|
||||
#include "toolframework_client.h"
|
||||
#include "particles/particles.h"
|
||||
#include "particle_parse.h"
|
||||
#include "rendertexture.h"
|
||||
#include "model_types.h"
|
||||
|
||||
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
#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 ¶ms, 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 EntitySearchResult GetEntity( HTOOLHANDLE handle );
|
||||
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, bool bRenderWithViewModels, RenderableTranslucencyType_t nType, RenderableModelType_t nModelType );
|
||||
virtual void RemoveClientRenderable( IClientRenderable *pRenderable );
|
||||
virtual void SetTranslucencyType( IClientRenderable *pRenderable, RenderableTranslucencyType_t nType );
|
||||
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 void DrawSprite( const Vector &vecOrigin, float flWidth, float flHeight, color32 color );
|
||||
|
||||
|
||||
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 IsCombatCharacter( EntitySearchResult entityToAttach );
|
||||
virtual bool IsNPC( EntitySearchResult entityToAttach );
|
||||
virtual bool IsRagdoll( EntitySearchResult currentEnt );
|
||||
virtual bool IsViewModel( EntitySearchResult entityToAttach );
|
||||
virtual bool IsViewModelOrAttachment( EntitySearchResult entityToAttach );
|
||||
virtual bool IsWeapon( EntitySearchResult entityToAttach );
|
||||
virtual bool IsSprite( EntitySearchResult entityToAttach );
|
||||
virtual bool IsProp( EntitySearchResult entityToAttach );
|
||||
virtual bool IsBrush( EntitySearchResult entityToAttach );
|
||||
|
||||
virtual Vector GetAbsOrigin( HTOOLHANDLE handle );
|
||||
virtual QAngle GetAbsAngles( HTOOLHANDLE handle );
|
||||
virtual void ReloadParticleDefintions( const char *pFileName, const void *pBufData, int nLen );
|
||||
|
||||
// ParticleSystem iteration, query, modification
|
||||
virtual ParticleSystemSearchResult NextParticleSystem( ParticleSystemSearchResult sr );
|
||||
virtual void SetRecording( ParticleSystemSearchResult sr, bool bRecord );
|
||||
|
||||
// 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 = ToBaseViewModel( 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, bool bRenderWithViewModels, RenderableTranslucencyType_t nType, RenderableModelType_t nModelType )
|
||||
{
|
||||
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, bRenderWithViewModels, nType, nModelType );
|
||||
}
|
||||
else
|
||||
{
|
||||
// handle already exists, just update group & origin
|
||||
ClientLeafSystem()->RenderWithViewModels( pRenderable->RenderHandle(), bRenderWithViewModels );
|
||||
ClientLeafSystem()->SetTranslucencyType( pRenderable->RenderHandle(), nType );
|
||||
ClientLeafSystem()->SetModelType( pRenderable->RenderHandle(), nModelType );
|
||||
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::SetTranslucencyType( IClientRenderable *pRenderable, RenderableTranslucencyType_t nType )
|
||||
{
|
||||
ClientLeafSystem()->SetTranslucencyType( pRenderable->RenderHandle(), nType );
|
||||
}
|
||||
|
||||
void CClientTools::DrawSprite( const Vector &vecOrigin, float flWidth, float flHeight, color32 color )
|
||||
{
|
||||
::DrawSprite( vecOrigin, flWidth, flHeight, color );
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
EntitySearchResult CClientTools::GetEntity( HTOOLHANDLE handle )
|
||||
{
|
||||
int idx = m_Handles.Find( HToolEntry_t( handle ) );
|
||||
if ( idx == m_Handles.InvalidIndex() )
|
||||
return reinterpret_cast< EntitySearchResult >( NULL );
|
||||
|
||||
HToolEntry_t *slot = &m_Handles[ idx ];
|
||||
Assert( slot );
|
||||
if ( slot == NULL )
|
||||
return reinterpret_cast< EntitySearchResult >( NULL );
|
||||
|
||||
C_BaseEntity *ent = slot->m_hEntity.Get();
|
||||
return reinterpret_cast< EntitySearchResult >( ent );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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 ( !ToolsEnabled() )
|
||||
return;
|
||||
|
||||
HTOOLHANDLE h = AttachToEntity( pEntity );
|
||||
|
||||
// Send deletion message to tool interface
|
||||
KeyValues *kv = new KeyValues( "created" );
|
||||
kv->SetPtr( "esr", ( void* )pEntity );
|
||||
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()
|
||||
{
|
||||
ACTIVE_SPLITSCREEN_PLAYER_GUARD( 0 );
|
||||
C_BasePlayer *p = C_BasePlayer::GetLocalPlayer();
|
||||
return reinterpret_cast< EntitySearchResult >( p );
|
||||
}
|
||||
|
||||
bool CClientTools::GetLocalPlayerEyePosition( Vector& org, QAngle& ang, float &fov )
|
||||
{
|
||||
ACTIVE_SPLITSCREEN_PLAYER_GUARD( 0 );
|
||||
C_BasePlayer *pl = C_BasePlayer::GetLocalPlayer();
|
||||
if ( pl == NULL )
|
||||
return false;
|
||||
|
||||
org = pl->EyePosition();
|
||||
ang = pl->EyeAngles();
|
||||
fov = pl->GetFOV();
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ParticleSystem iteration, query, modification
|
||||
//-----------------------------------------------------------------------------
|
||||
ParticleSystemSearchResult CClientTools::NextParticleSystem( ParticleSystemSearchResult sr )
|
||||
{
|
||||
CNewParticleEffect *pParticleEffect = NULL;
|
||||
if ( sr == NULL )
|
||||
{
|
||||
pParticleEffect = ParticleMgr()->FirstNewEffect();
|
||||
}
|
||||
else
|
||||
{
|
||||
pParticleEffect = ParticleMgr()->NextNewEffect( reinterpret_cast< CNewParticleEffect* >( sr ) );
|
||||
}
|
||||
return reinterpret_cast< ParticleSystemSearchResult >( pParticleEffect );
|
||||
}
|
||||
|
||||
void CClientTools::SetRecording( ParticleSystemSearchResult sr, bool bRecord )
|
||||
{
|
||||
Assert( sr );
|
||||
if ( sr == NULL )
|
||||
return;
|
||||
|
||||
CNewParticleEffect *pParticleEffect = reinterpret_cast< CNewParticleEffect* >( sr );
|
||||
pParticleEffect->SetToolRecording( bRecord );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Create, destroy shadow
|
||||
//-----------------------------------------------------------------------------
|
||||
ClientShadowHandle_t CClientTools::CreateShadow( CBaseHandle h, int nFlags )
|
||||
{
|
||||
return g_pClientShadowMgr->CreateShadow( h, nFlags, NULL );
|
||||
}
|
||||
|
||||
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::IsCombatCharacter( 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;
|
||||
}
|
||||
|
||||
bool CClientTools::IsRagdoll( EntitySearchResult currentEnt )
|
||||
{
|
||||
C_BaseEntity *ent = reinterpret_cast< C_BaseEntity* >( currentEnt );
|
||||
C_BaseAnimating *pBaseAnimating = ent ? ent->GetBaseAnimating() : NULL;
|
||||
return pBaseAnimating ? pBaseAnimating->IsClientRagdoll() : false;
|
||||
}
|
||||
|
||||
bool CClientTools::IsViewModel( EntitySearchResult currentEnt )
|
||||
{
|
||||
C_BaseEntity *ent = reinterpret_cast< C_BaseEntity* >( currentEnt );
|
||||
C_BaseAnimating *pBaseAnimating = ent ? ent->GetBaseAnimating() : NULL;
|
||||
return pBaseAnimating ? pBaseAnimating->IsViewModel() : false;
|
||||
}
|
||||
|
||||
bool CClientTools::IsViewModelOrAttachment( EntitySearchResult currentEnt )
|
||||
{
|
||||
C_BaseEntity *ent = reinterpret_cast< C_BaseEntity* >( currentEnt );
|
||||
C_BaseAnimating *pBaseAnimating = ent ? ent->GetBaseAnimating() : NULL;
|
||||
return pBaseAnimating ? pBaseAnimating->IsViewModelOrAttachment() : false;
|
||||
}
|
||||
|
||||
bool CClientTools::IsWeapon( EntitySearchResult currentEnt )
|
||||
{
|
||||
C_BaseEntity *ent = reinterpret_cast< C_BaseEntity* >( currentEnt );
|
||||
return ent ? ent->IsBaseCombatWeapon() : false;
|
||||
}
|
||||
|
||||
bool CClientTools::IsSprite( EntitySearchResult currentEnt )
|
||||
{
|
||||
C_BaseEntity *ent = reinterpret_cast< C_BaseEntity* >( currentEnt );
|
||||
return ent ? ent->IsSprite() : false;
|
||||
}
|
||||
|
||||
bool CClientTools::IsProp( EntitySearchResult currentEnt )
|
||||
{
|
||||
C_BaseEntity *ent = reinterpret_cast< C_BaseEntity* >( currentEnt );
|
||||
return ent ? ent->IsProp() : false;
|
||||
}
|
||||
|
||||
bool CClientTools::IsBrush( EntitySearchResult currentEnt )
|
||||
{
|
||||
C_BaseEntity *ent = reinterpret_cast< C_BaseEntity* >( currentEnt );
|
||||
return ent ? ent->IsBrushModel() : 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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
|
||||
{
|
||||
ACTIVE_SPLITSCREEN_PLAYER_GUARD( 0 );
|
||||
C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
if ( !pLocalPlayer )
|
||||
return false;
|
||||
|
||||
return pLocalPlayer->ShouldDrawLocalPlayer();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Reload particle definitions
|
||||
//-----------------------------------------------------------------------------
|
||||
void CClientTools::ReloadParticleDefintions( const char *pFileName, const void *pBufData, int nLen )
|
||||
{
|
||||
MDLCACHE_CRITICAL_SECTION(); // Copying particle attachment control points may end up needing to evaluate skeletons
|
||||
|
||||
//////////////
|
||||
// Find any systems that depend on any system in the buffer
|
||||
// slow, but necessary if we want live reloads to work - and doesn't happen too often
|
||||
CUtlVector<CUtlString> systemNamesToReload;
|
||||
|
||||
g_pParticleSystemMgr->GetParticleSystemsInBuffer( CUtlBuffer(pBufData, nLen, CUtlBuffer::READ_ONLY), &systemNamesToReload );
|
||||
|
||||
CUtlVector<CNewParticleEffect*> toReplaceEffects;
|
||||
CUtlVector<CUtlString> toReplaceNames;
|
||||
|
||||
for( CNewParticleEffect *pEffect = ParticleMgr()->FirstNewEffect(); pEffect; pEffect = ParticleMgr()->NextNewEffect(pEffect) )
|
||||
{
|
||||
for( int i = 0; i < systemNamesToReload.Count(); ++i )
|
||||
{
|
||||
if ( pEffect->DependsOnSystem( systemNamesToReload[i] ) )
|
||||
{
|
||||
// only reload a given effect once
|
||||
if ( -1 == toReplaceEffects.Find(pEffect) )
|
||||
{
|
||||
toReplaceNames.AddToTail( pEffect->GetName() );
|
||||
toReplaceEffects.AddToTail( pEffect );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CUtlVector<CNonDrawingParticleSystem*> toReplaceEffectsNonDrawing;
|
||||
CUtlVector<CUtlString> toReplaceNamesNonDrawing;
|
||||
for( CNonDrawingParticleSystem *i = ParticleMgr()->m_NonDrawingParticleSystems.Head(); i ; i = i->m_pNext )
|
||||
{
|
||||
for( int j = 0; j < systemNamesToReload.Count(); ++j )
|
||||
{
|
||||
if ( i->Get()->DependsOnSystem( systemNamesToReload[j] ) )
|
||||
{
|
||||
if ( -1 == toReplaceEffectsNonDrawing.Find( i ) )
|
||||
{
|
||||
toReplaceNamesNonDrawing.AddToTail( i->Get()->GetName() );
|
||||
toReplaceEffectsNonDrawing.AddToTail( i );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////
|
||||
// Load the data and stomp the old definitions
|
||||
g_pParticleSystemMgr->ReadParticleConfigFile( CUtlBuffer(pBufData, nLen, CUtlBuffer::READ_ONLY), true );
|
||||
|
||||
//////////////
|
||||
// Now replace all of the systems with their new versions
|
||||
Assert( toReplaceEffects.Count() == toReplaceNames.Count() );
|
||||
|
||||
for( int i = 0; i < toReplaceNames.Count(); ++i )
|
||||
{
|
||||
CNewParticleEffect *pEffect = toReplaceEffects[i];
|
||||
pEffect->ReplaceWith( toReplaceNames[i] );
|
||||
}
|
||||
|
||||
// update all the non-drawings ones
|
||||
for( int i = 0; i < toReplaceNamesNonDrawing.Count(); i++ )
|
||||
{
|
||||
CNonDrawingParticleSystem *pEffect = toReplaceEffectsNonDrawing[i];
|
||||
delete pEffect->m_pSystem;
|
||||
pEffect->m_pSystem = g_pParticleSystemMgr->CreateParticleCollection( toReplaceNamesNonDrawing[i] );
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user