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.

260 lines
6.9 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #ifndef AI_BLENDED_MOVEMENT_H
  8. #define AI_BLENDED_MOVEMENT_H
  9. #include "ai_basenpc.h"
  10. #include "ai_motor.h"
  11. #include "ai_navigator.h"
  12. struct AI_Waypoint_t;
  13. //-----------------------------------------------------------------------------
  14. // CLASS: CAI_BlendedMotor
  15. //
  16. // Purpose: Home of fancy human animation transition code
  17. //
  18. //-----------------------------------------------------------------------------
  19. class CAI_BlendedMotor : public CAI_Motor
  20. {
  21. typedef CAI_Motor BaseClass;
  22. public:
  23. CAI_BlendedMotor( CAI_BaseNPC *pOuter )
  24. : BaseClass( pOuter )
  25. {
  26. m_iPrimaryLayer = -1;
  27. m_nPrimarySequence = ACT_INVALID;
  28. m_iSecondaryLayer = -1;
  29. m_nSecondarySequence = ACT_INVALID;
  30. m_flSecondaryWeight = 0.0f;
  31. m_nSavedGoalActivity = ACT_INVALID;
  32. m_nSavedTranslatedGoalActivity = ACT_INVALID;
  33. m_nGoalSequence = ACT_INVALID;
  34. m_nPrevMovementSequence = ACT_INVALID;
  35. m_nInteriorSequence = ACT_INVALID;
  36. m_bDeceleratingToGoal = false;
  37. m_flStartCycle = 0.0f;
  38. m_flPredictiveSpeedAdjust = 1.0f;
  39. m_flReactiveSpeedAdjust = 1.0f;
  40. m_vecPrevOrigin1.Init();
  41. m_vecPrevOrigin2.Init();
  42. m_prevYaw = 0.0f;
  43. m_doTurn = 0.0f;
  44. m_doLeft = 0.0f;
  45. m_doRight = 0.0f;
  46. m_flNextTurnAct = 0.0f;
  47. }
  48. void MoveClimbStart( const Vector &climbDest, const Vector &climbDir, float climbDist, float yaw );
  49. void MoveJumpStart( const Vector &velocity );
  50. void ResetMoveCalculations();
  51. void MoveStart();
  52. void ResetGoalSequence();
  53. void MoveStop();
  54. void MovePaused();
  55. void MoveContinue();
  56. float OverrideMaxYawSpeed( Activity activity );
  57. void UpdateYaw( int speed );
  58. void RecalculateYawSpeed();
  59. bool IsDeceleratingToGoal() const { return m_bDeceleratingToGoal; }
  60. float GetMoveScriptTotalTime();
  61. void MaintainTurnActivity( void );
  62. bool AddTurnGesture( float flYD );
  63. private:
  64. AIMotorMoveResult_t MoveGroundExecute( const AILocalMoveGoal_t &move, AIMoveTrace_t *pTraceResult );
  65. AIMotorMoveResult_t MoveFlyExecute( const AILocalMoveGoal_t &move, AIMoveTrace_t *pTraceResult );
  66. // --------------------------------
  67. void BuildMoveScript( const AILocalMoveGoal_t &move, AIMoveTrace_t *pTraceResult );
  68. void BuildVelocityScript( const AILocalMoveGoal_t &move );
  69. void InsertSlowdown( float distToObstruction, float idealAccel, bool bAlwaysSlowdown );
  70. int BuildTurnScript( int i, int j );
  71. void BuildTurnScript( const AILocalMoveGoal_t &move );
  72. int BuildInsertNode( int i, float flTime );
  73. Activity GetTransitionActivity( void );
  74. // --------------------------------
  75. // helpers to simplify code
  76. float GetCycle() { return GetOuter()->GetCycle(); }
  77. int AddLayeredSequence( int sequence, int iPriority ) { return GetOuter()->AddLayeredSequence( sequence, iPriority ); }
  78. void SetLayerWeight( int iLayer, float flWeight ) { GetOuter()->SetLayerWeight( iLayer, flWeight ); }
  79. void SetLayerPlaybackRate( int iLayer, float flPlaybackRate ) { GetOuter()->SetLayerPlaybackRate( iLayer, flPlaybackRate ); }
  80. void SetLayerNoRestore( int iLayer, bool bNoRestore ) { GetOuter()->SetLayerNoRestore( iLayer, bNoRestore ); }
  81. void SetLayerCycle( int iLayer, float flCycle ) { GetOuter()->SetLayerCycle( iLayer, flCycle ); }
  82. void SetLayerCycle( int iLayer, float flCycle, float flPrevCycle ) { GetOuter()->SetLayerCycle( iLayer, flCycle, flPrevCycle ); }
  83. void RemoveLayer( int iLayer, float flKillRate, float flKillDelay ) { GetOuter()->RemoveLayer( iLayer, flKillRate, flKillDelay ); }
  84. // --------------------------------
  85. struct AI_Movementscript_t
  86. {
  87. public:
  88. AI_Movementscript_t( )
  89. {
  90. Init( );
  91. };
  92. void Init( void )
  93. {
  94. memset( this, 0, sizeof(*this) );
  95. };
  96. float flTime; // time till next entry
  97. float flElapsedTime; // time since first entry
  98. float flDist; // distance to next entry
  99. float flMaxVelocity;
  100. // float flVelocity;
  101. float flYaw;
  102. float flAngularVelocity;
  103. bool bLooping;
  104. int nFlags;
  105. AI_Waypoint_t *pWaypoint;
  106. public:
  107. AI_Movementscript_t *pNext;
  108. AI_Movementscript_t *pPrev;
  109. Vector vecLocation;
  110. };
  111. //---------------------------------
  112. CUtlVector<AI_Movementscript_t> m_scriptMove;
  113. CUtlVector<AI_Movementscript_t> m_scriptTurn;
  114. //---------------------------------
  115. bool m_bDeceleratingToGoal;
  116. int m_iPrimaryLayer;
  117. int m_iSecondaryLayer;
  118. int m_nPrimarySequence;
  119. int m_nSecondarySequence;
  120. float m_flSecondaryWeight;
  121. Activity m_nSavedGoalActivity;
  122. Activity m_nSavedTranslatedGoalActivity;
  123. int m_nGoalSequence;
  124. int m_nPrevMovementSequence;
  125. int m_nInteriorSequence;
  126. float m_flStartCycle;
  127. float m_flCurrRate;
  128. float m_flPredictiveSpeedAdjust; // predictive speed adjust from probing slope
  129. float m_flReactiveSpeedAdjust; // reactive speed adjust when slope movement detected
  130. Vector m_vecPrevOrigin1;
  131. Vector m_vecPrevOrigin2;
  132. //---------------------------------
  133. float m_flNextTurnGesture; // next time for large turn gesture
  134. //---------------------------------
  135. float m_prevYaw;
  136. float m_doTurn;
  137. float m_doLeft;
  138. float m_doRight;
  139. float m_flNextTurnAct; // next time for small turn gesture
  140. float GetMoveScriptDist( float &flNewSpeed );
  141. float GetMoveScriptYaw( void );
  142. void SetMoveScriptAnim( float flNewSpeed );
  143. int GetInteriorSequence( int fromSequence );
  144. DECLARE_SIMPLE_DATADESC();
  145. };
  146. //-----------------------------------------------------------------------------
  147. // CLASS: CAI_BlendingHost
  148. //
  149. // Purpose: Bridge to the home of fancy human animation transition code
  150. //
  151. //-----------------------------------------------------------------------------
  152. template <class BASE_NPC>
  153. class CAI_BlendingHost : public BASE_NPC
  154. {
  155. DECLARE_CLASS_NOFRIEND( CAI_BlendingHost, BASE_NPC );
  156. public:
  157. const CAI_BlendedMotor *GetBlendedMotor() const { return assert_cast<const CAI_BlendedMotor *>(this->GetMotor()); }
  158. CAI_BlendedMotor * GetBlendedMotor() { return assert_cast<CAI_BlendedMotor *>(this->GetMotor()); }
  159. CAI_Motor *CreateMotor()
  160. {
  161. MEM_ALLOC_CREDIT();
  162. return new CAI_BlendedMotor( this );
  163. }
  164. CAI_Navigator *CreateNavigator()
  165. {
  166. CAI_Navigator *pNavigator = BaseClass::CreateNavigator();
  167. pNavigator->SetValidateActivitySpeed( false );
  168. return pNavigator;
  169. }
  170. float MaxYawSpeed( void )
  171. {
  172. float override = GetBlendedMotor()->OverrideMaxYawSpeed( this->GetActivity() );
  173. if ( override != -1 )
  174. return override;
  175. return BaseClass::MaxYawSpeed();
  176. }
  177. float GetTimeToNavGoal()
  178. {
  179. float result = GetBlendedMotor()->GetMoveScriptTotalTime();
  180. if ( result != -1 )
  181. return result;
  182. return BaseClass::GetTimeToNavGoal();
  183. }
  184. };
  185. //-------------------------------------
  186. // to simplify basic usage:
  187. class CAI_BlendedNPC : public CAI_BlendingHost<CAI_BaseNPC>
  188. {
  189. DECLARE_CLASS( CAI_BlendedNPC, CAI_BlendingHost<CAI_BaseNPC> );
  190. };
  191. //-----------------------------------------------------------------------------
  192. #endif