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.

318 lines
10 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #ifndef AI_BEHAVIOR_ACTBUSY_H
  7. #define AI_BEHAVIOR_ACTBUSY_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "ai_behavior.h"
  12. #include "ai_goalentity.h"
  13. //-----------------------------------------------------------------------------
  14. enum
  15. {
  16. ACTBUSY_TYPE_DEFAULT = 0,
  17. ACTBUSY_TYPE_COMBAT,
  18. };
  19. enum busyinterrupt_t
  20. {
  21. BA_INT_NONE, // Nothing breaks us out of this
  22. BA_INT_DANGER, // Only danger signals interrupts this busy anim. The player will be ignored.
  23. BA_INT_PLAYER, // The Player's presence interrupts this busy anim
  24. BA_INT_AMBUSH, // We're waiting to ambush enemies. Don't break on danger sounds in front of us.
  25. BA_INT_COMBAT, // Only break out if we're shot at.
  26. BA_INT_ZOMBIESLUMP, // Zombies who are slumped on the ground.
  27. BA_INT_SIEGE_DEFENSE,
  28. };
  29. enum busyanimparts_t
  30. {
  31. BA_BUSY,
  32. BA_ENTRY,
  33. BA_EXIT,
  34. BA_MAX_ANIMS,
  35. };
  36. struct busyanim_t
  37. {
  38. string_t iszName;
  39. Activity iActivities[BA_MAX_ANIMS];
  40. string_t iszSequences[BA_MAX_ANIMS];
  41. string_t iszSounds[BA_MAX_ANIMS];
  42. float flMinTime; // Min time spent in this busy animation
  43. float flMaxTime; // Max time spent in this busy animation. 0 means continue until interrupted.
  44. busyinterrupt_t iBusyInterruptType;
  45. bool bUseAutomovement;
  46. };
  47. struct busysafezone_t
  48. {
  49. Vector vecMins;
  50. Vector vecMaxs;
  51. };
  52. #define NO_MAX_TIME -1
  53. class CAI_ActBusyGoal;
  54. //-----------------------------------------------------------------------------
  55. // Purpose:
  56. //-----------------------------------------------------------------------------
  57. class CAI_ActBusyBehavior : public CAI_SimpleBehavior
  58. {
  59. DECLARE_CLASS( CAI_ActBusyBehavior, CAI_SimpleBehavior );
  60. public:
  61. DECLARE_DATADESC();
  62. CAI_ActBusyBehavior();
  63. enum
  64. {
  65. // Schedules
  66. SCHED_ACTBUSY_START_BUSYING = BaseClass::NEXT_SCHEDULE,
  67. SCHED_ACTBUSY_BUSY,
  68. SCHED_ACTBUSY_STOP_BUSYING,
  69. SCHED_ACTBUSY_LEAVE,
  70. SCHED_ACTBUSY_TELEPORT_TO_BUSY,
  71. NEXT_SCHEDULE,
  72. // Tasks
  73. TASK_ACTBUSY_PLAY_BUSY_ANIM = BaseClass::NEXT_TASK,
  74. TASK_ACTBUSY_PLAY_ENTRY,
  75. TASK_ACTBUSY_PLAY_EXIT,
  76. TASK_ACTBUSY_TELEPORT_TO_BUSY,
  77. TASK_ACTBUSY_WALK_PATH_TO_BUSY,
  78. TASK_ACTBUSY_GET_PATH_TO_ACTBUSY,
  79. TASK_ACTBUSY_VERIFY_EXIT,
  80. NEXT_TASK,
  81. // Conditions
  82. COND_ACTBUSY_LOST_SEE_ENTITY = BaseClass::NEXT_CONDITION,
  83. COND_ACTBUSY_AWARE_OF_ENEMY_IN_SAFE_ZONE,
  84. COND_ACTBUSY_ENEMY_TOO_CLOSE,
  85. NEXT_CONDITION,
  86. };
  87. virtual const char *GetName() { return "ActBusy"; }
  88. void Enable( CAI_ActBusyGoal *pGoal, float flRange, bool bVisibleOnly );
  89. void OnRestore();
  90. void SetBusySearchRange( float flRange );
  91. void Disable( void );
  92. void ForceActBusy( CAI_ActBusyGoal *pGoal, CAI_Hint *pHintNode = NULL, float flMaxTime = NO_MAX_TIME, bool bVisibleOnly = false, bool bTeleportToBusy = false, bool bUseNearestBusy = false, CBaseEntity *pSeeEntity = NULL, Activity activity = ACT_INVALID );
  93. void ForceActBusyLeave( bool bVisibleOnly = false );
  94. void StopBusying( void );
  95. bool IsStopBusying();
  96. CAI_Hint *FindActBusyHintNode( void );
  97. CAI_Hint *FindCombatActBusyHintNode( void );
  98. CAI_Hint *FindCombatActBusyTeleportHintNode( void );
  99. bool CanSelectSchedule( void );
  100. bool IsCurScheduleOverridable( void );
  101. bool ShouldIgnoreSound( CSound *pSound );
  102. void OnFriendDamaged( CBaseCombatCharacter *pSquadmate, CBaseEntity *pAttacker );
  103. int OnTakeDamage_Alive( const CTakeDamageInfo &info );
  104. void GatherConditions( void );
  105. void BuildScheduleTestBits( void );
  106. void EndScheduleSelection( void );
  107. Activity NPC_TranslateActivity( Activity nActivity );
  108. void HandleAnimEvent( animevent_t *pEvent );
  109. void CheckAndCleanupOnExit( void );
  110. bool FValidateHintType( CAI_Hint *pHint );
  111. bool ActBusyNodeStillActive( void );
  112. bool IsMovingToBusy( void ) { return m_bMovingToBusy; }
  113. bool IsEnabled( void ) { return m_bEnabled; }
  114. float GetReasonableFacingDist( void ) { return 0; } // Actbusy ignores reasonable facing
  115. bool IsInterruptable( void );
  116. bool ShouldPlayerAvoid( void );
  117. void SetUseRenderBounds( bool bUseBounds ) { m_bUseRenderBoundsForCollision = bUseBounds; }
  118. void ComputeAndSetRenderBounds();
  119. bool CanFlinch( void );
  120. bool CanRunAScriptedNPCInteraction( bool bForced );
  121. void OnScheduleChange();
  122. bool QueryHearSound( CSound *pSound );
  123. void OnSeeEntity( CBaseEntity *pEntity );
  124. bool NeedsToPlayExitAnim() { return m_bNeedsToPlayExitAnim; }
  125. // Returns true if the current NPC is acting busy, or moving to an actbusy
  126. bool IsActive( void );
  127. // Returns true if the current NPC is actually acting busy (i.e. inside an act busy anim)
  128. bool IsInsideActBusy( void ) { return m_bBusy; }
  129. // Combat act busy stuff
  130. bool IsCombatActBusy();
  131. void CollectSafeZoneVolumes( CAI_ActBusyGoal *pActBusyGoal );
  132. bool IsInSafeZone( CBaseEntity *pEntity );
  133. int CountEnemiesInSafeZone();
  134. private:
  135. virtual int SelectSchedule( void );
  136. int SelectScheduleForLeaving( void );
  137. int SelectScheduleWhileNotBusy( int iBase );
  138. int SelectScheduleWhileBusy( void );
  139. virtual void StartTask( const Task_t *pTask );
  140. virtual void RunTask( const Task_t *pTask );
  141. void NotifyBusyEnding( void );
  142. bool HasAnimForActBusy( int iActBusy, busyanimparts_t AnimPart );
  143. bool PlayAnimForActBusy( busyanimparts_t AnimPart );
  144. void PlaySoundForActBusy( busyanimparts_t AnimPart );
  145. private:
  146. bool m_bEnabled;
  147. bool m_bForceActBusy;
  148. Activity m_ForcedActivity;
  149. bool m_bTeleportToBusy;
  150. bool m_bUseNearestBusy;
  151. bool m_bLeaving;
  152. bool m_bVisibleOnly;
  153. bool m_bUseRenderBoundsForCollision;
  154. float m_flForcedMaxTime;
  155. bool m_bBusy;
  156. bool m_bMovingToBusy;
  157. bool m_bNeedsToPlayExitAnim;
  158. float m_flNextBusySearchTime;
  159. float m_flEndBusyAt;
  160. float m_flBusySearchRange;
  161. bool m_bInQueue;
  162. int m_iCurrentBusyAnim;
  163. CHandle<CAI_ActBusyGoal> m_hActBusyGoal;
  164. bool m_bNeedToSetBounds;
  165. EHANDLE m_hSeeEntity;
  166. float m_fTimeLastSawSeeEntity;
  167. bool m_bExitedBusyToDueLostSeeEntity;
  168. bool m_bExitedBusyToDueSeeEnemy;
  169. int m_iNumConsecutivePathFailures; // Count how many times we failed to find a path to a node, so we can consider teleporting.
  170. bool m_bAutoFireWeapon;
  171. float m_flDeferUntil;
  172. int m_iNumEnemiesInSafeZone;
  173. CUtlVector<busysafezone_t>m_SafeZones;
  174. DEFINE_CUSTOM_SCHEDULE_PROVIDER;
  175. };
  176. //-----------------------------------------------------------------------------
  177. // Purpose: A level tool to control the actbusy behavior.
  178. //-----------------------------------------------------------------------------
  179. class CAI_ActBusyGoal : public CAI_GoalEntity
  180. {
  181. DECLARE_CLASS( CAI_ActBusyGoal, CAI_GoalEntity );
  182. public:
  183. CAI_ActBusyGoal()
  184. {
  185. // Support legacy maps, where this value used to be set from a constant (with a value of 1).
  186. // Now designers can specify whatever they want in Hammer. Take care of old maps by setting
  187. // this in the constructor. (sjb)
  188. m_flSeeEntityTimeout = 1;
  189. }
  190. virtual void NPCMovingToBusy( CAI_BaseNPC *pNPC );
  191. virtual void NPCAbortedMoveTo( CAI_BaseNPC *pNPC );
  192. virtual void NPCStartedBusy( CAI_BaseNPC *pNPC );
  193. virtual void NPCStartedLeavingBusy( CAI_BaseNPC *pNPC );
  194. virtual void NPCFinishedBusy( CAI_BaseNPC *pNPC );
  195. virtual void NPCLeft( CAI_BaseNPC *pNPC );
  196. virtual void NPCLostSeeEntity( CAI_BaseNPC *pNPC );
  197. virtual void NPCSeeEnemy( CAI_BaseNPC *pNPC );
  198. int GetType() { return m_iType; }
  199. bool IsCombatActBusyTeleportAllowed() { return m_bAllowCombatActBusyTeleport; }
  200. protected:
  201. CAI_ActBusyBehavior *GetBusyBehaviorForNPC( const char *pszActorName, CBaseEntity *pActivator, CBaseEntity *pCaller, const char *sInputName );
  202. CAI_ActBusyBehavior *GetBusyBehaviorForNPC( CBaseEntity *pEntity, const char *sInputName );
  203. void EnableGoal( CAI_BaseNPC *pAI );
  204. // Inputs
  205. virtual void InputActivate( inputdata_t &inputdata );
  206. virtual void InputDeactivate( inputdata_t &inputdata );
  207. void InputSetBusySearchRange( inputdata_t &inputdata );
  208. void InputForceNPCToActBusy( inputdata_t &inputdata );
  209. void InputForceThisNPCToActBusy( inputdata_t &inputdata );
  210. void InputForceThisNPCToLeave( inputdata_t &inputdata );
  211. DECLARE_DATADESC();
  212. protected:
  213. float m_flBusySearchRange;
  214. bool m_bVisibleOnly;
  215. int m_iType;
  216. bool m_bAllowCombatActBusyTeleport;
  217. public:
  218. // Let the actbusy behavior query these so we don't have to duplicate the data.
  219. string_t m_iszSeeEntityName;
  220. float m_flSeeEntityTimeout;
  221. string_t m_iszSafeZoneVolume;
  222. int m_iSightMethod;
  223. protected:
  224. COutputEHANDLE m_OnNPCStartedBusy;
  225. COutputEHANDLE m_OnNPCFinishedBusy;
  226. COutputEHANDLE m_OnNPCLeft;
  227. COutputEHANDLE m_OnNPCLostSeeEntity;
  228. COutputEHANDLE m_OnNPCSeeEnemy;
  229. };
  230. // Maximum number of nodes allowed in an actbusy queue
  231. #define MAX_QUEUE_NODES 20
  232. //-----------------------------------------------------------------------------
  233. // Purpose: A level tool to control the actbusy behavior to create NPC queues
  234. //-----------------------------------------------------------------------------
  235. class CAI_ActBusyQueueGoal : public CAI_ActBusyGoal
  236. {
  237. DECLARE_CLASS( CAI_ActBusyQueueGoal, CAI_ActBusyGoal );
  238. public:
  239. virtual void Spawn( void );
  240. virtual void DrawDebugGeometryOverlays( void );
  241. virtual void NPCMovingToBusy( CAI_BaseNPC *pNPC );
  242. virtual void NPCStartedBusy( CAI_BaseNPC *pNPC );
  243. virtual void NPCAbortedMoveTo( CAI_BaseNPC *pNPC );
  244. virtual void NPCFinishedBusy( CAI_BaseNPC *pNPC );
  245. virtual void NPCStartedLeavingBusy( CAI_BaseNPC *pNPC );
  246. virtual void InputActivate( inputdata_t &inputdata );
  247. void InputPlayerStartedBlocking( inputdata_t &inputdata );
  248. void InputPlayerStoppedBlocking( inputdata_t &inputdata );
  249. void InputMoveQueueUp( inputdata_t &inputdata );
  250. void PushNPCBackInQueue( CAI_BaseNPC *pNPC, int iStartingNode );
  251. void RemoveNPCFromQueue( CAI_BaseNPC *pNPC );
  252. void RecalculateQueueCount( void );
  253. void QueueThink( void );
  254. void MoveQueueUp( void );
  255. void MoveQueueUpThink( void );
  256. bool NodeIsOccupied( int i );
  257. CAI_BaseNPC *GetNPCOnNode( int iNode );
  258. CAI_ActBusyBehavior *GetQueueBehaviorForNPC( CAI_BaseNPC *pNPC );
  259. DECLARE_DATADESC();
  260. private:
  261. int m_iCurrentQueueCount;
  262. CHandle<CAI_Hint> m_hNodes[ MAX_QUEUE_NODES ];
  263. bool m_bPlayerBlockedNodes[ MAX_QUEUE_NODES ];
  264. EHANDLE m_hExitNode;
  265. EHANDLE m_hExitingNPC;
  266. bool m_bForceReachFront;
  267. // Read from mapdata
  268. string_t m_iszNodes[ MAX_QUEUE_NODES ];
  269. string_t m_iszExitNode;
  270. // Outputs
  271. COutputInt m_OnQueueMoved;
  272. COutputEHANDLE m_OnNPCLeftQueue;
  273. COutputEHANDLE m_OnNPCStartedLeavingQueue;
  274. };
  275. #endif // AI_BEHAVIOR_ACTBUSY_H