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.

276 lines
7.6 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Squad classes
  4. //
  5. //=============================================================================//
  6. #ifndef AI_SQUAD_H
  7. #define AI_SQUAD_H
  8. #include "ai_memory.h"
  9. #include "ai_squadslot.h"
  10. #include "bitstring.h"
  11. class CAI_Squad;
  12. typedef CHandle<CAI_BaseNPC> AIHANDLE;
  13. #define PER_ENEMY_SQUADSLOTS 1
  14. //-----------------------------------------------------------------------------
  15. DECLARE_POINTER_HANDLE(AISquadsIter_t);
  16. DECLARE_POINTER_HANDLE(AISquadIter_t);
  17. #define MAX_SQUAD_MEMBERS 16
  18. #define MAX_SQUAD_DATA_SLOTS 4
  19. //-----------------------------------------------------------------------------
  20. // CAI_SquadManager
  21. //
  22. // Purpose: Manages all the squads in the system
  23. //
  24. //-----------------------------------------------------------------------------
  25. class CAI_SquadManager
  26. {
  27. public:
  28. CAI_SquadManager()
  29. {
  30. m_pSquads = NULL;
  31. }
  32. CAI_Squad * GetFirstSquad( AISquadsIter_t *pIter );
  33. CAI_Squad * GetNextSquad( AISquadsIter_t *pIter );
  34. int NumSquads();
  35. CAI_Squad * FindSquad( string_t squadName ); // Returns squad of the given name
  36. CAI_Squad * CreateSquad( string_t squadName ); // Returns squad of the given name
  37. CAI_Squad * FindCreateSquad( string_t squadName ); // Returns squad of the given name
  38. CAI_Squad * FindCreateSquad( CAI_BaseNPC *pNPC, string_t squadName ); // Returns squad of the given name
  39. void DeleteSquad( CAI_Squad *pSquad );
  40. void DeleteAllSquads(void);
  41. private:
  42. CAI_Squad * m_pSquads; // A linked list of all squads
  43. };
  44. //-------------------------------------
  45. extern CAI_SquadManager g_AI_SquadManager;
  46. //-----------------------------------------------------------------------------
  47. #ifdef PER_ENEMY_SQUADSLOTS
  48. struct AISquadEnemyInfo_t
  49. {
  50. EHANDLE hEnemy;
  51. CBitVec<MAX_SQUADSLOTS> slots; // What squad slots are filled?
  52. DECLARE_SIMPLE_DATADESC();
  53. };
  54. #endif
  55. //-----------------------------------------------------------------------------
  56. // CAI_Squad
  57. //
  58. // Purpose: Tracks enemies, squad slots, squad members
  59. //
  60. //-----------------------------------------------------------------------------
  61. class CAI_Squad
  62. {
  63. public:
  64. const char * GetName() const { return STRING(m_Name); }
  65. void RemoveFromSquad( CAI_BaseNPC *pNPC, bool bDeath = false );
  66. CAI_BaseNPC * GetFirstMember( AISquadIter_t *pIter = NULL, bool bIgnoreSilentMembers = true );
  67. CAI_BaseNPC * GetNextMember( AISquadIter_t *pIter, bool bIgnoreSilentMembers = true );
  68. CAI_BaseNPC * GetAnyMember();
  69. int NumMembers( bool bIgnoreSilentMembers = true );
  70. int GetSquadIndex( CAI_BaseNPC * );
  71. void SquadNewEnemy ( CBaseEntity *pEnemy );
  72. void UpdateEnemyMemory( CAI_BaseNPC *pUpdater, CBaseEntity *pEnemy, const Vector &position );
  73. bool OccupyStrategySlotRange( CBaseEntity *pEnemy, int slotIDStart, int slotIDEnd, int *pSlot );
  74. void VacateStrategySlot( CBaseEntity *pEnemy, int slot);
  75. bool IsStrategySlotRangeOccupied( CBaseEntity *pEnemy, int slotIDStart, int slotIDEnd );
  76. CAI_BaseNPC * SquadMemberInRange( const Vector &vecLocation, float flDist );
  77. CAI_BaseNPC * NearestSquadMember( CAI_BaseNPC *pMember );
  78. int GetVisibleSquadMembers( CAI_BaseNPC *pMember );
  79. CAI_BaseNPC * GetSquadMemberNearestTo( const Vector &vecLocation );
  80. bool SquadIsMember( CBaseEntity *pMember );
  81. bool IsLeader( CAI_BaseNPC *pLeader );
  82. CAI_BaseNPC *GetLeader( void );
  83. int BroadcastInteraction( int interactionType, void *data, CBaseCombatCharacter *sender = NULL );
  84. void AddToSquad(CAI_BaseNPC *pNPC);
  85. bool FOkToMakeSound( int soundPriority );
  86. void JustMadeSound( int soundPriority, float time );
  87. float GetSquadSoundWaitTime() const { return m_flSquadSoundWaitTime; }
  88. void SetSquadSoundWaitTime( float time ) { m_flSquadSoundWaitTime = time; }
  89. void SquadRemember( int iMemory );
  90. void SetSquadInflictor( CBaseEntity *pInflictor );
  91. bool IsSquadInflictor( CBaseEntity *pInflictor );
  92. static bool IsSilentMember( const CAI_BaseNPC *pNPC );
  93. template <typename T>
  94. void SetSquadData( unsigned slot, const T &data )
  95. {
  96. Assert( slot < MAX_SQUAD_DATA_SLOTS );
  97. if ( slot < MAX_SQUAD_DATA_SLOTS )
  98. {
  99. m_SquadData[slot] = *((int *)&data);
  100. }
  101. }
  102. template <typename T>
  103. void GetSquadData( unsigned slot, T *pData )
  104. {
  105. Assert( slot < MAX_SQUAD_DATA_SLOTS );
  106. if ( slot < MAX_SQUAD_DATA_SLOTS )
  107. {
  108. *pData = *((T *)&m_SquadData[slot]);
  109. }
  110. }
  111. private:
  112. void OccupySlot( CBaseEntity *pEnemy, int i );
  113. void VacateSlot( CBaseEntity *pEnemy, int i );
  114. bool IsSlotOccupied( CBaseEntity *pEnemy, int i ) const;
  115. private:
  116. friend class CAI_SaveRestoreBlockHandler;
  117. friend class CAI_SquadManager;
  118. CAI_Squad();
  119. CAI_Squad(string_t squadName);
  120. ~CAI_Squad(void);
  121. CAI_Squad* GetNext() { return m_pNextSquad; }
  122. void Init( string_t squadName );
  123. CAI_Squad * m_pNextSquad; // The next squad is list of all squads
  124. string_t m_Name;
  125. CUtlVectorFixed<AIHANDLE, MAX_SQUAD_MEMBERS> m_SquadMembers;
  126. float m_flSquadSoundWaitTime; // Time when I'm allowed to make another sound
  127. int m_nSquadSoundPriority; // if we're still waiting, this is the priority of the current sound
  128. EHANDLE m_hSquadInflictor;
  129. int m_SquadData[MAX_SQUAD_DATA_SLOTS];
  130. #ifdef PER_ENEMY_SQUADSLOTS
  131. AISquadEnemyInfo_t *FindEnemyInfo( CBaseEntity *pEnemy );
  132. const AISquadEnemyInfo_t *FindEnemyInfo( CBaseEntity *pEnemy ) const { return const_cast<CAI_Squad *>(this)->FindEnemyInfo( pEnemy ); }
  133. AISquadEnemyInfo_t * m_pLastFoundEnemyInfo; // Occupy/Vacate need to be reworked to not want this
  134. CUtlVector<AISquadEnemyInfo_t> m_EnemyInfos;
  135. float m_flEnemyInfoCleanupTime;
  136. #else
  137. CVarBitVec m_squadSlotsUsed; // What squad slots are filled?
  138. #endif
  139. //---------------------------------
  140. public:
  141. DECLARE_SIMPLE_DATADESC();
  142. };
  143. //-----------------------------------------------------------------------------
  144. //
  145. // Purpose: CAI_SquadManager inline functions
  146. //
  147. //-----------------------------------------------------------------------------
  148. inline CAI_Squad *CAI_SquadManager::GetFirstSquad( AISquadsIter_t *pIter )
  149. {
  150. *pIter = (AISquadsIter_t)m_pSquads;
  151. return m_pSquads;
  152. }
  153. //-------------------------------------
  154. inline CAI_Squad *CAI_SquadManager::GetNextSquad( AISquadsIter_t *pIter )
  155. {
  156. CAI_Squad *pSquad = (CAI_Squad *)*pIter;
  157. if ( pSquad )
  158. pSquad = pSquad->m_pNextSquad;
  159. *pIter = (AISquadsIter_t)pSquad;
  160. return pSquad;
  161. }
  162. //-------------------------------------
  163. // Purpose: Returns squad of the given name or creates a new squad with the
  164. // given name if none exists and add pNPC to the list of members
  165. //-------------------------------------
  166. inline CAI_Squad *CAI_SquadManager::FindCreateSquad(CAI_BaseNPC *pNPC, string_t squadName)
  167. {
  168. CAI_Squad* pSquad = FindSquad( squadName );
  169. if ( !pSquad )
  170. pSquad = CreateSquad( squadName );
  171. pSquad->AddToSquad( pNPC );
  172. return pSquad;
  173. }
  174. //-----------------------------------------------------------------------------
  175. inline CAI_Squad *CAI_SquadManager::FindCreateSquad(string_t squadName)
  176. {
  177. CAI_Squad* pSquad = FindSquad( squadName );
  178. if ( !pSquad )
  179. pSquad = CreateSquad( squadName );
  180. return pSquad;
  181. }
  182. //-------------------------------------
  183. inline CAI_BaseNPC *CAI_Squad::GetAnyMember()
  184. {
  185. if ( m_SquadMembers.Count() )
  186. return m_SquadMembers[random->RandomInt( 0, m_SquadMembers.Count()-1 )];
  187. return NULL;
  188. }
  189. //-------------------------------------
  190. inline int CAI_Squad::GetSquadIndex( CAI_BaseNPC *pAI )
  191. {
  192. for ( int i = 0; i < m_SquadMembers.Count(); i++ )
  193. {
  194. if ( m_SquadMembers[i] == pAI )
  195. return i;
  196. }
  197. return -1;
  198. }
  199. //-----------------------------------------------------------------------------
  200. #endif // AI_SQUAD_H