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.

373 lines
8.0 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #include "cbase.h"
  9. #include "tier0/vprof.h"
  10. #ifdef CLIENT_DLL
  11. #include "hl1_player_shared.h"
  12. #include "hl1/c_hl1mp_player.h"
  13. //#define CRecipientFilter C_RecipientFilter
  14. #else
  15. #include "hl1mp_player.h"
  16. #endif
  17. // When moving this fast, he plays run anim.
  18. #define ARBITRARY_RUN_SPEED 175.0f
  19. #define MAX_STANDING_RUN_SPEED 320
  20. #define MAX_CROUCHED_RUN_SPEED 110
  21. // ------------------------------------------------------------------------------------------------ //
  22. // CPlayerAnimState declaration.
  23. // ------------------------------------------------------------------------------------------------ //
  24. class CPlayerAnimState : public IHL1MPPlayerAnimState, public CBasePlayerAnimState
  25. {
  26. public:
  27. DECLARE_CLASS( CPlayerAnimState, CBasePlayerAnimState );
  28. CPlayerAnimState();
  29. void Init( CHL1MP_Player *pPlayer );
  30. // This is called by both the client and the server in the same way to trigger events for
  31. // players firing, jumping, throwing grenades, etc.
  32. virtual void DoAnimationEvent( PlayerAnimEvent_t event, int nData );
  33. virtual int CalcAimLayerSequence( float *flCycle, float *flAimSequenceWeight, bool bForceIdle );
  34. virtual float SetOuterBodyYaw( float flValue );
  35. virtual Activity CalcMainActivity();
  36. virtual float GetCurrentMaxGroundSpeed();
  37. virtual void ClearAnimationState();
  38. virtual bool ShouldUpdateAnimState();
  39. virtual int SelectWeightedSequence( Activity activity ) ;
  40. float CalcMovementPlaybackRate( bool *bIsMoving );
  41. virtual void ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr );
  42. private:
  43. const char* GetWeaponSuffix();
  44. bool HandleJumping();
  45. bool HandleDeath( Activity *deathActivity );
  46. private:
  47. CHL1MP_Player *m_pOuter;
  48. bool m_bJumping;
  49. bool m_bFirstJumpFrame;
  50. float m_flJumpStartTime;
  51. bool m_bFiring;
  52. float m_flFireStartTime;
  53. bool m_bDying;
  54. Activity m_DeathActivity;
  55. };
  56. IHL1MPPlayerAnimState* CreatePlayerAnimState( CHL1MP_Player *pPlayer )
  57. {
  58. CPlayerAnimState *pRet = new CPlayerAnimState;
  59. pRet->Init( pPlayer );
  60. return pRet;
  61. }
  62. // ----------------------------------------------------------------------------- //
  63. // CPlayerAnimState implementation.
  64. // ----------------------------------------------------------------------------- //
  65. CPlayerAnimState::CPlayerAnimState()
  66. {
  67. m_pOuter = NULL;
  68. m_bJumping = false;
  69. m_bFirstJumpFrame = false;
  70. m_bFiring = false;
  71. }
  72. void CPlayerAnimState::Init( CHL1MP_Player *pPlayer )
  73. {
  74. m_pOuter = pPlayer;
  75. CModAnimConfig config;
  76. config.m_flMaxBodyYawDegrees = 90;
  77. config.m_LegAnimType = LEGANIM_GOLDSRC;
  78. config.m_bUseAimSequences = true;
  79. BaseClass::Init( pPlayer, config );
  80. }
  81. const char* CPlayerAnimState::GetWeaponSuffix()
  82. {
  83. CBaseCombatWeapon *pWeapon = m_pOuter->GetActiveWeapon();
  84. if ( pWeapon )
  85. return pWeapon->GetWpnData().szAnimationPrefix;
  86. else
  87. return "shotgun";
  88. }
  89. int CPlayerAnimState::CalcAimLayerSequence( float *flCycle, float *flAimSequenceWeight, bool bForceIdle )
  90. {
  91. const char *pWeaponSuffix = GetWeaponSuffix();
  92. if ( !pWeaponSuffix )
  93. return 0;
  94. if ( strcmp( pWeaponSuffix, "glock" ) == 0 )
  95. pWeaponSuffix = "onehanded";
  96. // Are we aiming or firing?
  97. const char *pAimOrShoot = "aim";
  98. if ( m_bFiring )
  99. pAimOrShoot = "shoot";
  100. // Are we standing or crouching?
  101. int iSequence = 0;
  102. const char *pPrefix = "ref";
  103. if ( m_bDying )
  104. {
  105. // While dying, only play the main sequence.. don't layer this one on top.
  106. *flAimSequenceWeight = 0;
  107. }
  108. else
  109. {
  110. switch ( GetCurrentMainSequenceActivity() )
  111. {
  112. case ACT_CROUCHIDLE:
  113. case ACT_RUN_CROUCH:
  114. pPrefix = "crouch";
  115. break;
  116. }
  117. }
  118. iSequence = CalcSequenceIndex( "%s_%s_%s", pPrefix, pAimOrShoot, pWeaponSuffix );
  119. // Check if we're done firing.
  120. if ( m_bFiring )
  121. {
  122. float dur = m_pOuter->SequenceDuration( iSequence );
  123. *flCycle = (gpGlobals->curtime - m_flFireStartTime) / dur;
  124. if ( *flCycle >= 1 )
  125. {
  126. *flCycle = 1;
  127. m_bFiring = false;
  128. }
  129. }
  130. return iSequence;
  131. }
  132. void CPlayerAnimState::DoAnimationEvent( PlayerAnimEvent_t event, int nData )
  133. {
  134. if ( event == PLAYERANIMEVENT_JUMP )
  135. {
  136. // Main animation goes to ACT_HOP.
  137. m_bJumping = true;
  138. m_bFirstJumpFrame = true;
  139. m_flJumpStartTime = gpGlobals->curtime;
  140. }
  141. else if ( event == PLAYERANIMEVENT_FIRE_GUN )
  142. {
  143. // The middle part of the aim layer sequence becomes "shoot" until that animation is complete.
  144. m_bFiring = true;
  145. m_flFireStartTime = gpGlobals->curtime;
  146. }
  147. }
  148. float CPlayerAnimState::SetOuterBodyYaw( float flValue )
  149. {
  150. // m_pOuter->SetBoneController( 0, flValue );
  151. float fAcc = flValue / 4;
  152. for ( int i = 0; i < 4; i++ )
  153. {
  154. m_pOuter->SetBoneController( i, fAcc );
  155. }
  156. return flValue;
  157. }
  158. bool CPlayerAnimState::HandleJumping()
  159. {
  160. if ( m_bJumping )
  161. {
  162. if ( m_bFirstJumpFrame )
  163. {
  164. m_bFirstJumpFrame = false;
  165. RestartMainSequence(); // Reset the animation.
  166. }
  167. // Don't check if he's on the ground for a sec.. sometimes the client still has the
  168. // on-ground flag set right when the message comes in.
  169. if ( gpGlobals->curtime - m_flJumpStartTime > 0.2f )
  170. {
  171. if ( m_pOuter->GetFlags() & FL_ONGROUND )
  172. {
  173. m_bJumping = false;
  174. RestartMainSequence(); // Reset the animation.
  175. }
  176. }
  177. }
  178. // Are we still jumping? If so, keep playing the jump animation.
  179. return m_bJumping;
  180. }
  181. int CPlayerAnimState::SelectWeightedSequence( Activity activity )
  182. {
  183. return m_pOuter->m_iRealSequence;
  184. }
  185. bool CPlayerAnimState::HandleDeath( Activity *deathActivity )
  186. {
  187. if ( m_bDying )
  188. {
  189. if ( m_pOuter->IsAlive() )
  190. {
  191. m_bDying = false;
  192. }
  193. else
  194. {
  195. *deathActivity = m_DeathActivity;
  196. }
  197. }
  198. return m_bDying;
  199. }
  200. Activity CPlayerAnimState::CalcMainActivity()
  201. {
  202. Activity deathActivity = ACT_IDLE;
  203. if ( HandleDeath( &deathActivity ) )
  204. {
  205. return deathActivity;
  206. }
  207. else if ( HandleJumping() )
  208. {
  209. return ACT_HOP;
  210. }
  211. else
  212. {
  213. Activity idealActivity = ACT_IDLE;
  214. float flOuterSpeed = GetOuterXYSpeed();
  215. if ( m_pOuter->GetFlags() & FL_DUCKING )
  216. {
  217. if ( flOuterSpeed > 0.1f )
  218. idealActivity = ACT_RUN_CROUCH;
  219. else
  220. idealActivity = ACT_CROUCHIDLE;
  221. }
  222. else
  223. {
  224. if ( flOuterSpeed > 0.1f )
  225. {
  226. if ( flOuterSpeed > ARBITRARY_RUN_SPEED )
  227. idealActivity = ACT_RUN;
  228. else
  229. idealActivity = ACT_WALK;
  230. }
  231. else
  232. {
  233. idealActivity = ACT_IDLE;
  234. }
  235. }
  236. return idealActivity ;
  237. }
  238. }
  239. float CPlayerAnimState::GetCurrentMaxGroundSpeed()
  240. {
  241. Activity act = GetCurrentMainSequenceActivity();
  242. if ( act == ACT_CROUCHIDLE || act == ACT_RUN_CROUCH )
  243. return MAX_CROUCHED_RUN_SPEED;
  244. else
  245. return MAX_STANDING_RUN_SPEED;
  246. }
  247. void CPlayerAnimState::ClearAnimationState()
  248. {
  249. m_bJumping = false;
  250. m_bFiring = false;
  251. m_bDying = false;
  252. BaseClass::ClearAnimationState();
  253. }
  254. bool CPlayerAnimState::ShouldUpdateAnimState()
  255. {
  256. return true;
  257. }
  258. float CPlayerAnimState::CalcMovementPlaybackRate( bool *bIsMoving )
  259. {
  260. // Determine ideal playback rate
  261. Vector vel;
  262. GetOuterAbsVelocity( vel );
  263. float flReturnValue = BaseClass::CalcMovementPlaybackRate( bIsMoving );
  264. Activity eActivity = GetOuter()->GetSequenceActivity( GetOuter()->GetSequence() ) ;
  265. if ( eActivity == ACT_RUN || eActivity == ACT_WALK || eActivity == ACT_CROUCH )
  266. {
  267. VectorNormalize( vel );
  268. Vector vForward;
  269. AngleVectors( GetOuter()->EyeAngles(), &vForward );
  270. float flDot = DotProduct( vel, vForward );
  271. if ( flDot < 0 )
  272. {
  273. flReturnValue *= -1;
  274. }
  275. }
  276. return flReturnValue;
  277. }
  278. //-----------------------------------------------------------------------------
  279. // Purpose:
  280. //-----------------------------------------------------------------------------
  281. void CPlayerAnimState::ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr )
  282. {
  283. VPROF( "CBasePlayerAnimState::ComputePoseParam_BodyPitch" );
  284. // Get pitch from v_angle
  285. float flPitch = -m_flEyePitch;
  286. if ( flPitch > 180.0f )
  287. {
  288. flPitch -= 360.0f;
  289. }
  290. flPitch = clamp( flPitch, -50, 45 );
  291. // See if we have a blender for pitch
  292. int pitch = GetOuter()->LookupPoseParameter( pStudioHdr, "XR" );
  293. if ( pitch < 0 )
  294. return;
  295. GetOuter()->SetPoseParameter( pStudioHdr, pitch, flPitch );
  296. g_flLastBodyPitch = flPitch;
  297. }