summaryrefslogtreecommitdiff
path: root/game/shared/hl1/hl1_player_shared.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/shared/hl1/hl1_player_shared.cpp')
-rw-r--r--game/shared/hl1/hl1_player_shared.cpp373
1 files changed, 373 insertions, 0 deletions
diff --git a/game/shared/hl1/hl1_player_shared.cpp b/game/shared/hl1/hl1_player_shared.cpp
new file mode 100644
index 0000000..2d74018
--- /dev/null
+++ b/game/shared/hl1/hl1_player_shared.cpp
@@ -0,0 +1,373 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#include "cbase.h"
+#include "tier0/vprof.h"
+
+#ifdef CLIENT_DLL
+#include "hl1_player_shared.h"
+#include "hl1/c_hl1mp_player.h"
+//#define CRecipientFilter C_RecipientFilter
+#else
+#include "hl1mp_player.h"
+#endif
+
+// When moving this fast, he plays run anim.
+#define ARBITRARY_RUN_SPEED 175.0f
+
+#define MAX_STANDING_RUN_SPEED 320
+#define MAX_CROUCHED_RUN_SPEED 110
+
+
+// ------------------------------------------------------------------------------------------------ //
+// CPlayerAnimState declaration.
+// ------------------------------------------------------------------------------------------------ //
+
+class CPlayerAnimState : public IHL1MPPlayerAnimState, public CBasePlayerAnimState
+{
+public:
+
+ DECLARE_CLASS( CPlayerAnimState, CBasePlayerAnimState );
+
+ CPlayerAnimState();
+ void Init( CHL1MP_Player *pPlayer );
+
+ // This is called by both the client and the server in the same way to trigger events for
+ // players firing, jumping, throwing grenades, etc.
+ virtual void DoAnimationEvent( PlayerAnimEvent_t event, int nData );
+ virtual int CalcAimLayerSequence( float *flCycle, float *flAimSequenceWeight, bool bForceIdle );
+ virtual float SetOuterBodyYaw( float flValue );
+ virtual Activity CalcMainActivity();
+ virtual float GetCurrentMaxGroundSpeed();
+ virtual void ClearAnimationState();
+ virtual bool ShouldUpdateAnimState();
+ virtual int SelectWeightedSequence( Activity activity ) ;
+
+ float CalcMovementPlaybackRate( bool *bIsMoving );
+
+ virtual void ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr );
+
+
+private:
+
+ const char* GetWeaponSuffix();
+ bool HandleJumping();
+ bool HandleDeath( Activity *deathActivity );
+
+
+private:
+
+ CHL1MP_Player *m_pOuter;
+
+ bool m_bJumping;
+ bool m_bFirstJumpFrame;
+ float m_flJumpStartTime;
+
+ bool m_bFiring;
+ float m_flFireStartTime;
+
+ bool m_bDying;
+ Activity m_DeathActivity;
+};
+
+
+IHL1MPPlayerAnimState* CreatePlayerAnimState( CHL1MP_Player *pPlayer )
+{
+ CPlayerAnimState *pRet = new CPlayerAnimState;
+ pRet->Init( pPlayer );
+ return pRet;
+}
+
+
+// ----------------------------------------------------------------------------- //
+// CPlayerAnimState implementation.
+// ----------------------------------------------------------------------------- //
+
+CPlayerAnimState::CPlayerAnimState()
+{
+ m_pOuter = NULL;
+ m_bJumping = false;
+ m_bFirstJumpFrame = false;
+ m_bFiring = false;
+}
+
+
+void CPlayerAnimState::Init( CHL1MP_Player *pPlayer )
+{
+ m_pOuter = pPlayer;
+
+ CModAnimConfig config;
+ config.m_flMaxBodyYawDegrees = 90;
+ config.m_LegAnimType = LEGANIM_GOLDSRC;
+ config.m_bUseAimSequences = true;
+
+ BaseClass::Init( pPlayer, config );
+}
+
+
+const char* CPlayerAnimState::GetWeaponSuffix()
+{
+ CBaseCombatWeapon *pWeapon = m_pOuter->GetActiveWeapon();
+ if ( pWeapon )
+ return pWeapon->GetWpnData().szAnimationPrefix;
+ else
+ return "shotgun";
+}
+
+
+int CPlayerAnimState::CalcAimLayerSequence( float *flCycle, float *flAimSequenceWeight, bool bForceIdle )
+{
+ const char *pWeaponSuffix = GetWeaponSuffix();
+ if ( !pWeaponSuffix )
+ return 0;
+
+ if ( strcmp( pWeaponSuffix, "glock" ) == 0 )
+ pWeaponSuffix = "onehanded";
+
+ // Are we aiming or firing?
+ const char *pAimOrShoot = "aim";
+ if ( m_bFiring )
+ pAimOrShoot = "shoot";
+
+ // Are we standing or crouching?
+ int iSequence = 0;
+ const char *pPrefix = "ref";
+ if ( m_bDying )
+ {
+ // While dying, only play the main sequence.. don't layer this one on top.
+ *flAimSequenceWeight = 0;
+ }
+ else
+ {
+ switch ( GetCurrentMainSequenceActivity() )
+ {
+ case ACT_CROUCHIDLE:
+ case ACT_RUN_CROUCH:
+ pPrefix = "crouch";
+ break;
+ }
+ }
+
+ iSequence = CalcSequenceIndex( "%s_%s_%s", pPrefix, pAimOrShoot, pWeaponSuffix );
+
+ // Check if we're done firing.
+ if ( m_bFiring )
+ {
+ float dur = m_pOuter->SequenceDuration( iSequence );
+ *flCycle = (gpGlobals->curtime - m_flFireStartTime) / dur;
+ if ( *flCycle >= 1 )
+ {
+ *flCycle = 1;
+ m_bFiring = false;
+ }
+ }
+
+ return iSequence;
+}
+
+
+void CPlayerAnimState::DoAnimationEvent( PlayerAnimEvent_t event, int nData )
+{
+ if ( event == PLAYERANIMEVENT_JUMP )
+ {
+ // Main animation goes to ACT_HOP.
+ m_bJumping = true;
+ m_bFirstJumpFrame = true;
+ m_flJumpStartTime = gpGlobals->curtime;
+ }
+ else if ( event == PLAYERANIMEVENT_FIRE_GUN )
+ {
+ // The middle part of the aim layer sequence becomes "shoot" until that animation is complete.
+ m_bFiring = true;
+ m_flFireStartTime = gpGlobals->curtime;
+ }
+}
+
+
+float CPlayerAnimState::SetOuterBodyYaw( float flValue )
+{
+// m_pOuter->SetBoneController( 0, flValue );
+
+ float fAcc = flValue / 4;
+
+ for ( int i = 0; i < 4; i++ )
+ {
+ m_pOuter->SetBoneController( i, fAcc );
+ }
+
+ return flValue;
+}
+
+
+bool CPlayerAnimState::HandleJumping()
+{
+ if ( m_bJumping )
+ {
+ if ( m_bFirstJumpFrame )
+ {
+ m_bFirstJumpFrame = false;
+ RestartMainSequence(); // Reset the animation.
+ }
+
+ // Don't check if he's on the ground for a sec.. sometimes the client still has the
+ // on-ground flag set right when the message comes in.
+ if ( gpGlobals->curtime - m_flJumpStartTime > 0.2f )
+ {
+ if ( m_pOuter->GetFlags() & FL_ONGROUND )
+ {
+ m_bJumping = false;
+ RestartMainSequence(); // Reset the animation.
+ }
+ }
+ }
+
+ // Are we still jumping? If so, keep playing the jump animation.
+ return m_bJumping;
+}
+
+int CPlayerAnimState::SelectWeightedSequence( Activity activity )
+{
+ return m_pOuter->m_iRealSequence;
+}
+
+bool CPlayerAnimState::HandleDeath( Activity *deathActivity )
+{
+ if ( m_bDying )
+ {
+ if ( m_pOuter->IsAlive() )
+ {
+ m_bDying = false;
+ }
+ else
+ {
+ *deathActivity = m_DeathActivity;
+ }
+ }
+ return m_bDying;
+}
+
+
+Activity CPlayerAnimState::CalcMainActivity()
+{
+ Activity deathActivity = ACT_IDLE;
+ if ( HandleDeath( &deathActivity ) )
+ {
+ return deathActivity;
+ }
+ else if ( HandleJumping() )
+ {
+ return ACT_HOP;
+ }
+ else
+ {
+ Activity idealActivity = ACT_IDLE;
+ float flOuterSpeed = GetOuterXYSpeed();
+
+ if ( m_pOuter->GetFlags() & FL_DUCKING )
+ {
+ if ( flOuterSpeed > 0.1f )
+ idealActivity = ACT_RUN_CROUCH;
+ else
+ idealActivity = ACT_CROUCHIDLE;
+ }
+ else
+ {
+ if ( flOuterSpeed > 0.1f )
+ {
+ if ( flOuterSpeed > ARBITRARY_RUN_SPEED )
+ idealActivity = ACT_RUN;
+ else
+ idealActivity = ACT_WALK;
+ }
+ else
+ {
+ idealActivity = ACT_IDLE;
+ }
+ }
+
+ return idealActivity ;
+ }
+}
+
+
+float CPlayerAnimState::GetCurrentMaxGroundSpeed()
+{
+ Activity act = GetCurrentMainSequenceActivity();
+ if ( act == ACT_CROUCHIDLE || act == ACT_RUN_CROUCH )
+ return MAX_CROUCHED_RUN_SPEED;
+ else
+ return MAX_STANDING_RUN_SPEED;
+}
+
+
+void CPlayerAnimState::ClearAnimationState()
+{
+ m_bJumping = false;
+ m_bFiring = false;
+ m_bDying = false;
+
+ BaseClass::ClearAnimationState();
+}
+
+
+bool CPlayerAnimState::ShouldUpdateAnimState()
+{
+ return true;
+}
+
+float CPlayerAnimState::CalcMovementPlaybackRate( bool *bIsMoving )
+{
+ // Determine ideal playback rate
+ Vector vel;
+ GetOuterAbsVelocity( vel );
+
+ float flReturnValue = BaseClass::CalcMovementPlaybackRate( bIsMoving );
+
+ Activity eActivity = GetOuter()->GetSequenceActivity( GetOuter()->GetSequence() ) ;
+
+ if ( eActivity == ACT_RUN || eActivity == ACT_WALK || eActivity == ACT_CROUCH )
+ {
+ VectorNormalize( vel );
+
+ Vector vForward;
+ AngleVectors( GetOuter()->EyeAngles(), &vForward );
+
+ float flDot = DotProduct( vel, vForward );
+
+ if ( flDot < 0 )
+ {
+ flReturnValue *= -1;
+ }
+ }
+
+ return flReturnValue;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CPlayerAnimState::ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr )
+{
+ VPROF( "CBasePlayerAnimState::ComputePoseParam_BodyPitch" );
+
+ // Get pitch from v_angle
+ float flPitch = -m_flEyePitch;
+ if ( flPitch > 180.0f )
+ {
+ flPitch -= 360.0f;
+ }
+ flPitch = clamp( flPitch, -50, 45 );
+
+ // See if we have a blender for pitch
+ int pitch = GetOuter()->LookupPoseParameter( pStudioHdr, "XR" );
+ if ( pitch < 0 )
+ return;
+
+ GetOuter()->SetPoseParameter( pStudioHdr, pitch, flPitch );
+ g_flLastBodyPitch = flPitch;
+}
+