aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/client/cliententitylist.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/cliententitylist.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/cliententitylist.cpp')
-rw-r--r--mp/src/game/client/cliententitylist.cpp1008
1 files changed, 504 insertions, 504 deletions
diff --git a/mp/src/game/client/cliententitylist.cpp b/mp/src/game/client/cliententitylist.cpp
index 758ab8f8..294d4ff1 100644
--- a/mp/src/game/client/cliententitylist.cpp
+++ b/mp/src/game/client/cliententitylist.cpp
@@ -1,505 +1,505 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $Workfile: $
-// $NoKeywords: $
-//===========================================================================//
-
-//-----------------------------------------------------------------------------
-// Purpose: a global list of all the entities in the game. All iteration through
-// entities is done through this object.
-//-----------------------------------------------------------------------------
-#include "cbase.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-//-----------------------------------------------------------------------------
-// Globals
-//-----------------------------------------------------------------------------
-
-// Create interface
-static CClientEntityList s_EntityList;
-CBaseEntityList *g_pEntityList = &s_EntityList;
-
-// Expose list to engine
-EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CClientEntityList, IClientEntityList, VCLIENTENTITYLIST_INTERFACE_VERSION, s_EntityList );
-
-// Store local pointer to interface for rest of client .dll only
-// (CClientEntityList instead of IClientEntityList )
-CClientEntityList *cl_entitylist = &s_EntityList;
-
-
-bool PVSNotifierMap_LessFunc( IClientUnknown* const &a, IClientUnknown* const &b )
-{
- return a < b;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-CClientEntityList::CClientEntityList( void ) :
- m_PVSNotifierMap( 0, 0, PVSNotifierMap_LessFunc )
-{
- m_iMaxUsedServerIndex = -1;
- m_iMaxServerEnts = 0;
- Release();
-
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-CClientEntityList::~CClientEntityList( void )
-{
- Release();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Clears all entity lists and releases entities
-//-----------------------------------------------------------------------------
-void CClientEntityList::Release( void )
-{
- // Free all the entities.
- ClientEntityHandle_t iter = FirstHandle();
- while( iter != InvalidHandle() )
- {
- // Try to call release on anything we can.
- IClientNetworkable *pNet = GetClientNetworkableFromHandle( iter );
- if ( pNet )
- {
- pNet->Release();
- }
- else
- {
- // Try to call release on anything we can.
- IClientThinkable *pThinkable = GetClientThinkableFromHandle( iter );
- if ( pThinkable )
- {
- pThinkable->Release();
- }
- }
- RemoveEntity( iter );
-
- iter = FirstHandle();
- }
-
- m_iNumServerEnts = 0;
- m_iMaxServerEnts = 0;
- m_iNumClientNonNetworkable = 0;
- m_iMaxUsedServerIndex = -1;
-}
-
-IClientNetworkable* CClientEntityList::GetClientNetworkable( int entnum )
-{
- Assert( entnum >= 0 );
- Assert( entnum < MAX_EDICTS );
- return m_EntityCacheInfo[entnum].m_pNetworkable;
-}
-
-
-IClientEntity* CClientEntityList::GetClientEntity( int entnum )
-{
- IClientUnknown *pEnt = GetListedEntity( entnum );
- return pEnt ? pEnt->GetIClientEntity() : 0;
-}
-
-
-int CClientEntityList::NumberOfEntities( bool bIncludeNonNetworkable )
-{
- if ( bIncludeNonNetworkable == true )
- return m_iNumServerEnts + m_iNumClientNonNetworkable;
-
- return m_iNumServerEnts;
-}
-
-
-void CClientEntityList::SetMaxEntities( int maxents )
-{
- m_iMaxServerEnts = maxents;
-}
-
-
-int CClientEntityList::GetMaxEntities( void )
-{
- return m_iMaxServerEnts;
-}
-
-
-//-----------------------------------------------------------------------------
-// Convenience methods to convert between entindex + ClientEntityHandle_t
-//-----------------------------------------------------------------------------
-int CClientEntityList::HandleToEntIndex( ClientEntityHandle_t handle )
-{
- if ( handle == INVALID_EHANDLE_INDEX )
- return -1;
- C_BaseEntity *pEnt = GetBaseEntityFromHandle( handle );
- return pEnt ? pEnt->entindex() : -1;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Because m_iNumServerEnts != last index
-// Output : int
-//-----------------------------------------------------------------------------
-int CClientEntityList::GetHighestEntityIndex( void )
-{
- return m_iMaxUsedServerIndex;
-}
-
-void CClientEntityList::RecomputeHighestEntityUsed( void )
-{
- m_iMaxUsedServerIndex = -1;
-
- // Walk backward looking for first valid index
- int i;
- for ( i = MAX_EDICTS - 1; i >= 0; i-- )
- {
- if ( GetListedEntity( i ) != NULL )
- {
- m_iMaxUsedServerIndex = i;
- break;
- }
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Add a raw C_BaseEntity to the entity list.
-// Input : index -
-//-----------------------------------------------------------------------------
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : index -
-//-----------------------------------------------------------------------------
-
-C_BaseEntity* CClientEntityList::GetBaseEntity( int entnum )
-{
- IClientUnknown *pEnt = GetListedEntity( entnum );
- return pEnt ? pEnt->GetBaseEntity() : 0;
-}
-
-
-ICollideable* CClientEntityList::GetCollideable( int entnum )
-{
- IClientUnknown *pEnt = GetListedEntity( entnum );
- return pEnt ? pEnt->GetCollideable() : 0;
-}
-
-
-IClientNetworkable* CClientEntityList::GetClientNetworkableFromHandle( ClientEntityHandle_t hEnt )
-{
- IClientUnknown *pEnt = GetClientUnknownFromHandle( hEnt );
- return pEnt ? pEnt->GetClientNetworkable() : 0;
-}
-
-
-IClientEntity* CClientEntityList::GetClientEntityFromHandle( ClientEntityHandle_t hEnt )
-{
- IClientUnknown *pEnt = GetClientUnknownFromHandle( hEnt );
- return pEnt ? pEnt->GetIClientEntity() : 0;
-}
-
-
-IClientRenderable* CClientEntityList::GetClientRenderableFromHandle( ClientEntityHandle_t hEnt )
-{
- IClientUnknown *pEnt = GetClientUnknownFromHandle( hEnt );
- return pEnt ? pEnt->GetClientRenderable() : 0;
-}
-
-
-C_BaseEntity* CClientEntityList::GetBaseEntityFromHandle( ClientEntityHandle_t hEnt )
-{
- IClientUnknown *pEnt = GetClientUnknownFromHandle( hEnt );
- return pEnt ? pEnt->GetBaseEntity() : 0;
-}
-
-
-ICollideable* CClientEntityList::GetCollideableFromHandle( ClientEntityHandle_t hEnt )
-{
- IClientUnknown *pEnt = GetClientUnknownFromHandle( hEnt );
- return pEnt ? pEnt->GetCollideable() : 0;
-}
-
-
-IClientThinkable* CClientEntityList::GetClientThinkableFromHandle( ClientEntityHandle_t hEnt )
-{
- IClientUnknown *pEnt = GetClientUnknownFromHandle( hEnt );
- return pEnt ? pEnt->GetClientThinkable() : 0;
-}
-
-
-void CClientEntityList::AddPVSNotifier( IClientUnknown *pUnknown )
-{
- IClientRenderable *pRen = pUnknown->GetClientRenderable();
- if ( pRen )
- {
- IPVSNotify *pNotify = pRen->GetPVSNotifyInterface();
- if ( pNotify )
- {
- unsigned short index = m_PVSNotifyInfos.AddToTail();
- CPVSNotifyInfo *pInfo = &m_PVSNotifyInfos[index];
- pInfo->m_pNotify = pNotify;
- pInfo->m_pRenderable = pRen;
- pInfo->m_InPVSStatus = 0;
- pInfo->m_PVSNotifiersLink = index;
-
- m_PVSNotifierMap.Insert( pUnknown, index );
- }
- }
-}
-
-
-void CClientEntityList::RemovePVSNotifier( IClientUnknown *pUnknown )
-{
- IClientRenderable *pRenderable = pUnknown->GetClientRenderable();
- if ( pRenderable )
- {
- IPVSNotify *pNotify = pRenderable->GetPVSNotifyInterface();
- if ( pNotify )
- {
- unsigned short index = m_PVSNotifierMap.Find( pUnknown );
- if ( !m_PVSNotifierMap.IsValidIndex( index ) )
- {
- Warning( "PVS notifier not in m_PVSNotifierMap\n" );
- Assert( false );
- return;
- }
-
- unsigned short indexIntoPVSNotifyInfos = m_PVSNotifierMap[index];
-
- Assert( m_PVSNotifyInfos[indexIntoPVSNotifyInfos].m_pNotify == pNotify );
- Assert( m_PVSNotifyInfos[indexIntoPVSNotifyInfos].m_pRenderable == pRenderable );
-
- m_PVSNotifyInfos.Remove( indexIntoPVSNotifyInfos );
- m_PVSNotifierMap.RemoveAt( index );
- return;
- }
- }
-
- // If it didn't report itself as a notifier, let's hope it's not in the notifier list now
- // (which would mean that it reported itself as a notifier earlier, but not now).
-#ifdef _DEBUG
- unsigned short index = m_PVSNotifierMap.Find( pUnknown );
- Assert( !m_PVSNotifierMap.IsValidIndex( index ) );
-#endif
-}
-
-void CClientEntityList::AddListenerEntity( IClientEntityListener *pListener )
-{
- if ( m_entityListeners.Find( pListener ) >= 0 )
- {
- AssertMsg( 0, "Can't add listeners multiple times\n" );
- return;
- }
- m_entityListeners.AddToTail( pListener );
-}
-
-void CClientEntityList::RemoveListenerEntity( IClientEntityListener *pListener )
-{
- m_entityListeners.FindAndRemove( pListener );
-}
-
-void CClientEntityList::OnAddEntity( IHandleEntity *pEnt, CBaseHandle handle )
-{
- int entnum = handle.GetEntryIndex();
- EntityCacheInfo_t *pCache = &m_EntityCacheInfo[entnum];
-
- if ( entnum >= 0 && entnum < MAX_EDICTS )
- {
- // Update our counters.
- m_iNumServerEnts++;
- if ( entnum > m_iMaxUsedServerIndex )
- {
- m_iMaxUsedServerIndex = entnum;
- }
-
-
- // Cache its networkable pointer.
- Assert( dynamic_cast< IClientUnknown* >( pEnt ) );
- Assert( ((IClientUnknown*)pEnt)->GetClientNetworkable() ); // Server entities should all be networkable.
- pCache->m_pNetworkable = ((IClientUnknown*)pEnt)->GetClientNetworkable();
- }
-
- IClientUnknown *pUnknown = (IClientUnknown*)pEnt;
-
- // If this thing wants PVS notifications, hook it up.
- AddPVSNotifier( pUnknown );
-
- // Store it in a special list for fast iteration if it's a C_BaseEntity.
- C_BaseEntity *pBaseEntity = pUnknown->GetBaseEntity();
- if ( pBaseEntity )
- {
- pCache->m_BaseEntitiesIndex = m_BaseEntities.AddToTail( pBaseEntity );
-
- if ( pBaseEntity->ObjectCaps() & FCAP_SAVE_NON_NETWORKABLE )
- {
- m_iNumClientNonNetworkable++;
- }
-
- //DevMsg(2,"Created %s\n", pBaseEnt->GetClassname() );
- for ( int i = m_entityListeners.Count()-1; i >= 0; i-- )
- {
- m_entityListeners[i]->OnEntityCreated( pBaseEntity );
- }
- }
- else
- {
- pCache->m_BaseEntitiesIndex = m_BaseEntities.InvalidIndex();
- }
-
-
-}
-
-
-void CClientEntityList::OnRemoveEntity( IHandleEntity *pEnt, CBaseHandle handle )
-{
- int entnum = handle.GetEntryIndex();
- EntityCacheInfo_t *pCache = &m_EntityCacheInfo[entnum];
-
- if ( entnum >= 0 && entnum < MAX_EDICTS )
- {
- // This is a networkable ent. Clear out our cache info for it.
- pCache->m_pNetworkable = NULL;
- m_iNumServerEnts--;
-
- if ( entnum >= m_iMaxUsedServerIndex )
- {
- RecomputeHighestEntityUsed();
- }
- }
-
-
- IClientUnknown *pUnknown = (IClientUnknown*)pEnt;
-
- // If this is a PVS notifier, remove it.
- RemovePVSNotifier( pUnknown );
-
- C_BaseEntity *pBaseEntity = pUnknown->GetBaseEntity();
-
- if ( pBaseEntity )
- {
- if ( pBaseEntity->ObjectCaps() & FCAP_SAVE_NON_NETWORKABLE )
- {
- m_iNumClientNonNetworkable--;
- }
-
- //DevMsg(2,"Deleted %s\n", pBaseEnt->GetClassname() );
- for ( int i = m_entityListeners.Count()-1; i >= 0; i-- )
- {
- m_entityListeners[i]->OnEntityDeleted( pBaseEntity );
- }
- }
-
- if ( pCache->m_BaseEntitiesIndex != m_BaseEntities.InvalidIndex() )
- m_BaseEntities.Remove( pCache->m_BaseEntitiesIndex );
-
- pCache->m_BaseEntitiesIndex = m_BaseEntities.InvalidIndex();
-}
-
-
-// Use this to iterate over all the C_BaseEntities.
-C_BaseEntity* CClientEntityList::FirstBaseEntity() const
-{
- const CEntInfo *pList = FirstEntInfo();
- while ( pList )
- {
- if ( pList->m_pEntity )
- {
- IClientUnknown *pUnk = static_cast<IClientUnknown*>( pList->m_pEntity );
- C_BaseEntity *pRet = pUnk->GetBaseEntity();
- if ( pRet )
- return pRet;
- }
- pList = pList->m_pNext;
- }
-
- return NULL;
-
-}
-
-C_BaseEntity* CClientEntityList::NextBaseEntity( C_BaseEntity *pEnt ) const
-{
- if ( pEnt == NULL )
- return FirstBaseEntity();
-
- // Run through the list until we get a C_BaseEntity.
- const CEntInfo *pList = GetEntInfoPtr( pEnt->GetRefEHandle() );
- if ( pList )
- {
- pList = NextEntInfo(pList);
- }
-
- while ( pList )
- {
- if ( pList->m_pEntity )
- {
- IClientUnknown *pUnk = static_cast<IClientUnknown*>( pList->m_pEntity );
- C_BaseEntity *pRet = pUnk->GetBaseEntity();
- if ( pRet )
- return pRet;
- }
- pList = pList->m_pNext;
- }
-
- return NULL;
-}
-
-
-
-// -------------------------------------------------------------------------------------------------- //
-// C_AllBaseEntityIterator
-// -------------------------------------------------------------------------------------------------- //
-C_AllBaseEntityIterator::C_AllBaseEntityIterator()
-{
- Restart();
-}
-
-
-void C_AllBaseEntityIterator::Restart()
-{
- m_CurBaseEntity = ClientEntityList().m_BaseEntities.Head();
-}
-
-
-C_BaseEntity* C_AllBaseEntityIterator::Next()
-{
- if ( m_CurBaseEntity == ClientEntityList().m_BaseEntities.InvalidIndex() )
- return NULL;
-
- C_BaseEntity *pRet = ClientEntityList().m_BaseEntities[m_CurBaseEntity];
- m_CurBaseEntity = ClientEntityList().m_BaseEntities.Next( m_CurBaseEntity );
- return pRet;
-}
-
-
-// -------------------------------------------------------------------------------------------------- //
-// C_BaseEntityIterator
-// -------------------------------------------------------------------------------------------------- //
-C_BaseEntityIterator::C_BaseEntityIterator()
-{
- Restart();
-}
-
-void C_BaseEntityIterator::Restart()
-{
- m_CurBaseEntity = ClientEntityList().m_BaseEntities.Head();
-}
-
-C_BaseEntity* C_BaseEntityIterator::Next()
-{
- // Skip dormant entities
- while ( m_CurBaseEntity != ClientEntityList().m_BaseEntities.InvalidIndex() )
- {
- C_BaseEntity *pRet = ClientEntityList().m_BaseEntities[m_CurBaseEntity];
- m_CurBaseEntity = ClientEntityList().m_BaseEntities.Next( m_CurBaseEntity );
-
- if (!pRet->IsDormant())
- return pRet;
- }
-
- return NULL;
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $Workfile: $
+// $NoKeywords: $
+//===========================================================================//
+
+//-----------------------------------------------------------------------------
+// Purpose: a global list of all the entities in the game. All iteration through
+// entities is done through this object.
+//-----------------------------------------------------------------------------
+#include "cbase.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//-----------------------------------------------------------------------------
+// Globals
+//-----------------------------------------------------------------------------
+
+// Create interface
+static CClientEntityList s_EntityList;
+CBaseEntityList *g_pEntityList = &s_EntityList;
+
+// Expose list to engine
+EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CClientEntityList, IClientEntityList, VCLIENTENTITYLIST_INTERFACE_VERSION, s_EntityList );
+
+// Store local pointer to interface for rest of client .dll only
+// (CClientEntityList instead of IClientEntityList )
+CClientEntityList *cl_entitylist = &s_EntityList;
+
+
+bool PVSNotifierMap_LessFunc( IClientUnknown* const &a, IClientUnknown* const &b )
+{
+ return a < b;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CClientEntityList::CClientEntityList( void ) :
+ m_PVSNotifierMap( 0, 0, PVSNotifierMap_LessFunc )
+{
+ m_iMaxUsedServerIndex = -1;
+ m_iMaxServerEnts = 0;
+ Release();
+
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CClientEntityList::~CClientEntityList( void )
+{
+ Release();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Clears all entity lists and releases entities
+//-----------------------------------------------------------------------------
+void CClientEntityList::Release( void )
+{
+ // Free all the entities.
+ ClientEntityHandle_t iter = FirstHandle();
+ while( iter != InvalidHandle() )
+ {
+ // Try to call release on anything we can.
+ IClientNetworkable *pNet = GetClientNetworkableFromHandle( iter );
+ if ( pNet )
+ {
+ pNet->Release();
+ }
+ else
+ {
+ // Try to call release on anything we can.
+ IClientThinkable *pThinkable = GetClientThinkableFromHandle( iter );
+ if ( pThinkable )
+ {
+ pThinkable->Release();
+ }
+ }
+ RemoveEntity( iter );
+
+ iter = FirstHandle();
+ }
+
+ m_iNumServerEnts = 0;
+ m_iMaxServerEnts = 0;
+ m_iNumClientNonNetworkable = 0;
+ m_iMaxUsedServerIndex = -1;
+}
+
+IClientNetworkable* CClientEntityList::GetClientNetworkable( int entnum )
+{
+ Assert( entnum >= 0 );
+ Assert( entnum < MAX_EDICTS );
+ return m_EntityCacheInfo[entnum].m_pNetworkable;
+}
+
+
+IClientEntity* CClientEntityList::GetClientEntity( int entnum )
+{
+ IClientUnknown *pEnt = GetListedEntity( entnum );
+ return pEnt ? pEnt->GetIClientEntity() : 0;
+}
+
+
+int CClientEntityList::NumberOfEntities( bool bIncludeNonNetworkable )
+{
+ if ( bIncludeNonNetworkable == true )
+ return m_iNumServerEnts + m_iNumClientNonNetworkable;
+
+ return m_iNumServerEnts;
+}
+
+
+void CClientEntityList::SetMaxEntities( int maxents )
+{
+ m_iMaxServerEnts = maxents;
+}
+
+
+int CClientEntityList::GetMaxEntities( void )
+{
+ return m_iMaxServerEnts;
+}
+
+
+//-----------------------------------------------------------------------------
+// Convenience methods to convert between entindex + ClientEntityHandle_t
+//-----------------------------------------------------------------------------
+int CClientEntityList::HandleToEntIndex( ClientEntityHandle_t handle )
+{
+ if ( handle == INVALID_EHANDLE_INDEX )
+ return -1;
+ C_BaseEntity *pEnt = GetBaseEntityFromHandle( handle );
+ return pEnt ? pEnt->entindex() : -1;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Because m_iNumServerEnts != last index
+// Output : int
+//-----------------------------------------------------------------------------
+int CClientEntityList::GetHighestEntityIndex( void )
+{
+ return m_iMaxUsedServerIndex;
+}
+
+void CClientEntityList::RecomputeHighestEntityUsed( void )
+{
+ m_iMaxUsedServerIndex = -1;
+
+ // Walk backward looking for first valid index
+ int i;
+ for ( i = MAX_EDICTS - 1; i >= 0; i-- )
+ {
+ if ( GetListedEntity( i ) != NULL )
+ {
+ m_iMaxUsedServerIndex = i;
+ break;
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Add a raw C_BaseEntity to the entity list.
+// Input : index -
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : index -
+//-----------------------------------------------------------------------------
+
+C_BaseEntity* CClientEntityList::GetBaseEntity( int entnum )
+{
+ IClientUnknown *pEnt = GetListedEntity( entnum );
+ return pEnt ? pEnt->GetBaseEntity() : 0;
+}
+
+
+ICollideable* CClientEntityList::GetCollideable( int entnum )
+{
+ IClientUnknown *pEnt = GetListedEntity( entnum );
+ return pEnt ? pEnt->GetCollideable() : 0;
+}
+
+
+IClientNetworkable* CClientEntityList::GetClientNetworkableFromHandle( ClientEntityHandle_t hEnt )
+{
+ IClientUnknown *pEnt = GetClientUnknownFromHandle( hEnt );
+ return pEnt ? pEnt->GetClientNetworkable() : 0;
+}
+
+
+IClientEntity* CClientEntityList::GetClientEntityFromHandle( ClientEntityHandle_t hEnt )
+{
+ IClientUnknown *pEnt = GetClientUnknownFromHandle( hEnt );
+ return pEnt ? pEnt->GetIClientEntity() : 0;
+}
+
+
+IClientRenderable* CClientEntityList::GetClientRenderableFromHandle( ClientEntityHandle_t hEnt )
+{
+ IClientUnknown *pEnt = GetClientUnknownFromHandle( hEnt );
+ return pEnt ? pEnt->GetClientRenderable() : 0;
+}
+
+
+C_BaseEntity* CClientEntityList::GetBaseEntityFromHandle( ClientEntityHandle_t hEnt )
+{
+ IClientUnknown *pEnt = GetClientUnknownFromHandle( hEnt );
+ return pEnt ? pEnt->GetBaseEntity() : 0;
+}
+
+
+ICollideable* CClientEntityList::GetCollideableFromHandle( ClientEntityHandle_t hEnt )
+{
+ IClientUnknown *pEnt = GetClientUnknownFromHandle( hEnt );
+ return pEnt ? pEnt->GetCollideable() : 0;
+}
+
+
+IClientThinkable* CClientEntityList::GetClientThinkableFromHandle( ClientEntityHandle_t hEnt )
+{
+ IClientUnknown *pEnt = GetClientUnknownFromHandle( hEnt );
+ return pEnt ? pEnt->GetClientThinkable() : 0;
+}
+
+
+void CClientEntityList::AddPVSNotifier( IClientUnknown *pUnknown )
+{
+ IClientRenderable *pRen = pUnknown->GetClientRenderable();
+ if ( pRen )
+ {
+ IPVSNotify *pNotify = pRen->GetPVSNotifyInterface();
+ if ( pNotify )
+ {
+ unsigned short index = m_PVSNotifyInfos.AddToTail();
+ CPVSNotifyInfo *pInfo = &m_PVSNotifyInfos[index];
+ pInfo->m_pNotify = pNotify;
+ pInfo->m_pRenderable = pRen;
+ pInfo->m_InPVSStatus = 0;
+ pInfo->m_PVSNotifiersLink = index;
+
+ m_PVSNotifierMap.Insert( pUnknown, index );
+ }
+ }
+}
+
+
+void CClientEntityList::RemovePVSNotifier( IClientUnknown *pUnknown )
+{
+ IClientRenderable *pRenderable = pUnknown->GetClientRenderable();
+ if ( pRenderable )
+ {
+ IPVSNotify *pNotify = pRenderable->GetPVSNotifyInterface();
+ if ( pNotify )
+ {
+ unsigned short index = m_PVSNotifierMap.Find( pUnknown );
+ if ( !m_PVSNotifierMap.IsValidIndex( index ) )
+ {
+ Warning( "PVS notifier not in m_PVSNotifierMap\n" );
+ Assert( false );
+ return;
+ }
+
+ unsigned short indexIntoPVSNotifyInfos = m_PVSNotifierMap[index];
+
+ Assert( m_PVSNotifyInfos[indexIntoPVSNotifyInfos].m_pNotify == pNotify );
+ Assert( m_PVSNotifyInfos[indexIntoPVSNotifyInfos].m_pRenderable == pRenderable );
+
+ m_PVSNotifyInfos.Remove( indexIntoPVSNotifyInfos );
+ m_PVSNotifierMap.RemoveAt( index );
+ return;
+ }
+ }
+
+ // If it didn't report itself as a notifier, let's hope it's not in the notifier list now
+ // (which would mean that it reported itself as a notifier earlier, but not now).
+#ifdef _DEBUG
+ unsigned short index = m_PVSNotifierMap.Find( pUnknown );
+ Assert( !m_PVSNotifierMap.IsValidIndex( index ) );
+#endif
+}
+
+void CClientEntityList::AddListenerEntity( IClientEntityListener *pListener )
+{
+ if ( m_entityListeners.Find( pListener ) >= 0 )
+ {
+ AssertMsg( 0, "Can't add listeners multiple times\n" );
+ return;
+ }
+ m_entityListeners.AddToTail( pListener );
+}
+
+void CClientEntityList::RemoveListenerEntity( IClientEntityListener *pListener )
+{
+ m_entityListeners.FindAndRemove( pListener );
+}
+
+void CClientEntityList::OnAddEntity( IHandleEntity *pEnt, CBaseHandle handle )
+{
+ int entnum = handle.GetEntryIndex();
+ EntityCacheInfo_t *pCache = &m_EntityCacheInfo[entnum];
+
+ if ( entnum >= 0 && entnum < MAX_EDICTS )
+ {
+ // Update our counters.
+ m_iNumServerEnts++;
+ if ( entnum > m_iMaxUsedServerIndex )
+ {
+ m_iMaxUsedServerIndex = entnum;
+ }
+
+
+ // Cache its networkable pointer.
+ Assert( dynamic_cast< IClientUnknown* >( pEnt ) );
+ Assert( ((IClientUnknown*)pEnt)->GetClientNetworkable() ); // Server entities should all be networkable.
+ pCache->m_pNetworkable = ((IClientUnknown*)pEnt)->GetClientNetworkable();
+ }
+
+ IClientUnknown *pUnknown = (IClientUnknown*)pEnt;
+
+ // If this thing wants PVS notifications, hook it up.
+ AddPVSNotifier( pUnknown );
+
+ // Store it in a special list for fast iteration if it's a C_BaseEntity.
+ C_BaseEntity *pBaseEntity = pUnknown->GetBaseEntity();
+ if ( pBaseEntity )
+ {
+ pCache->m_BaseEntitiesIndex = m_BaseEntities.AddToTail( pBaseEntity );
+
+ if ( pBaseEntity->ObjectCaps() & FCAP_SAVE_NON_NETWORKABLE )
+ {
+ m_iNumClientNonNetworkable++;
+ }
+
+ //DevMsg(2,"Created %s\n", pBaseEnt->GetClassname() );
+ for ( int i = m_entityListeners.Count()-1; i >= 0; i-- )
+ {
+ m_entityListeners[i]->OnEntityCreated( pBaseEntity );
+ }
+ }
+ else
+ {
+ pCache->m_BaseEntitiesIndex = m_BaseEntities.InvalidIndex();
+ }
+
+
+}
+
+
+void CClientEntityList::OnRemoveEntity( IHandleEntity *pEnt, CBaseHandle handle )
+{
+ int entnum = handle.GetEntryIndex();
+ EntityCacheInfo_t *pCache = &m_EntityCacheInfo[entnum];
+
+ if ( entnum >= 0 && entnum < MAX_EDICTS )
+ {
+ // This is a networkable ent. Clear out our cache info for it.
+ pCache->m_pNetworkable = NULL;
+ m_iNumServerEnts--;
+
+ if ( entnum >= m_iMaxUsedServerIndex )
+ {
+ RecomputeHighestEntityUsed();
+ }
+ }
+
+
+ IClientUnknown *pUnknown = (IClientUnknown*)pEnt;
+
+ // If this is a PVS notifier, remove it.
+ RemovePVSNotifier( pUnknown );
+
+ C_BaseEntity *pBaseEntity = pUnknown->GetBaseEntity();
+
+ if ( pBaseEntity )
+ {
+ if ( pBaseEntity->ObjectCaps() & FCAP_SAVE_NON_NETWORKABLE )
+ {
+ m_iNumClientNonNetworkable--;
+ }
+
+ //DevMsg(2,"Deleted %s\n", pBaseEnt->GetClassname() );
+ for ( int i = m_entityListeners.Count()-1; i >= 0; i-- )
+ {
+ m_entityListeners[i]->OnEntityDeleted( pBaseEntity );
+ }
+ }
+
+ if ( pCache->m_BaseEntitiesIndex != m_BaseEntities.InvalidIndex() )
+ m_BaseEntities.Remove( pCache->m_BaseEntitiesIndex );
+
+ pCache->m_BaseEntitiesIndex = m_BaseEntities.InvalidIndex();
+}
+
+
+// Use this to iterate over all the C_BaseEntities.
+C_BaseEntity* CClientEntityList::FirstBaseEntity() const
+{
+ const CEntInfo *pList = FirstEntInfo();
+ while ( pList )
+ {
+ if ( pList->m_pEntity )
+ {
+ IClientUnknown *pUnk = static_cast<IClientUnknown*>( pList->m_pEntity );
+ C_BaseEntity *pRet = pUnk->GetBaseEntity();
+ if ( pRet )
+ return pRet;
+ }
+ pList = pList->m_pNext;
+ }
+
+ return NULL;
+
+}
+
+C_BaseEntity* CClientEntityList::NextBaseEntity( C_BaseEntity *pEnt ) const
+{
+ if ( pEnt == NULL )
+ return FirstBaseEntity();
+
+ // Run through the list until we get a C_BaseEntity.
+ const CEntInfo *pList = GetEntInfoPtr( pEnt->GetRefEHandle() );
+ if ( pList )
+ {
+ pList = NextEntInfo(pList);
+ }
+
+ while ( pList )
+ {
+ if ( pList->m_pEntity )
+ {
+ IClientUnknown *pUnk = static_cast<IClientUnknown*>( pList->m_pEntity );
+ C_BaseEntity *pRet = pUnk->GetBaseEntity();
+ if ( pRet )
+ return pRet;
+ }
+ pList = pList->m_pNext;
+ }
+
+ return NULL;
+}
+
+
+
+// -------------------------------------------------------------------------------------------------- //
+// C_AllBaseEntityIterator
+// -------------------------------------------------------------------------------------------------- //
+C_AllBaseEntityIterator::C_AllBaseEntityIterator()
+{
+ Restart();
+}
+
+
+void C_AllBaseEntityIterator::Restart()
+{
+ m_CurBaseEntity = ClientEntityList().m_BaseEntities.Head();
+}
+
+
+C_BaseEntity* C_AllBaseEntityIterator::Next()
+{
+ if ( m_CurBaseEntity == ClientEntityList().m_BaseEntities.InvalidIndex() )
+ return NULL;
+
+ C_BaseEntity *pRet = ClientEntityList().m_BaseEntities[m_CurBaseEntity];
+ m_CurBaseEntity = ClientEntityList().m_BaseEntities.Next( m_CurBaseEntity );
+ return pRet;
+}
+
+
+// -------------------------------------------------------------------------------------------------- //
+// C_BaseEntityIterator
+// -------------------------------------------------------------------------------------------------- //
+C_BaseEntityIterator::C_BaseEntityIterator()
+{
+ Restart();
+}
+
+void C_BaseEntityIterator::Restart()
+{
+ m_CurBaseEntity = ClientEntityList().m_BaseEntities.Head();
+}
+
+C_BaseEntity* C_BaseEntityIterator::Next()
+{
+ // Skip dormant entities
+ while ( m_CurBaseEntity != ClientEntityList().m_BaseEntities.InvalidIndex() )
+ {
+ C_BaseEntity *pRet = ClientEntityList().m_BaseEntities[m_CurBaseEntity];
+ m_CurBaseEntity = ClientEntityList().m_BaseEntities.Next( m_CurBaseEntity );
+
+ if (!pRet->IsDormant())
+ return pRet;
+ }
+
+ return NULL;
} \ No newline at end of file