diff --git a/game/client/cstrike/c_cs_player.cpp b/game/client/cstrike/c_cs_player.cpp index 52804aa1f3..8132447bed 100644 --- a/game/client/cstrike/c_cs_player.cpp +++ b/game/client/cstrike/c_cs_player.cpp @@ -905,7 +905,7 @@ const QAngle& C_CSPlayer::GetRenderAngles() } else { - return GetAbsAngles(); + return BaseClass::GetRenderAngles(); } } diff --git a/game/client/prediction.cpp b/game/client/prediction.cpp index edb7b5cbde..0edb674ce2 100644 --- a/game/client/prediction.cpp +++ b/game/client/prediction.cpp @@ -708,6 +708,8 @@ void CPrediction::FinishMove( C_BasePlayer *player, CUserCmd *ucmd, CMoveData *m player->SetPoseParameter(player->LookupPoseParameter("body_pitch"), pitch); + move->m_vecAngles[PITCH] = 0.0f; + player->SetLocalAngles(move->m_vecAngles); // NOTE: Don't copy this. the movement code modifies its local copy but is not expecting to be authoritative diff --git a/game/server/cstrike/cs_player.cpp b/game/server/cstrike/cs_player.cpp index 8cfd96024d..8d6a8ef11c 100644 --- a/game/server/cstrike/cs_player.cpp +++ b/game/server/cstrike/cs_player.cpp @@ -1614,10 +1614,6 @@ void CCSPlayer::PostThink() } } - QAngle angles = GetLocalAngles(); - angles[PITCH] = 0; - SetLocalAngles( angles ); - // Store the eye angles pitch so the client can compute its animation state correctly. m_angEyeAngles = EyeAngles(); diff --git a/game/server/player_command.cpp b/game/server/player_command.cpp index fc69967676..c657952d1d 100644 --- a/game/server/player_command.cpp +++ b/game/server/player_command.cpp @@ -229,6 +229,7 @@ void CPlayerMove::FinishMove( CBasePlayer *player, CUserCmd *ucmd, CMoveData *mo player->SetBodyPitch( pitch ); + move->m_vecAngles[ PITCH ] = 0.0f; player->SetLocalAngles( move->m_vecAngles ); // The class had better not have changed during the move!! diff --git a/game/shared/base_playeranimstate.cpp b/game/shared/base_playeranimstate.cpp index 5f04bf84ca..a834bdc11b 100644 --- a/game/shared/base_playeranimstate.cpp +++ b/game/shared/base_playeranimstate.cpp @@ -669,6 +669,41 @@ void CBasePlayerAnimState::ComputePoseParam_MoveYaw( CStudioHdr *pStudioHdr ) { GetOuter()->SetPoseParameter( pStudioHdr, iMoveYaw, flYaw ); m_flLastMoveYaw = flYaw; + + // Now blend in his idle animation. + // This makes the 8-way blend act like a 9-way blend by blending to + // an idle sequence as he slows down. +#if defined(CLIENT_DLL) + bool bIsMoving; + CAnimationLayer *pLayer = m_pOuter->GetAnimOverlay( MAIN_IDLE_SEQUENCE_LAYER ); + + pLayer->m_flWeight = 1 - CalcMovementPlaybackRate( &bIsMoving ); + if ( !bIsMoving ) + { + pLayer->m_flWeight = 1; + } + + if ( ShouldChangeSequences() ) + { + // Whenever this layer stops blending, we can choose a new idle sequence to blend to, so he + // doesn't always use the same idle. + if ( pLayer->m_flWeight < 0.02f || m_iCurrent8WayIdleSequence == -1 ) + { + m_iCurrent8WayIdleSequence = m_pOuter->SelectWeightedSequence( ACT_IDLE ); + m_iCurrent8WayCrouchIdleSequence = m_pOuter->SelectWeightedSequence( ACT_CROUCHIDLE ); + } + + if ( m_eCurrentMainSequenceActivity == ACT_CROUCHIDLE || m_eCurrentMainSequenceActivity == ACT_RUN_CROUCH ) + pLayer->m_nSequence = m_iCurrent8WayCrouchIdleSequence; + else + pLayer->m_nSequence = m_iCurrent8WayIdleSequence; + } + + pLayer->m_flPlaybackRate = 1; + pLayer->m_flCycle += m_pOuter->GetSequenceCycleRate( pStudioHdr, pLayer->m_nSequence ) * gpGlobals->frametime; + pLayer->m_flCycle = fmod( pLayer->m_flCycle, 1 ); + pLayer->m_nOrder = MAIN_IDLE_SEQUENCE_LAYER; +#endif } } } @@ -884,7 +919,7 @@ const QAngle& CBasePlayerAnimState::GetRenderAngles() void CBasePlayerAnimState::GetOuterAbsVelocity( Vector& vel ) const { #if defined( CLIENT_DLL ) - vel = GetOuter()->GetAbsVelocity(); + GetOuter()->EstimateAbsVelocity( vel ); #else vel = GetOuter()->GetAbsVelocity(); #endif