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.

341 lines
12 KiB

  1. //========= Copyright 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. //-----------------------------------------------------------------------------
  29. //
  30. // hints - these MUST coincide with the HINTS listed under
  31. // info_node in the FGD file!
  32. //
  33. // For debugging, they must also coincide with g_pszHintDescriptions.
  34. //
  35. //-----------------------------------------------------------------------------
  36. enum Hint_e
  37. {
  38. HINT_ANY = -1,
  39. HINT_NONE = 0,
  40. HINT_NOT_USED_WORLD_DOOR,
  41. HINT_WORLD_WINDOW,
  42. HINT_NOT_USED_WORLD_BUTTON,
  43. HINT_NOT_USED_WORLD_MACHINERY,
  44. HINT_NOT_USED_WORLD_LEDGE,
  45. HINT_NOT_USED_WORLD_LIGHT_SOURCE,
  46. HINT_NOT_USED_WORLD_HEAT_SOURCE,
  47. HINT_NOT_USED_WORLD_BLINKING_LIGHT,
  48. HINT_NOT_USED_WORLD_BRIGHT_COLORS,
  49. HINT_NOT_USED_WORLD_HUMAN_BLOOD,
  50. HINT_NOT_USED_WORLD_ALIEN_BLOOD,
  51. HINT_WORLD_WORK_POSITION,
  52. HINT_WORLD_VISUALLY_INTERESTING,
  53. HINT_WORLD_VISUALLY_INTERESTING_DONT_AIM,
  54. HINT_WORLD_INHIBIT_COMBINE_MINES,
  55. HINT_WORLD_VISUALLY_INTERESTING_STEALTH,
  56. HINT_TACTICAL_COVER_MED = 100,
  57. HINT_TACTICAL_COVER_LOW,
  58. HINT_TACTICAL_SPAWN,
  59. HINT_TACTICAL_PINCH, // Exit / entrance to an arena
  60. HINT_NOT_USED_TACTICAL_GUARD,
  61. HINT_TACTICAL_ENEMY_DISADVANTAGED, //Disadvantageous position for the enemy
  62. HINT_NOT_USED_HEALTH_KIT,
  63. HINT_NOT_USED_URBAN_STREETCORNER = 200,
  64. HINT_NOT_USED_URBAN_STREETLAMP,
  65. HINT_NOT_USED_URBAN_DARK_SPOT,
  66. HINT_NOT_USED_URBAN_POSTER,
  67. HINT_NOT_USED_URBAN_SHELTER,
  68. HINT_NOT_USED_ASSASSIN_SECLUDED = 300,
  69. HINT_NOT_USED_ASSASSIN_RAFTERS,
  70. HINT_NOT_USED_ASSASSIN_GROUND,
  71. HINT_NOT_USED_ASSASSIN_MONKEYBARS,
  72. HINT_ANTLION_BURROW_POINT = 400,
  73. HINT_ANTLION_THUMPER_FLEE_POINT,
  74. HINT_HEADCRAB_BURROW_POINT = 450,
  75. HINT_HEADCRAB_EXIT_POD_POINT,
  76. HINT_NOT_USED_ROLLER_PATROL_POINT = 500,
  77. HINT_NOT_USED_ROLLER_CLEANUP_POINT,
  78. HINT_NOT_USED_PSTORM_ROCK_SPAWN = 600,
  79. HINT_CROW_FLYTO_POINT = 700,
  80. // TF2 Hints
  81. HINT_BUG_PATROL_POINT = 800,
  82. // HL2 Hints
  83. HINT_FOLLOW_WAIT_POINT = 900,
  84. HINT_JUMP_OVERRIDE = 901,
  85. HINT_PLAYER_SQUAD_TRANSITON_POINT = 902,
  86. HINT_NPC_EXIT_POINT = 903,
  87. HINT_STRIDER_NODE = 904,
  88. HINT_PLAYER_ALLY_MOVE_AWAY_DEST = 950,
  89. HINT_PLAYER_ALLY_FEAR_DEST,
  90. // HL1 port hints
  91. HINT_HL1_WORLD_MACHINERY = 1000,
  92. HINT_HL1_WORLD_BLINKING_LIGHT,
  93. HINT_HL1_WORLD_HUMAN_BLOOD,
  94. HINT_HL1_WORLD_ALIEN_BLOOD,
  95. // CS port hints
  96. HINT_CSTRIKE_HOSTAGE_ESCAPE = 1100,
  97. };
  98. const char *GetHintTypeDescription( Hint_e iHintType );
  99. const char *GetHintTypeDescription( CAI_Hint *pHint );
  100. //-----------------------------------------------------------------------------
  101. // CHintCriteria
  102. //-----------------------------------------------------------------------------
  103. class CHintCriteria
  104. {
  105. public:
  106. CHintCriteria();
  107. ~CHintCriteria();
  108. bool HasFlag( int bitmask ) const { return ( m_iFlags & bitmask ) != 0; }
  109. void SetFlag( int bitmask );
  110. void ClearFlag( int bitmask );
  111. void SetGroup( string_t group );
  112. string_t GetGroup( void ) const { return m_strGroup; }
  113. int GetFirstHintType( void ) const { return m_iFirstHintType; }
  114. int GetLastHintType( void ) const { return m_iLastHintType; }
  115. bool MatchesHintType( int hintType ) const;
  116. bool MatchesSingleHintType() const;
  117. bool HasIncludeZones( void ) const { return ( m_zoneInclude.Count() != 0 ); }
  118. bool HasExcludeZones( void ) const { return ( m_zoneExclude.Count() != 0 ); }
  119. void AddIncludePosition( const Vector &position, float radius );
  120. void AddExcludePosition( const Vector &position, float radius );
  121. void SetHintType( int hintType );
  122. void SetHintTypeRange( int firstType, int lastType );
  123. void AddHintType( int hintType );
  124. bool InIncludedZone( const Vector &testPosition ) const;
  125. bool InExcludedZone( const Vector &testPosition ) const;
  126. int NumHintTypes() const;
  127. int GetHintType( int idx ) const;
  128. private:
  129. struct hintZone_t
  130. {
  131. Vector position;
  132. float radiussqr;
  133. };
  134. typedef CUtlVector < hintZone_t > zoneList_t;
  135. void AddZone( zoneList_t &list, const Vector &position, float radius );
  136. bool InZone( const zoneList_t &zone, const Vector &testPosition ) const;
  137. CUtlVector<int> m_HintTypes;
  138. int m_iFlags;
  139. int m_iFirstHintType;
  140. int m_iLastHintType;
  141. string_t m_strGroup;
  142. zoneList_t m_zoneInclude;
  143. zoneList_t m_zoneExclude;
  144. };
  145. class CAI_Node;
  146. //-----------------------------------------------------------------------------
  147. // CAI_HintManager
  148. //-----------------------------------------------------------------------------
  149. DECLARE_POINTER_HANDLE(AIHintIter_t);
  150. class CAIHintVector : public CUtlVector< CAI_Hint * >
  151. {
  152. public:
  153. CAIHintVector() : CUtlVector< CAI_Hint * >( 1, 0 )
  154. {
  155. }
  156. CAIHintVector( const CAIHintVector& src )
  157. {
  158. CopyArray( src.Base(), src.Count() );
  159. }
  160. CAIHintVector &operator=( const CAIHintVector &src )
  161. {
  162. CopyArray( src.Base(), src.Count() );
  163. return *this;
  164. }
  165. };
  166. class CAI_HintManager
  167. {
  168. friend class CAI_Hint;
  169. public:
  170. // Hint node creation
  171. static CAI_Hint *CreateHint( HintNodeData *pNodeData, const char *pMapData = NULL );
  172. static void DrawHintOverlays(float flDrawDuration);
  173. static void AddHint( CAI_Hint *pTestHint );
  174. static void RemoveHint( CAI_Hint *pTestHint );
  175. static void AddHintByType( CAI_Hint *pHint );
  176. static void RemoveHintByType( CAI_Hint *pHintToRemove );
  177. // Interface for searching the hint node list
  178. static CAI_Hint *FindHint( CAI_BaseNPC *pNPC, const Vector &position, const CHintCriteria &hintCriteria );
  179. static CAI_Hint *FindHint( CAI_BaseNPC *pNPC, const CHintCriteria &hintCriteria );
  180. static CAI_Hint *FindHint( const Vector &position, const CHintCriteria &hintCriteria );
  181. static CAI_Hint *FindHint( CAI_BaseNPC *pNPC, Hint_e nHintType, int nFlags, float flMaxDist, const Vector *pMaxDistFrom = NULL );
  182. // Purpose: Finds a random suitable hint within the requested radious of the npc
  183. static CAI_Hint *FindHintRandom( CAI_BaseNPC *pNPC, const Vector &position, const CHintCriteria &hintCriteria );
  184. static int FindAllHints( CAI_BaseNPC *pNPC, const Vector &position, const CHintCriteria &hintCriteria, CUtlVector<CAI_Hint *> *pResult );
  185. static int FindAllHints( const Vector &position, const CHintCriteria &hintCriteria, CUtlVector<CAI_Hint *> *pResult ) { return FindAllHints( NULL, position, hintCriteria, pResult ); }
  186. static int FindAllHints( CAI_BaseNPC *pNPC, const CHintCriteria &hintCriteria, CUtlVector<CAI_Hint *> *pResult ) { return FindAllHints( pNPC, pNPC->GetAbsOrigin(), hintCriteria, pResult ); }
  187. static int GetFlags( const char *token );
  188. static CAI_Hint *GetFirstHint( AIHintIter_t *pIter );
  189. static CAI_Hint *GetNextHint( AIHintIter_t *pIter );
  190. static void DumpHints();
  191. static void ValidateHints();
  192. private:
  193. enum
  194. {
  195. // MUST BE POWER OF 2
  196. HINT_HISTORY = (1<<3),
  197. HINT_HISTORY_MASK = (HINT_HISTORY-1)
  198. };
  199. static CAI_Hint *AddFoundHint( CAI_Hint *hint );
  200. static int GetFoundHintCount();
  201. static CAI_Hint *GetFoundHint( int index );
  202. static CAI_Hint *GetLastFoundHint();
  203. static void ResetFoundHints();
  204. static bool IsInFoundHintList( CAI_Hint *hint );
  205. static int gm_nFoundHintIndex;
  206. static CAI_Hint *gm_pLastFoundHints[ HINT_HISTORY ]; // Last used hint
  207. static CAIHintVector gm_AllHints; // A linked list of all hints
  208. static CUtlMap< int, CAIHintVector > gm_TypedHints;
  209. };
  210. //-----------------------------------------------------------------------------
  211. // CAI_Hint
  212. //-----------------------------------------------------------------------------
  213. class CAI_Hint : public CServerOnlyEntity
  214. {
  215. DECLARE_CLASS( CAI_Hint, CServerOnlyEntity );
  216. public:
  217. CAI_Hint( void );
  218. ~CAI_Hint( void );
  219. // Interface for specific nodes
  220. bool Lock( CBaseEntity *pNPC ); // Makes unavailable for hints
  221. void Unlock( float delay = 0.0 ); // Makes available for hints after delay
  222. bool IsLocked(void); // Whether this node is available for use.
  223. bool IsLockedBy( CBaseEntity *pNPC ); // Whether this node is available for use.
  224. void GetPosition(CBaseCombatCharacter *pBCC, Vector *vPosition);
  225. void GetPosition( Hull_t hull, Vector *vPosition );
  226. Vector GetDirection( void );
  227. float Yaw( void );
  228. CAI_Node *GetNode( void );
  229. string_t GetGroup( void ) const { return m_NodeData.strGroup; }
  230. CBaseEntity *User( void ) const { return m_hHintOwner; };
  231. Hint_e HintType( void ) const { return (Hint_e)m_NodeData.nHintType; };
  232. void SetHintType( int hintType, bool force = false );
  233. string_t HintActivityName( void ) const { return m_NodeData.iszActivityName; }
  234. int GetTargetNode( void ) const { return m_nTargetNodeID; }
  235. bool IsDisabled( void ) const { return (m_NodeData.iDisabled != 0); }
  236. void SetDisabled( bool bDisabled ) { m_NodeData.iDisabled = bDisabled; }
  237. void DisableForSeconds( float flSeconds );
  238. void EnableThink();
  239. void FixupTargetNode();
  240. void NPCStartedUsing( CAI_BaseNPC *pNPC );
  241. void NPCStoppedUsing( CAI_BaseNPC *pNPC );
  242. HintIgnoreFacing_t GetIgnoreFacing() const { return m_NodeData.fIgnoreFacing; }
  243. NPC_STATE GetMinState() const { return m_NodeData.minState; }
  244. NPC_STATE GetMaxState() const { return m_NodeData.maxState; }
  245. int GetNodeId() { return m_NodeData.nNodeID; }
  246. int GetWCId() { return m_NodeData.nWCNodeID; }
  247. bool HintMatchesCriteria( CAI_BaseNPC *pNPC, const CHintCriteria &hintCriteria, const Vector &position, float *flNearestDistance, bool bIgnoreLock = false, bool bIgnoreHintType = false );
  248. bool IsInNodeFOV( CBaseEntity *pOther );
  249. private:
  250. void Spawn( void );
  251. virtual void Activate();
  252. virtual void UpdateOnRemove( void );
  253. int DrawDebugTextOverlays(void);
  254. virtual int ObjectCaps( void ) { return (BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION); }
  255. virtual void OnRestore();
  256. bool IsViewable( void );
  257. // Input handlers
  258. void InputEnableHint( inputdata_t &inputdata );
  259. void InputDisableHint( inputdata_t &inputdata );
  260. private:
  261. HintNodeData m_NodeData;
  262. int m_nTargetNodeID;
  263. EHANDLE m_hHintOwner; // Is hint locked (being used by NPC / NPC en-route to use it)
  264. float m_flNextUseTime; // When can I be used again?
  265. COutputEHANDLE m_OnNPCStartedUsing; // Triggered when an NPC has actively begun to use the node.
  266. COutputEHANDLE m_OnNPCStoppedUsing; // Triggered when an NPC has finished using this node.
  267. float m_nodeFOV;
  268. Vector m_vecForward;
  269. // The next hint in list of all hints
  270. friend class CAI_HintManager;
  271. DECLARE_DATADESC();
  272. };
  273. #define SF_ALLOW_JUMP_UP 65536
  274. #endif //AI_HINT_H