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.

323 lines
6.7 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "tfc_playeranimstate.h"
  8. #include "base_playeranimstate.h"
  9. #include "tier0/vprof.h"
  10. #include "animation.h"
  11. #include "studio.h"
  12. #include "apparent_velocity_helper.h"
  13. #include "utldict.h"
  14. #ifdef CLIENT_DLL
  15. #include "c_tfc_player.h"
  16. #else
  17. #include "tfc_player.h"
  18. #endif
  19. // When moving this fast, he plays run anim.
  20. #define ARBITRARY_RUN_SPEED 175.0f
  21. #define MAX_STANDING_RUN_SPEED 320
  22. #define MAX_CROUCHED_RUN_SPEED 110
  23. // ------------------------------------------------------------------------------------------------ //
  24. // CPlayerAnimState declaration.
  25. // ------------------------------------------------------------------------------------------------ //
  26. class CTFCPlayerAnimState : public ITFCPlayerAnimState, public CBasePlayerAnimState
  27. {
  28. public:
  29. DECLARE_CLASS( CTFCPlayerAnimState, CBasePlayerAnimState );
  30. CTFCPlayerAnimState();
  31. void InitTFC( CTFCPlayer *pPlayer );
  32. // This is called by both the client and the server in the same way to trigger events for
  33. // players firing, jumping, throwing grenades, etc.
  34. virtual void DoAnimationEvent( PlayerAnimEvent_t event, int nData );
  35. virtual int CalcAimLayerSequence( float *flCycle, float *flAimSequenceWeight );
  36. virtual float SetOuterBodyYaw( float flValue );
  37. virtual Activity CalcMainActivity();
  38. virtual float GetCurrentMaxGroundSpeed();
  39. virtual void ClearAnimationState();
  40. virtual bool ShouldUpdateAnimState();
  41. private:
  42. const char* GetWeaponSuffix();
  43. bool HandleJumping();
  44. bool HandleDeath( Activity *deathActivity );
  45. private:
  46. CTFCPlayer *m_pOuterTFC;
  47. bool m_bJumping;
  48. bool m_bFirstJumpFrame;
  49. float m_flJumpStartTime;
  50. bool m_bFiring;
  51. float m_flFireStartTime;
  52. bool m_bDying;
  53. Activity m_DeathActivity;
  54. };
  55. ITFCPlayerAnimState* CreatePlayerAnimState( CTFCPlayer *pPlayer )
  56. {
  57. CTFCPlayerAnimState *pRet = new CTFCPlayerAnimState;
  58. pRet->InitTFC( pPlayer );
  59. return pRet;
  60. }
  61. // ----------------------------------------------------------------------------- //
  62. // CTFCPlayerAnimState implementation.
  63. // ----------------------------------------------------------------------------- //
  64. CTFCPlayerAnimState::CTFCPlayerAnimState()
  65. {
  66. m_pOuterTFC = NULL;
  67. m_bJumping = false;
  68. m_bFirstJumpFrame = false;
  69. m_bFiring = false;
  70. }
  71. void CTFCPlayerAnimState::InitTFC( CTFCPlayer *pPlayer )
  72. {
  73. m_pOuterTFC = pPlayer;
  74. CModAnimConfig config;
  75. config.m_flMaxBodyYawDegrees = 30;
  76. config.m_LegAnimType = LEGANIM_GOLDSRC;
  77. config.m_bUseAimSequences = true;
  78. BaseClass::Init( pPlayer, config );
  79. }
  80. const char* CTFCPlayerAnimState::GetWeaponSuffix()
  81. {
  82. CBaseCombatWeapon *pWeapon = m_pOuterTFC->GetActiveWeapon();
  83. if ( pWeapon )
  84. return pWeapon->GetWpnData().szAnimationPrefix;
  85. else
  86. return "shotgun";
  87. }
  88. int CTFCPlayerAnimState::CalcAimLayerSequence( float *flCycle, float *flAimSequenceWeight )
  89. {
  90. const char *pWeaponSuffix = GetWeaponSuffix();
  91. if ( !pWeaponSuffix )
  92. return 0;
  93. // Are we aiming or firing?
  94. const char *pAimOrShoot = "aim";
  95. if ( m_bFiring )
  96. pAimOrShoot = "shoot";
  97. // Are we standing or crouching?
  98. int iSequence = 0;
  99. const char *pPrefix = "ref";
  100. if ( m_bDying )
  101. {
  102. // While dying, only play the main sequence.. don't layer this one on top.
  103. *flAimSequenceWeight = 0;
  104. }
  105. else
  106. {
  107. switch ( GetCurrentMainSequenceActivity() )
  108. {
  109. case ACT_CROUCHIDLE:
  110. case ACT_RUN_CROUCH:
  111. pPrefix = "crouch";
  112. break;
  113. }
  114. }
  115. iSequence = CalcSequenceIndex( "%s_%s_%s", pPrefix, pAimOrShoot, pWeaponSuffix );
  116. // Check if we're done firing.
  117. if ( m_bFiring )
  118. {
  119. float dur = m_pOuterTFC->SequenceDuration( iSequence );
  120. *flCycle = (gpGlobals->curtime - m_flFireStartTime) / dur;
  121. if ( *flCycle >= 1 )
  122. {
  123. *flCycle = 1;
  124. m_bFiring = false;
  125. }
  126. }
  127. return iSequence;
  128. }
  129. void CTFCPlayerAnimState::DoAnimationEvent( PlayerAnimEvent_t event, int nData )
  130. {
  131. if ( event == PLAYERANIMEVENT_JUMP )
  132. {
  133. // Main animation goes to ACT_HOP.
  134. m_bJumping = true;
  135. m_bFirstJumpFrame = true;
  136. m_flJumpStartTime = gpGlobals->curtime;
  137. }
  138. else if ( event == PLAYERANIMEVENT_FIRE_GUN )
  139. {
  140. // The middle part of the aim layer sequence becomes "shoot" until that animation is complete.
  141. m_bFiring = true;
  142. m_flFireStartTime = gpGlobals->curtime;
  143. }
  144. else if ( event == PLAYERANIMEVENT_DIE )
  145. {
  146. m_bFiring = m_bJumping = false;
  147. m_bDying = true;
  148. Activity acts[] =
  149. {
  150. ACT_DIESIMPLE,
  151. ACT_DIEBACKWARD,
  152. ACT_DIEFORWARD,
  153. ACT_DIE_HEADSHOT,
  154. ACT_DIE_GUTSHOT
  155. };
  156. m_DeathActivity = acts[ RandomInt( 0, ARRAYSIZE( acts ) - 1 ) ];
  157. RestartMainSequence(); // Play a death animation.
  158. }
  159. }
  160. float CTFCPlayerAnimState::SetOuterBodyYaw( float flValue )
  161. {
  162. m_pOuterTFC->SetBoneController( 0, flValue );
  163. return flValue;
  164. }
  165. bool CTFCPlayerAnimState::HandleJumping()
  166. {
  167. if ( m_bJumping )
  168. {
  169. if ( m_bFirstJumpFrame )
  170. {
  171. m_bFirstJumpFrame = false;
  172. RestartMainSequence(); // Reset the animation.
  173. }
  174. // Don't check if he's on the ground for a sec.. sometimes the client still has the
  175. // on-ground flag set right when the message comes in.
  176. if ( gpGlobals->curtime - m_flJumpStartTime > 0.2f )
  177. {
  178. if ( m_pOuterTFC->GetFlags() & FL_ONGROUND )
  179. {
  180. m_bJumping = false;
  181. RestartMainSequence(); // Reset the animation.
  182. }
  183. }
  184. }
  185. // Are we still jumping? If so, keep playing the jump animation.
  186. return m_bJumping;
  187. }
  188. bool CTFCPlayerAnimState::HandleDeath( Activity *deathActivity )
  189. {
  190. if ( m_bDying )
  191. {
  192. if ( m_pOuterTFC->IsAlive() )
  193. {
  194. m_bDying = false;
  195. }
  196. else
  197. {
  198. *deathActivity = m_DeathActivity;
  199. }
  200. }
  201. return m_bDying;
  202. }
  203. Activity CTFCPlayerAnimState::CalcMainActivity()
  204. {
  205. Activity deathActivity = ACT_IDLE;
  206. if ( HandleDeath( &deathActivity ) )
  207. {
  208. return deathActivity;
  209. }
  210. else if ( HandleJumping() )
  211. {
  212. return ACT_HOP;
  213. }
  214. else
  215. {
  216. Activity idealActivity = ACT_IDLE;
  217. float flOuterSpeed = GetOuterXYSpeed();
  218. if ( m_pOuterTFC->GetFlags() & FL_DUCKING )
  219. {
  220. if ( flOuterSpeed > 0.1f )
  221. idealActivity = ACT_RUN_CROUCH;
  222. else
  223. idealActivity = ACT_CROUCHIDLE;
  224. }
  225. else
  226. {
  227. if ( flOuterSpeed > 0.1f )
  228. {
  229. if ( flOuterSpeed > ARBITRARY_RUN_SPEED )
  230. idealActivity = ACT_RUN;
  231. else
  232. idealActivity = ACT_WALK;
  233. }
  234. else
  235. {
  236. idealActivity = ACT_IDLE;
  237. }
  238. }
  239. return idealActivity;
  240. }
  241. }
  242. float CTFCPlayerAnimState::GetCurrentMaxGroundSpeed()
  243. {
  244. Activity act = GetCurrentMainSequenceActivity();
  245. if ( act == ACT_CROUCHIDLE || act == ACT_RUN_CROUCH )
  246. return MAX_CROUCHED_RUN_SPEED;
  247. else
  248. return MAX_STANDING_RUN_SPEED;
  249. }
  250. void CTFCPlayerAnimState::ClearAnimationState()
  251. {
  252. m_bJumping = false;
  253. m_bFiring = false;
  254. m_bDying = false;
  255. BaseClass::ClearAnimationState();
  256. }
  257. bool CTFCPlayerAnimState::ShouldUpdateAnimState()
  258. {
  259. return true;
  260. }