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.

383 lines
9.9 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #ifndef AI_BEHAVIOR_FOLLOW_H
  7. #define AI_BEHAVIOR_FOLLOW_H
  8. #include "simtimer.h"
  9. #include "ai_behavior.h"
  10. #include "ai_goalentity.h"
  11. #include "ai_utils.h"
  12. #include "ai_moveshoot.h"
  13. #ifdef HL2_EPISODIC
  14. #include "hl2_gamerules.h"
  15. #endif
  16. #if defined( _WIN32 )
  17. #pragma once
  18. #endif
  19. //-----------------------------------------------------------------------------
  20. // NOTE: these must correspond with the AI_FollowFormation_t array in AI_Behavior_Follow.cpp!!
  21. //-----------------------------------------------------------------------------
  22. enum AI_Formations_t
  23. {
  24. AIF_SIMPLE,
  25. AIF_WIDE,
  26. AIF_ANTLION,
  27. AIF_COMMANDER,
  28. AIF_TIGHT,
  29. AIF_MEDIUM,
  30. AIF_SIDEKICK,
  31. AIF_HUNTER,
  32. AIF_VORTIGAUNT,
  33. };
  34. enum AI_FollowFormationFlags_t
  35. {
  36. AIFF_DEFAULT = 0,
  37. AIFF_USE_FOLLOW_POINTS = 0x01,
  38. AIFF_REQUIRE_LOS_OUTSIDE_COMBAT = 0x02,
  39. };
  40. //-----------------------------------------------------------------------------
  41. //
  42. // CAI_FollowGoal
  43. //
  44. // Purpose: A level tool to control the follow behavior. Use is not required
  45. // in order to use behavior.
  46. //
  47. //-----------------------------------------------------------------------------
  48. class CAI_FollowGoal : public CAI_GoalEntity
  49. {
  50. DECLARE_CLASS( CAI_FollowGoal, CAI_GoalEntity );
  51. public:
  52. virtual void EnableGoal( CAI_BaseNPC *pAI );
  53. virtual void DisableGoal( CAI_BaseNPC *pAI );
  54. #ifdef HL2_EPISODIC
  55. virtual void InputOutsideTransition( inputdata_t &inputdata );
  56. #endif
  57. int m_iFormation;
  58. DECLARE_DATADESC();
  59. };
  60. //-----------------------------------------------------------------------------
  61. int AIGetNumFollowers( CBaseEntity *pEntity, string_t iszClassname = NULL_STRING );
  62. //-----------------------------------------------------------------------------
  63. struct AI_FollowNavInfo_t
  64. {
  65. int flags;
  66. Vector position;
  67. float range;
  68. float Zrange;
  69. float tolerance;
  70. float followPointTolerance;
  71. float targetMoveTolerance;
  72. float repathOnRouteTolerance;
  73. float walkTolerance;
  74. float coverTolerance;
  75. float enemyLOSTolerance;
  76. float chaseEnemyTolerance;
  77. DECLARE_SIMPLE_DATADESC();
  78. };
  79. struct AI_FollowGroup_t;
  80. struct AI_FollowManagerInfoHandle_t
  81. {
  82. AI_FollowGroup_t *m_pGroup;
  83. int m_hFollower;
  84. };
  85. //-------------------------------------
  86. struct AI_FollowParams_t
  87. {
  88. AI_FollowParams_t( AI_Formations_t formation = AIF_SIMPLE, bool bNormalMemoryDiscard = false )
  89. : formation(formation),
  90. bNormalMemoryDiscard( bNormalMemoryDiscard )
  91. {
  92. }
  93. AI_Formations_t formation;
  94. bool bNormalMemoryDiscard;
  95. DECLARE_SIMPLE_DATADESC();
  96. };
  97. //-------------------------------------
  98. class CAI_FollowBehavior : public CAI_SimpleBehavior
  99. {
  100. DECLARE_CLASS( CAI_FollowBehavior, CAI_SimpleBehavior );
  101. public:
  102. CAI_FollowBehavior( const AI_FollowParams_t &params = AIF_SIMPLE );
  103. ~CAI_FollowBehavior();
  104. virtual int DrawDebugTextOverlays( int text_offset );
  105. virtual void DrawDebugGeometryOverlays();
  106. // Returns true if the NPC is actively following a target.
  107. bool IsActive( void );
  108. void SetParameters( const AI_FollowParams_t &params );
  109. virtual const char *GetName() { return "Follow"; }
  110. AI_Formations_t GetFormation() const { return m_params.formation; }
  111. virtual bool CanSelectSchedule();
  112. const AI_FollowNavInfo_t &GetFollowGoalInfo();
  113. CBaseEntity * GetFollowTarget();
  114. void SetFollowTarget( CBaseEntity *pLeader, bool fFinishCurSchedule = false );
  115. CAI_FollowGoal *GetFollowGoal() { return m_hFollowGoalEnt; } // if any
  116. bool SetFollowGoal( CAI_FollowGoal *pGoal, bool fFinishCurSchedule = false );
  117. void ClearFollowGoal( CAI_FollowGoal *pGoal );
  118. void SetFollowGoalDirect( CAI_FollowGoal *pGoal );
  119. virtual bool FarFromFollowTarget() { return ( m_hFollowTarget && (GetAbsOrigin() - m_hFollowTarget->GetAbsOrigin()).LengthSqr() > (75*12)*(75*12) ); }
  120. virtual bool TargetIsUnreachable() { return m_bTargetUnreachable; }
  121. int GetNumFailedFollowAttempts() { return m_nFailedFollowAttempts; }
  122. float GetTimeFailFollowStarted() { return m_flTimeFailFollowStarted; }
  123. bool FollowTargetVisible() { return HasCondition( COND_FOLLOW_TARGET_VISIBLE ); };
  124. bool IsMovingToFollowTarget();
  125. float GetGoalRange();
  126. float GetGoalZRange();
  127. virtual Activity NPC_TranslateActivity( Activity activity );
  128. virtual int TranslateSchedule( int scheduleType );
  129. virtual void StartTask( const Task_t *pTask );
  130. virtual int SelectFailSchedule( int failedSchedule, int failedTask, AI_TaskFailureCode_t taskFailCode );
  131. virtual void TaskComplete( bool fIgnoreSetFailedCondition = false );
  132. virtual void GatherConditions();
  133. protected:
  134. const Vector &GetGoalPosition();
  135. virtual bool ShouldFollow();
  136. friend class CAI_FollowManager;
  137. virtual void BeginScheduleSelection();
  138. virtual void EndScheduleSelection();
  139. virtual void CleanupOnDeath( CBaseEntity *pCulprit, bool bFireDeathOutput );
  140. virtual void Precache();
  141. virtual int SelectSchedule();
  142. virtual int FollowCallBaseSelectSchedule() { return BaseClass::SelectSchedule(); }
  143. virtual void OnStartSchedule( int scheduleType );
  144. virtual void RunTask( const Task_t *pTask );
  145. void BuildScheduleTestBits();
  146. bool IsCurScheduleFollowSchedule();
  147. virtual bool IsCurTaskContinuousMove();
  148. virtual void OnMovementFailed();
  149. virtual void OnMovementComplete();
  150. virtual bool FValidateHintType( CAI_Hint *pHint );
  151. bool IsValidCover( const Vector &vLocation, CAI_Hint const *pHint );
  152. bool IsValidShootPosition( const Vector &vLocation, CAI_Node *pNode, CAI_Hint const *pHint );
  153. bool FindCoverFromEnemyAtFollowTarget( float coverRadius, Vector *pResult );
  154. bool ShouldAlwaysThink();
  155. bool ShouldMoveToFollowTarget();
  156. int SelectScheduleManagePosition();
  157. int SelectScheduleFollowPoints();
  158. int SelectScheduleMoveToFormation();
  159. void GetFollowTargetViewLoc( Vector *pResult);
  160. bool ValidateFaceTarget( Vector *pFaceTarget );
  161. //----------------------------
  162. bool ShouldUseFollowPoints();
  163. bool HasFollowPoint();
  164. void SetFollowPoint( CAI_Hint *pHintNode );
  165. void ClearFollowPoint();
  166. const Vector & GetFollowPoint();
  167. CAI_Hint * FindFollowPoint();
  168. bool IsFollowPointInRange();
  169. bool ShouldIgnoreFollowPointFacing();
  170. //----------------------------
  171. bool UpdateFollowPosition();
  172. const int GetGoalFlags();
  173. float GetGoalTolerance();
  174. bool PlayerIsPushing();
  175. bool IsFollowTargetInRange( float rangeMultiplier = 1.0 );
  176. bool IsFollowGoalInRange( float tolerance, float zTolerance, int flags );
  177. virtual bool IsChaseGoalInRange();
  178. void NoteFailedFollow();
  179. void NoteSuccessfulFollow();
  180. //----------------------------
  181. protected:
  182. enum
  183. {
  184. SCHED_FOLLOWER_MOVE_AWAY_FAIL = BaseClass::NEXT_SCHEDULE, // Turn back toward player
  185. SCHED_FOLLOWER_MOVE_AWAY_END,
  186. SCHED_FOLLOW,
  187. SCHED_FOLLOWER_IDLE_STAND,
  188. SCHED_MOVE_TO_FACE_FOLLOW_TARGET,
  189. SCHED_FACE_FOLLOW_TARGET,
  190. SCHED_FOLLOWER_GO_TO_WAIT_POINT,
  191. SCHED_FOLLOWER_GO_TO_WAIT_POINT_FAIL,
  192. SCHED_FOLLOWER_STAND_AT_WAIT_POINT,
  193. SCHED_FOLLOWER_COMBAT_FACE,
  194. NEXT_SCHEDULE,
  195. TASK_CANT_FOLLOW = BaseClass::NEXT_TASK,
  196. TASK_FACE_FOLLOW_TARGET,
  197. TASK_MOVE_TO_FOLLOW_POSITION,
  198. TASK_GET_PATH_TO_FOLLOW_POSITION,
  199. TASK_SET_FOLLOW_TARGET_MARK,
  200. TASK_FOLLOWER_FACE_TACTICAL,
  201. TASK_SET_FOLLOW_DELAY,
  202. TASK_GET_PATH_TO_FOLLOW_POINT,
  203. TASK_ARRIVE_AT_FOLLOW_POINT,
  204. TASK_SET_FOLLOW_POINT_STAND_SCHEDULE,
  205. TASK_BEGIN_STAND_AT_WAIT_POINT,
  206. NEXT_TASK,
  207. COND_TARGET_MOVED_FROM_MARK = BaseClass::NEXT_CONDITION,
  208. COND_FOUND_WAIT_POINT,
  209. COND_FOLLOW_DELAY_EXPIRED,
  210. COND_FOLLOW_TARGET_VISIBLE,
  211. COND_FOLLOW_TARGET_NOT_VISIBLE,
  212. COND_FOLLOW_WAIT_POINT_INVALID,
  213. COND_FOLLOW_PLAYER_IS_LIT,
  214. COND_FOLLOW_PLAYER_IS_NOT_LIT,
  215. NEXT_CONDITION,
  216. };
  217. DEFINE_CUSTOM_SCHEDULE_PROVIDER;
  218. protected:
  219. //----------------------------
  220. EHANDLE m_hFollowTarget;
  221. AI_FollowNavInfo_t m_FollowNavGoal;
  222. float m_flTimeUpdatedFollowPosition;
  223. bool m_bFirstFacing;
  224. float m_flTimeFollowTargetVisible;
  225. CAI_MoveMonitor m_TargetMonitor;
  226. bool m_bTargetUnreachable;
  227. bool m_bFollowNavFailed; // Set when pathfinding fails to limit impact of m_FollowDelay on ShouldFollow
  228. int m_nFailedFollowAttempts;
  229. float m_flTimeFailFollowStarted;
  230. Vector m_vFollowMoveAnchor;
  231. bool m_bMovingToCover;
  232. float m_flOriginalEnemyDiscardTime;
  233. float m_SavedDistTooFar;
  234. CRandStopwatch m_FollowDelay;
  235. CSimpleSimTimer m_RepathOnFollowTimer;
  236. //---------------------------------
  237. Activity m_CurrentFollowActivity;
  238. //---------------------------------
  239. CRandSimTimer m_TimeBlockUseWaitPoint;
  240. CSimTimer m_TimeCheckForWaitPoint;
  241. CAI_Hint * m_pInterruptWaitPoint;
  242. //---------------------------------
  243. CRandSimTimer m_TimeBeforeSpreadFacing;
  244. CRandSimTimer m_TimeNextSpreadFacing;
  245. //---------------------------------
  246. AI_FollowManagerInfoHandle_t m_hFollowManagerInfo;
  247. AI_FollowParams_t m_params;
  248. //---------------------------------
  249. CHandle<CAI_FollowGoal> m_hFollowGoalEnt;
  250. //---------------------------------
  251. DECLARE_DATADESC();
  252. };
  253. //-------------------------------------
  254. inline const AI_FollowNavInfo_t &CAI_FollowBehavior::GetFollowGoalInfo()
  255. {
  256. return m_FollowNavGoal;
  257. }
  258. //-------------------------------------
  259. inline const int CAI_FollowBehavior::GetGoalFlags()
  260. {
  261. return m_FollowNavGoal.flags;
  262. }
  263. //-------------------------------------
  264. inline const Vector &CAI_FollowBehavior::GetGoalPosition()
  265. {
  266. return m_FollowNavGoal.position;
  267. }
  268. //-------------------------------------
  269. inline float CAI_FollowBehavior::GetGoalTolerance()
  270. {
  271. return m_FollowNavGoal.tolerance;
  272. }
  273. //-------------------------------------
  274. inline float CAI_FollowBehavior::GetGoalRange()
  275. {
  276. return m_FollowNavGoal.range;
  277. }
  278. //-------------------------------------
  279. inline float CAI_FollowBehavior::GetGoalZRange()
  280. {
  281. return m_FollowNavGoal.Zrange;
  282. }
  283. //-----------------------------------------------------------------------------
  284. #endif // AI_BEHAVIOR_FOLLOW_H