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.

274 lines
10 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. // NextBotGroundLocomotion.h
  3. // Basic ground-based movement for NextBotCombatCharacters
  4. // Author: Michael Booth, February 2009
  5. // Note: This is a refactoring of ZombieBotLocomotion from L4D
  6. #ifndef NEXT_BOT_GROUND_LOCOMOTION_H
  7. #define NEXT_BOT_GROUND_LOCOMOTION_H
  8. #include "NextBotLocomotionInterface.h"
  9. #include "nav_mesh.h"
  10. class NextBotCombatCharacter;
  11. //----------------------------------------------------------------------------------------------------------------
  12. /**
  13. * Basic ground-based movement for NextBotCombatCharacters.
  14. * This locomotor resolves collisions and assumes a ground-based bot under the influence of gravity.
  15. */
  16. class NextBotGroundLocomotion : public ILocomotion
  17. {
  18. public:
  19. DECLARE_CLASS( NextBotGroundLocomotion, ILocomotion );
  20. NextBotGroundLocomotion( INextBot *bot );
  21. virtual ~NextBotGroundLocomotion();
  22. virtual void Reset( void ); // reset locomotor to initial state
  23. virtual void Update( void ); // update internal state
  24. virtual void Approach( const Vector &pos, float goalWeight = 1.0f ); // move directly towards the given position
  25. virtual void DriveTo( const Vector &pos ); // Move the bot to the precise given position immediately,
  26. virtual bool ClimbUpToLedge( const Vector &landingGoal, const Vector &landingForward, const CBaseEntity *obstacle ); // initiate a jump to an adjacent high ledge, return false if climb can't start
  27. virtual void JumpAcrossGap( const Vector &landingGoal, const Vector &landingForward ); // initiate a jump across an empty volume of space to far side
  28. virtual void Jump( void ); // initiate a simple undirected jump in the air
  29. virtual bool IsClimbingOrJumping( void ) const; // is jumping in any form
  30. virtual bool IsClimbingUpToLedge( void ) const; // is climbing up to a high ledge
  31. virtual bool IsJumpingAcrossGap( void ) const; // is jumping across a gap to the far side
  32. virtual void Run( void ); // set desired movement speed to running
  33. virtual void Walk( void ); // set desired movement speed to walking
  34. virtual void Stop( void ); // set desired movement speed to stopped
  35. virtual bool IsRunning( void ) const;
  36. virtual void SetDesiredSpeed( float speed ); // set desired speed for locomotor movement
  37. virtual float GetDesiredSpeed( void ) const; // returns the current desired speed
  38. virtual float GetSpeedLimit( void ) const; // get maximum speed bot can reach, regardless of desired speed
  39. virtual bool IsOnGround( void ) const; // return true if standing on something
  40. virtual void OnLeaveGround( CBaseEntity *ground ); // invoked when bot leaves ground for any reason
  41. virtual void OnLandOnGround( CBaseEntity *ground ); // invoked when bot lands on the ground after being in the air
  42. virtual CBaseEntity *GetGround( void ) const; // return the current ground entity or NULL if not on the ground
  43. virtual const Vector &GetGroundNormal( void ) const;// surface normal of the ground we are in contact with
  44. virtual void ClimbLadder( const CNavLadder *ladder, const CNavArea *dismountGoal ); // climb the given ladder to the top and dismount
  45. virtual void DescendLadder( const CNavLadder *ladder, const CNavArea *dismountGoal ); // descend the given ladder to the bottom and dismount
  46. virtual bool IsUsingLadder( void ) const;
  47. virtual bool IsAscendingOrDescendingLadder( void ) const; // we are actually on the ladder right now, either climbing up or down
  48. virtual void FaceTowards( const Vector &target ); // rotate body to face towards "target"
  49. virtual void SetDesiredLean( const QAngle &lean );
  50. virtual const QAngle &GetDesiredLean( void ) const;
  51. virtual const Vector &GetFeet( void ) const; // return position of "feet" - the driving point where the bot contacts the ground
  52. virtual float GetStepHeight( void ) const; // if delta Z is greater than this, we have to jump to get up
  53. virtual float GetMaxJumpHeight( void ) const; // return maximum height of a jump
  54. virtual float GetDeathDropHeight( void ) const; // distance at which we will die if we fall
  55. virtual float GetRunSpeed( void ) const; // get maximum running speed
  56. virtual float GetWalkSpeed( void ) const; // get maximum walking speed
  57. virtual float GetMaxAcceleration( void ) const; // return maximum acceleration of locomotor
  58. virtual float GetMaxDeceleration( void ) const; // return maximum deceleration of locomotor
  59. virtual const Vector &GetAcceleration( void ) const; // return current world space acceleration
  60. virtual void SetAcceleration( const Vector &accel ); // set world space acceleration
  61. virtual const Vector &GetVelocity( void ) const; // return current world space velocity
  62. virtual void SetVelocity( const Vector &vel ); // set world space velocity
  63. virtual void OnMoveToSuccess( const Path *path ); // invoked when an bot reaches its MoveTo goal
  64. virtual void OnMoveToFailure( const Path *path, MoveToFailureType reason ); // invoked when an bot fails to reach a MoveTo goal
  65. private:
  66. void UpdatePosition( const Vector &newPos ); // move to newPos, resolving any collisions along the way
  67. void UpdateGroundConstraint( void ); // keep ground solid
  68. Vector ResolveCollisionV0( Vector from, Vector to, int recursionLimit );
  69. Vector ResolveZombieCollisions( const Vector &pos ); // push away zombies that are interpenetrating
  70. Vector ResolveCollision( const Vector &from, const Vector &to, int recursionLimit ); // check for collisions along move
  71. bool DetectCollision( trace_t *pTrace, int &nDestructionAllowed, const Vector &from, const Vector &to, const Vector &vecMins, const Vector &vecMaxs );
  72. void ApplyAccumulatedApproach( void );
  73. bool DidJustJump( void ) const; // return true if we just started a jump
  74. bool TraverseLadder( void ); // return true if we are climbing a ladder
  75. virtual float GetGravity( void ) const; // return gravity force acting on bot
  76. virtual float GetFrictionForward( void ) const; // return magnitude of forward friction
  77. virtual float GetFrictionSideways( void ) const; // return magnitude of lateral friction
  78. virtual float GetMaxYawRate( void ) const; // return max rate of yaw rotation
  79. private:
  80. NextBotCombatCharacter *m_nextBot;
  81. Vector m_priorPos; // last update's position
  82. Vector m_lastValidPos; // last valid position (not interpenetrating)
  83. Vector m_acceleration;
  84. Vector m_velocity;
  85. float m_desiredSpeed; // speed bot wants to be moving
  86. float m_actualSpeed; // actual speed bot is moving
  87. float m_maxRunSpeed;
  88. float m_forwardLean;
  89. float m_sideLean;
  90. QAngle m_desiredLean;
  91. bool m_isJumping; // if true, we have jumped and have not yet hit the ground
  92. bool m_isJumpingAcrossGap; // if true, we have jumped across a gap and have not yet hit the ground
  93. EHANDLE m_ground; // have to manage this ourselves, since MOVETYPE_CUSTOM always NULLs out GetGroundEntity()
  94. Vector m_groundNormal; // surface normal of the ground we are in contact with
  95. bool m_isClimbingUpToLedge; // true if we are jumping up to an adjacent ledge
  96. Vector m_ledgeJumpGoalPos;
  97. bool m_isUsingFullFeetTrace; // true if we're in the air and tracing the lowest StepHeight in ResolveCollision
  98. const CNavLadder *m_ladder; // ladder we are currently climbing/descending
  99. const CNavArea *m_ladderDismountGoal; // the area we enter when finished with our ladder move
  100. bool m_isGoingUpLadder; // if false, we're going down
  101. CountdownTimer m_inhibitObstacleAvoidanceTimer; // when active, turn off path following feelers
  102. CountdownTimer m_wiggleTimer; // for wiggling
  103. NavRelativeDirType m_wiggleDirection;
  104. mutable Vector m_eyePos; // for use with GetEyes(), etc.
  105. Vector m_moveVector; // the direction of our motion in XY plane
  106. float m_moveYaw; // global yaw of movement direction
  107. Vector m_accumApproachVectors; // weighted sum of Approach() calls since last update
  108. float m_accumApproachWeights;
  109. bool m_bRecomputePostureOnCollision;
  110. CountdownTimer m_ignorePhysicsPropTimer; // if active, don't collide with physics props (because we got stuck in one)
  111. EHANDLE m_ignorePhysicsProp; // which prop to ignore
  112. };
  113. inline float NextBotGroundLocomotion::GetGravity( void ) const
  114. {
  115. return 1000.0f;
  116. }
  117. inline float NextBotGroundLocomotion::GetFrictionForward( void ) const
  118. {
  119. return 0.0f;
  120. }
  121. inline float NextBotGroundLocomotion::GetFrictionSideways( void ) const
  122. {
  123. return 3.0f;
  124. }
  125. inline float NextBotGroundLocomotion::GetMaxYawRate( void ) const
  126. {
  127. return 250.0f;
  128. }
  129. inline CBaseEntity *NextBotGroundLocomotion::GetGround( void ) const
  130. {
  131. return m_ground;
  132. }
  133. inline const Vector &NextBotGroundLocomotion::GetGroundNormal( void ) const
  134. {
  135. return m_groundNormal;
  136. }
  137. inline void NextBotGroundLocomotion::SetDesiredLean( const QAngle &lean )
  138. {
  139. m_desiredLean = lean;
  140. }
  141. inline const QAngle &NextBotGroundLocomotion::GetDesiredLean( void ) const
  142. {
  143. return m_desiredLean;
  144. }
  145. inline void NextBotGroundLocomotion::SetDesiredSpeed( float speed )
  146. {
  147. m_desiredSpeed = speed;
  148. }
  149. inline float NextBotGroundLocomotion::GetDesiredSpeed( void ) const
  150. {
  151. return m_desiredSpeed;
  152. }
  153. inline bool NextBotGroundLocomotion::IsClimbingOrJumping( void ) const
  154. {
  155. return m_isJumping;
  156. }
  157. inline bool NextBotGroundLocomotion::IsClimbingUpToLedge( void ) const
  158. {
  159. return m_isClimbingUpToLedge;
  160. }
  161. inline bool NextBotGroundLocomotion::IsJumpingAcrossGap( void ) const
  162. {
  163. return m_isJumpingAcrossGap;
  164. }
  165. inline bool NextBotGroundLocomotion::IsRunning( void ) const
  166. {
  167. /// @todo Rethink interface to distinguish actual state vs desired state (do we want to be running, or are we actually at running speed right now)
  168. return m_actualSpeed > 0.9f * GetRunSpeed();
  169. }
  170. inline float NextBotGroundLocomotion::GetStepHeight( void ) const
  171. {
  172. return 18.0f;
  173. }
  174. inline float NextBotGroundLocomotion::GetMaxJumpHeight( void ) const
  175. {
  176. return 180.0f; // 120.0f; // 84.0f; // 58.0f;
  177. }
  178. inline float NextBotGroundLocomotion::GetDeathDropHeight( void ) const
  179. {
  180. return 200.0f;
  181. }
  182. inline float NextBotGroundLocomotion::GetRunSpeed( void ) const
  183. {
  184. return 150.0f;
  185. }
  186. inline float NextBotGroundLocomotion::GetWalkSpeed( void ) const
  187. {
  188. return 75.0f;
  189. }
  190. inline float NextBotGroundLocomotion::GetMaxAcceleration( void ) const
  191. {
  192. return 500.0f;
  193. }
  194. inline float NextBotGroundLocomotion::GetMaxDeceleration( void ) const
  195. {
  196. return 500.0f;
  197. }
  198. #endif // NEXT_BOT_GROUND_LOCOMOTION_H