diff options
| author | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:31:46 -0800 |
|---|---|---|
| committer | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:46:31 -0800 |
| commit | f56bb35301836e56582a575a75864392a0177875 (patch) | |
| tree | de61ddd39de3e7df52759711950b4c288592f0dc /mp/src/game/shared/hl2mp/hl2mp_player_shared.cpp | |
| parent | Mark some more files as text. (diff) | |
| download | source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip | |
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/game/shared/hl2mp/hl2mp_player_shared.cpp')
| -rw-r--r-- | mp/src/game/shared/hl2mp/hl2mp_player_shared.cpp | 1152 |
1 files changed, 576 insertions, 576 deletions
diff --git a/mp/src/game/shared/hl2mp/hl2mp_player_shared.cpp b/mp/src/game/shared/hl2mp/hl2mp_player_shared.cpp index ff8d28f2..503d498c 100644 --- a/mp/src/game/shared/hl2mp/hl2mp_player_shared.cpp +++ b/mp/src/game/shared/hl2mp/hl2mp_player_shared.cpp @@ -1,577 +1,577 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-#include "cbase.h"
-
-#ifdef CLIENT_DLL
-#include "c_hl2mp_player.h"
-#include "prediction.h"
-#define CRecipientFilter C_RecipientFilter
-#else
-#include "hl2mp_player.h"
-#endif
-
-#include "engine/IEngineSound.h"
-#include "SoundEmitterSystem/isoundemittersystembase.h"
-
-extern ConVar sv_footsteps;
-
-const char *g_ppszPlayerSoundPrefixNames[PLAYER_SOUNDS_MAX] =
-{
- "NPC_Citizen",
- "NPC_CombineS",
- "NPC_MetroPolice",
-};
-
-const char *CHL2MP_Player::GetPlayerModelSoundPrefix( void )
-{
- return g_ppszPlayerSoundPrefixNames[m_iPlayerSoundType];
-}
-
-void CHL2MP_Player::PrecacheFootStepSounds( void )
-{
- int iFootstepSounds = ARRAYSIZE( g_ppszPlayerSoundPrefixNames );
- int i;
-
- for ( i = 0; i < iFootstepSounds; ++i )
- {
- char szFootStepName[128];
-
- Q_snprintf( szFootStepName, sizeof( szFootStepName ), "%s.RunFootstepLeft", g_ppszPlayerSoundPrefixNames[i] );
- PrecacheScriptSound( szFootStepName );
-
- Q_snprintf( szFootStepName, sizeof( szFootStepName ), "%s.RunFootstepRight", g_ppszPlayerSoundPrefixNames[i] );
- PrecacheScriptSound( szFootStepName );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Consider the weapon's built-in accuracy, this character's proficiency with
-// the weapon, and the status of the target. Use this information to determine
-// how accurately to shoot at the target.
-//-----------------------------------------------------------------------------
-Vector CHL2MP_Player::GetAttackSpread( CBaseCombatWeapon *pWeapon, CBaseEntity *pTarget )
-{
- if ( pWeapon )
- return pWeapon->GetBulletSpread( WEAPON_PROFICIENCY_PERFECT );
-
- return VECTOR_CONE_15DEGREES;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : step -
-// fvol -
-// force - force sound to play
-//-----------------------------------------------------------------------------
-void CHL2MP_Player::PlayStepSound( Vector &vecOrigin, surfacedata_t *psurface, float fvol, bool force )
-{
- if ( gpGlobals->maxClients > 1 && !sv_footsteps.GetFloat() )
- return;
-
-#if defined( CLIENT_DLL )
- // during prediction play footstep sounds only once
- if ( !prediction->IsFirstTimePredicted() )
- return;
-#endif
-
- if ( GetFlags() & FL_DUCKING )
- return;
-
- m_Local.m_nStepside = !m_Local.m_nStepside;
-
- char szStepSound[128];
-
- if ( m_Local.m_nStepside )
- {
- Q_snprintf( szStepSound, sizeof( szStepSound ), "%s.RunFootstepLeft", g_ppszPlayerSoundPrefixNames[m_iPlayerSoundType] );
- }
- else
- {
- Q_snprintf( szStepSound, sizeof( szStepSound ), "%s.RunFootstepRight", g_ppszPlayerSoundPrefixNames[m_iPlayerSoundType] );
- }
-
- CSoundParameters params;
- if ( GetParametersForSound( szStepSound, params, NULL ) == false )
- return;
-
- CRecipientFilter filter;
- filter.AddRecipientsByPAS( vecOrigin );
-
-#ifndef CLIENT_DLL
- // im MP, server removed all players in origins PVS, these players
- // generate the footsteps clientside
- if ( gpGlobals->maxClients > 1 )
- filter.RemoveRecipientsByPVS( vecOrigin );
-#endif
-
- EmitSound_t ep;
- ep.m_nChannel = CHAN_BODY;
- ep.m_pSoundName = params.soundname;
- ep.m_flVolume = fvol;
- ep.m_SoundLevel = params.soundlevel;
- ep.m_nFlags = 0;
- ep.m_nPitch = params.pitch;
- ep.m_pOrigin = &vecOrigin;
-
- EmitSound( filter, entindex(), ep );
-}
-
-
-//==========================
-// ANIMATION CODE
-//==========================
-
-
-// Below this many degrees, slow down turning rate linearly
-#define FADE_TURN_DEGREES 45.0f
-// After this, need to start turning feet
-#define MAX_TORSO_ANGLE 90.0f
-// Below this amount, don't play a turning animation/perform IK
-#define MIN_TURN_ANGLE_REQUIRING_TURN_ANIMATION 15.0f
-
-static ConVar tf2_feetyawrunscale( "tf2_feetyawrunscale", "2", FCVAR_REPLICATED, "Multiplier on tf2_feetyawrate to allow turning faster when running." );
-extern ConVar sv_backspeed;
-extern ConVar mp_feetyawrate;
-extern ConVar mp_facefronttime;
-extern ConVar mp_ik;
-
-CPlayerAnimState::CPlayerAnimState( CHL2MP_Player *outer )
- : m_pOuter( outer )
-{
- m_flGaitYaw = 0.0f;
- m_flGoalFeetYaw = 0.0f;
- m_flCurrentFeetYaw = 0.0f;
- m_flCurrentTorsoYaw = 0.0f;
- m_flLastYaw = 0.0f;
- m_flLastTurnTime = 0.0f;
- m_flTurnCorrectionTime = 0.0f;
-};
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CPlayerAnimState::Update()
-{
- m_angRender = GetOuter()->GetLocalAngles();
- m_angRender[ PITCH ] = m_angRender[ ROLL ] = 0.0f;
-
- ComputePoseParam_BodyYaw();
- ComputePoseParam_BodyPitch(GetOuter()->GetModelPtr());
- ComputePoseParam_BodyLookYaw();
-
- ComputePlaybackRate();
-
-#ifdef CLIENT_DLL
- GetOuter()->UpdateLookAt();
-#endif
-
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CPlayerAnimState::ComputePlaybackRate()
-{
- // Determine ideal playback rate
- Vector vel;
- GetOuterAbsVelocity( vel );
-
- float speed = vel.Length2D();
-
- bool isMoving = ( speed > 0.5f ) ? true : false;
-
- float maxspeed = GetOuter()->GetSequenceGroundSpeed( GetOuter()->GetSequence() );
-
- if ( isMoving && ( maxspeed > 0.0f ) )
- {
- float flFactor = 1.0f;
-
- // Note this gets set back to 1.0 if sequence changes due to ResetSequenceInfo below
- GetOuter()->SetPlaybackRate( ( speed * flFactor ) / maxspeed );
-
- // BUG BUG:
- // This stuff really should be m_flPlaybackRate = speed / m_flGroundSpeed
- }
- else
- {
- GetOuter()->SetPlaybackRate( 1.0f );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : CBasePlayer
-//-----------------------------------------------------------------------------
-CHL2MP_Player *CPlayerAnimState::GetOuter()
-{
- return m_pOuter;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : dt -
-//-----------------------------------------------------------------------------
-void CPlayerAnimState::EstimateYaw( void )
-{
- float dt = gpGlobals->frametime;
-
- if ( !dt )
- {
- return;
- }
-
- Vector est_velocity;
- QAngle angles;
-
- GetOuterAbsVelocity( est_velocity );
-
- angles = GetOuter()->GetLocalAngles();
-
- if ( est_velocity[1] == 0 && est_velocity[0] == 0 )
- {
- float flYawDiff = angles[YAW] - m_flGaitYaw;
- flYawDiff = flYawDiff - (int)(flYawDiff / 360) * 360;
- if (flYawDiff > 180)
- flYawDiff -= 360;
- if (flYawDiff < -180)
- flYawDiff += 360;
-
- if (dt < 0.25)
- flYawDiff *= dt * 4;
- else
- flYawDiff *= dt;
-
- m_flGaitYaw += flYawDiff;
- m_flGaitYaw = m_flGaitYaw - (int)(m_flGaitYaw / 360) * 360;
- }
- else
- {
- m_flGaitYaw = (atan2(est_velocity[1], est_velocity[0]) * 180 / M_PI);
-
- if (m_flGaitYaw > 180)
- m_flGaitYaw = 180;
- else if (m_flGaitYaw < -180)
- m_flGaitYaw = -180;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Override for backpeddling
-// Input : dt -
-//-----------------------------------------------------------------------------
-void CPlayerAnimState::ComputePoseParam_BodyYaw( void )
-{
- int iYaw = GetOuter()->LookupPoseParameter( "move_yaw" );
- if ( iYaw < 0 )
- return;
-
- // view direction relative to movement
- float flYaw;
-
- EstimateYaw();
-
- QAngle angles = GetOuter()->GetLocalAngles();
- float ang = angles[ YAW ];
- if ( ang > 180.0f )
- {
- ang -= 360.0f;
- }
- else if ( ang < -180.0f )
- {
- ang += 360.0f;
- }
-
- // calc side to side turning
- flYaw = ang - m_flGaitYaw;
- // Invert for mapping into 8way blend
- flYaw = -flYaw;
- flYaw = flYaw - (int)(flYaw / 360) * 360;
-
- if (flYaw < -180)
- {
- flYaw = flYaw + 360;
- }
- else if (flYaw > 180)
- {
- flYaw = flYaw - 360;
- }
-
- GetOuter()->SetPoseParameter( iYaw, flYaw );
-
-#ifndef CLIENT_DLL
- //Adrian: Make the model's angle match the legs so the hitboxes match on both sides.
- GetOuter()->SetLocalAngles( QAngle( GetOuter()->GetAnimEyeAngles().x, m_flCurrentFeetYaw, 0 ) );
-#endif
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CPlayerAnimState::ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr )
-{
- // Get pitch from v_angle
- float flPitch = GetOuter()->GetLocalAngles()[ PITCH ];
-
- if ( flPitch > 180.0f )
- {
- flPitch -= 360.0f;
- }
- flPitch = clamp( flPitch, -90, 90 );
-
- QAngle absangles = GetOuter()->GetAbsAngles();
- absangles.x = 0.0f;
- m_angRender = absangles;
- m_angRender[ PITCH ] = m_angRender[ ROLL ] = 0.0f;
-
- // See if we have a blender for pitch
- GetOuter()->SetPoseParameter( pStudioHdr, "aim_pitch", flPitch );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : goal -
-// maxrate -
-// dt -
-// current -
-// Output : int
-//-----------------------------------------------------------------------------
-int CPlayerAnimState::ConvergeAngles( float goal,float maxrate, float dt, float& current )
-{
- int direction = TURN_NONE;
-
- float anglediff = goal - current;
- float anglediffabs = fabs( anglediff );
-
- anglediff = AngleNormalize( anglediff );
-
- float scale = 1.0f;
- if ( anglediffabs <= FADE_TURN_DEGREES )
- {
- scale = anglediffabs / FADE_TURN_DEGREES;
- // Always do at least a bit of the turn ( 1% )
- scale = clamp( scale, 0.01f, 1.0f );
- }
-
- float maxmove = maxrate * dt * scale;
-
- if ( fabs( anglediff ) < maxmove )
- {
- current = goal;
- }
- else
- {
- if ( anglediff > 0 )
- {
- current += maxmove;
- direction = TURN_LEFT;
- }
- else
- {
- current -= maxmove;
- direction = TURN_RIGHT;
- }
- }
-
- current = AngleNormalize( current );
-
- return direction;
-}
-
-void CPlayerAnimState::ComputePoseParam_BodyLookYaw( void )
-{
- QAngle absangles = GetOuter()->GetAbsAngles();
- absangles.y = AngleNormalize( absangles.y );
- m_angRender = absangles;
- m_angRender[ PITCH ] = m_angRender[ ROLL ] = 0.0f;
-
- // See if we even have a blender for pitch
- int upper_body_yaw = GetOuter()->LookupPoseParameter( "aim_yaw" );
- if ( upper_body_yaw < 0 )
- {
- return;
- }
-
- // Assume upper and lower bodies are aligned and that we're not turning
- float flGoalTorsoYaw = 0.0f;
- int turning = TURN_NONE;
- float turnrate = 360.0f;
-
- Vector vel;
-
- GetOuterAbsVelocity( vel );
-
- bool isMoving = ( vel.Length() > 1.0f ) ? true : false;
-
- if ( !isMoving )
- {
- // Just stopped moving, try and clamp feet
- if ( m_flLastTurnTime <= 0.0f )
- {
- m_flLastTurnTime = gpGlobals->curtime;
- m_flLastYaw = GetOuter()->GetAnimEyeAngles().y;
- // Snap feet to be perfectly aligned with torso/eyes
- m_flGoalFeetYaw = GetOuter()->GetAnimEyeAngles().y;
- m_flCurrentFeetYaw = m_flGoalFeetYaw;
- m_nTurningInPlace = TURN_NONE;
- }
-
- // If rotating in place, update stasis timer
- if ( m_flLastYaw != GetOuter()->GetAnimEyeAngles().y )
- {
- m_flLastTurnTime = gpGlobals->curtime;
- m_flLastYaw = GetOuter()->GetAnimEyeAngles().y;
- }
-
- if ( m_flGoalFeetYaw != m_flCurrentFeetYaw )
- {
- m_flLastTurnTime = gpGlobals->curtime;
- }
-
- turning = ConvergeAngles( m_flGoalFeetYaw, turnrate, gpGlobals->frametime, m_flCurrentFeetYaw );
-
- QAngle eyeAngles = GetOuter()->GetAnimEyeAngles();
- QAngle vAngle = GetOuter()->GetLocalAngles();
-
- // See how far off current feetyaw is from true yaw
- float yawdelta = GetOuter()->GetAnimEyeAngles().y - m_flCurrentFeetYaw;
- yawdelta = AngleNormalize( yawdelta );
-
- bool rotated_too_far = false;
-
- float yawmagnitude = fabs( yawdelta );
-
- // If too far, then need to turn in place
- if ( yawmagnitude > 45 )
- {
- rotated_too_far = true;
- }
-
- // Standing still for a while, rotate feet around to face forward
- // Or rotated too far
- // FIXME: Play an in place turning animation
- if ( rotated_too_far ||
- ( gpGlobals->curtime > m_flLastTurnTime + mp_facefronttime.GetFloat() ) )
- {
- m_flGoalFeetYaw = GetOuter()->GetAnimEyeAngles().y;
- m_flLastTurnTime = gpGlobals->curtime;
-
- /* float yd = m_flCurrentFeetYaw - m_flGoalFeetYaw;
- if ( yd > 0 )
- {
- m_nTurningInPlace = TURN_RIGHT;
- }
- else if ( yd < 0 )
- {
- m_nTurningInPlace = TURN_LEFT;
- }
- else
- {
- m_nTurningInPlace = TURN_NONE;
- }
-
- turning = ConvergeAngles( m_flGoalFeetYaw, turnrate, gpGlobals->frametime, m_flCurrentFeetYaw );
- yawdelta = GetOuter()->GetAnimEyeAngles().y - m_flCurrentFeetYaw;*/
-
- }
-
- // Snap upper body into position since the delta is already smoothed for the feet
- flGoalTorsoYaw = yawdelta;
- m_flCurrentTorsoYaw = flGoalTorsoYaw;
- }
- else
- {
- m_flLastTurnTime = 0.0f;
- m_nTurningInPlace = TURN_NONE;
- m_flCurrentFeetYaw = m_flGoalFeetYaw = GetOuter()->GetAnimEyeAngles().y;
- flGoalTorsoYaw = 0.0f;
- m_flCurrentTorsoYaw = GetOuter()->GetAnimEyeAngles().y - m_flCurrentFeetYaw;
- }
-
-
- if ( turning == TURN_NONE )
- {
- m_nTurningInPlace = turning;
- }
-
- if ( m_nTurningInPlace != TURN_NONE )
- {
- // If we're close to finishing the turn, then turn off the turning animation
- if ( fabs( m_flCurrentFeetYaw - m_flGoalFeetYaw ) < MIN_TURN_ANGLE_REQUIRING_TURN_ANIMATION )
- {
- m_nTurningInPlace = TURN_NONE;
- }
- }
-
- // Rotate entire body into position
- absangles = GetOuter()->GetAbsAngles();
- absangles.y = m_flCurrentFeetYaw;
- m_angRender = absangles;
- m_angRender[ PITCH ] = m_angRender[ ROLL ] = 0.0f;
-
- GetOuter()->SetPoseParameter( upper_body_yaw, clamp( m_flCurrentTorsoYaw, -60.0f, 60.0f ) );
-
- /*
- // FIXME: Adrian, what is this?
- int body_yaw = GetOuter()->LookupPoseParameter( "body_yaw" );
-
- if ( body_yaw >= 0 )
- {
- GetOuter()->SetPoseParameter( body_yaw, 30 );
- }
- */
-
-}
-
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : activity -
-// Output : Activity
-//-----------------------------------------------------------------------------
-Activity CPlayerAnimState::BodyYawTranslateActivity( Activity activity )
-{
- // Not even standing still, sigh
- if ( activity != ACT_IDLE )
- return activity;
-
- // Not turning
- switch ( m_nTurningInPlace )
- {
- default:
- case TURN_NONE:
- return activity;
- /*
- case TURN_RIGHT:
- return ACT_TURNRIGHT45;
- case TURN_LEFT:
- return ACT_TURNLEFT45;
- */
- case TURN_RIGHT:
- case TURN_LEFT:
- return mp_ik.GetBool() ? ACT_TURN : activity;
- }
-
- Assert( 0 );
- return activity;
-}
-
-const QAngle& CPlayerAnimState::GetRenderAngles()
-{
- return m_angRender;
-}
-
-
-void CPlayerAnimState::GetOuterAbsVelocity( Vector& vel )
-{
-#if defined( CLIENT_DLL )
- GetOuter()->EstimateAbsVelocity( vel );
-#else
- vel = GetOuter()->GetAbsVelocity();
-#endif
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#include "cbase.h" + +#ifdef CLIENT_DLL +#include "c_hl2mp_player.h" +#include "prediction.h" +#define CRecipientFilter C_RecipientFilter +#else +#include "hl2mp_player.h" +#endif + +#include "engine/IEngineSound.h" +#include "SoundEmitterSystem/isoundemittersystembase.h" + +extern ConVar sv_footsteps; + +const char *g_ppszPlayerSoundPrefixNames[PLAYER_SOUNDS_MAX] = +{ + "NPC_Citizen", + "NPC_CombineS", + "NPC_MetroPolice", +}; + +const char *CHL2MP_Player::GetPlayerModelSoundPrefix( void ) +{ + return g_ppszPlayerSoundPrefixNames[m_iPlayerSoundType]; +} + +void CHL2MP_Player::PrecacheFootStepSounds( void ) +{ + int iFootstepSounds = ARRAYSIZE( g_ppszPlayerSoundPrefixNames ); + int i; + + for ( i = 0; i < iFootstepSounds; ++i ) + { + char szFootStepName[128]; + + Q_snprintf( szFootStepName, sizeof( szFootStepName ), "%s.RunFootstepLeft", g_ppszPlayerSoundPrefixNames[i] ); + PrecacheScriptSound( szFootStepName ); + + Q_snprintf( szFootStepName, sizeof( szFootStepName ), "%s.RunFootstepRight", g_ppszPlayerSoundPrefixNames[i] ); + PrecacheScriptSound( szFootStepName ); + } +} + +//----------------------------------------------------------------------------- +// Consider the weapon's built-in accuracy, this character's proficiency with +// the weapon, and the status of the target. Use this information to determine +// how accurately to shoot at the target. +//----------------------------------------------------------------------------- +Vector CHL2MP_Player::GetAttackSpread( CBaseCombatWeapon *pWeapon, CBaseEntity *pTarget ) +{ + if ( pWeapon ) + return pWeapon->GetBulletSpread( WEAPON_PROFICIENCY_PERFECT ); + + return VECTOR_CONE_15DEGREES; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : step - +// fvol - +// force - force sound to play +//----------------------------------------------------------------------------- +void CHL2MP_Player::PlayStepSound( Vector &vecOrigin, surfacedata_t *psurface, float fvol, bool force ) +{ + if ( gpGlobals->maxClients > 1 && !sv_footsteps.GetFloat() ) + return; + +#if defined( CLIENT_DLL ) + // during prediction play footstep sounds only once + if ( !prediction->IsFirstTimePredicted() ) + return; +#endif + + if ( GetFlags() & FL_DUCKING ) + return; + + m_Local.m_nStepside = !m_Local.m_nStepside; + + char szStepSound[128]; + + if ( m_Local.m_nStepside ) + { + Q_snprintf( szStepSound, sizeof( szStepSound ), "%s.RunFootstepLeft", g_ppszPlayerSoundPrefixNames[m_iPlayerSoundType] ); + } + else + { + Q_snprintf( szStepSound, sizeof( szStepSound ), "%s.RunFootstepRight", g_ppszPlayerSoundPrefixNames[m_iPlayerSoundType] ); + } + + CSoundParameters params; + if ( GetParametersForSound( szStepSound, params, NULL ) == false ) + return; + + CRecipientFilter filter; + filter.AddRecipientsByPAS( vecOrigin ); + +#ifndef CLIENT_DLL + // im MP, server removed all players in origins PVS, these players + // generate the footsteps clientside + if ( gpGlobals->maxClients > 1 ) + filter.RemoveRecipientsByPVS( vecOrigin ); +#endif + + EmitSound_t ep; + ep.m_nChannel = CHAN_BODY; + ep.m_pSoundName = params.soundname; + ep.m_flVolume = fvol; + ep.m_SoundLevel = params.soundlevel; + ep.m_nFlags = 0; + ep.m_nPitch = params.pitch; + ep.m_pOrigin = &vecOrigin; + + EmitSound( filter, entindex(), ep ); +} + + +//========================== +// ANIMATION CODE +//========================== + + +// Below this many degrees, slow down turning rate linearly +#define FADE_TURN_DEGREES 45.0f +// After this, need to start turning feet +#define MAX_TORSO_ANGLE 90.0f +// Below this amount, don't play a turning animation/perform IK +#define MIN_TURN_ANGLE_REQUIRING_TURN_ANIMATION 15.0f + +static ConVar tf2_feetyawrunscale( "tf2_feetyawrunscale", "2", FCVAR_REPLICATED, "Multiplier on tf2_feetyawrate to allow turning faster when running." ); +extern ConVar sv_backspeed; +extern ConVar mp_feetyawrate; +extern ConVar mp_facefronttime; +extern ConVar mp_ik; + +CPlayerAnimState::CPlayerAnimState( CHL2MP_Player *outer ) + : m_pOuter( outer ) +{ + m_flGaitYaw = 0.0f; + m_flGoalFeetYaw = 0.0f; + m_flCurrentFeetYaw = 0.0f; + m_flCurrentTorsoYaw = 0.0f; + m_flLastYaw = 0.0f; + m_flLastTurnTime = 0.0f; + m_flTurnCorrectionTime = 0.0f; +}; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPlayerAnimState::Update() +{ + m_angRender = GetOuter()->GetLocalAngles(); + m_angRender[ PITCH ] = m_angRender[ ROLL ] = 0.0f; + + ComputePoseParam_BodyYaw(); + ComputePoseParam_BodyPitch(GetOuter()->GetModelPtr()); + ComputePoseParam_BodyLookYaw(); + + ComputePlaybackRate(); + +#ifdef CLIENT_DLL + GetOuter()->UpdateLookAt(); +#endif + +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPlayerAnimState::ComputePlaybackRate() +{ + // Determine ideal playback rate + Vector vel; + GetOuterAbsVelocity( vel ); + + float speed = vel.Length2D(); + + bool isMoving = ( speed > 0.5f ) ? true : false; + + float maxspeed = GetOuter()->GetSequenceGroundSpeed( GetOuter()->GetSequence() ); + + if ( isMoving && ( maxspeed > 0.0f ) ) + { + float flFactor = 1.0f; + + // Note this gets set back to 1.0 if sequence changes due to ResetSequenceInfo below + GetOuter()->SetPlaybackRate( ( speed * flFactor ) / maxspeed ); + + // BUG BUG: + // This stuff really should be m_flPlaybackRate = speed / m_flGroundSpeed + } + else + { + GetOuter()->SetPlaybackRate( 1.0f ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : CBasePlayer +//----------------------------------------------------------------------------- +CHL2MP_Player *CPlayerAnimState::GetOuter() +{ + return m_pOuter; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : dt - +//----------------------------------------------------------------------------- +void CPlayerAnimState::EstimateYaw( void ) +{ + float dt = gpGlobals->frametime; + + if ( !dt ) + { + return; + } + + Vector est_velocity; + QAngle angles; + + GetOuterAbsVelocity( est_velocity ); + + angles = GetOuter()->GetLocalAngles(); + + if ( est_velocity[1] == 0 && est_velocity[0] == 0 ) + { + float flYawDiff = angles[YAW] - m_flGaitYaw; + flYawDiff = flYawDiff - (int)(flYawDiff / 360) * 360; + if (flYawDiff > 180) + flYawDiff -= 360; + if (flYawDiff < -180) + flYawDiff += 360; + + if (dt < 0.25) + flYawDiff *= dt * 4; + else + flYawDiff *= dt; + + m_flGaitYaw += flYawDiff; + m_flGaitYaw = m_flGaitYaw - (int)(m_flGaitYaw / 360) * 360; + } + else + { + m_flGaitYaw = (atan2(est_velocity[1], est_velocity[0]) * 180 / M_PI); + + if (m_flGaitYaw > 180) + m_flGaitYaw = 180; + else if (m_flGaitYaw < -180) + m_flGaitYaw = -180; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Override for backpeddling +// Input : dt - +//----------------------------------------------------------------------------- +void CPlayerAnimState::ComputePoseParam_BodyYaw( void ) +{ + int iYaw = GetOuter()->LookupPoseParameter( "move_yaw" ); + if ( iYaw < 0 ) + return; + + // view direction relative to movement + float flYaw; + + EstimateYaw(); + + QAngle angles = GetOuter()->GetLocalAngles(); + float ang = angles[ YAW ]; + if ( ang > 180.0f ) + { + ang -= 360.0f; + } + else if ( ang < -180.0f ) + { + ang += 360.0f; + } + + // calc side to side turning + flYaw = ang - m_flGaitYaw; + // Invert for mapping into 8way blend + flYaw = -flYaw; + flYaw = flYaw - (int)(flYaw / 360) * 360; + + if (flYaw < -180) + { + flYaw = flYaw + 360; + } + else if (flYaw > 180) + { + flYaw = flYaw - 360; + } + + GetOuter()->SetPoseParameter( iYaw, flYaw ); + +#ifndef CLIENT_DLL + //Adrian: Make the model's angle match the legs so the hitboxes match on both sides. + GetOuter()->SetLocalAngles( QAngle( GetOuter()->GetAnimEyeAngles().x, m_flCurrentFeetYaw, 0 ) ); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CPlayerAnimState::ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr ) +{ + // Get pitch from v_angle + float flPitch = GetOuter()->GetLocalAngles()[ PITCH ]; + + if ( flPitch > 180.0f ) + { + flPitch -= 360.0f; + } + flPitch = clamp( flPitch, -90, 90 ); + + QAngle absangles = GetOuter()->GetAbsAngles(); + absangles.x = 0.0f; + m_angRender = absangles; + m_angRender[ PITCH ] = m_angRender[ ROLL ] = 0.0f; + + // See if we have a blender for pitch + GetOuter()->SetPoseParameter( pStudioHdr, "aim_pitch", flPitch ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : goal - +// maxrate - +// dt - +// current - +// Output : int +//----------------------------------------------------------------------------- +int CPlayerAnimState::ConvergeAngles( float goal,float maxrate, float dt, float& current ) +{ + int direction = TURN_NONE; + + float anglediff = goal - current; + float anglediffabs = fabs( anglediff ); + + anglediff = AngleNormalize( anglediff ); + + float scale = 1.0f; + if ( anglediffabs <= FADE_TURN_DEGREES ) + { + scale = anglediffabs / FADE_TURN_DEGREES; + // Always do at least a bit of the turn ( 1% ) + scale = clamp( scale, 0.01f, 1.0f ); + } + + float maxmove = maxrate * dt * scale; + + if ( fabs( anglediff ) < maxmove ) + { + current = goal; + } + else + { + if ( anglediff > 0 ) + { + current += maxmove; + direction = TURN_LEFT; + } + else + { + current -= maxmove; + direction = TURN_RIGHT; + } + } + + current = AngleNormalize( current ); + + return direction; +} + +void CPlayerAnimState::ComputePoseParam_BodyLookYaw( void ) +{ + QAngle absangles = GetOuter()->GetAbsAngles(); + absangles.y = AngleNormalize( absangles.y ); + m_angRender = absangles; + m_angRender[ PITCH ] = m_angRender[ ROLL ] = 0.0f; + + // See if we even have a blender for pitch + int upper_body_yaw = GetOuter()->LookupPoseParameter( "aim_yaw" ); + if ( upper_body_yaw < 0 ) + { + return; + } + + // Assume upper and lower bodies are aligned and that we're not turning + float flGoalTorsoYaw = 0.0f; + int turning = TURN_NONE; + float turnrate = 360.0f; + + Vector vel; + + GetOuterAbsVelocity( vel ); + + bool isMoving = ( vel.Length() > 1.0f ) ? true : false; + + if ( !isMoving ) + { + // Just stopped moving, try and clamp feet + if ( m_flLastTurnTime <= 0.0f ) + { + m_flLastTurnTime = gpGlobals->curtime; + m_flLastYaw = GetOuter()->GetAnimEyeAngles().y; + // Snap feet to be perfectly aligned with torso/eyes + m_flGoalFeetYaw = GetOuter()->GetAnimEyeAngles().y; + m_flCurrentFeetYaw = m_flGoalFeetYaw; + m_nTurningInPlace = TURN_NONE; + } + + // If rotating in place, update stasis timer + if ( m_flLastYaw != GetOuter()->GetAnimEyeAngles().y ) + { + m_flLastTurnTime = gpGlobals->curtime; + m_flLastYaw = GetOuter()->GetAnimEyeAngles().y; + } + + if ( m_flGoalFeetYaw != m_flCurrentFeetYaw ) + { + m_flLastTurnTime = gpGlobals->curtime; + } + + turning = ConvergeAngles( m_flGoalFeetYaw, turnrate, gpGlobals->frametime, m_flCurrentFeetYaw ); + + QAngle eyeAngles = GetOuter()->GetAnimEyeAngles(); + QAngle vAngle = GetOuter()->GetLocalAngles(); + + // See how far off current feetyaw is from true yaw + float yawdelta = GetOuter()->GetAnimEyeAngles().y - m_flCurrentFeetYaw; + yawdelta = AngleNormalize( yawdelta ); + + bool rotated_too_far = false; + + float yawmagnitude = fabs( yawdelta ); + + // If too far, then need to turn in place + if ( yawmagnitude > 45 ) + { + rotated_too_far = true; + } + + // Standing still for a while, rotate feet around to face forward + // Or rotated too far + // FIXME: Play an in place turning animation + if ( rotated_too_far || + ( gpGlobals->curtime > m_flLastTurnTime + mp_facefronttime.GetFloat() ) ) + { + m_flGoalFeetYaw = GetOuter()->GetAnimEyeAngles().y; + m_flLastTurnTime = gpGlobals->curtime; + + /* float yd = m_flCurrentFeetYaw - m_flGoalFeetYaw; + if ( yd > 0 ) + { + m_nTurningInPlace = TURN_RIGHT; + } + else if ( yd < 0 ) + { + m_nTurningInPlace = TURN_LEFT; + } + else + { + m_nTurningInPlace = TURN_NONE; + } + + turning = ConvergeAngles( m_flGoalFeetYaw, turnrate, gpGlobals->frametime, m_flCurrentFeetYaw ); + yawdelta = GetOuter()->GetAnimEyeAngles().y - m_flCurrentFeetYaw;*/ + + } + + // Snap upper body into position since the delta is already smoothed for the feet + flGoalTorsoYaw = yawdelta; + m_flCurrentTorsoYaw = flGoalTorsoYaw; + } + else + { + m_flLastTurnTime = 0.0f; + m_nTurningInPlace = TURN_NONE; + m_flCurrentFeetYaw = m_flGoalFeetYaw = GetOuter()->GetAnimEyeAngles().y; + flGoalTorsoYaw = 0.0f; + m_flCurrentTorsoYaw = GetOuter()->GetAnimEyeAngles().y - m_flCurrentFeetYaw; + } + + + if ( turning == TURN_NONE ) + { + m_nTurningInPlace = turning; + } + + if ( m_nTurningInPlace != TURN_NONE ) + { + // If we're close to finishing the turn, then turn off the turning animation + if ( fabs( m_flCurrentFeetYaw - m_flGoalFeetYaw ) < MIN_TURN_ANGLE_REQUIRING_TURN_ANIMATION ) + { + m_nTurningInPlace = TURN_NONE; + } + } + + // Rotate entire body into position + absangles = GetOuter()->GetAbsAngles(); + absangles.y = m_flCurrentFeetYaw; + m_angRender = absangles; + m_angRender[ PITCH ] = m_angRender[ ROLL ] = 0.0f; + + GetOuter()->SetPoseParameter( upper_body_yaw, clamp( m_flCurrentTorsoYaw, -60.0f, 60.0f ) ); + + /* + // FIXME: Adrian, what is this? + int body_yaw = GetOuter()->LookupPoseParameter( "body_yaw" ); + + if ( body_yaw >= 0 ) + { + GetOuter()->SetPoseParameter( body_yaw, 30 ); + } + */ + +} + + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : activity - +// Output : Activity +//----------------------------------------------------------------------------- +Activity CPlayerAnimState::BodyYawTranslateActivity( Activity activity ) +{ + // Not even standing still, sigh + if ( activity != ACT_IDLE ) + return activity; + + // Not turning + switch ( m_nTurningInPlace ) + { + default: + case TURN_NONE: + return activity; + /* + case TURN_RIGHT: + return ACT_TURNRIGHT45; + case TURN_LEFT: + return ACT_TURNLEFT45; + */ + case TURN_RIGHT: + case TURN_LEFT: + return mp_ik.GetBool() ? ACT_TURN : activity; + } + + Assert( 0 ); + return activity; +} + +const QAngle& CPlayerAnimState::GetRenderAngles() +{ + return m_angRender; +} + + +void CPlayerAnimState::GetOuterAbsVelocity( Vector& vel ) +{ +#if defined( CLIENT_DLL ) + GetOuter()->EstimateAbsVelocity( vel ); +#else + vel = GetOuter()->GetAbsVelocity(); +#endif }
\ No newline at end of file |