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.

374 lines
13 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Hint node utilities and functions.
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #ifndef AI_HINT_H
  8. #define AI_HINT_H
  9. #pragma once
  10. #include "ai_initutils.h"
  11. #include "tier1/utlmap.h"
  12. //Flags for FindHintNode
  13. #define bits_HINT_NODE_NONE 0x00000000
  14. #define bits_HINT_NODE_VISIBLE 0x00000001
  15. #define bits_HINT_NODE_NEAREST 0x00000002 // Choose the node nearest me
  16. #define bits_HINT_NODE_RANDOM 0x00000004 // Find a random hintnode meeting other criteria
  17. #define bits_HINT_NODE_CLEAR 0x00000008 // Only choose nodes that have clear room for my bounding box (requires NPC)
  18. #define bits_HINT_NODE_USE_GROUP 0x00000010 // Use the NPC's hintgroup when searching for a node (requires NPC)
  19. #define bits_HINT_NODE_VISIBLE_TO_PLAYER 0x00000020
  20. #define bits_HINT_NODE_NOT_VISIBLE_TO_PLAYER 0x00000040
  21. #define bits_HINT_NODE_REPORT_FAILURES 0x00000080
  22. #define bits_HINT_NODE_IN_VIEWCONE 0x00000100
  23. #define bits_HINT_NODE_IN_AIMCONE 0x00000200
  24. #define bits_HINT_NPC_IN_NODE_FOV 0x00000400 // Is the searcher inside the hint node's FOV?
  25. #define bits_HINT_NOT_CLOSE_TO_ENEMY 0x00000800 // Hint must not be within 30 feet of my enemy
  26. #define bits_HINT_HAS_LOS_TO_PLAYER 0x00001000 // Like VISIBLE_TO_PLAYER but doesn't care about player's facing
  27. #define bits_HAS_EYEPOSITION_LOS_TO_PLAYER 0x00002000 // Like HAS LOS TO PLAYER, but checks NPC's eye position at the node, not node origin.
  28. #define bits_HINT_HAS_NO_EYEPOSITION_LOS_TO_ENEMY 0x00004000 // Like an inverted HAS LOS TO PLAYER, but checks NPC's eye position at the node, not node origin.
  29. //-----------------------------------------------------------------------------
  30. //
  31. // hints - these MUST coincide with the HINTS listed under
  32. // info_node in the FGD file!
  33. //
  34. // For debugging, they must also coincide with g_pszHintDescriptions.
  35. //
  36. //-----------------------------------------------------------------------------
  37. enum Hint_e
  38. {
  39. HINT_ANY = -1,
  40. HINT_NONE = 0,
  41. HINT_NOT_USED_WORLD_DOOR,
  42. HINT_WORLD_WINDOW,
  43. HINT_NOT_USED_WORLD_BUTTON,
  44. HINT_NOT_USED_WORLD_MACHINERY,
  45. HINT_NOT_USED_WORLD_LEDGE,
  46. HINT_NOT_USED_WORLD_LIGHT_SOURCE,
  47. HINT_NOT_USED_WORLD_HEAT_SOURCE,
  48. HINT_NOT_USED_WORLD_BLINKING_LIGHT,
  49. HINT_NOT_USED_WORLD_BRIGHT_COLORS,
  50. HINT_NOT_USED_WORLD_HUMAN_BLOOD,
  51. HINT_NOT_USED_WORLD_ALIEN_BLOOD,
  52. HINT_WORLD_WORK_POSITION,
  53. HINT_WORLD_VISUALLY_INTERESTING,
  54. HINT_WORLD_VISUALLY_INTERESTING_DONT_AIM,
  55. HINT_WORLD_INHIBIT_COMBINE_MINES,
  56. HINT_WORLD_VISUALLY_INTERESTING_STEALTH,
  57. HINT_GENERIC,
  58. HINT_TACTICAL_COVER_MED = 100,
  59. HINT_TACTICAL_COVER_LOW,
  60. HINT_NOT_USED_TACTICAL_SPAWN,
  61. HINT_TACTICAL_PINCH, // Exit / entrance to an arena
  62. HINT_NOT_USED_TACTICAL_GUARD,
  63. HINT_TACTICAL_ENEMY_DISADVANTAGED, //Disadvantageous position for the enemy
  64. HINT_NOT_USED_HEALTH_KIT,
  65. HINT_TACTICAL_HIGH_GROUND,
  66. HINT_NOT_USED_URBAN_STREETCORNER = 200,
  67. HINT_NOT_USED_URBAN_STREETLAMP,
  68. HINT_NOT_USED_URBAN_DARK_SPOT,
  69. HINT_NOT_USED_URBAN_POSTER,
  70. HINT_NOT_USED_URBAN_SHELTER,
  71. HINT_NOT_USED_ASSASSIN_SECLUDED = 300,
  72. HINT_NOT_USED_ASSASSIN_RAFTERS,
  73. HINT_NOT_USED_ASSASSIN_GROUND,
  74. HINT_NOT_USED_ASSASSIN_MONKEYBARS,
  75. HINT_ANTLION_BURROW_POINT = 400,
  76. HINT_ANTLION_THUMPER_FLEE_POINT,
  77. HINT_HEADCRAB_BURROW_POINT = 450,
  78. HINT_HEADCRAB_EXIT_POD_POINT,
  79. HINT_NOT_USED_ROLLER_PATROL_POINT = 500,
  80. HINT_NOT_USED_ROLLER_CLEANUP_POINT,
  81. HINT_NOT_USED_PSTORM_ROCK_SPAWN = 600,
  82. HINT_CROW_FLYTO_POINT = 700,
  83. // TF2 Hints
  84. HINT_BUG_PATROL_POINT = 800,
  85. // HL2 Hints
  86. HINT_FOLLOW_WAIT_POINT = 900,
  87. HINT_JUMP_OVERRIDE = 901,
  88. HINT_PLAYER_SQUAD_TRANSITON_POINT = 902,
  89. HINT_NPC_EXIT_POINT = 903,
  90. HINT_STRIDER_NODE = 904,
  91. HINT_PLAYER_ALLY_MOVE_AWAY_DEST = 950,
  92. HINT_PLAYER_ALLY_FEAR_DEST,
  93. // CS port hints
  94. HINT_CSTRIKE_HOSTAGE_ESCAPE = 1100,
  95. // Ep3 hints
  96. #ifdef HL2_EP3
  97. HINT_EP3_BLOB_SHAKE_POSITION = 1200,
  98. HINT_EP3_BLOB_FIRE_COVER_POSITION = 1201,
  99. HINT_EP3_BLOB_BRAIN_COVER_POSITION = 1202,
  100. HINT_EP3_BLOB_BRAIN_REGENERATE_POSITION = 1203,
  101. HINT_EP3_BLOB_SPIT_POSITION = 1204,
  102. HINT_EP3_BLOB_SPAWN_REGENERATOR_POSITION = 1205,
  103. #endif
  104. #ifdef PORTAL2
  105. // Aperture hints
  106. HINT_PORTAL2_NEST = 1200, // FIXME: Stomping on EP3
  107. #endif // PORTAL2
  108. #ifdef INFESTED_DLL
  109. HINT_ASW_COVERED_SPAWN = 1300,
  110. #endif
  111. };
  112. const char *GetHintTypeDescription( Hint_e iHintType );
  113. const char *GetHintTypeDescription( CAI_Hint *pHint );
  114. //-----------------------------------------------------------------------------
  115. // CHintCriteria
  116. //-----------------------------------------------------------------------------
  117. typedef bool (*HintSearchFilterFunc_t)( void *pContext, CAI_Hint *pCandidate );
  118. class CHintCriteria
  119. {
  120. public:
  121. CHintCriteria();
  122. ~CHintCriteria();
  123. bool HasFlag( int bitmask ) const { return ( m_iFlags & bitmask ) != 0; }
  124. void SetFlag( int bitmask );
  125. void ClearFlag( int bitmask );
  126. void SetGroup( string_t group );
  127. string_t GetGroup( void ) const { return m_strGroup; }
  128. void SetFilterFunc( HintSearchFilterFunc_t pfnFilter, void *pContext = NULL ) { m_pfnFilter = pfnFilter; m_pFilterContext = pContext; }
  129. bool PassesFilter( CAI_Hint *pCandidate ) const { return ( m_pfnFilter ) ? (*m_pfnFilter)( m_pFilterContext, pCandidate ) : true; }
  130. void SetGenericType( string_t genericType ) { m_strGenericType = genericType; }
  131. string_t GetGenericType( void ) const { return m_strGenericType; }
  132. int GetFirstHintType( void ) const { return m_iFirstHintType; }
  133. int GetLastHintType( void ) const { return m_iLastHintType; }
  134. bool MatchesHintType( int hintType, string_t iszGenericType = NULL_STRING ) const;
  135. bool MatchesSingleHintType() const;
  136. bool HasIncludeZones( void ) const { return ( m_zoneInclude.Count() != 0 ); }
  137. bool HasExcludeZones( void ) const { return ( m_zoneExclude.Count() != 0 ); }
  138. void AddIncludePosition( const Vector &position, float radius );
  139. void AddExcludePosition( const Vector &position, float radius );
  140. void SetHintType( int hintType );
  141. void SetHintTypeRange( int firstType, int lastType );
  142. void AddHintType( int hintType );
  143. bool InIncludedZone( const Vector &testPosition ) const;
  144. bool InExcludedZone( const Vector &testPosition ) const;
  145. int NumHintTypes() const;
  146. int GetHintType( int idx ) const;
  147. private:
  148. struct hintZone_t
  149. {
  150. Vector position;
  151. float radiussqr;
  152. };
  153. typedef CUtlVector < hintZone_t > zoneList_t;
  154. void AddZone( zoneList_t &list, const Vector &position, float radius );
  155. bool InZone( const zoneList_t &zone, const Vector &testPosition ) const;
  156. CUtlVector<int> m_HintTypes;
  157. int m_iFlags;
  158. int m_iFirstHintType;
  159. int m_iLastHintType;
  160. string_t m_strGroup;
  161. string_t m_strGenericType;
  162. zoneList_t m_zoneInclude;
  163. zoneList_t m_zoneExclude;
  164. HintSearchFilterFunc_t m_pfnFilter;
  165. void * m_pFilterContext;
  166. };
  167. class CAI_Node;
  168. //-----------------------------------------------------------------------------
  169. // CAI_HintManager
  170. //-----------------------------------------------------------------------------
  171. DECLARE_POINTER_HANDLE(AIHintIter_t);
  172. class CAIHintVector : public CUtlVector< CAI_Hint * >
  173. {
  174. public:
  175. CAIHintVector() : CUtlVector< CAI_Hint * >( 1, 0 )
  176. {
  177. }
  178. CAIHintVector( const CAIHintVector& src )
  179. {
  180. CopyArray( src.Base(), src.Count() );
  181. }
  182. CAIHintVector &operator=( const CAIHintVector &src )
  183. {
  184. CopyArray( src.Base(), src.Count() );
  185. return *this;
  186. }
  187. };
  188. class CAI_HintManager
  189. {
  190. friend class CAI_Hint;
  191. public:
  192. // Hint node creation
  193. static CAI_Hint *CreateHint( HintNodeData *pNodeData, const char *pMapData = NULL );
  194. static void DrawHintOverlays(float flDrawDuration);
  195. static void AddHint( CAI_Hint *pTestHint );
  196. static void RemoveHint( CAI_Hint *pTestHint );
  197. static void AddHintByType( CAI_Hint *pHint );
  198. static void RemoveHintByType( CAI_Hint *pHintToRemove );
  199. // Interface for searching the hint node list
  200. static CAI_Hint *FindHint( CAI_BaseNPC *pNPC, const Vector &position, const CHintCriteria &hintCriteria );
  201. static CAI_Hint *FindHint( CAI_BaseNPC *pNPC, const CHintCriteria &hintCriteria );
  202. static CAI_Hint *FindHint( const Vector &position, const CHintCriteria &hintCriteria );
  203. static CAI_Hint *FindHint( CAI_BaseNPC *pNPC, Hint_e nHintType, int nFlags, float flMaxDist, const Vector *pMaxDistFrom = NULL );
  204. // Purpose: Finds a random suitable hint within the requested radious of the npc
  205. static CAI_Hint *FindHintRandom( CAI_BaseNPC *pNPC, const Vector &position, const CHintCriteria &hintCriteria );
  206. static int FindAllHints( CAI_BaseNPC *pNPC, const Vector &position, const CHintCriteria &hintCriteria, CUtlVector<CAI_Hint *> *pResult );
  207. static int FindAllHints( const Vector &position, const CHintCriteria &hintCriteria, CUtlVector<CAI_Hint *> *pResult ) { return FindAllHints( NULL, position, hintCriteria, pResult ); }
  208. static int FindAllHints( CAI_BaseNPC *pNPC, const CHintCriteria &hintCriteria, CUtlVector<CAI_Hint *> *pResult ) { return FindAllHints( pNPC, pNPC->GetAbsOrigin(), hintCriteria, pResult ); }
  209. static int GetFlags( const char *token );
  210. static CAI_Hint *GetFirstHint( AIHintIter_t *pIter );
  211. static CAI_Hint *GetNextHint( AIHintIter_t *pIter );
  212. static void DumpHints();
  213. static void ValidateHints();
  214. private:
  215. enum
  216. {
  217. // MUST BE POWER OF 2
  218. HINT_HISTORY = (1<<3),
  219. HINT_HISTORY_MASK = (HINT_HISTORY-1)
  220. };
  221. static CAI_Hint *AddFoundHint( CAI_Hint *hint );
  222. static int GetFoundHintCount();
  223. static CAI_Hint *GetFoundHint( int index );
  224. static CAI_Hint *GetLastFoundHint();
  225. static void ResetFoundHints();
  226. static bool IsInFoundHintList( CAI_Hint *hint );
  227. static int gm_nFoundHintIndex;
  228. static CAI_Hint *gm_pLastFoundHints[ HINT_HISTORY ]; // Last used hint
  229. static CAIHintVector gm_AllHints; // A linked list of all hints
  230. static CUtlMap< int, CAIHintVector > gm_TypedHints;
  231. };
  232. //-----------------------------------------------------------------------------
  233. // CAI_Hint
  234. //-----------------------------------------------------------------------------
  235. class CAI_Hint : public CServerOnlyEntity
  236. {
  237. DECLARE_CLASS( CAI_Hint, CServerOnlyEntity );
  238. public:
  239. CAI_Hint( void );
  240. ~CAI_Hint( void );
  241. // Interface for specific nodes
  242. bool Lock( CBaseEntity *pNPC ); // Makes unavailable for hints
  243. void Unlock( float delay = 0.0 ); // Makes available for hints after delay
  244. bool IsLocked(void); // Whether this node is available for use.
  245. bool IsLockedBy( CBaseEntity *pNPC ); // Whether this node is available for use.
  246. void GetPosition(CBaseCombatCharacter *pBCC, Vector *vPosition);
  247. void GetPosition( Hull_t hull, Vector *vPosition );
  248. Vector GetDirection( void );
  249. float Yaw( void );
  250. CAI_Node *GetNode( void );
  251. string_t GetGroup( void ) const { return m_NodeData.strGroup; }
  252. CBaseEntity *User( void ) const { return m_hHintOwner; };
  253. Hint_e HintType( void ) const { return (Hint_e)m_NodeData.nHintType; };
  254. void SetHintType( int hintType, bool force = false );
  255. string_t HintActivityName( void ) const { return m_NodeData.iszActivityName; }
  256. int GetTargetNode( void ) const { return m_nTargetNodeID; }
  257. bool IsDisabled( void ) const { return (m_NodeData.iDisabled != 0); }
  258. void SetDisabled( bool bDisabled ) { m_NodeData.iDisabled = bDisabled; }
  259. void DisableForSeconds( float flSeconds );
  260. void EnableThink();
  261. void FixupTargetNode();
  262. void NPCStartedUsing( CAI_BaseNPC *pNPC );
  263. void NPCStoppedUsing( CAI_BaseNPC *pNPC );
  264. HintIgnoreFacing_t GetIgnoreFacing() const { return m_NodeData.fIgnoreFacing; }
  265. NPC_STATE GetMinState() const { return m_NodeData.minState; }
  266. NPC_STATE GetMaxState() const { return m_NodeData.maxState; }
  267. string_t GetGenericType() const { return m_NodeData.iszGenericType; }
  268. int GetNodeId() { return m_NodeData.nNodeID; }
  269. int GetWCId() { return m_NodeData.nWCNodeID; }
  270. int GetRadius() { return m_NodeData.nRadius; }
  271. bool HintMatchesCriteria( CAI_BaseNPC *pNPC, const CHintCriteria &hintCriteria, const Vector &position, float *flNearestDistance, bool bIgnoreLock = false, bool bIgnoreHintType = false );
  272. bool IsInNodeFOV( CBaseEntity *pOther );
  273. private:
  274. void Spawn( void );
  275. virtual void Activate();
  276. virtual void UpdateOnRemove( void );
  277. int DrawDebugTextOverlays(void);
  278. virtual int ObjectCaps( void ) { return (BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION); }
  279. virtual void OnRestore();
  280. bool IsViewable( void );
  281. // Input handlers
  282. void InputEnableHint( inputdata_t &inputdata );
  283. void InputDisableHint( inputdata_t &inputdata );
  284. private:
  285. HintNodeData m_NodeData;
  286. int m_nTargetNodeID;
  287. EHANDLE m_hHintOwner; // Is hint locked (being used by NPC / NPC en-route to use it)
  288. float m_flNextUseTime; // When can I be used again?
  289. COutputEHANDLE m_OnNPCStartedUsing; // Triggered when an NPC has actively begun to use the node.
  290. COutputEHANDLE m_OnNPCStoppedUsing; // Triggered when an NPC has finished using this node.
  291. float m_nodeFOV;
  292. Vector m_vecForward;
  293. // The next hint in list of all hints
  294. friend class CAI_HintManager;
  295. DECLARE_DATADESC();
  296. };
  297. #define SF_ALLOW_JUMP_UP 65536
  298. #endif //AI_HINT_H