Team Fortress 2 Source Code as on 22/4/2020
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.

363 lines
12 KiB

  1. //========= Copyright 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. #include "baseentity.h"
  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. IServerNetworkable* GetServerNetworkable( CBaseHandle hEnt ) const;
  72. CBaseNetworkable* GetBaseNetworkable( CBaseHandle hEnt ) const;
  73. CBaseEntity* GetBaseEntity( CBaseHandle hEnt ) const;
  74. edict_t* GetEdict( CBaseHandle hEnt ) const;
  75. int NumberOfEntities( void );
  76. int NumberOfEdicts( void );
  77. // mark an entity as deleted
  78. void AddToDeleteList( IServerNetworkable *ent );
  79. // call this before and after each frame to delete all of the marked entities.
  80. void CleanupDeleteList( void );
  81. int ResetDeleteList( void );
  82. // frees all entities in the game
  83. void Clear( void );
  84. // Returns true while in the Clear() call.
  85. bool IsClearingEntities() {return m_bClearingEntities;}
  86. // add a class that gets notified of entity events
  87. void AddListenerEntity( IEntityListener *pListener );
  88. void RemoveListenerEntity( IEntityListener *pListener );
  89. void ReportEntityFlagsChanged( CBaseEntity *pEntity, unsigned int flagsOld, unsigned int flagsNow );
  90. // entity is about to be removed, notify the listeners
  91. void NotifyCreateEntity( CBaseEntity *pEnt );
  92. void NotifySpawn( CBaseEntity *pEnt );
  93. void NotifyRemoveEntity( CBaseHandle hEnt );
  94. // iteration functions
  95. // returns the next entity after pCurrentEnt; if pCurrentEnt is NULL, return the first entity
  96. CBaseEntity *NextEnt( CBaseEntity *pCurrentEnt );
  97. CBaseEntity *FirstEnt() { return NextEnt(NULL); }
  98. // returns the next entity of the specified class, using RTTI
  99. template< class T >
  100. T *NextEntByClass( T *start )
  101. {
  102. for ( CBaseEntity *x = NextEnt( start ); x; x = NextEnt( x ) )
  103. {
  104. start = dynamic_cast<T*>( x );
  105. if ( start )
  106. return start;
  107. }
  108. return NULL;
  109. }
  110. // search functions
  111. bool IsEntityPtr( void *pTest );
  112. CBaseEntity *FindEntityByClassname( CBaseEntity *pStartEntity, const char *szName );
  113. CBaseEntity *FindEntityByName( CBaseEntity *pStartEntity, const char *szName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL, IEntityFindFilter *pFilter = NULL );
  114. CBaseEntity *FindEntityByName( CBaseEntity *pStartEntity, string_t iszName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL, IEntityFindFilter *pFilter = NULL )
  115. {
  116. return FindEntityByName( pStartEntity, STRING(iszName), pSearchingEntity, pActivator, pCaller, pFilter );
  117. }
  118. CBaseEntity *FindEntityInSphere( CBaseEntity *pStartEntity, const Vector &vecCenter, float flRadius );
  119. CBaseEntity *FindEntityByTarget( CBaseEntity *pStartEntity, const char *szName );
  120. CBaseEntity *FindEntityByModel( CBaseEntity *pStartEntity, const char *szModelName );
  121. CBaseEntity *FindEntityByNameNearest( const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL );
  122. CBaseEntity *FindEntityByNameWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL );
  123. CBaseEntity *FindEntityByClassnameNearest( const char *szName, const Vector &vecSrc, float flRadius );
  124. CBaseEntity *FindEntityByClassnameWithin( CBaseEntity *pStartEntity , const char *szName, const Vector &vecSrc, float flRadius );
  125. CBaseEntity *FindEntityByClassnameWithin( CBaseEntity *pStartEntity , const char *szName, const Vector &vecMins, const Vector &vecMaxs );
  126. CBaseEntity *FindEntityGeneric( CBaseEntity *pStartEntity, const char *szName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL );
  127. CBaseEntity *FindEntityGenericWithin( CBaseEntity *pStartEntity, const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL );
  128. CBaseEntity *FindEntityGenericNearest( const char *szName, const Vector &vecSrc, float flRadius, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL );
  129. CBaseEntity *FindEntityNearestFacing( const Vector &origin, const Vector &facing, float threshold);
  130. CBaseEntity *FindEntityClassNearestFacing( const Vector &origin, const Vector &facing, float threshold, char *classname);
  131. CBaseEntity *FindEntityProcedural( const char *szName, CBaseEntity *pSearchingEntity = NULL, CBaseEntity *pActivator = NULL, CBaseEntity *pCaller = NULL );
  132. CGlobalEntityList();
  133. // CBaseEntityList overrides.
  134. protected:
  135. virtual void OnAddEntity( IHandleEntity *pEnt, CBaseHandle handle );
  136. virtual void OnRemoveEntity( IHandleEntity *pEnt, CBaseHandle handle );
  137. };
  138. extern CGlobalEntityList gEntList;
  139. //-----------------------------------------------------------------------------
  140. // Inlines.
  141. //-----------------------------------------------------------------------------
  142. inline edict_t* CGlobalEntityList::GetEdict( CBaseHandle hEnt ) const
  143. {
  144. IServerUnknown *pUnk = static_cast<IServerUnknown*>(LookupEntity( hEnt ));
  145. if ( pUnk )
  146. return pUnk->GetNetworkable()->GetEdict();
  147. else
  148. return NULL;
  149. }
  150. inline CBaseNetworkable* CGlobalEntityList::GetBaseNetworkable( CBaseHandle hEnt ) const
  151. {
  152. IServerUnknown *pUnk = static_cast<IServerUnknown*>(LookupEntity( hEnt ));
  153. if ( pUnk )
  154. return pUnk->GetNetworkable()->GetBaseNetworkable();
  155. else
  156. return NULL;
  157. }
  158. inline IServerNetworkable* CGlobalEntityList::GetServerNetworkable( CBaseHandle hEnt ) const
  159. {
  160. IServerUnknown *pUnk = static_cast<IServerUnknown*>(LookupEntity( hEnt ));
  161. if ( pUnk )
  162. return pUnk->GetNetworkable();
  163. else
  164. return NULL;
  165. }
  166. inline CBaseEntity* CGlobalEntityList::GetBaseEntity( CBaseHandle hEnt ) const
  167. {
  168. IServerUnknown *pUnk = static_cast<IServerUnknown*>(LookupEntity( hEnt ));
  169. if ( pUnk )
  170. return pUnk->GetBaseEntity();
  171. else
  172. return NULL;
  173. }
  174. //-----------------------------------------------------------------------------
  175. // Common finds
  176. #if 0
  177. template <class ENT_TYPE>
  178. inline bool FindEntityByName( const char *pszName, ENT_TYPE **ppResult)
  179. {
  180. CBaseEntity *pBaseEntity = gEntList.FindEntityByName( NULL, pszName );
  181. if ( pBaseEntity )
  182. *ppResult = dynamic_cast<ENT_TYPE *>( pBaseEntity );
  183. else
  184. *ppResult = NULL;
  185. return ( *ppResult != NULL );
  186. }
  187. template <>
  188. inline bool FindEntityByName<CBaseEntity>( const char *pszName, CBaseEntity **ppResult)
  189. {
  190. *ppResult = gEntList.FindEntityByName( NULL, pszName );
  191. return ( *ppResult != NULL );
  192. }
  193. template <>
  194. inline bool FindEntityByName<CAI_BaseNPC>( const char *pszName, CAI_BaseNPC **ppResult)
  195. {
  196. CBaseEntity *pBaseEntity = gEntList.FindEntityByName( NULL, pszName );
  197. if ( pBaseEntity )
  198. *ppResult = pBaseEntity->MyNPCPointer();
  199. else
  200. *ppResult = NULL;
  201. return ( *ppResult != NULL );
  202. }
  203. #endif
  204. //-----------------------------------------------------------------------------
  205. // Purpose: Simple object for storing a list of objects
  206. //-----------------------------------------------------------------------------
  207. struct entitem_t
  208. {
  209. EHANDLE hEnt;
  210. struct entitem_t *pNext;
  211. // uses pool memory
  212. static void* operator new( size_t stAllocateBlock );
  213. static void *operator new( size_t stAllocateBlock, int nBlockUse, const char *pFileName, int nLine );
  214. static void operator delete( void *pMem );
  215. static void operator delete( void *pMem, int nBlockUse, const char *pFileName, int nLine ) { operator delete( pMem ); }
  216. };
  217. class CEntityList
  218. {
  219. public:
  220. CEntityList();
  221. ~CEntityList();
  222. int m_iNumItems;
  223. entitem_t *m_pItemList; // null terminated singly-linked list
  224. void AddEntity( CBaseEntity * );
  225. void DeleteEntity( CBaseEntity * );
  226. };
  227. enum notify_system_event_t
  228. {
  229. NOTIFY_EVENT_TELEPORT = 0,
  230. NOTIFY_EVENT_DESTROY,
  231. };
  232. struct notify_teleport_params_t
  233. {
  234. Vector prevOrigin;
  235. QAngle prevAngles;
  236. bool physicsRotate;
  237. };
  238. struct notify_destroy_params_t
  239. {
  240. };
  241. struct notify_system_event_params_t
  242. {
  243. union
  244. {
  245. const notify_teleport_params_t *pTeleport;
  246. const notify_destroy_params_t *pDestroy;
  247. };
  248. notify_system_event_params_t( const notify_teleport_params_t *pInTeleport ) { pTeleport = pInTeleport; }
  249. notify_system_event_params_t( const notify_destroy_params_t *pInDestroy ) { pDestroy = pInDestroy; }
  250. };
  251. abstract_class INotify
  252. {
  253. public:
  254. // Add notification for an entity
  255. virtual void AddEntity( CBaseEntity *pNotify, CBaseEntity *pWatched ) = 0;
  256. // Remove notification for an entity
  257. virtual void RemoveEntity( CBaseEntity *pNotify, CBaseEntity *pWatched ) = 0;
  258. // Call the named input in each entity who is watching pEvent's status
  259. virtual void ReportNamedEvent( CBaseEntity *pEntity, const char *pEventName ) = 0;
  260. // System events don't make sense as inputs, so are handled through a generic notify function
  261. virtual void ReportSystemEvent( CBaseEntity *pEntity, notify_system_event_t eventType, const notify_system_event_params_t &params ) = 0;
  262. inline void ReportDestroyEvent( CBaseEntity *pEntity )
  263. {
  264. notify_destroy_params_t destroy;
  265. ReportSystemEvent( pEntity, NOTIFY_EVENT_DESTROY, notify_system_event_params_t(&destroy) );
  266. }
  267. inline void ReportTeleportEvent( CBaseEntity *pEntity, const Vector &prevOrigin, const QAngle &prevAngles, bool physicsRotate )
  268. {
  269. notify_teleport_params_t teleport;
  270. teleport.prevOrigin = prevOrigin;
  271. teleport.prevAngles = prevAngles;
  272. teleport.physicsRotate = physicsRotate;
  273. ReportSystemEvent( pEntity, NOTIFY_EVENT_TELEPORT, notify_system_event_params_t(&teleport) );
  274. }
  275. // Remove this entity from the notify list
  276. virtual void ClearEntity( CBaseEntity *pNotify ) = 0;
  277. };
  278. // Implement this class and register with gEntList to receive entity create/delete notification
  279. class IEntityListener
  280. {
  281. public:
  282. virtual void OnEntityCreated( CBaseEntity *pEntity ) {};
  283. virtual void OnEntitySpawned( CBaseEntity *pEntity ) {};
  284. virtual void OnEntityDeleted( CBaseEntity *pEntity ) {};
  285. };
  286. // singleton
  287. extern INotify *g_pNotify;
  288. void EntityTouch_Add( CBaseEntity *pEntity );
  289. int AimTarget_ListCount();
  290. int AimTarget_ListCopy( CBaseEntity *pList[], int listMax );
  291. void AimTarget_ForceRepopulateList();
  292. void SimThink_EntityChanged( CBaseEntity *pEntity );
  293. int SimThink_ListCount();
  294. int SimThink_ListCopy( CBaseEntity *pList[], int listMax );
  295. #endif // ENTITYLIST_H