Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

396 lines
13 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #ifndef ENTITYLIST_H
  9. #define ENTITYLIST_H
  10. #ifdef _WIN32
  11. #pragma once
  12. #endif
  13. class CBaseEntity;
  14. class IEntityListener;
  15. abstract_class CBaseEntityClassList
  16. {
  17. public:
  18. CBaseEntityClassList();
  19. ~CBaseEntityClassList();
  20. virtual void LevelShutdownPostEntity() = 0;
  21. CBaseEntityClassList *m_pNextClassList;
  22. };
  23. template< class T >
  24. class CEntityClassList : public CBaseEntityClassList
  25. {
  26. public:
  27. virtual void LevelShutdownPostEntity() { m_pClassList = NULL; }
  28. void Insert( T *pEntity )
  29. {
  30. pEntity->m_pNext = m_pClassList;
  31. m_pClassList = pEntity;
  32. }
  33. void Remove( T *pEntity )
  34. {
  35. T **pPrev = &m_pClassList;
  36. T *pCur = *pPrev;
  37. while ( pCur )
  38. {
  39. if ( pCur == pEntity )
  40. {
  41. *pPrev = pCur->m_pNext;
  42. return;
  43. }
  44. pPrev = &pCur->m_pNext;
  45. pCur = *pPrev;
  46. }
  47. }
  48. static T *m_pClassList;
  49. };
  50. // Derive a class from this if you want to filter entity list searches
  51. abstract_class IEntityFindFilter
  52. {
  53. public:
  54. virtual bool ShouldFindEntity( CBaseEntity *pEntity ) = 0;
  55. virtual CBaseEntity *GetFilterResult( void ) = 0;
  56. };
  57. //-----------------------------------------------------------------------------
  58. // Purpose: a global list of all the entities in the game. All iteration through
  59. // entities is done through this object.
  60. //-----------------------------------------------------------------------------
  61. class CGlobalEntityList : public CBaseEntityList
  62. {
  63. public:
  64. private:
  65. int m_iHighestEnt; // the topmost used array index
  66. int m_iNumEnts;
  67. int m_iNumEdicts;
  68. bool m_bClearingEntities;
  69. CUtlVector<IEntityListener *> m_entityListeners;
  70. public:
  71. CBaseHandle AddNetworkableEntity( IHandleEntity *pEnt, int index, int iForcedSerialNum = -1 );
  72. CBaseHandle AddNonNetworkableEntity( IHandleEntity *pEnt );
  73. void UpdateName( IHandleEntity *pEnt, CBaseHandle hEnt );
  74. void UpdateName( IHandleEntity *pEnt );
  75. IServerNetworkable* GetServerNetworkable( CBaseHandle hEnt ) const;
  76. CBaseNetworkable* GetBaseNetworkable( CBaseHandle hEnt ) const;
  77. CBaseEntity* GetBaseEntity( CBaseHandle hEnt ) const;
  78. edict_t* GetEdict( CBaseHandle hEnt ) const;
  79. int NumberOfEntities( void );
  80. int NumberOfEdicts( void );
  81. // mark an entity as deleted
  82. void AddToDeleteList( IServerNetworkable *ent );
  83. // call this before and after each frame to delete all of the marked entities.
  84. void CleanupDeleteList( void );
  85. int ResetDeleteList( void );
  86. // frees all entities in the game
  87. void Clear( void );
  88. // Returns true while in the Clear() call.
  89. bool IsClearingEntities() {return m_bClearingEntities;}
  90. // add a class that gets notified of entity events
  91. void AddListenerEntity( IEntityListener *pListener );
  92. void RemoveListenerEntity( IEntityListener *pListener );
  93. void ReportEntityFlagsChanged( CBaseEntity *pEntity, unsigned int flagsOld, unsigned int flagsNow );
  94. // Schedule this entity for notification once client messages have been sent
  95. void AddPostClientMessageEntity( CBaseEntity *pEntity );
  96. void PostClientMessagesSent();
  97. // entity is about to be removed, notify the listeners
  98. void NotifyCreateEntity( CBaseEntity *pEnt );
  99. void NotifySpawn( CBaseEntity *pEnt );
  100. void NotifyRemoveEntity( CBaseEntity *pEnt );
  101. // iteration functions
  102. // returns the next entity after pCurrentEnt; if pCurrentEnt is NULL, return the first entity
  103. CBaseEntity *NextEnt( CBaseEntity *pCurrentEnt );
  104. CBaseEntity *FirstEnt() { return NextEnt(NULL); }
  105. // returns the next entity of the specified class, using RTTI
  106. template< class T >
  107. T *NextEntByClass( T *start )
  108. {
  109. for ( CBaseEntity *x = NextEnt( start ); x; x = NextEnt( x ) )
  110. {
  111. start = dynamic_cast<T*>( x );
  112. if ( start )
  113. return start;
  114. }
  115. return NULL;
  116. }
  117. // search functions
  118. bool IsEntityPtr( void *pTest );
  119. CBaseEntity *FindEntityByClassname( CBaseEntity *pStartEntity, const char *szName );
  120. CBaseEntity *FindEntityByName( CBaseEntity *pStartEntity, const char *szName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL, IEntityFindFilter *pFilter = NULL );
  121. CBaseEntity *FindEntityByName( CBaseEntity *pStartEntity, string_t iszName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL, IEntityFindFilter *pFilter = NULL )
  122. {
  123. return FindEntityByName( pStartEntity, STRING(iszName), pSearchingEntity, pActivator, pCaller, pFilter );
  124. }
  125. CBaseEntity *FindEntityInSphere( CBaseEntity *pStartEntity, const Vector &vecCenter, float flRadius );
  126. CBaseEntity *FindEntityByTarget( CBaseEntity *pStartEntity, const char *szName );
  127. CBaseEntity *FindEntityByModel( CBaseEntity *pStartEntity, const char *szModelName );
  128. CBaseEntity *FindEntityByOutputTarget( CBaseEntity *pStartEntity, string_t iTarget );
  129. CBaseEntity *FindEntityByNameNearest( const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL );
  130. CBaseEntity *FindEntityByNameWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL );
  131. CBaseEntity *FindEntityByClassnameNearest( const char *szName, const Vector &vecSrc, float flRadius );
  132. CBaseEntity *FindEntityByClassnameNearest2D( const char *szName, const Vector &vecSrc, float flRadius );
  133. CBaseEntity *FindEntityByClassnameWithin( CBaseEntity *pStartEntity , const char *szName, const Vector &vecSrc, float flRadius );
  134. CBaseEntity *FindEntityByClassnameWithin( CBaseEntity *pStartEntity , const char *szName, const Vector &vecMins, const Vector &vecMaxs );
  135. CBaseEntity *FindEntityGeneric( CBaseEntity *pStartEntity, const char *szName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL );
  136. CBaseEntity *FindEntityGenericWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL );
  137. CBaseEntity *FindEntityGenericNearest( const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL );
  138. CBaseEntity *FindEntityNearestFacing( const Vector &origin, const Vector &facing, float threshold);
  139. CBaseEntity *FindEntityClassNearestFacing( const Vector &origin, const Vector &facing, float threshold, char *classname);
  140. CBaseEntity *FindEntityByNetname( CBaseEntity *pStartEntity, const char *szModelName );
  141. CBaseEntity *FindEntityProcedural( const char *szName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL );
  142. // Fast versions that require a (real) string_t, and won't do wildcarding
  143. CBaseEntity *FindEntityByClassnameFast( CBaseEntity *pStartEntity, string_t iszClassname );
  144. CBaseEntity *FindEntityByClassnameNearestFast( string_t iszClassname, const Vector &vecSrc, float flRadius );
  145. CBaseEntity *FindEntityByNameFast( CBaseEntity *pStartEntity, string_t iszName );
  146. CGlobalEntityList();
  147. // CBaseEntityList overrides.
  148. protected:
  149. virtual void OnAddEntity( IHandleEntity *pEnt, CBaseHandle handle );
  150. virtual void OnRemoveEntity( IHandleEntity *pEnt, CBaseHandle handle );
  151. };
  152. extern CGlobalEntityList gEntList;
  153. //-----------------------------------------------------------------------------
  154. // Inlines.
  155. //-----------------------------------------------------------------------------
  156. inline CBaseHandle CGlobalEntityList::AddNetworkableEntity( IHandleEntity *pEnt, int index, int iForcedSerialNum )
  157. {
  158. CBaseHandle h = CBaseEntityList::AddNetworkableEntity( pEnt, index, iForcedSerialNum );
  159. UpdateName( pEnt, h );
  160. return h;
  161. }
  162. inline CBaseHandle CGlobalEntityList::AddNonNetworkableEntity( IHandleEntity *pEnt )
  163. {
  164. CBaseHandle h = CBaseEntityList::AddNonNetworkableEntity( pEnt );
  165. UpdateName( pEnt, h );
  166. return h;
  167. }
  168. inline edict_t* CGlobalEntityList::GetEdict( CBaseHandle hEnt ) const
  169. {
  170. IServerUnknown *pUnk = static_cast<IServerUnknown*>(LookupEntity( hEnt ));
  171. if ( pUnk )
  172. return pUnk->GetNetworkable()->GetEdict();
  173. else
  174. return NULL;
  175. }
  176. inline CBaseNetworkable* CGlobalEntityList::GetBaseNetworkable( CBaseHandle hEnt ) const
  177. {
  178. IServerUnknown *pUnk = static_cast<IServerUnknown*>(LookupEntity( hEnt ));
  179. if ( pUnk )
  180. return pUnk->GetNetworkable()->GetBaseNetworkable();
  181. else
  182. return NULL;
  183. }
  184. inline IServerNetworkable* CGlobalEntityList::GetServerNetworkable( CBaseHandle hEnt ) const
  185. {
  186. IServerUnknown *pUnk = static_cast<IServerUnknown*>(LookupEntity( hEnt ));
  187. if ( pUnk )
  188. return pUnk->GetNetworkable();
  189. else
  190. return NULL;
  191. }
  192. inline CBaseEntity* CGlobalEntityList::GetBaseEntity( CBaseHandle hEnt ) const
  193. {
  194. IServerUnknown *pUnk = static_cast<IServerUnknown*>(LookupEntity( hEnt ));
  195. if ( pUnk )
  196. return pUnk->GetBaseEntity();
  197. else
  198. return NULL;
  199. }
  200. //-----------------------------------------------------------------------------
  201. // Common finds
  202. #if 0
  203. template <class ENT_TYPE>
  204. inline bool FindEntityByName( const char *pszName, ENT_TYPE **ppResult)
  205. {
  206. CBaseEntity *pBaseEntity = gEntList.FindEntityByName( NULL, pszName );
  207. if ( pBaseEntity )
  208. *ppResult = dynamic_cast<ENT_TYPE *>( pBaseEntity );
  209. else
  210. *ppResult = NULL;
  211. return ( *ppResult != NULL );
  212. }
  213. template <>
  214. inline bool FindEntityByName<CBaseEntity>( const char *pszName, CBaseEntity **ppResult)
  215. {
  216. *ppResult = gEntList.FindEntityByName( NULL, pszName );
  217. return ( *ppResult != NULL );
  218. }
  219. template <>
  220. inline bool FindEntityByName<CAI_BaseNPC>( const char *pszName, CAI_BaseNPC **ppResult)
  221. {
  222. CBaseEntity *pBaseEntity = gEntList.FindEntityByName( NULL, pszName );
  223. if ( pBaseEntity )
  224. *ppResult = pBaseEntity->MyNPCPointer();
  225. else
  226. *ppResult = NULL;
  227. return ( *ppResult != NULL );
  228. }
  229. #endif
  230. //-----------------------------------------------------------------------------
  231. // Purpose: Simple object for storing a list of objects
  232. //-----------------------------------------------------------------------------
  233. struct entitem_t
  234. {
  235. EHANDLE hEnt;
  236. struct entitem_t *pNext;
  237. // uses pool memory
  238. static void* operator new( size_t stAllocateBlock );
  239. static void *operator new( size_t stAllocateBlock, int nBlockUse, const char *pFileName, int nLine );
  240. static void operator delete( void *pMem );
  241. static void operator delete( void *pMem, int nBlockUse, const char *pFileName, int nLine ) { operator delete( pMem ); }
  242. };
  243. class CEntityList
  244. {
  245. public:
  246. CEntityList();
  247. ~CEntityList();
  248. int m_iNumItems;
  249. entitem_t *m_pItemList; // null terminated singly-linked list
  250. void AddEntity( CBaseEntity * );
  251. void DeleteEntity( CBaseEntity * );
  252. };
  253. enum notify_system_event_t
  254. {
  255. NOTIFY_EVENT_TELEPORT = 0,
  256. NOTIFY_EVENT_DESTROY,
  257. };
  258. struct notify_teleport_params_t
  259. {
  260. Vector prevOrigin;
  261. QAngle prevAngles;
  262. bool physicsRotate;
  263. };
  264. struct notify_destroy_params_t
  265. {
  266. };
  267. struct notify_system_event_params_t
  268. {
  269. union
  270. {
  271. const notify_teleport_params_t *pTeleport;
  272. const notify_destroy_params_t *pDestroy;
  273. };
  274. notify_system_event_params_t( const notify_teleport_params_t *pInTeleport ) { pTeleport = pInTeleport; }
  275. notify_system_event_params_t( const notify_destroy_params_t *pInDestroy ) { pDestroy = pInDestroy; }
  276. };
  277. abstract_class INotify
  278. {
  279. public:
  280. // Add notification for an entity
  281. virtual void AddEntity( CBaseEntity *pNotify, CBaseEntity *pWatched ) = 0;
  282. // Remove notification for an entity
  283. virtual void RemoveEntity( CBaseEntity *pNotify, CBaseEntity *pWatched ) = 0;
  284. // Call the named input in each entity who is watching pEvent's status
  285. virtual void ReportNamedEvent( CBaseEntity *pEntity, const char *pEventName ) = 0;
  286. // System events don't make sense as inputs, so are handled through a generic notify function
  287. virtual void ReportSystemEvent( CBaseEntity *pEntity, notify_system_event_t eventType, const notify_system_event_params_t &params ) = 0;
  288. inline void ReportDestroyEvent( CBaseEntity *pEntity )
  289. {
  290. notify_destroy_params_t destroy;
  291. ReportSystemEvent( pEntity, NOTIFY_EVENT_DESTROY, notify_system_event_params_t(&destroy) );
  292. }
  293. inline void ReportTeleportEvent( CBaseEntity *pEntity, const Vector &prevOrigin, const QAngle &prevAngles, bool physicsRotate )
  294. {
  295. notify_teleport_params_t teleport;
  296. teleport.prevOrigin = prevOrigin;
  297. teleport.prevAngles = prevAngles;
  298. teleport.physicsRotate = physicsRotate;
  299. ReportSystemEvent( pEntity, NOTIFY_EVENT_TELEPORT, notify_system_event_params_t(&teleport) );
  300. }
  301. // Remove this entity from the notify list
  302. virtual void ClearEntity( CBaseEntity *pNotify ) = 0;
  303. };
  304. // Implement this class and register with gEntList to receive entity create/delete notification
  305. class IEntityListener
  306. {
  307. public:
  308. virtual void OnEntityCreated( CBaseEntity *pEntity ) {};
  309. virtual void OnEntitySpawned( CBaseEntity *pEntity ) {};
  310. virtual void OnEntityDeleted( CBaseEntity *pEntity ) {};
  311. };
  312. // singleton
  313. extern INotify *g_pNotify;
  314. void EntityTouch_Add( CBaseEntity *pEntity );
  315. void EntityTouch_Remove( CBaseEntity *pEntity );
  316. int AimTarget_ListCount();
  317. int AimTarget_ListCopy( CBaseEntity *pList[], int listMax );
  318. CBaseEntity *AimTarget_ListElement( int iIndex );
  319. void AimTarget_ForceRepopulateList();
  320. void SimThink_EntityChanged( CBaseEntity *pEntity );
  321. int SimThink_ListCount();
  322. int SimThink_ListCopy( CBaseEntity *pList[], int listMax );
  323. #endif // ENTITYLIST_H