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.

335 lines
12 KiB

  1. // NextBotLocomotionInterface.h
  2. // NextBot interface for movement through the environment
  3. // Author: Michael Booth, April 2005
  4. //========= Copyright Valve Corporation, All rights reserved. ============//
  5. #ifndef _NEXT_BOT_LOCOMOTION_INTERFACE_H_
  6. #define _NEXT_BOT_LOCOMOTION_INTERFACE_H_
  7. #include "NextBotComponentInterface.h"
  8. class Path;
  9. class INextBot;
  10. class CNavLadder;
  11. //----------------------------------------------------------------------------------------------------------------
  12. /**
  13. * The interface encapsulating *how* a bot moves through the world (walking? flying? etc)
  14. */
  15. class ILocomotion : public INextBotComponent
  16. {
  17. public:
  18. ILocomotion( INextBot *bot );
  19. virtual ~ILocomotion();
  20. virtual void Reset( void ); // (EXTEND) reset to initial state
  21. virtual void Update( void ); // (EXTEND) update internal state
  22. //
  23. // The primary locomotive method
  24. // Depending on the physics of the bot's motion, it may not actually
  25. // reach the given position precisely.
  26. // The 'weight' can be used to combine multiple Approach() calls within
  27. // a single frame into a single goal (ie: weighted average)
  28. //
  29. virtual void Approach( const Vector &goalPos, float goalWeight = 1.0f ); // (EXTEND) move directly towards the given position
  30. //
  31. // Move the bot to the precise given position immediately,
  32. // updating internal state as needed
  33. // Collision resolution is done to prevent interpenetration, which may prevent
  34. // the bot from reaching the given position. If no collisions occur, the
  35. // bot will be at the given position when this method returns.
  36. //
  37. virtual void DriveTo( const Vector &pos ); // (EXTEND) Move the bot to the precise given position immediately,
  38. //
  39. // Locomotion modifiers
  40. //
  41. virtual bool ClimbUpToLedge( const Vector &landingGoal, const Vector &landingForward, const CBaseEntity *obstacle ) { return true; } // initiate a jump to an adjacent high ledge, return false if climb can't start
  42. virtual void JumpAcrossGap( const Vector &landingGoal, const Vector &landingForward ) { } // initiate a jump across an empty volume of space to far side
  43. virtual void Jump( void ) { } // initiate a simple undirected jump in the air
  44. virtual bool IsClimbingOrJumping( void ) const; // is jumping in any form
  45. virtual bool IsClimbingUpToLedge( void ) const; // is climbing up to a high ledge
  46. virtual bool IsJumpingAcrossGap( void ) const; // is jumping across a gap to the far side
  47. virtual bool IsScrambling( void ) const; // is in the middle of a complex action (climbing a ladder, climbing a ledge, jumping, etc) that shouldn't be interrupted
  48. virtual void Run( void ) { } // set desired movement speed to running
  49. virtual void Walk( void ) { } // set desired movement speed to walking
  50. virtual void Stop( void ) { } // set desired movement speed to stopped
  51. virtual bool IsRunning( void ) const;
  52. virtual void SetDesiredSpeed( float speed ) { } // set desired speed for locomotor movement
  53. virtual float GetDesiredSpeed( void ) const; // returns the current desired speed
  54. virtual void SetSpeedLimit( float speed ) { } // set maximum speed bot can reach, regardless of desired speed
  55. virtual float GetSpeedLimit( void ) const { return 1000.0f; } // get maximum speed bot can reach, regardless of desired speed
  56. virtual bool IsOnGround( void ) const; // return true if standing on something
  57. virtual void OnLeaveGround( CBaseEntity *ground ) { } // invoked when bot leaves ground for any reason
  58. virtual void OnLandOnGround( CBaseEntity *ground ) { } // invoked when bot lands on the ground after being in the air
  59. virtual CBaseEntity *GetGround( void ) const; // return the current ground entity or NULL if not on the ground
  60. virtual const Vector &GetGroundNormal( void ) const; // surface normal of the ground we are in contact with
  61. virtual float GetGroundSpeed( void ) const; // return current world space speed in XY plane
  62. virtual const Vector &GetGroundMotionVector( void ) const; // return unit vector in XY plane describing our direction of motion - even if we are currently not moving
  63. virtual void ClimbLadder( const CNavLadder *ladder, const CNavArea *dismountGoal ) { } // climb the given ladder to the top and dismount
  64. virtual void DescendLadder( const CNavLadder *ladder, const CNavArea *dismountGoal ) { } // descend the given ladder to the bottom and dismount
  65. virtual bool IsUsingLadder( void ) const; // we are moving to get on, ascending/descending, and/or dismounting a ladder
  66. virtual bool IsAscendingOrDescendingLadder( void ) const; // we are actually on the ladder right now, either climbing up or down
  67. virtual bool IsAbleToAutoCenterOnLadder( void ) const { return false; }
  68. virtual void FaceTowards( const Vector &target ) { } // rotate body to face towards "target"
  69. virtual void SetDesiredLean( const QAngle &lean ) { }
  70. virtual const QAngle &GetDesiredLean( void ) const;
  71. //
  72. // Locomotion information
  73. //
  74. virtual bool IsAbleToJumpAcrossGaps( void ) const; // return true if this bot can jump across gaps in its path
  75. virtual bool IsAbleToClimb( void ) const; // return true if this bot can climb arbitrary geometry it encounters
  76. virtual const Vector &GetFeet( void ) const; // return position of "feet" - the driving point where the bot contacts the ground
  77. virtual float GetStepHeight( void ) const; // if delta Z is greater than this, we have to jump to get up
  78. virtual float GetMaxJumpHeight( void ) const; // return maximum height of a jump
  79. virtual float GetDeathDropHeight( void ) const; // distance at which we will die if we fall
  80. virtual float GetRunSpeed( void ) const; // get maximum running speed
  81. virtual float GetWalkSpeed( void ) const; // get maximum walking speed
  82. virtual float GetMaxAcceleration( void ) const; // return maximum acceleration of locomotor
  83. virtual float GetMaxDeceleration( void ) const; // return maximum deceleration of locomotor
  84. virtual const Vector &GetVelocity( void ) const; // return current world space velocity
  85. virtual float GetSpeed( void ) const; // return current world space speed (magnitude of velocity)
  86. virtual const Vector &GetMotionVector( void ) const; // return unit vector describing our direction of motion - even if we are currently not moving
  87. virtual bool IsAreaTraversable( const CNavArea *baseArea ) const; // return true if given area can be used for navigation
  88. virtual float GetTraversableSlopeLimit( void ) const; // return Z component of unit normal of steepest traversable slope
  89. // return true if the given entity can be ignored during locomotion
  90. enum TraverseWhenType
  91. {
  92. IMMEDIATELY, // the entity will not block our motion - we'll carry right through
  93. EVENTUALLY // the entity will block us until we spend effort to open/destroy it
  94. };
  95. /**
  96. * Return true if this locomotor could potentially move along the line given.
  97. * If false is returned, fraction of walkable ray is returned in 'fraction'
  98. */
  99. virtual bool IsPotentiallyTraversable( const Vector &from, const Vector &to, TraverseWhenType when = EVENTUALLY, float *fraction = NULL ) const;
  100. /**
  101. * Return true if there is a possible "gap" that will need to be jumped over
  102. * If true is returned, fraction of ray before gap is returned in 'fraction'
  103. */
  104. virtual bool HasPotentialGap( const Vector &from, const Vector &to, float *fraction = NULL ) const;
  105. // return true if there is a "gap" here when moving in the given direction
  106. virtual bool IsGap( const Vector &pos, const Vector &forward ) const;
  107. virtual bool IsEntityTraversable( CBaseEntity *obstacle, TraverseWhenType when = EVENTUALLY ) const;
  108. //
  109. // Stuck state. If the locomotor cannot make progress, it becomes "stuck" and can only leave
  110. // this stuck state by successfully moving and becoming un-stuck.
  111. //
  112. virtual bool IsStuck( void ) const; // return true if bot is stuck
  113. virtual float GetStuckDuration( void ) const; // return how long we've been stuck
  114. virtual void ClearStuckStatus( const char *reason = "" ); // reset stuck status to un-stuck
  115. virtual bool IsAttemptingToMove( void ) const; // return true if we have tried to Approach() or DriveTo() very recently
  116. void TraceHull( const Vector& start, const Vector& end, const Vector &mins, const Vector &maxs, unsigned int fMask, ITraceFilter *pFilter, trace_t *pTrace ) const;
  117. /**
  118. * Should we collide with this entity?
  119. */
  120. virtual bool ShouldCollideWith( const CBaseEntity *object ) const { return true; }
  121. protected:
  122. virtual void AdjustPosture( const Vector &moveGoal );
  123. virtual void StuckMonitor( void );
  124. private:
  125. Vector m_motionVector;
  126. Vector m_groundMotionVector;
  127. float m_speed;
  128. float m_groundSpeed;
  129. // stuck monitoring
  130. bool m_isStuck; // if true, we are stuck
  131. IntervalTimer m_stuckTimer; // how long we've been stuck
  132. CountdownTimer m_stillStuckTimer; // for resending stuck events
  133. Vector m_stuckPos; // where we got stuck
  134. IntervalTimer m_moveRequestTimer;
  135. };
  136. inline bool ILocomotion::IsAbleToJumpAcrossGaps( void ) const
  137. {
  138. return true;
  139. }
  140. inline bool ILocomotion::IsAbleToClimb( void ) const
  141. {
  142. return true;
  143. }
  144. inline bool ILocomotion::IsAttemptingToMove( void ) const
  145. {
  146. return m_moveRequestTimer.HasStarted() && m_moveRequestTimer.GetElapsedTime() < 0.25f;
  147. }
  148. inline bool ILocomotion::IsScrambling( void ) const
  149. {
  150. return !IsOnGround() || IsClimbingOrJumping() || IsAscendingOrDescendingLadder();
  151. }
  152. inline bool ILocomotion::IsClimbingOrJumping( void ) const
  153. {
  154. return false;
  155. }
  156. inline bool ILocomotion::IsClimbingUpToLedge( void ) const
  157. {
  158. return false;
  159. }
  160. inline bool ILocomotion::IsJumpingAcrossGap( void ) const
  161. {
  162. return false;
  163. }
  164. inline bool ILocomotion::IsRunning( void ) const
  165. {
  166. return false;
  167. }
  168. inline float ILocomotion::GetDesiredSpeed( void ) const
  169. {
  170. return 0.0f;
  171. }
  172. inline bool ILocomotion::IsOnGround( void ) const
  173. {
  174. return false;
  175. }
  176. inline CBaseEntity *ILocomotion::GetGround( void ) const
  177. {
  178. return NULL;
  179. }
  180. inline const Vector &ILocomotion::GetGroundNormal( void ) const
  181. {
  182. return vec3_origin;
  183. }
  184. inline float ILocomotion::GetGroundSpeed( void ) const
  185. {
  186. return m_groundSpeed;
  187. }
  188. inline const Vector & ILocomotion::GetGroundMotionVector( void ) const
  189. {
  190. return m_groundMotionVector;
  191. }
  192. inline bool ILocomotion::IsUsingLadder( void ) const
  193. {
  194. return false;
  195. }
  196. inline bool ILocomotion::IsAscendingOrDescendingLadder( void ) const
  197. {
  198. return false;
  199. }
  200. inline const QAngle &ILocomotion::GetDesiredLean( void ) const
  201. {
  202. return vec3_angle;
  203. }
  204. inline float ILocomotion::GetStepHeight( void ) const
  205. {
  206. return 0.0f;
  207. }
  208. inline float ILocomotion::GetMaxJumpHeight( void ) const
  209. {
  210. return 0.0f;
  211. }
  212. inline float ILocomotion::GetDeathDropHeight( void ) const
  213. {
  214. return 0.0f;
  215. }
  216. inline float ILocomotion::GetRunSpeed( void ) const
  217. {
  218. return 0.0f;
  219. }
  220. inline float ILocomotion::GetWalkSpeed( void ) const
  221. {
  222. return 0.0f;
  223. }
  224. inline float ILocomotion::GetMaxAcceleration( void ) const
  225. {
  226. return 0.0f;
  227. }
  228. inline float ILocomotion::GetMaxDeceleration( void ) const
  229. {
  230. return 0.0f;
  231. }
  232. inline const Vector &ILocomotion::GetVelocity( void ) const
  233. {
  234. return vec3_origin;
  235. }
  236. inline float ILocomotion::GetSpeed( void ) const
  237. {
  238. return m_speed;
  239. }
  240. inline const Vector & ILocomotion::GetMotionVector( void ) const
  241. {
  242. return m_motionVector;
  243. }
  244. inline float ILocomotion::GetTraversableSlopeLimit( void ) const
  245. {
  246. return 0.6;
  247. }
  248. inline bool ILocomotion::IsStuck( void ) const
  249. {
  250. return m_isStuck;
  251. }
  252. inline float ILocomotion::GetStuckDuration( void ) const
  253. {
  254. return ( IsStuck() ) ? m_stuckTimer.GetElapsedTime() : 0.0f;
  255. }
  256. inline void ILocomotion::TraceHull( const Vector& start, const Vector& end, const Vector &mins, const Vector &maxs, unsigned int fMask, ITraceFilter *pFilter, trace_t *pTrace ) const
  257. {
  258. // VPROF_BUDGET( "ILocomotion::TraceHull", "TraceHull" );
  259. Ray_t ray;
  260. ray.Init( start, end, mins, maxs );
  261. enginetrace->TraceRay( ray, fMask, pFilter, pTrace );
  262. }
  263. #endif // _NEXT_BOT_LOCOMOTION_INTERFACE_H_