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.

302 lines
9.3 KiB

  1. // NextBotInterface.h
  2. // Interface for NextBot
  3. // Author: Michael Booth, May 2006
  4. //========= Copyright Valve Corporation, All rights reserved. ============//
  5. #ifndef _NEXT_BOT_INTERFACE_H_
  6. #define _NEXT_BOT_INTERFACE_H_
  7. #include "NextBot/NextBotKnownEntity.h"
  8. #include "NextBotComponentInterface.h"
  9. #include "NextBotLocomotionInterface.h"
  10. #include "NextBotBodyInterface.h"
  11. #include "NextBotIntentionInterface.h"
  12. #include "NextBotVisionInterface.h"
  13. #include "NextBotDebug.h"
  14. class CBaseCombatCharacter;
  15. class PathFollower;
  16. //----------------------------------------------------------------------------------------------------------------
  17. /**
  18. * A general purpose filter interface for various bot systems
  19. */
  20. class INextBotFilter
  21. {
  22. public:
  23. virtual bool IsSelected( const CBaseEntity *candidate ) const = 0; // return true if this entity passes the filter
  24. };
  25. //----------------------------------------------------------------------------------------------------------------
  26. class INextBot : public INextBotEventResponder
  27. {
  28. public:
  29. INextBot( void );
  30. virtual ~INextBot();
  31. int GetBotId() const;
  32. bool BeginUpdate();
  33. void EndUpdate();
  34. virtual void Reset( void ); // (EXTEND) reset to initial state
  35. virtual void Update( void ); // (EXTEND) update internal state
  36. virtual void Upkeep( void ); // (EXTEND) lightweight update guaranteed to occur every server tick
  37. void FlagForUpdate( bool b = true );
  38. bool IsFlaggedForUpdate();
  39. int GetTickLastUpdate() const;
  40. void SetTickLastUpdate( int );
  41. virtual bool IsRemovedOnReset( void ) const { return true; } // remove this bot when the NextBot manager calls Reset
  42. virtual CBaseCombatCharacter *GetEntity( void ) const = 0;
  43. virtual class NextBotCombatCharacter *GetNextBotCombatCharacter( void ) const { return NULL; }
  44. #ifdef TERROR
  45. virtual class SurvivorBot *MySurvivorBotPointer() const { return NULL; }
  46. #endif
  47. // interfaces are never NULL - return base no-op interfaces at a minimum
  48. virtual ILocomotion * GetLocomotionInterface( void ) const;
  49. virtual IBody * GetBodyInterface( void ) const;
  50. virtual IIntention * GetIntentionInterface( void ) const;
  51. virtual IVision * GetVisionInterface( void ) const;
  52. /**
  53. * Attempt to change the bot's position. Return true if successful.
  54. */
  55. virtual bool SetPosition( const Vector &pos );
  56. virtual const Vector &GetPosition( void ) const; // get the global position of the bot
  57. /**
  58. * Friend/enemy/neutral queries
  59. */
  60. virtual bool IsEnemy( const CBaseEntity *them ) const; // return true if given entity is our enemy
  61. virtual bool IsFriend( const CBaseEntity *them ) const; // return true if given entity is our friend
  62. virtual bool IsSelf( const CBaseEntity *them ) const; // return true if 'them' is actually me
  63. /**
  64. * Can we climb onto this entity?
  65. */
  66. virtual bool IsAbleToClimbOnto( const CBaseEntity *object ) const;
  67. /**
  68. * Can we break this entity?
  69. */
  70. virtual bool IsAbleToBreak( const CBaseEntity *object ) const;
  71. /**
  72. * Sometimes we want to pass through other NextBots. OnContact() will always
  73. * be invoked, but collision resolution can be skipped if this
  74. * method returns false.
  75. */
  76. virtual bool IsAbleToBlockMovementOf( const INextBot *botInMotion ) const { return true; }
  77. /**
  78. * Should we ever care about noticing physical contact with this entity?
  79. */
  80. virtual bool ShouldTouch( const CBaseEntity *object ) const { return true; }
  81. /**
  82. * This immobile system is used to track the global state of "am I actually moving or not".
  83. * The OnStuck() event is only emitted when following a path, and paths can be recomputed, etc.
  84. */
  85. virtual bool IsImmobile( void ) const; // return true if we haven't moved in awhile
  86. virtual float GetImmobileDuration( void ) const; // how long have we been immobile
  87. virtual void ClearImmobileStatus( void );
  88. virtual float GetImmobileSpeedThreshold( void ) const; // return units/second below which this actor is considered "immobile"
  89. /**
  90. * Get the last PathFollower we followed. This method gives other interfaces a
  91. * single accessor to the most recent Path being followed by the myriad of
  92. * different PathFollowers used in the various behaviors the bot may be doing.
  93. */
  94. virtual const PathFollower *GetCurrentPath( void ) const;
  95. virtual void SetCurrentPath( const PathFollower *path );
  96. virtual void NotifyPathDestruction( const PathFollower *path ); // this PathFollower is going away, which may or may not be ours
  97. // between distance utility methods
  98. virtual bool IsRangeLessThan( CBaseEntity *subject, float range ) const;
  99. virtual bool IsRangeLessThan( const Vector &pos, float range ) const;
  100. virtual bool IsRangeGreaterThan( CBaseEntity *subject, float range ) const;
  101. virtual bool IsRangeGreaterThan( const Vector &pos, float range ) const;
  102. virtual float GetRangeTo( CBaseEntity *subject ) const;
  103. virtual float GetRangeTo( const Vector &pos ) const;
  104. virtual float GetRangeSquaredTo( CBaseEntity *subject ) const;
  105. virtual float GetRangeSquaredTo( const Vector &pos ) const;
  106. // event propagation
  107. virtual INextBotEventResponder *FirstContainedResponder( void ) const;
  108. virtual INextBotEventResponder *NextContainedResponder( INextBotEventResponder *current ) const;
  109. virtual bool IsDebugging( unsigned int type ) const; // return true if this bot is debugging any of the given types
  110. virtual const char *GetDebugIdentifier( void ) const; // return the name of this bot for debugging purposes
  111. virtual bool IsDebugFilterMatch( const char *name ) const; // return true if we match the given debug symbol
  112. virtual void DisplayDebugText( const char *text ) const; // show a line of text on the bot in the world
  113. void DebugConColorMsg( NextBotDebugType debugType, const Color &color, PRINTF_FORMAT_STRING const char *fmt, ... );
  114. enum {
  115. MAX_NEXTBOT_DEBUG_HISTORY = 100,
  116. MAX_NEXTBOT_DEBUG_LINE_LENGTH = 256,
  117. };
  118. struct NextBotDebugLineType
  119. {
  120. NextBotDebugType debugType;
  121. char data[ MAX_NEXTBOT_DEBUG_LINE_LENGTH ];
  122. };
  123. void GetDebugHistory( unsigned int type, CUtlVector< const NextBotDebugLineType * > *lines ) const; // build a vector of debug history of the given types
  124. //------------------------------------------------------------------------------
  125. private:
  126. friend class INextBotComponent;
  127. void RegisterComponent( INextBotComponent *comp ); // components call this to register themselves with the bot that contains them
  128. INextBotComponent *m_componentList; // the first component
  129. const PathFollower *m_currentPath; // the path we most recently followed
  130. int m_id;
  131. bool m_bFlaggedForUpdate;
  132. int m_tickLastUpdate;
  133. unsigned int m_debugType;
  134. mutable int m_debugDisplayLine;
  135. Vector m_immobileAnchor;
  136. CountdownTimer m_immobileCheckTimer;
  137. IntervalTimer m_immobileTimer;
  138. void UpdateImmobileStatus( void );
  139. mutable ILocomotion *m_baseLocomotion;
  140. mutable IBody *m_baseBody;
  141. mutable IIntention *m_baseIntention;
  142. mutable IVision *m_baseVision;
  143. //mutable IAttention *m_baseAttention;
  144. // Debugging info
  145. void ResetDebugHistory( void );
  146. CUtlVector< NextBotDebugLineType * > m_debugHistory;
  147. };
  148. inline const PathFollower *INextBot::GetCurrentPath( void ) const
  149. {
  150. return m_currentPath;
  151. }
  152. inline void INextBot::SetCurrentPath( const PathFollower *path )
  153. {
  154. m_currentPath = path;
  155. }
  156. inline void INextBot::NotifyPathDestruction( const PathFollower *path )
  157. {
  158. if ( m_currentPath == path )
  159. m_currentPath = NULL;
  160. }
  161. inline ILocomotion *INextBot::GetLocomotionInterface( void ) const
  162. {
  163. // these base interfaces are lazy-allocated (instead of being fully instanced classes) for two reasons:
  164. // 1) so the memory is only used if needed
  165. // 2) so the component is registered properly
  166. if ( m_baseLocomotion == NULL )
  167. {
  168. m_baseLocomotion = new ILocomotion( const_cast< INextBot * >( this ) );
  169. }
  170. return m_baseLocomotion;
  171. }
  172. inline IBody *INextBot::GetBodyInterface( void ) const
  173. {
  174. if ( m_baseBody == NULL )
  175. {
  176. m_baseBody = new IBody( const_cast< INextBot * >( this ) );
  177. }
  178. return m_baseBody;
  179. }
  180. inline IIntention *INextBot::GetIntentionInterface( void ) const
  181. {
  182. if ( m_baseIntention == NULL )
  183. {
  184. m_baseIntention = new IIntention( const_cast< INextBot * >( this ) );
  185. }
  186. return m_baseIntention;
  187. }
  188. inline IVision *INextBot::GetVisionInterface( void ) const
  189. {
  190. if ( m_baseVision == NULL )
  191. {
  192. m_baseVision = new IVision( const_cast< INextBot * >( this ) );
  193. }
  194. return m_baseVision;
  195. }
  196. inline int INextBot::GetBotId() const
  197. {
  198. return m_id;
  199. }
  200. inline void INextBot::FlagForUpdate( bool b )
  201. {
  202. m_bFlaggedForUpdate = b;
  203. }
  204. inline bool INextBot::IsFlaggedForUpdate()
  205. {
  206. return m_bFlaggedForUpdate;
  207. }
  208. inline int INextBot::GetTickLastUpdate() const
  209. {
  210. return m_tickLastUpdate;
  211. }
  212. inline void INextBot::SetTickLastUpdate( int tick )
  213. {
  214. m_tickLastUpdate = tick;
  215. }
  216. inline bool INextBot::IsImmobile( void ) const
  217. {
  218. return m_immobileTimer.HasStarted();
  219. }
  220. inline float INextBot::GetImmobileDuration( void ) const
  221. {
  222. return m_immobileTimer.GetElapsedTime();
  223. }
  224. inline void INextBot::ClearImmobileStatus( void )
  225. {
  226. m_immobileTimer.Invalidate();
  227. m_immobileAnchor = GetEntity()->GetAbsOrigin();
  228. }
  229. inline float INextBot::GetImmobileSpeedThreshold( void ) const
  230. {
  231. return 30.0f;
  232. }
  233. inline INextBotEventResponder *INextBot::FirstContainedResponder( void ) const
  234. {
  235. return m_componentList;
  236. }
  237. inline INextBotEventResponder *INextBot::NextContainedResponder( INextBotEventResponder *current ) const
  238. {
  239. return static_cast< INextBotComponent * >( current )->m_nextComponent;
  240. }
  241. #endif // _NEXT_BOT_INTERFACE_H_