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.

226 lines
7.6 KiB

  1. // NextBotVisionInterface.h
  2. // Visual information query interface for bots
  3. // Author: Michael Booth, April 2005
  4. //========= Copyright Valve Corporation, All rights reserved. ============//
  5. #ifndef _NEXT_BOT_VISION_INTERFACE_H_
  6. #define _NEXT_BOT_VISION_INTERFACE_H_
  7. #include "NextBotComponentInterface.h"
  8. #include "NextBotKnownEntity.h"
  9. class IBody;
  10. class INextBotEntityFilter;
  11. //----------------------------------------------------------------------------------------------------------------
  12. /**
  13. * The interface for HOW the bot sees (near sighted? night vision? etc)
  14. */
  15. class IVision : public INextBotComponent
  16. {
  17. public:
  18. IVision( INextBot *bot );
  19. virtual ~IVision() { }
  20. virtual void Reset( void ); // reset to initial state
  21. virtual void Update( void ); // update internal state
  22. //-- attention/short term memory interface follows ------------------------------------------
  23. //
  24. // WARNING: Do not keep CKnownEntity pointers returned by these methods, as they can be invalidated/freed
  25. //
  26. /**
  27. * Iterate each interesting entity we are aware of.
  28. * If functor returns false, stop iterating and return false.
  29. * NOTE: known.GetEntity() is guaranteed to be non-NULL
  30. */
  31. class IForEachKnownEntity
  32. {
  33. public:
  34. virtual bool Inspect( const CKnownEntity &known ) = 0;
  35. };
  36. virtual bool ForEachKnownEntity( IForEachKnownEntity &func );
  37. virtual void CollectKnownEntities( CUtlVector< CKnownEntity > *knownVector ); // populate given vector with all currently known entities
  38. virtual const CKnownEntity *GetPrimaryKnownThreat( bool onlyVisibleThreats = false ) const; // return the biggest threat to ourselves that we are aware of
  39. virtual float GetTimeSinceVisible( int team ) const; // return time since we saw any member of the given team
  40. virtual const CKnownEntity *GetClosestKnown( int team = TEAM_ANY ) const; // return the closest known entity
  41. virtual int GetKnownCount( int team, bool onlyVisible = false, float rangeLimit = -1.0f ) const; // return the number of entities on the given team known to us closer than rangeLimit
  42. virtual const CKnownEntity *GetClosestKnown( const INextBotEntityFilter &filter ) const; // return the closest known entity that passes the given filter
  43. virtual const CKnownEntity *GetKnown( const CBaseEntity *entity ) const; // given an entity, return our known version of it (or NULL if we don't know of it)
  44. // Introduce a known entity into the system. Its position is assumed to be known
  45. // and will be updated, and it is assumed to not yet have been seen by us, allowing for learning
  46. // of known entities by being told about them, hearing them, etc.
  47. virtual void AddKnownEntity( CBaseEntity *entity );
  48. virtual void ForgetEntity( CBaseEntity *forgetMe ); // remove the given entity from our awareness (whether we know if it or not)
  49. virtual void ForgetAllKnownEntities( void );
  50. //-- physical vision interface follows ------------------------------------------------------
  51. /**
  52. * Populate "potentiallyVisible" with the set of all entities we could potentially see.
  53. * Entities in this set will be tested for visibility/recognition in IVision::Update()
  54. */
  55. virtual void CollectPotentiallyVisibleEntities( CUtlVector< CBaseEntity * > *potentiallyVisible );
  56. virtual float GetMaxVisionRange( void ) const; // return maximum distance vision can reach
  57. virtual float GetMinRecognizeTime( void ) const; // return VISUAL reaction time
  58. /**
  59. * IsAbleToSee() returns true if the viewer can ACTUALLY SEE the subject or position,
  60. * taking into account blindness, smoke effects, invisibility, etc.
  61. * If 'visibleSpot' is non-NULL, the highest priority spot on the subject that is visible is returned.
  62. */
  63. enum FieldOfViewCheckType { USE_FOV, DISREGARD_FOV };
  64. virtual bool IsAbleToSee( CBaseEntity *subject, FieldOfViewCheckType checkFOV, Vector *visibleSpot = NULL ) const;
  65. virtual bool IsAbleToSee( const Vector &pos, FieldOfViewCheckType checkFOV ) const;
  66. virtual bool IsIgnored( CBaseEntity *subject ) const; // return true to completely ignore this entity (may not be in sight when this is called)
  67. virtual bool IsVisibleEntityNoticed( CBaseEntity *subject ) const; // return true if we 'notice' the subject, even though we have LOS to it
  68. /**
  69. * Check if 'subject' is within the viewer's field of view
  70. */
  71. virtual bool IsInFieldOfView( const Vector &pos ) const;
  72. virtual bool IsInFieldOfView( CBaseEntity *subject ) const;
  73. virtual float GetDefaultFieldOfView( void ) const; // return default FOV in degrees
  74. virtual float GetFieldOfView( void ) const; // return FOV in degrees
  75. virtual void SetFieldOfView( float horizAngle ); // angle given in degrees
  76. virtual bool IsLineOfSightClear( const Vector &pos ) const; // return true if the ray to the given point is unobstructed
  77. /**
  78. * Returns true if the ray between the position and the subject is unobstructed.
  79. * A visible spot on the subject is returned in 'visibleSpot'.
  80. */
  81. virtual bool IsLineOfSightClearToEntity( const CBaseEntity *subject, Vector *visibleSpot = NULL ) const;
  82. /// @todo: Implement LookAt system
  83. virtual bool IsLookingAt( const Vector &pos, float cosTolerance = 0.95f ) const; // are we looking at the given position
  84. virtual bool IsLookingAt( const CBaseCombatCharacter *actor, float cosTolerance = 0.95f ) const; // are we looking at the given actor
  85. private:
  86. CountdownTimer m_scanTimer; // for throttling update rate
  87. float m_FOV; // current FOV in degrees
  88. float m_cosHalfFOV; // the cosine of FOV/2
  89. CUtlVector< CKnownEntity > m_knownEntityVector; // the set of enemies/friends we are aware of
  90. void UpdateKnownEntities( void );
  91. bool IsAwareOf( const CKnownEntity &known ) const; // return true if our reaction time has passed for this entity
  92. mutable CHandle< CBaseEntity > m_primaryThreat;
  93. float m_lastVisionUpdateTimestamp;
  94. IntervalTimer m_notVisibleTimer[ MAX_TEAMS ]; // for tracking interval since last saw a member of the given team
  95. };
  96. inline void IVision::CollectKnownEntities( CUtlVector< CKnownEntity > *knownVector )
  97. {
  98. if ( knownVector )
  99. {
  100. knownVector->RemoveAll();
  101. for( int i=0; i<m_knownEntityVector.Count(); ++i )
  102. {
  103. if ( !m_knownEntityVector[i].IsObsolete() )
  104. {
  105. knownVector->AddToTail( m_knownEntityVector[i] );
  106. }
  107. }
  108. }
  109. }
  110. inline float IVision::GetDefaultFieldOfView( void ) const
  111. {
  112. return 90.0f;
  113. }
  114. inline float IVision::GetFieldOfView( void ) const
  115. {
  116. return m_FOV;
  117. }
  118. inline float IVision::GetTimeSinceVisible( int team ) const
  119. {
  120. if ( team == TEAM_ANY )
  121. {
  122. // return minimum time
  123. float time = 9999999999.9f;
  124. for( int i=0; i<MAX_TEAMS; ++i )
  125. {
  126. if ( m_notVisibleTimer[i].HasStarted() )
  127. {
  128. if ( time > m_notVisibleTimer[i].GetElapsedTime() )
  129. {
  130. team = m_notVisibleTimer[i].GetElapsedTime();
  131. }
  132. }
  133. }
  134. return time;
  135. }
  136. if ( team >= 0 && team < MAX_TEAMS )
  137. {
  138. return m_notVisibleTimer[ team ].GetElapsedTime();
  139. }
  140. return 0.0f;
  141. }
  142. inline bool IVision::IsAwareOf( const CKnownEntity &known ) const
  143. {
  144. return known.GetTimeSinceBecameKnown() >= GetMinRecognizeTime();
  145. }
  146. inline bool IVision::ForEachKnownEntity( IVision::IForEachKnownEntity &func )
  147. {
  148. for( int i=0; i<m_knownEntityVector.Count(); ++i )
  149. {
  150. const CKnownEntity &known = m_knownEntityVector[i];
  151. if ( !known.IsObsolete() && IsAwareOf( known ) )
  152. {
  153. if ( func.Inspect( known ) == false )
  154. {
  155. return false;
  156. }
  157. }
  158. }
  159. return true;
  160. }
  161. inline bool IVision::IsVisibleEntityNoticed( CBaseEntity *subject ) const
  162. {
  163. return true;
  164. }
  165. inline bool IVision::IsIgnored( CBaseEntity *subject ) const
  166. {
  167. return false;
  168. }
  169. inline float IVision::GetMaxVisionRange( void ) const
  170. {
  171. return 2000.0f;
  172. }
  173. inline float IVision::GetMinRecognizeTime( void ) const
  174. {
  175. return 0.0f;
  176. }
  177. #endif // _NEXT_BOT_VISION_INTERFACE_H_