//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
# include "cbase.h"
# include "tier0/vprof.h"
# include "animation.h"
# include "studio.h"
# include "apparent_velocity_helper.h"
# include "utldict.h"
# include "multiplayer_animstate.h"
# include "activitylist.h"
# ifdef CLIENT_DLL
# include "c_baseplayer.h"
# include "engine/ivdebugoverlay.h"
# include "filesystem.h"
# include "eventlist.h"
ConVar anim_showmainactivity ( " anim_showmainactivity " , " 0 " , FCVAR_CHEAT , " Show the idle, walk, run, and/or sprint activities. " ) ;
# else
# include "player.h"
# endif
# if defined(TF_CLIENT_DLL) || defined(TF_DLL)
# include "tf_gamerules.h"
# endif
# ifndef CALL_ATTRIB_HOOK_FLOAT_ON_OTHER
# define CALL_ATTRIB_HOOK_FLOAT_ON_OTHER( o, r, n )
# endif
# define MOVING_MINIMUM_SPEED 0.5f
ConVar anim_showstate ( " anim_showstate " , " -1 " , FCVAR_CHEAT | FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY , " Show the (client) animation state for the specified entity ( - 1 for none ) . " ) ;
ConVar anim_showstatelog ( " anim_showstatelog " , " 0 " , FCVAR_CHEAT | FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY , " 1 to output anim_showstate to Msg() . 2 to store in AnimState . log . 3 for both . " ) ;
ConVar mp_showgestureslots ( " mp_showgestureslots " , " -1 " , FCVAR_CHEAT | FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY , " Show multiplayer client/server gesture slot information for the specified player index (-1 for no one) . " ) ;
ConVar mp_slammoveyaw ( " mp_slammoveyaw " , " 0 " , FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY , " Force movement yaw along an animation path. " ) ;
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pPlayer -
// &movementData -
//-----------------------------------------------------------------------------
CMultiPlayerAnimState : : CMultiPlayerAnimState ( CBasePlayer * pPlayer , MultiPlayerMovementData_t & movementData )
# ifdef CLIENT_DLL
: m_iv_flMaxGroundSpeed ( " CMultiPlayerAnimState::m_iv_flMaxGroundSpeed " )
# endif
{
// Pose parameters.
m_bPoseParameterInit = false ;
m_PoseParameterData . Init ( ) ;
m_DebugAnimData . Init ( ) ;
m_pPlayer = NULL ;
m_angRender . Init ( ) ;
m_bCurrentFeetYawInitialized = false ;
m_flLastAnimationStateClearTime = 0.0f ;
m_flEyeYaw = 0.0f ;
m_flEyePitch = 0.0f ;
m_flGoalFeetYaw = 0.0f ;
m_flCurrentFeetYaw = 0.0f ;
m_flLastAimTurnTime = 0.0f ;
// Jumping.
m_bJumping = false ;
m_flJumpStartTime = 0.0f ;
m_bFirstJumpFrame = false ;
// Swimming
m_bInSwim = false ;
m_bFirstSwimFrame = true ;
// Dying
m_bDying = false ;
m_bFirstDyingFrame = true ;
m_eCurrentMainSequenceActivity = ACT_INVALID ;
m_nSpecificMainSequence = - 1 ;
// Weapon data.
m_hActiveWeapon = NULL ;
// Ground speed interpolators.
# ifdef CLIENT_DLL
m_iv_flMaxGroundSpeed . Setup ( & m_flMaxGroundSpeed , LATCH_ANIMATION_VAR | INTERPOLATE_LINEAR_ONLY ) ;
m_flLastGroundSpeedUpdateTime = 0.0f ;
# endif
m_flMaxGroundSpeed = 0.0f ;
m_bForceAimYaw = false ;
Init ( pPlayer , movementData ) ;
// movement playback options
m_nMovementSequence = - 1 ;
m_LegAnimType = LEGANIM_9WAY ;
InitGestureSlots ( ) ;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : -
//-----------------------------------------------------------------------------
CMultiPlayerAnimState : : ~ CMultiPlayerAnimState ( )
{
ShutdownGestureSlots ( ) ;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pPlayer -
// &movementData -
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : Init ( CBasePlayer * pPlayer , MultiPlayerMovementData_t & movementData )
{
// Get the player this animation data works on.
m_pPlayer = pPlayer ;
// Copy the movement data.
memcpy ( & m_MovementData , & movementData , sizeof ( MultiPlayerMovementData_t ) ) ;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : -
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : ClearAnimationState ( )
{
// Reset state.
m_bJumping = false ;
m_bDying = false ;
m_bCurrentFeetYawInitialized = false ;
m_flLastAnimationStateClearTime = gpGlobals - > curtime ;
m_nSpecificMainSequence = - 1 ;
ResetGestureSlots ( ) ;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : event -
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : DoAnimationEvent ( PlayerAnimEvent_t event , int nData )
{
switch ( event )
{
case PLAYERANIMEVENT_ATTACK_PRIMARY :
{
// Weapon primary fire.
RestartGesture ( GESTURE_SLOT_ATTACK_AND_RELOAD , ACT_MP_ATTACK_STAND_PRIMARYFIRE ) ;
break ;
}
case PLAYERANIMEVENT_ATTACK_SECONDARY :
{
// Weapon secondary fire.
RestartGesture ( GESTURE_SLOT_ATTACK_AND_RELOAD , ACT_MP_ATTACK_STAND_SECONDARYFIRE ) ;
break ;
}
case PLAYERANIMEVENT_ATTACK_GRENADE :
{
// Grenade throw.
RestartGesture ( GESTURE_SLOT_GRENADE , ACT_MP_ATTACK_STAND_GRENADE ) ;
break ;
}
case PLAYERANIMEVENT_RELOAD :
{
// Weapon reload.
if ( GetBasePlayer ( ) - > GetFlags ( ) & FL_DUCKING )
{
RestartGesture ( GESTURE_SLOT_ATTACK_AND_RELOAD , ACT_MP_RELOAD_CROUCH ) ;
}
else if ( m_bInSwim )
{
RestartGesture ( GESTURE_SLOT_ATTACK_AND_RELOAD , ACT_MP_RELOAD_SWIM ) ;
}
else
{
RestartGesture ( GESTURE_SLOT_ATTACK_AND_RELOAD , ACT_MP_RELOAD_STAND ) ;
}
// Set the modified reload playback rate
float flPlaybackRate = 1.0f ;
# if defined(TF_CLIENT_DLL) || defined(TF_DLL)
CALL_ATTRIB_HOOK_FLOAT_ON_OTHER ( GetBasePlayer ( ) , flPlaybackRate , mult_reload_time ) ;
CALL_ATTRIB_HOOK_FLOAT_ON_OTHER ( GetBasePlayer ( ) , flPlaybackRate , mult_reload_time_hidden ) ;
CALL_ATTRIB_HOOK_FLOAT_ON_OTHER ( GetBasePlayer ( ) , flPlaybackRate , fast_reload ) ;
# endif
m_aGestureSlots [ GESTURE_SLOT_ATTACK_AND_RELOAD ] . m_pAnimLayer - > m_flPlaybackRate = flPlaybackRate ;
break ;
}
case PLAYERANIMEVENT_RELOAD_LOOP :
{
// Weapon reload.
if ( GetBasePlayer ( ) - > GetFlags ( ) & FL_DUCKING )
{
RestartGesture ( GESTURE_SLOT_ATTACK_AND_RELOAD , ACT_MP_RELOAD_CROUCH_LOOP ) ;
}
else if ( m_bInSwim )
{
RestartGesture ( GESTURE_SLOT_ATTACK_AND_RELOAD , ACT_MP_RELOAD_SWIM_LOOP ) ;
}
else
{
RestartGesture ( GESTURE_SLOT_ATTACK_AND_RELOAD , ACT_MP_RELOAD_STAND_LOOP ) ;
}
// Set the modified reload playback rate
float flPlaybackRate = 1.0f ;
# if defined(TF_CLIENT_DLL) || defined(TF_DLL)
CALL_ATTRIB_HOOK_FLOAT_ON_OTHER ( GetBasePlayer ( ) , flPlaybackRate , mult_reload_time ) ;
CALL_ATTRIB_HOOK_FLOAT_ON_OTHER ( GetBasePlayer ( ) , flPlaybackRate , mult_reload_time_hidden ) ;
CALL_ATTRIB_HOOK_FLOAT_ON_OTHER ( GetBasePlayer ( ) , flPlaybackRate , fast_reload ) ;
# endif
m_aGestureSlots [ GESTURE_SLOT_ATTACK_AND_RELOAD ] . m_pAnimLayer - > m_flPlaybackRate = flPlaybackRate ;
break ;
}
case PLAYERANIMEVENT_RELOAD_END :
{
// Weapon reload.
if ( GetBasePlayer ( ) - > GetFlags ( ) & FL_DUCKING )
{
RestartGesture ( GESTURE_SLOT_ATTACK_AND_RELOAD , ACT_MP_RELOAD_CROUCH_END ) ;
}
else if ( m_bInSwim )
{
RestartGesture ( GESTURE_SLOT_ATTACK_AND_RELOAD , ACT_MP_RELOAD_SWIM_END ) ;
}
else
{
RestartGesture ( GESTURE_SLOT_ATTACK_AND_RELOAD , ACT_MP_RELOAD_STAND_END ) ;
}
// Set the modified reload playback rate
float flPlaybackRate = 1.0f ;
# if defined(TF_CLIENT_DLL) || defined(TF_DLL)
CALL_ATTRIB_HOOK_FLOAT_ON_OTHER ( GetBasePlayer ( ) , flPlaybackRate , mult_reload_time ) ;
CALL_ATTRIB_HOOK_FLOAT_ON_OTHER ( GetBasePlayer ( ) , flPlaybackRate , mult_reload_time_hidden ) ;
CALL_ATTRIB_HOOK_FLOAT_ON_OTHER ( GetBasePlayer ( ) , flPlaybackRate , fast_reload ) ;
# endif
m_aGestureSlots [ GESTURE_SLOT_ATTACK_AND_RELOAD ] . m_pAnimLayer - > m_flPlaybackRate = flPlaybackRate ;
break ;
}
case PLAYERANIMEVENT_JUMP :
{
// Jump.
m_bJumping = true ;
m_bFirstJumpFrame = true ;
m_flJumpStartTime = gpGlobals - > curtime ;
RestartMainSequence ( ) ;
break ;
}
case PLAYERANIMEVENT_DIE :
{
// Should be here - not supporting this yet!
Assert ( 0 ) ;
// Start playing the death animation
m_bDying = true ;
RestartMainSequence ( ) ;
break ;
}
case PLAYERANIMEVENT_SPAWN :
{
// Player has respawned. Clear flags.
ClearAnimationState ( ) ;
break ;
}
case PLAYERANIMEVENT_SNAP_YAW :
m_PoseParameterData . m_flLastAimTurnTime = 0.0f ;
break ;
case PLAYERANIMEVENT_CUSTOM :
{
Activity iIdealActivity = TranslateActivity ( ( Activity ) nData ) ;
m_nSpecificMainSequence = GetBasePlayer ( ) - > SelectWeightedSequence ( iIdealActivity ) ;
RestartMainSequence ( ) ;
}
break ;
case PLAYERANIMEVENT_CUSTOM_GESTURE :
// Weapon primary fire.
RestartGesture ( GESTURE_SLOT_CUSTOM , ( Activity ) nData ) ;
break ;
case PLAYERANIMEVENT_CUSTOM_SEQUENCE :
m_nSpecificMainSequence = nData ;
RestartMainSequence ( ) ;
break ;
case PLAYERANIMEVENT_CUSTOM_GESTURE_SEQUENCE :
// Weapon primary fire.
// RestartGestureSequence( nData, false );
break ;
case PLAYERANIMEVENT_FLINCH_CHEST :
PlayFlinchGesture ( ACT_MP_GESTURE_FLINCH_CHEST ) ;
break ;
case PLAYERANIMEVENT_FLINCH_HEAD :
PlayFlinchGesture ( ACT_MP_GESTURE_FLINCH_HEAD ) ;
break ;
case PLAYERANIMEVENT_FLINCH_LEFTARM :
PlayFlinchGesture ( ACT_MP_GESTURE_FLINCH_LEFTARM ) ;
break ;
case PLAYERANIMEVENT_FLINCH_RIGHTARM :
PlayFlinchGesture ( ACT_MP_GESTURE_FLINCH_RIGHTARM ) ;
break ;
case PLAYERANIMEVENT_FLINCH_LEFTLEG :
PlayFlinchGesture ( ACT_MP_GESTURE_FLINCH_LEFTLEG ) ;
break ;
case PLAYERANIMEVENT_FLINCH_RIGHTLEG :
PlayFlinchGesture ( ACT_MP_GESTURE_FLINCH_RIGHTLEG ) ;
break ;
default :
break ;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : PlayFlinchGesture ( Activity iActivity )
{
if ( ! IsGestureSlotActive ( GESTURE_SLOT_FLINCH ) )
{
// See if we have the custom flinch. If not, revert to chest
if ( iActivity ! = ACT_MP_GESTURE_FLINCH_CHEST & & GetBasePlayer ( ) - > SelectWeightedSequence ( iActivity ) = = - 1 )
{
RestartGesture ( GESTURE_SLOT_FLINCH , ACT_MP_GESTURE_FLINCH_CHEST ) ;
}
else
{
RestartGesture ( GESTURE_SLOT_FLINCH , iActivity ) ;
}
}
}
//=============================================================================
//
// Multiplayer gesture code.
//
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CMultiPlayerAnimState : : InitGestureSlots ( void )
{
// Setup the number of gesture slots.
m_aGestureSlots . AddMultipleToTail ( GESTURE_SLOT_COUNT ) ;
// Assign all of the the CAnimationLayer pointers to null early in case we bail.
for ( int iGesture = 0 ; iGesture < GESTURE_SLOT_COUNT ; + + iGesture )
{
m_aGestureSlots [ iGesture ] . m_pAnimLayer = NULL ;
}
// Get the base player.
CBasePlayer * pPlayer = GetBasePlayer ( ) ;
// Set the number of animation overlays we will use.
pPlayer - > SetNumAnimOverlays ( GESTURE_SLOT_COUNT ) ;
for ( int iGesture = 0 ; iGesture < GESTURE_SLOT_COUNT ; + + iGesture )
{
m_aGestureSlots [ iGesture ] . m_pAnimLayer = pPlayer - > GetAnimOverlay ( iGesture ) ;
if ( ! m_aGestureSlots [ iGesture ] . m_pAnimLayer )
return false ;
ResetGestureSlot ( iGesture ) ;
}
return true ;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : ShutdownGestureSlots ( void )
{
// Clean up the gesture slots.
m_aGestureSlots . Purge ( ) ;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : ResetGestureSlots ( void )
{
// Clear out all the gesture slots.
for ( int iGesture = 0 ; iGesture < GESTURE_SLOT_COUNT ; + + iGesture )
{
ResetGestureSlot ( iGesture ) ;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : ResetGestureSlot ( int iGestureSlot )
{
// Sanity Check
Assert ( iGestureSlot > = 0 & & iGestureSlot < GESTURE_SLOT_COUNT ) ;
if ( ! VerifyAnimLayerInSlot ( iGestureSlot ) )
return ;
GestureSlot_t * pGestureSlot = & m_aGestureSlots [ iGestureSlot ] ;
if ( pGestureSlot )
{
# ifdef CLIENT_DLL
// briefly set to 1.0 so we catch the events, before we reset the slot
pGestureSlot - > m_pAnimLayer - > m_flCycle = 1.0 ;
RunGestureSlotAnimEventsToCompletion ( pGestureSlot ) ;
# endif
pGestureSlot - > m_iGestureSlot = GESTURE_SLOT_INVALID ;
pGestureSlot - > m_iActivity = ACT_INVALID ;
pGestureSlot - > m_bAutoKill = false ;
pGestureSlot - > m_bActive = false ;
if ( pGestureSlot - > m_pAnimLayer )
{
pGestureSlot - > m_pAnimLayer - > SetOrder ( CBaseAnimatingOverlay : : MAX_OVERLAYS ) ;
# ifdef CLIENT_DLL
pGestureSlot - > m_pAnimLayer - > Reset ( ) ;
# endif
}
}
}
# ifdef CLIENT_DLL
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : RunGestureSlotAnimEventsToCompletion ( GestureSlot_t * pGesture )
{
CBasePlayer * pPlayer = GetBasePlayer ( ) ;
if ( ! pPlayer )
return ;
// Get the studio header for the player.
CStudioHdr * pStudioHdr = pPlayer - > GetModelPtr ( ) ;
if ( ! pStudioHdr )
return ;
// Do all the anim events between previous cycle and 1.0, inclusive
mstudioseqdesc_t & seqdesc = pStudioHdr - > pSeqdesc ( pGesture - > m_pAnimLayer - > m_nSequence ) ;
if ( seqdesc . numevents > 0 )
{
mstudioevent_t * pevent = seqdesc . pEvent ( 0 ) ;
for ( int i = 0 ; i < ( int ) seqdesc . numevents ; i + + )
{
if ( pevent [ i ] . type & AE_TYPE_NEWEVENTSYSTEM )
{
if ( ! ( pevent [ i ] . type & AE_TYPE_CLIENT ) )
continue ;
}
else if ( pevent [ i ] . event < 5000 ) //Adrian - Support the old event system
continue ;
if ( pevent [ i ] . cycle > pGesture - > m_pAnimLayer - > m_flPrevCycle & &
pevent [ i ] . cycle < = pGesture - > m_pAnimLayer - > m_flCycle )
{
pPlayer - > FireEvent ( pPlayer - > GetAbsOrigin ( ) , pPlayer - > GetAbsAngles ( ) , pevent [ i ] . event , pevent [ i ] . pszOptions ( ) ) ;
}
}
}
}
# endif
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CMultiPlayerAnimState : : IsGestureSlotActive ( int iGestureSlot )
{
// Sanity Check
Assert ( iGestureSlot > = 0 & & iGestureSlot < GESTURE_SLOT_COUNT ) ;
return m_aGestureSlots [ iGestureSlot ] . m_bActive ;
}
//-----------------------------------------------------------------------------
// Purpose: Track down a crash
//-----------------------------------------------------------------------------
bool CMultiPlayerAnimState : : VerifyAnimLayerInSlot ( int iGestureSlot )
{
if ( iGestureSlot < 0 | | iGestureSlot > = GESTURE_SLOT_COUNT )
{
return false ;
}
if ( GetBasePlayer ( ) - > GetNumAnimOverlays ( ) < iGestureSlot + 1 )
{
AssertMsg2 ( false , " Player %d doesn't have gesture slot %d any more. " , GetBasePlayer ( ) - > entindex ( ) , iGestureSlot ) ;
Msg ( " Player %d doesn't have gesture slot %d any more. \n " , GetBasePlayer ( ) - > entindex ( ) , iGestureSlot ) ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer = NULL ;
return false ;
}
CAnimationLayer * pExpected = GetBasePlayer ( ) - > GetAnimOverlay ( iGestureSlot ) ;
if ( m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer ! = pExpected )
{
AssertMsg3 ( false , " Gesture slot %d pointing to wrong address %p. Updating to new address %p. " , iGestureSlot , m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer , pExpected ) ;
Msg ( " Gesture slot %d pointing to wrong address %p. Updating to new address %p. \n " , iGestureSlot , m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer , pExpected ) ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer = pExpected ;
}
return true ;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CMultiPlayerAnimState : : IsGestureSlotPlaying ( int iGestureSlot , Activity iGestureActivity )
{
// Sanity Check
Assert ( iGestureSlot > = 0 & & iGestureSlot < GESTURE_SLOT_COUNT ) ;
// Check to see if the slot is active.
if ( ! IsGestureSlotActive ( iGestureSlot ) )
return false ;
return ( m_aGestureSlots [ iGestureSlot ] . m_iActivity = = iGestureActivity ) ;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : RestartGesture ( int iGestureSlot , Activity iGestureActivity , bool bAutoKill )
{
// Sanity Check
Assert ( iGestureSlot > = 0 & & iGestureSlot < GESTURE_SLOT_COUNT ) ;
if ( ! VerifyAnimLayerInSlot ( iGestureSlot ) )
return ;
if ( ! IsGestureSlotPlaying ( iGestureSlot , iGestureActivity ) )
{
# ifdef CLIENT_DLL
if ( IsGestureSlotActive ( iGestureSlot ) )
{
GestureSlot_t * pGesture = & m_aGestureSlots [ iGestureSlot ] ;
if ( pGesture & & pGesture - > m_pAnimLayer )
{
pGesture - > m_pAnimLayer - > m_flCycle = 1.0 ; // run until the end
RunGestureSlotAnimEventsToCompletion ( & m_aGestureSlots [ iGestureSlot ] ) ;
}
}
# endif
Activity iIdealGestureActivity = TranslateActivity ( iGestureActivity ) ;
AddToGestureSlot ( iGestureSlot , iIdealGestureActivity , bAutoKill ) ;
return ;
}
// Reset the cycle = restart the gesture.
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flCycle = 0.0f ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flPrevCycle = 0.0f ;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : AddToGestureSlot ( int iGestureSlot , Activity iGestureActivity , bool bAutoKill )
{
// Sanity Check
Assert ( iGestureSlot > = 0 & & iGestureSlot < GESTURE_SLOT_COUNT ) ;
CBasePlayer * pPlayer = GetBasePlayer ( ) ;
if ( ! pPlayer )
return ;
// Make sure we have a valid animation layer to fill out.
if ( ! m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer )
return ;
if ( ! VerifyAnimLayerInSlot ( iGestureSlot ) )
return ;
// Get the sequence.
int iGestureSequence = pPlayer - > SelectWeightedSequence ( iGestureActivity ) ;
if ( iGestureSequence < = 0 )
return ;
# ifdef CLIENT_DLL
// Setup the gesture.
m_aGestureSlots [ iGestureSlot ] . m_iGestureSlot = iGestureSlot ;
m_aGestureSlots [ iGestureSlot ] . m_iActivity = iGestureActivity ;
m_aGestureSlots [ iGestureSlot ] . m_bAutoKill = bAutoKill ;
m_aGestureSlots [ iGestureSlot ] . m_bActive = true ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_nSequence = iGestureSequence ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_nOrder = iGestureSlot ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flWeight = 1.0f ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flPlaybackRate = 1.0f ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flCycle = 0.0f ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flPrevCycle = 0.0f ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flLayerAnimtime = 0.0f ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flLayerFadeOuttime = 0.0f ;
pPlayer - > m_flOverlayPrevEventCycle [ iGestureSlot ] = - 1.0 ;
# else
// Setup the gesture.
m_aGestureSlots [ iGestureSlot ] . m_iGestureSlot = iGestureSlot ;
m_aGestureSlots [ iGestureSlot ] . m_iActivity = iGestureActivity ;
m_aGestureSlots [ iGestureSlot ] . m_bAutoKill = bAutoKill ;
m_aGestureSlots [ iGestureSlot ] . m_bActive = true ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_nActivity = iGestureActivity ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_nOrder = iGestureSlot ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_nPriority = 0 ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flCycle = 0.0f ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flPrevCycle = 0.0f ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flPlaybackRate = 1.0f ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_nActivity = iGestureActivity ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_nSequence = iGestureSequence ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flWeight = 1.0f ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flBlendIn = 0.0f ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flBlendOut = 0.0f ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_bSequenceFinished = false ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flLastEventCheck = 0.0f ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flLastEventCheck = gpGlobals - > curtime ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_bLooping = false ; //( ( GetSequenceFlags( GetModelPtr(), iGestureSequence ) & STUDIO_LOOPING ) != 0);
if ( bAutoKill )
{
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_fFlags | = ANIM_LAYER_AUTOKILL ;
}
else
{
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_fFlags & = ~ ANIM_LAYER_AUTOKILL ;
}
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_fFlags | = ANIM_LAYER_ACTIVE ;
# endif
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : AddVCDSequenceToGestureSlot ( int iGestureSlot , int iGestureSequence , float flCycle , bool bAutoKill )
{
// Sanity Check
Assert ( iGestureSlot > = 0 & & iGestureSlot < GESTURE_SLOT_COUNT ) ;
CBasePlayer * pPlayer = GetBasePlayer ( ) ;
if ( ! pPlayer )
return ;
// Make sure we have a valid animation layer to fill out.
if ( ! m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer )
return ;
if ( ! VerifyAnimLayerInSlot ( iGestureSlot ) )
return ;
// Set the activity.
Activity iGestureActivity = ACT_MP_VCD ;
# ifdef CLIENT_DLL
// Setup the gesture.
m_aGestureSlots [ iGestureSlot ] . m_iGestureSlot = iGestureSlot ;
m_aGestureSlots [ iGestureSlot ] . m_iActivity = iGestureActivity ;
m_aGestureSlots [ iGestureSlot ] . m_bAutoKill = bAutoKill ;
m_aGestureSlots [ iGestureSlot ] . m_bActive = true ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_nSequence = iGestureSequence ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_nOrder = iGestureSlot ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flWeight = 1.0f ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flPlaybackRate = 1.0f ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flCycle = flCycle ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flPrevCycle = 0.0f ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flLayerAnimtime = 0.0f ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flLayerFadeOuttime = 0.0f ;
pPlayer - > m_flOverlayPrevEventCycle [ iGestureSlot ] = - 1.0 ;
# else
// Setup the gesture.
m_aGestureSlots [ iGestureSlot ] . m_iGestureSlot = iGestureSlot ;
m_aGestureSlots [ iGestureSlot ] . m_iActivity = iGestureActivity ;
m_aGestureSlots [ iGestureSlot ] . m_bAutoKill = bAutoKill ;
m_aGestureSlots [ iGestureSlot ] . m_bActive = true ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_nActivity = iGestureActivity ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_nOrder = iGestureSlot ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_nPriority = 0 ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flCycle = flCycle ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flPrevCycle = 0.0f ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flPlaybackRate = 1.0f ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_nActivity = iGestureActivity ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_nSequence = iGestureSequence ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flWeight = 1.0f ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flBlendIn = 0.0f ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flBlendOut = 0.0f ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_bSequenceFinished = false ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flLastEventCheck = 0.0f ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_flLastEventCheck = gpGlobals - > curtime ;
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_bLooping = false ; //( ( GetSequenceFlags( GetModelPtr(), iGestureSequence ) & STUDIO_LOOPING ) != 0);
if ( bAutoKill )
{
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_fFlags | = ANIM_LAYER_AUTOKILL ;
}
else
{
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_fFlags & = ~ ANIM_LAYER_AUTOKILL ;
}
m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer - > m_fFlags | = ANIM_LAYER_ACTIVE ;
# endif
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CAnimationLayer * CMultiPlayerAnimState : : GetGestureSlotLayer ( int iGestureSlot )
{
return m_aGestureSlots [ iGestureSlot ] . m_pAnimLayer ;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : ShowDebugInfo ( void )
{
if ( anim_showstate . GetInt ( ) = = GetBasePlayer ( ) - > entindex ( ) )
{
DebugShowAnimStateForPlayer ( GetBasePlayer ( ) - > IsServer ( ) ) ;
}
}
//-----------------------------------------------------------------------------
// Purpose: Cancel the current gesture and restart the main sequence.
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : RestartMainSequence ( void )
{
CBaseAnimatingOverlay * pPlayer = GetBasePlayer ( ) ;
if ( pPlayer )
{
pPlayer - > m_flAnimTime = gpGlobals - > curtime ;
pPlayer - > SetCycle ( 0 ) ;
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *idealActivity -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CMultiPlayerAnimState : : HandleJumping ( Activity & idealActivity )
{
if ( m_bJumping )
{
if ( m_bFirstJumpFrame )
{
m_bFirstJumpFrame = false ;
RestartMainSequence ( ) ; // Reset the animation.
}
// Check to see if we hit water and stop jumping animation.
if ( GetBasePlayer ( ) - > GetWaterLevel ( ) > = WL_Waist )
{
m_bJumping = false ;
RestartMainSequence ( ) ;
}
// 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.
else if ( gpGlobals - > curtime - m_flJumpStartTime > 0.2f )
{
if ( GetBasePlayer ( ) - > GetFlags ( ) & FL_ONGROUND )
{
m_bJumping = false ;
RestartMainSequence ( ) ;
}
}
}
if ( m_bJumping )
{
idealActivity = ACT_MP_JUMP ;
return true ;
}
else
{
return false ;
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *idealActivity -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CMultiPlayerAnimState : : HandleDucking ( Activity & idealActivity )
{
if ( GetBasePlayer ( ) - > GetFlags ( ) & FL_DUCKING )
{
if ( GetOuterXYSpeed ( ) > MOVING_MINIMUM_SPEED )
{
idealActivity = ACT_MP_CROUCHWALK ;
}
else
{
idealActivity = ACT_MP_CROUCH_IDLE ;
}
return true ;
}
return false ;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : &idealActivity -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CMultiPlayerAnimState : : HandleSwimming ( Activity & idealActivity )
{
if ( GetBasePlayer ( ) - > GetWaterLevel ( ) > = WL_Waist )
{
if ( m_bFirstSwimFrame )
{
// Reset the animation.
RestartMainSequence ( ) ;
m_bFirstSwimFrame = false ;
}
idealActivity = ACT_MP_SWIM ;
m_bInSwim = true ;
return true ;
}
else
{
m_bInSwim = false ;
if ( ! m_bFirstSwimFrame )
{
m_bFirstSwimFrame = true ;
}
}
return false ;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *idealActivity -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CMultiPlayerAnimState : : HandleDying ( Activity & idealActivity )
{
if ( m_bDying )
{
if ( m_bFirstDyingFrame )
{
// Reset the animation.
RestartMainSequence ( ) ;
m_bFirstDyingFrame = false ;
}
idealActivity = ACT_DIESIMPLE ;
return true ;
}
else
{
if ( ! m_bFirstDyingFrame )
{
m_bFirstDyingFrame = true ;
}
}
return false ;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *idealActivity -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CMultiPlayerAnimState : : HandleMoving ( Activity & idealActivity )
{
// In TF we run all the time now.
float flSpeed = GetOuterXYSpeed ( ) ;
if ( flSpeed > MOVING_MINIMUM_SPEED )
{
// Always assume a run.
idealActivity = ACT_MP_RUN ;
}
return true ;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : -
// Output : Activity
//-----------------------------------------------------------------------------
Activity CMultiPlayerAnimState : : CalcMainActivity ( )
{
Activity idealActivity = ACT_MP_STAND_IDLE ;
if ( HandleJumping ( idealActivity ) | |
HandleDucking ( idealActivity ) | |
HandleSwimming ( idealActivity ) | |
HandleDying ( idealActivity ) )
{
// intentionally blank
}
else
{
HandleMoving ( idealActivity ) ;
}
ShowDebugInfo ( ) ;
// Client specific.
# ifdef CLIENT_DLL
if ( anim_showmainactivity . GetBool ( ) )
{
DebugShowActivity ( idealActivity ) ;
}
# endif
return idealActivity ;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : actDesired -
// Output : Activity
//-----------------------------------------------------------------------------
Activity CMultiPlayerAnimState : : TranslateActivity ( Activity actDesired )
{
// Translate activities for swimming.
if ( m_bInSwim )
{
switch ( actDesired )
{
case ACT_MP_ATTACK_STAND_PRIMARYFIRE : { actDesired = ACT_MP_ATTACK_SWIM_PRIMARYFIRE ; break ; }
case ACT_MP_ATTACK_STAND_SECONDARYFIRE : { actDesired = ACT_MP_ATTACK_SWIM_SECONDARYFIRE ; break ; }
case ACT_MP_ATTACK_STAND_GRENADE : { actDesired = ACT_MP_ATTACK_SWIM_GRENADE ; break ; }
case ACT_MP_RELOAD_STAND : { actDesired = ACT_MP_RELOAD_SWIM ; break ; }
}
}
return actDesired ;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : -
// Output : float
//-----------------------------------------------------------------------------
float CMultiPlayerAnimState : : GetCurrentMaxGroundSpeed ( )
{
CStudioHdr * pStudioHdr = GetBasePlayer ( ) - > GetModelPtr ( ) ;
if ( pStudioHdr = = NULL )
return 1.0f ;
float prevX = GetBasePlayer ( ) - > GetPoseParameter ( m_PoseParameterData . m_iMoveX ) ;
float prevY = GetBasePlayer ( ) - > GetPoseParameter ( m_PoseParameterData . m_iMoveY ) ;
float d = MAX ( fabs ( prevX ) , fabs ( prevY ) ) ;
float newX , newY ;
if ( d = = 0.0 )
{
newX = 1.0 ;
newY = 0.0 ;
}
else
{
newX = prevX / d ;
newY = prevY / d ;
}
GetBasePlayer ( ) - > SetPoseParameter ( pStudioHdr , m_PoseParameterData . m_iMoveX , newX ) ;
GetBasePlayer ( ) - > SetPoseParameter ( pStudioHdr , m_PoseParameterData . m_iMoveY , newY ) ;
float speed = GetBasePlayer ( ) - > GetSequenceGroundSpeed ( GetBasePlayer ( ) - > GetSequence ( ) ) ;
GetBasePlayer ( ) - > SetPoseParameter ( pStudioHdr , m_PoseParameterData . m_iMoveX , prevX ) ;
GetBasePlayer ( ) - > SetPoseParameter ( pStudioHdr , m_PoseParameterData . m_iMoveY , prevY ) ;
return speed ;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *bIsMoving -
// Output : float
//-----------------------------------------------------------------------------
float CMultiPlayerAnimState : : CalcMovementSpeed ( bool * bIsMoving )
{
// Get the player's current velocity and speed.
Vector vecVelocity ;
GetOuterAbsVelocity ( vecVelocity ) ;
float flSpeed = vecVelocity . Length2D ( ) ;
if ( flSpeed > MOVING_MINIMUM_SPEED )
{
* bIsMoving = true ;
return flSpeed ;
}
* bIsMoving = false ;
return 0.0f ;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *bIsMoving -
// Output : float
//-----------------------------------------------------------------------------
float CMultiPlayerAnimState : : CalcMovementPlaybackRate ( bool * bIsMoving )
{
float flSpeed = CalcMovementSpeed ( bIsMoving ) ;
float flReturn = 1.0f ;
// If we are moving.
if ( * bIsMoving )
{
// float flGroundSpeed = GetInterpolatedGroundSpeed();
float flGroundSpeed = GetCurrentMaxGroundSpeed ( ) ;
if ( flGroundSpeed < 0.001f )
{
flReturn = 0.01f ;
}
else
{
// Note this gets set back to 1.0 if sequence changes due to ResetSequenceInfo below
flReturn = flSpeed / flGroundSpeed ;
flReturn = clamp ( flReturn , 0.01f , 10.0f ) ;
}
}
return flReturn ;
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : float
//-----------------------------------------------------------------------------
float CMultiPlayerAnimState : : GetInterpolatedGroundSpeed ( void )
{
return m_flMaxGroundSpeed ;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pStudioHdr -
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : ComputeSequences ( CStudioHdr * pStudioHdr )
{
VPROF ( " CBasePlayerAnimState::ComputeSequences " ) ;
// Lower body (walk/run/idle).
ComputeMainSequence ( ) ;
// The groundspeed interpolator uses the main sequence info.
UpdateInterpolators ( ) ;
ComputeGestureSequence ( pStudioHdr ) ;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : -
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : ComputeMainSequence ( )
{
VPROF ( " CBasePlayerAnimState::ComputeMainSequence " ) ;
CBaseAnimatingOverlay * pPlayer = GetBasePlayer ( ) ;
// Have our class or the mod-specific class determine what the current activity is.
Activity idealActivity = CalcMainActivity ( ) ;
# ifdef CLIENT_DLL
Activity oldActivity = m_eCurrentMainSequenceActivity ;
# endif
// Store our current activity so the aim and fire layers know what to do.
m_eCurrentMainSequenceActivity = idealActivity ;
// Hook to force playback of a specific requested full-body sequence
if ( m_nSpecificMainSequence > = 0 )
{
if ( pPlayer - > GetSequence ( ) ! = m_nSpecificMainSequence )
{
pPlayer - > ResetSequence ( m_nSpecificMainSequence ) ;
ResetGroundSpeed ( ) ;
return ;
}
if ( ! pPlayer - > IsSequenceFinished ( ) )
return ;
m_nSpecificMainSequence = - 1 ;
RestartMainSequence ( ) ;
ResetGroundSpeed ( ) ;
}
// Export to our outer class..
int animDesired = SelectWeightedSequence ( TranslateActivity ( idealActivity ) ) ;
if ( pPlayer - > GetSequenceActivity ( pPlayer - > GetSequence ( ) ) = = pPlayer - > GetSequenceActivity ( animDesired ) )
return ;
if ( animDesired < 0 )
{
animDesired = 0 ;
}
pPlayer - > ResetSequence ( animDesired ) ;
# ifdef CLIENT_DLL
// If we went from idle to walk, reset the interpolation history.
// Kind of hacky putting this here.. it might belong outside the base class.
if ( ( oldActivity = = ACT_MP_CROUCH_IDLE | | oldActivity = = ACT_MP_STAND_IDLE | | oldActivity = = ACT_MP_DEPLOYED_IDLE | | oldActivity = = ACT_MP_CROUCH_DEPLOYED_IDLE ) & &
( idealActivity = = ACT_MP_WALK | | idealActivity = = ACT_MP_CROUCHWALK ) )
{
ResetGroundSpeed ( ) ;
}
# endif
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : ResetGroundSpeed ( void )
{
# ifdef CLIENT_DLL
m_flMaxGroundSpeed = GetCurrentMaxGroundSpeed ( ) ;
m_iv_flMaxGroundSpeed . Reset ( ) ;
m_iv_flMaxGroundSpeed . NoteChanged ( gpGlobals - > curtime , 0 , false ) ;
# endif
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : -
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : UpdateInterpolators ( )
{
VPROF ( " CBasePlayerAnimState::UpdateInterpolators " ) ;
// First, figure out their current max speed based on their current activity.
float flCurMaxSpeed = GetCurrentMaxGroundSpeed ( ) ;
# ifdef CLIENT_DLL
float flGroundSpeedInterval = 0.1 ;
// Only update this 10x/sec so it has an interval to interpolate over.
if ( gpGlobals - > curtime - m_flLastGroundSpeedUpdateTime > = flGroundSpeedInterval )
{
m_flLastGroundSpeedUpdateTime = gpGlobals - > curtime ;
m_flMaxGroundSpeed = flCurMaxSpeed ;
m_iv_flMaxGroundSpeed . NoteChanged ( gpGlobals - > curtime , flGroundSpeedInterval , false ) ;
}
m_iv_flMaxGroundSpeed . Interpolate ( gpGlobals - > curtime , flGroundSpeedInterval ) ;
# else
m_flMaxGroundSpeed = flCurMaxSpeed ;
# endif
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : ComputeFireSequence ( void )
{
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pStudioHdr -
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : ComputeGestureSequence ( CStudioHdr * pStudioHdr )
{
// Update all active gesture layers.
for ( int iGesture = 0 ; iGesture < GESTURE_SLOT_COUNT ; + + iGesture )
{
if ( ! m_aGestureSlots [ iGesture ] . m_bActive )
continue ;
if ( ! VerifyAnimLayerInSlot ( iGesture ) )
continue ;
UpdateGestureLayer ( pStudioHdr , & m_aGestureSlots [ iGesture ] ) ;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : UpdateGestureLayer ( CStudioHdr * pStudioHdr , GestureSlot_t * pGesture )
{
// Sanity check.
if ( ! pStudioHdr | | ! pGesture )
return ;
CBasePlayer * pPlayer = GetBasePlayer ( ) ;
if ( ! pPlayer )
return ;
# ifdef CLIENT_DLL
// Get the current cycle.
float flCycle = pGesture - > m_pAnimLayer - > m_flCycle ;
flCycle + = pPlayer - > GetSequenceCycleRate ( pStudioHdr , pGesture - > m_pAnimLayer - > m_nSequence ) * gpGlobals - > frametime * GetGesturePlaybackRate ( ) * pGesture - > m_pAnimLayer - > m_flPlaybackRate ;
pGesture - > m_pAnimLayer - > m_flPrevCycle = pGesture - > m_pAnimLayer - > m_flCycle ;
pGesture - > m_pAnimLayer - > m_flCycle = flCycle ;
if ( flCycle > 1.0f )
{
RunGestureSlotAnimEventsToCompletion ( pGesture ) ;
if ( pGesture - > m_bAutoKill )
{
ResetGestureSlot ( pGesture - > m_iGestureSlot ) ;
return ;
}
else
{
pGesture - > m_pAnimLayer - > m_flCycle = 1.0f ;
}
}
# else
if ( pGesture - > m_iActivity ! = ACT_INVALID & & pGesture - > m_pAnimLayer - > m_nActivity = = ACT_INVALID )
{
ResetGestureSlot ( pGesture - > m_iGestureSlot ) ;
}
# endif
}
extern ConVar mp_facefronttime ;
extern ConVar mp_feetyawrate ;
//-----------------------------------------------------------------------------
// Purpose:
// Input : eyeYaw -
// eyePitch -
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : Update ( float eyeYaw , float eyePitch )
{
// Profile the animation update.
VPROF ( " CMultiPlayerAnimState::Update " ) ;
// Get the studio header for the player.
CStudioHdr * pStudioHdr = GetBasePlayer ( ) - > GetModelPtr ( ) ;
if ( ! pStudioHdr )
return ;
// Check to see if we should be updating the animation state - dead, ragdolled?
if ( ! ShouldUpdateAnimState ( ) )
{
ClearAnimationState ( ) ;
return ;
}
// Store the eye angles.
m_flEyeYaw = AngleNormalize ( eyeYaw ) ;
m_flEyePitch = AngleNormalize ( eyePitch ) ;
// Compute the player sequences.
ComputeSequences ( pStudioHdr ) ;
if ( SetupPoseParameters ( pStudioHdr ) )
{
// Pose parameter - what direction are the player's legs running in.
ComputePoseParam_MoveYaw ( pStudioHdr ) ;
// Pose parameter - Torso aiming (up/down).
ComputePoseParam_AimPitch ( pStudioHdr ) ;
// Pose parameter - Torso aiming (rotation).
ComputePoseParam_AimYaw ( pStudioHdr ) ;
}
# ifdef CLIENT_DLL
if ( C_BasePlayer : : ShouldDrawLocalPlayer ( ) )
{
GetBasePlayer ( ) - > SetPlaybackRate ( 1.0f ) ;
}
# endif
if ( mp_showgestureslots . GetInt ( ) = = GetBasePlayer ( ) - > entindex ( ) )
{
DebugGestureInfo ( ) ;
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CMultiPlayerAnimState : : ShouldUpdateAnimState ( )
{
// Don't update anim state if we're not visible
if ( GetBasePlayer ( ) - > IsEffectActive ( EF_NODRAW ) )
return false ;
// By default, don't update their animation state when they're dead because they're
// either a ragdoll or they're not drawn.
# ifdef CLIENT_DLL
if ( GetBasePlayer ( ) - > IsDormant ( ) )
return false ;
# endif
return ( GetBasePlayer ( ) - > IsAlive ( ) | | m_bDying ) ;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CMultiPlayerAnimState : : SetupPoseParameters ( CStudioHdr * pStudioHdr )
{
// Check to see if this has already been done.
if ( m_bPoseParameterInit )
return true ;
// Save off the pose parameter indices.
if ( ! pStudioHdr )
return false ;
m_bPoseParameterInit = true ;
// Look for the movement blenders.
m_PoseParameterData . m_iMoveX = GetBasePlayer ( ) - > LookupPoseParameter ( pStudioHdr , " move_x " ) ;
m_PoseParameterData . m_iMoveY = GetBasePlayer ( ) - > LookupPoseParameter ( pStudioHdr , " move_y " ) ;
/*
if ( ( m_PoseParameterData . m_iMoveX < 0 ) | | ( m_PoseParameterData . m_iMoveY < 0 ) )
return false ;
*/
// Look for the aim pitch blender.
m_PoseParameterData . m_iAimPitch = GetBasePlayer ( ) - > LookupPoseParameter ( pStudioHdr , " body_pitch " ) ;
/*
if ( m_PoseParameterData . m_iAimPitch < 0 )
return false ;
*/
// Look for aim yaw blender.
m_PoseParameterData . m_iAimYaw = GetBasePlayer ( ) - > LookupPoseParameter ( pStudioHdr , " body_yaw " ) ;
/*
if ( m_PoseParameterData . m_iAimYaw < 0 )
return false ;
*/
m_PoseParameterData . m_iMoveYaw = GetBasePlayer ( ) - > LookupPoseParameter ( pStudioHdr , " move_yaw " ) ;
m_PoseParameterData . m_iMoveScale = GetBasePlayer ( ) - > LookupPoseParameter ( pStudioHdr , " move_scale " ) ;
/*
if ( ( m_PoseParameterData . m_iMoveYaw < 0 ) | | ( m_PoseParameterData . m_iMoveScale < 0 ) )
return false ;
*/
return true ;
}
float SnapYawTo ( float flValue )
{
float flSign = 1.0f ;
if ( flValue < 0.0f )
{
flSign = - 1.0f ;
flValue = - flValue ;
}
if ( flValue < 23.0f )
{
flValue = 0.0f ;
}
else if ( flValue < 67.0f )
{
flValue = 45.0f ;
}
else if ( flValue < 113.0f )
{
flValue = 90.0f ;
}
else if ( flValue < 157 )
{
flValue = 135.0f ;
}
else
{
flValue = 180.0f ;
}
return ( flValue * flSign ) ;
}
//-----------------------------------------------------------------------------
// Purpose: double check that the movement animations actually have movement
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : DoMovementTest ( CStudioHdr * pStudioHdr , float flX , float flY )
{
GetBasePlayer ( ) - > SetPoseParameter ( pStudioHdr , m_PoseParameterData . m_iMoveX , flX ) ;
GetBasePlayer ( ) - > SetPoseParameter ( pStudioHdr , m_PoseParameterData . m_iMoveY , flY ) ;
# ifdef STAGING_ONLY
float flTestSpeed = GetBasePlayer ( ) - > GetSequenceGroundSpeed ( m_nMovementSequence ) ;
if ( flTestSpeed < 10.0f )
{
Warning ( " %s : %s (X %.0f Y %.0f) missing movement \n " , pStudioHdr - > pszName ( ) , GetBasePlayer ( ) - > GetSequenceName ( m_nMovementSequence ) , flX , flY ) ;
}
# endif
/*
GetBasePlayer ( ) - > SetPoseParameter ( pStudioHdr , m_PoseParameterData . m_iMoveX , flX ) ;
GetBasePlayer ( ) - > SetPoseParameter ( pStudioHdr , m_PoseParameterData . m_iMoveY , flY ) ;
float flDuration = GetBasePlayer ( ) - > SequenceDuration ( m_nMovementSequence ) ;
GetBasePlayer ( ) - > SetPoseParameter ( pStudioHdr , m_PoseParameterData . m_iMoveX , 1.0f ) ;
GetBasePlayer ( ) - > SetPoseParameter ( pStudioHdr , m_PoseParameterData . m_iMoveY , 0.0f ) ;
float flForward = GetBasePlayer ( ) - > SequenceDuration ( m_nMovementSequence ) ;
GetBasePlayer ( ) - > SetPoseParameter ( pStudioHdr , m_PoseParameterData . m_iMoveX , 0.0f ) ;
GetBasePlayer ( ) - > SetPoseParameter ( pStudioHdr , m_PoseParameterData . m_iMoveY , 0.0f ) ;
float flCenter = GetBasePlayer ( ) - > SequenceDuration ( m_nMovementSequence ) ;
if ( flDuration > flForward * 1.1f | | flDuration < flForward * 0.9f )
{
Warning ( " %s : %s (X %.0f Y %.0f) mismatched duration with forward %.1f vs %.1f \n " , pStudioHdr - > pszName ( ) , GetBasePlayer ( ) - > GetSequenceName ( m_nMovementSequence ) , flX , flY , flDuration , flForward ) ;
}
if ( flDuration > flCenter * 1.1f | | flDuration < flCenter * 0.9f )
{
Warning ( " %s : %s (X %.0f Y %.0f) mismatched duration with center %.1f vs %.1f \n " , pStudioHdr - > pszName ( ) , GetBasePlayer ( ) - > GetSequenceName ( m_nMovementSequence ) , flX , flY , flDuration , flCenter ) ;
}
*/
}
void CMultiPlayerAnimState : : DoMovementTest ( CStudioHdr * pStudioHdr )
{
if ( m_LegAnimType = = LEGANIM_9WAY )
{
DoMovementTest ( pStudioHdr , - 1.0f , - 1.0f ) ;
DoMovementTest ( pStudioHdr , - 1.0f , 0.0f ) ;
DoMovementTest ( pStudioHdr , - 1.0f , 1.0f ) ;
DoMovementTest ( pStudioHdr , 0.0f , - 1.0f ) ;
DoMovementTest ( pStudioHdr , 0.0f , 1.0f ) ;
DoMovementTest ( pStudioHdr , 1.0f , - 1.0f ) ;
DoMovementTest ( pStudioHdr , 1.0f , 0.0f ) ;
DoMovementTest ( pStudioHdr , 1.0f , 1.0f ) ;
}
}
void CMultiPlayerAnimState : : GetMovementFlags ( CStudioHdr * pStudioHdr )
{
if ( m_nMovementSequence = = GetBasePlayer ( ) - > GetSequence ( ) )
{
return ;
}
m_nMovementSequence = GetBasePlayer ( ) - > GetSequence ( ) ;
m_LegAnimType = LEGANIM_9WAY ;
KeyValues * seqKeyValues = GetBasePlayer ( ) - > GetSequenceKeyValues ( m_nMovementSequence ) ;
// Msg("sequence %d : %s (%d)\n", sequence, GetOuter()->GetSequenceName( sequence ), seqKeyValues != NULL );
if ( seqKeyValues )
{
KeyValues * pkvMovement = seqKeyValues - > FindKey ( " movement " ) ;
if ( pkvMovement )
{
const char * szStyle = pkvMovement - > GetString ( ) ;
if ( V_stricmp ( szStyle , " robot2 " ) = = 0 )
{
m_LegAnimType = LEGANIM_8WAY ;
}
}
seqKeyValues - > deleteThis ( ) ;
}
// skip tests if it's not a movement animation
if ( m_nMovementSequence < 0 | | ! ( GetBasePlayer ( ) - > GetFlags ( ) & FL_ONGROUND ) | | pStudioHdr - > pSeqdesc ( m_nMovementSequence ) . groupsize [ 0 ] = = 1 )
{
return ;
}
DoMovementTest ( pStudioHdr ) ;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pStudioHdr -
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : ComputePoseParam_MoveYaw ( CStudioHdr * pStudioHdr )
{
// Get the estimated movement yaw.
EstimateYaw ( ) ;
// Get the view yaw.
float flAngle = AngleNormalize ( m_flEyeYaw ) ;
// Calc side to side turning - the view vs. movement yaw.
float flYaw = flAngle - m_PoseParameterData . m_flEstimateYaw ;
flYaw = AngleNormalize ( - flYaw ) ;
// Get the current speed the character is running.
bool bIsMoving ;
float flSpeed = CalcMovementSpeed ( & bIsMoving ) ;
// Setup the 9-way blend parameters based on our speed and direction.
Vector2D vecCurrentMoveYaw ( 0.0f , 0.0f ) ;
if ( bIsMoving )
{
GetMovementFlags ( pStudioHdr ) ;
if ( mp_slammoveyaw . GetBool ( ) )
{
flYaw = SnapYawTo ( flYaw ) ;
}
if ( m_LegAnimType = = LEGANIM_9WAY )
{
// convert YAW back into vector
vecCurrentMoveYaw . x = cos ( DEG2RAD ( flYaw ) ) ;
vecCurrentMoveYaw . y = - sin ( DEG2RAD ( flYaw ) ) ;
// push edges out to -1 to 1 box
float flInvScale = MAX ( fabs ( vecCurrentMoveYaw . x ) , fabs ( vecCurrentMoveYaw . y ) ) ;
if ( flInvScale ! = 0.0f )
{
vecCurrentMoveYaw . x / = flInvScale ;
vecCurrentMoveYaw . y / = flInvScale ;
}
// find what speed was actually authored
GetBasePlayer ( ) - > SetPoseParameter ( pStudioHdr , m_PoseParameterData . m_iMoveX , vecCurrentMoveYaw . x ) ;
GetBasePlayer ( ) - > SetPoseParameter ( pStudioHdr , m_PoseParameterData . m_iMoveY , vecCurrentMoveYaw . y ) ;
float flMaxSpeed = GetBasePlayer ( ) - > GetSequenceGroundSpeed ( GetBasePlayer ( ) - > GetSequence ( ) ) ;
// scale playback
if ( flMaxSpeed > flSpeed )
{
vecCurrentMoveYaw . x * = flSpeed / flMaxSpeed ;
vecCurrentMoveYaw . y * = flSpeed / flMaxSpeed ;
}
// Set the 9-way blend movement pose parameters.
GetBasePlayer ( ) - > SetPoseParameter ( pStudioHdr , m_PoseParameterData . m_iMoveX , vecCurrentMoveYaw . x ) ;
GetBasePlayer ( ) - > SetPoseParameter ( pStudioHdr , m_PoseParameterData . m_iMoveY , vecCurrentMoveYaw . y ) ;
}
else
{
// find what speed was actually authored
GetBasePlayer ( ) - > SetPoseParameter ( pStudioHdr , m_PoseParameterData . m_iMoveYaw , flYaw ) ;
GetBasePlayer ( ) - > SetPoseParameter ( pStudioHdr , m_PoseParameterData . m_iMoveScale , 1.0f ) ;
float flMaxSpeed = GetBasePlayer ( ) - > GetSequenceGroundSpeed ( GetBasePlayer ( ) - > GetSequence ( ) ) ;
// scale playback
if ( flMaxSpeed > flSpeed )
{
GetBasePlayer ( ) - > SetPoseParameter ( pStudioHdr , m_PoseParameterData . m_iMoveScale , flSpeed / flMaxSpeed ) ;
}
}
}
else
{
// Set the 9-way blend movement pose parameters.
GetBasePlayer ( ) - > SetPoseParameter ( pStudioHdr , m_PoseParameterData . m_iMoveX , 0.0f ) ;
GetBasePlayer ( ) - > SetPoseParameter ( pStudioHdr , m_PoseParameterData . m_iMoveY , 0.0f ) ;
}
m_DebugAnimData . m_vecMoveYaw = vecCurrentMoveYaw ;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : EstimateYaw ( void )
{
// Get the frame time.
float flDeltaTime = gpGlobals - > frametime ;
if ( flDeltaTime = = 0.0f )
return ;
// Get the player's velocity and angles.
Vector vecEstVelocity ;
GetOuterAbsVelocity ( vecEstVelocity ) ;
QAngle angles = GetBasePlayer ( ) - > GetLocalAngles ( ) ;
// If we are not moving, sync up the feet and eyes slowly.
if ( vecEstVelocity . x = = 0.0f & & vecEstVelocity . y = = 0.0f )
{
float flYawDelta = angles [ YAW ] - m_PoseParameterData . m_flEstimateYaw ;
flYawDelta = AngleNormalize ( flYawDelta ) ;
if ( flDeltaTime < 0.25f )
{
flYawDelta * = ( flDeltaTime * 4.0f ) ;
}
else
{
flYawDelta * = flDeltaTime ;
}
m_PoseParameterData . m_flEstimateYaw + = flYawDelta ;
AngleNormalize ( m_PoseParameterData . m_flEstimateYaw ) ;
}
else
{
m_PoseParameterData . m_flEstimateYaw = ( atan2 ( vecEstVelocity . y , vecEstVelocity . x ) * 180.0f / M_PI ) ;
m_PoseParameterData . m_flEstimateYaw = clamp ( m_PoseParameterData . m_flEstimateYaw , - 180.0f , 180.0f ) ;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : ComputePoseParam_AimPitch ( CStudioHdr * pStudioHdr )
{
// Get the view pitch.
float flAimPitch = m_flEyePitch ;
// Set the aim pitch pose parameter and save.
GetBasePlayer ( ) - > SetPoseParameter ( pStudioHdr , m_PoseParameterData . m_iAimPitch , - flAimPitch ) ;
m_DebugAnimData . m_flAimPitch = flAimPitch ;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : ComputePoseParam_AimYaw ( CStudioHdr * pStudioHdr )
{
// Get the movement velocity.
Vector vecVelocity ;
GetOuterAbsVelocity ( vecVelocity ) ;
// Check to see if we are moving.
bool bMoving = ( vecVelocity . Length ( ) > 1.0f ) ? true : false ;
// If we are moving or are prone and undeployed.
if ( bMoving | | m_bForceAimYaw )
{
// The feet match the eye direction when moving - the move yaw takes care of the rest.
m_flGoalFeetYaw = m_flEyeYaw ;
}
// Else if we are not moving.
else
{
// Initialize the feet.
if ( m_PoseParameterData . m_flLastAimTurnTime < = 0.0f )
{
m_flGoalFeetYaw = m_flEyeYaw ;
m_flCurrentFeetYaw = m_flEyeYaw ;
m_PoseParameterData . m_flLastAimTurnTime = gpGlobals - > curtime ;
}
// Make sure the feet yaw isn't too far out of sync with the eye yaw.
// TODO: Do something better here!
else
{
float flYawDelta = AngleNormalize ( m_flGoalFeetYaw - m_flEyeYaw ) ;
if ( fabs ( flYawDelta ) > 45.0f /*m_AnimConfig.m_flMaxBodyYawDegrees*/ )
{
float flSide = ( flYawDelta > 0.0f ) ? - 1.0f : 1.0f ;
m_flGoalFeetYaw + = ( 45.0f /*m_AnimConfig.m_flMaxBodyYawDegrees*/ * flSide ) ;
}
}
}
// Fix up the feet yaw.
m_flGoalFeetYaw = AngleNormalize ( m_flGoalFeetYaw ) ;
if ( m_flGoalFeetYaw ! = m_flCurrentFeetYaw )
{
if ( m_bForceAimYaw )
{
m_flCurrentFeetYaw = m_flGoalFeetYaw ;
}
else
{
ConvergeYawAngles ( m_flGoalFeetYaw , /*DOD_BODYYAW_RATE*/ 720.0f , gpGlobals - > frametime , m_flCurrentFeetYaw ) ;
m_flLastAimTurnTime = gpGlobals - > curtime ;
}
}
// Rotate the body into position.
m_angRender [ YAW ] = m_flCurrentFeetYaw ;
// Find the aim(torso) yaw base on the eye and feet yaws.
float flAimYaw = m_flEyeYaw - m_flCurrentFeetYaw ;
flAimYaw = AngleNormalize ( flAimYaw ) ;
// Set the aim yaw and save.
GetBasePlayer ( ) - > SetPoseParameter ( pStudioHdr , m_PoseParameterData . m_iAimYaw , - flAimYaw ) ;
m_DebugAnimData . m_flAimYaw = flAimYaw ;
// Turn off a force aim yaw - either we have already updated or we don't need to.
m_bForceAimYaw = false ;
# ifndef CLIENT_DLL
QAngle angle = GetBasePlayer ( ) - > GetAbsAngles ( ) ;
angle [ YAW ] = m_flCurrentFeetYaw ;
GetBasePlayer ( ) - > SetAbsAngles ( angle ) ;
# endif
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : flGoalYaw -
// flYawRate -
// flDeltaTime -
// &flCurrentYaw -
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : ConvergeYawAngles ( float flGoalYaw , float flYawRate , float flDeltaTime , float & flCurrentYaw )
{
# define FADE_TURN_DEGREES 60.0f
// Find the yaw delta.
float flDeltaYaw = flGoalYaw - flCurrentYaw ;
float flDeltaYawAbs = fabs ( flDeltaYaw ) ;
flDeltaYaw = AngleNormalize ( flDeltaYaw ) ;
// Always do at least a bit of the turn (1%).
float flScale = 1.0f ;
flScale = flDeltaYawAbs / FADE_TURN_DEGREES ;
flScale = clamp ( flScale , 0.01f , 1.0f ) ;
float flYaw = flYawRate * flDeltaTime * flScale ;
if ( flDeltaYawAbs < flYaw )
{
flCurrentYaw = flGoalYaw ;
}
else
{
float flSide = ( flDeltaYaw < 0.0f ) ? - 1.0f : 1.0f ;
flCurrentYaw + = ( flYaw * flSide ) ;
}
flCurrentYaw = AngleNormalize ( flCurrentYaw ) ;
# undef FADE_TURN_DEGREES
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : -
// Output : const QAngle&
//-----------------------------------------------------------------------------
const QAngle & CMultiPlayerAnimState : : GetRenderAngles ( )
{
return m_angRender ;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : vel -
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : GetOuterAbsVelocity ( Vector & vel )
{
# if defined( CLIENT_DLL )
GetBasePlayer ( ) - > EstimateAbsVelocity ( vel ) ;
# else
vel = GetBasePlayer ( ) - > GetAbsVelocity ( ) ;
# endif
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : Release ( void )
{
delete this ;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : -
// Output : float
//-----------------------------------------------------------------------------
float CMultiPlayerAnimState : : GetOuterXYSpeed ( )
{
Vector vel ;
GetOuterAbsVelocity ( vel ) ;
return vel . Length2D ( ) ;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Anim_StateLog ( const char * pMsg , . . . )
{
// Format the string.
char str [ 4096 ] ;
va_list marker ;
va_start ( marker , pMsg ) ;
Q_vsnprintf ( str , sizeof ( str ) , pMsg , marker ) ;
va_end ( marker ) ;
// Log it?
if ( anim_showstatelog . GetInt ( ) = = 1 | | anim_showstatelog . GetInt ( ) = = 3 )
{
Msg ( " %s " , str ) ;
}
if ( anim_showstatelog . GetInt ( ) > 1 )
{
// static FileHandle_t hFile = filesystem->Open( "AnimState.log", "wt" );
// filesystem->FPrintf( hFile, "%s", str );
// filesystem->Flush( hFile );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Anim_StatePrintf ( int iLine , const char * pMsg , . . . )
{
// Format the string.
char str [ 4096 ] ;
va_list marker ;
va_start ( marker , pMsg ) ;
Q_vsnprintf ( str , sizeof ( str ) , pMsg , marker ) ;
va_end ( marker ) ;
// Show it with Con_NPrintf.
engine - > Con_NPrintf ( iLine , " %s " , str ) ;
// Log it.
Anim_StateLog ( " %s \n " , str ) ;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : DebugShowAnimStateForPlayer ( bool bIsServer )
{
// Get the player's velocity.
Vector vecVelocity ;
GetOuterAbsVelocity ( vecVelocity ) ;
// Start animation state logging.
int iLine = 5 ;
if ( bIsServer )
{
iLine = 12 ;
}
// Anim_StateLog( "-------------%s: frame %d -----------------\n", bIsServer ? "Server" : "Client", gpGlobals->framecount );
Anim_StatePrintf ( iLine + + , " -------------%s: frame %d ----------------- \n " , bIsServer ? " Server " : " Client " , gpGlobals - > framecount ) ;
// Write out the main sequence and its data.
Anim_StatePrintf ( iLine + + , " Main: %s, Cycle: %.2f \n " , GetSequenceName ( GetBasePlayer ( ) - > GetModelPtr ( ) , GetBasePlayer ( ) - > GetSequence ( ) ) , GetBasePlayer ( ) - > GetCycle ( ) ) ;
#if 0
if ( m_bPlayingGesture )
{
Anim_StatePrintf ( iLine + + , " Gesture: %s, Cycle: %.2f \n " ,
GetSequenceName ( GetBasePlayer ( ) - > GetModelPtr ( ) , m_iGestureSequence ) ,
m_flGestureCycle ) ;
}
# endif
// Write out the layers and their data.
for ( int iAnim = 0 ; iAnim < GetBasePlayer ( ) - > GetNumAnimOverlays ( ) ; + + iAnim )
{
# ifdef CLIENT_DLL
C_AnimationLayer * pLayer = GetBasePlayer ( ) - > GetAnimOverlay ( iAnim ) ;
if ( pLayer & & ( pLayer - > m_nOrder ! = CBaseAnimatingOverlay : : MAX_OVERLAYS ) )
{
Anim_StatePrintf ( iLine + + , " Layer %s: Weight: %.2f, Cycle: %.2f " , GetSequenceName ( GetBasePlayer ( ) - > GetModelPtr ( ) , pLayer - > m_nSequence ) , ( float ) pLayer - > m_flWeight , ( float ) pLayer - > m_flCycle ) ;
}
# else
CAnimationLayer * pLayer = GetBasePlayer ( ) - > GetAnimOverlay ( iAnim ) ;
if ( pLayer & & ( pLayer - > m_nOrder ! = CBaseAnimatingOverlay : : MAX_OVERLAYS ) )
{
Anim_StatePrintf ( iLine + + , " Layer %s: Weight: %.2f, Cycle: %.2f " , GetSequenceName ( GetBasePlayer ( ) - > GetModelPtr ( ) , pLayer - > m_nSequence ) , ( float ) pLayer - > m_flWeight , ( float ) pLayer - > m_flCycle ) ;
}
# endif
}
// Write out the speed data.
Anim_StatePrintf ( iLine + + , " Time: %.2f, Speed: %.2f, MaxSpeed: %.2f " , gpGlobals - > curtime , vecVelocity . Length2D ( ) , GetCurrentMaxGroundSpeed ( ) ) ;
// Write out the 9-way blend data.
Anim_StatePrintf ( iLine + + , " EntityYaw: %.2f, AimYaw: %.2f, AimPitch: %.2f, MoveX: %.2f, MoveY: %.2f " , m_angRender [ YAW ] , m_DebugAnimData . m_flAimYaw , m_DebugAnimData . m_flAimPitch , m_DebugAnimData . m_vecMoveYaw . x , m_DebugAnimData . m_vecMoveYaw . y ) ;
// Anim_StateLog( "--------------------------------------------\n\n" );
Anim_StatePrintf ( iLine + + , " -------------------------------------------- \n \n " ) ;
DebugShowEyeYaw ( ) ;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : DebugShowEyeYaw ( void )
{
# ifdef _NDEBUG
float flBaseSize = 10 ;
float flHeight = 80 ;
Vector vecPos = GetOuter ( ) - > GetAbsOrigin ( ) + Vector ( 0.0f , 0.0f , 3.0f ) ;
QAngle angles ( 0.0f , 0.0f , 0.0f ) ;
angles [ YAW ] = m_flEyeYaw ;
Vector vecForward , vecRight , vecUp ;
AngleVectors ( angles , & vecForward , & vecRight , & vecUp ) ;
// Draw a red triangle on the ground for the eye yaw.
debugoverlay - > AddTriangleOverlay ( ( vecPos + vecRight * flBaseSize / 2.0f ) ,
( vecPos - vecRight * flBaseSize / 2.0f ) ,
( vecPos + vecForward * flHeight , 255 , 0 , 0 , 255 , false , 0.01f ) ;
# endif
}
# if defined( CLIENT_DLL )
//-----------------------------------------------------------------------------
// Purpose:
// Input : activity -
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : DebugShowActivity ( Activity activity )
{
# ifdef _DEBUG
const char * pszActivity = " other " ;
switch ( activity )
{
case ACT_MP_STAND_IDLE :
{
pszActivity = " idle " ;
break ;
}
case ACT_MP_SPRINT :
{
pszActivity = " sprint " ;
break ;
}
case ACT_MP_WALK :
{
pszActivity = " walk " ;
break ;
}
case ACT_MP_RUN :
{
pszActivity = " run " ;
break ;
}
}
Msg ( " Activity: %s \n " , pszActivity ) ;
# endif
}
# endif
//-----------------------------------------------------------------------------
// Purpose:
// Input : iStartLine -
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : DebugShowAnimState ( int iStartLine )
{
Vector vOuterVel ;
GetOuterAbsVelocity ( vOuterVel ) ;
Anim_StateLog ( " ----------------- frame %d ----------------- \n " , gpGlobals - > framecount ) ;
int iLine = iStartLine ;
Anim_StatePrintf ( iLine + + , " main: %s, cycle: %.2f \n " , GetSequenceName ( GetBasePlayer ( ) - > GetModelPtr ( ) , GetBasePlayer ( ) - > GetSequence ( ) ) , GetBasePlayer ( ) - > GetCycle ( ) ) ;
# if defined( CLIENT_DLL )
for ( int i = 0 ; i < GetBasePlayer ( ) - > GetNumAnimOverlays ( ) - 1 ; i + + )
{
C_AnimationLayer * pLayer = GetBasePlayer ( ) - > GetAnimOverlay ( i /*i+1?*/ ) ;
Anim_StatePrintf ( iLine + + , " %s, weight: %.2f, cycle: %.2f, aim (%d) " ,
pLayer - > m_nOrder = = CBaseAnimatingOverlay : : MAX_OVERLAYS ? " -- " : GetSequenceName ( GetBasePlayer ( ) - > GetModelPtr ( ) , pLayer - > m_nSequence ) ,
pLayer - > m_nOrder = = CBaseAnimatingOverlay : : MAX_OVERLAYS ? - 1 : ( float ) pLayer - > m_flWeight ,
pLayer - > m_nOrder = = CBaseAnimatingOverlay : : MAX_OVERLAYS ? - 1 : ( float ) pLayer - > m_flCycle ,
i
) ;
}
# endif
Anim_StatePrintf ( iLine + + , " vel: %.2f, time: %.2f, max: %.2f " ,
vOuterVel . Length2D ( ) , gpGlobals - > curtime , GetInterpolatedGroundSpeed ( ) ) ;
// AnimStatePrintf( iLine++, "ent yaw: %.2f, body_yaw: %.2f, body_pitch: %.2f, move_x: %.2f, move_y: %.2f",
// m_angRender[YAW], g_flLastBodyYaw, g_flLastBodyPitch, m_vLastMovePose.x, m_vLastMovePose.y );
Anim_StateLog ( " -------------------------------------------- \n \n " ) ;
// Draw a red triangle on the ground for the eye yaw.
float flBaseSize = 10 ;
float flHeight = 80 ;
Vector vBasePos = GetBasePlayer ( ) - > GetAbsOrigin ( ) + Vector ( 0 , 0 , 3 ) ;
QAngle angles ( 0 , 0 , 0 ) ;
angles [ YAW ] = m_flEyeYaw ;
Vector vForward , vRight , vUp ;
AngleVectors ( angles , & vForward , & vRight , & vUp ) ;
debugoverlay - > AddTriangleOverlay ( vBasePos + vRight * flBaseSize / 2 , vBasePos - vRight * flBaseSize / 2 , vBasePos + vForward * flHeight , 255 , 0 , 0 , 255 , false , 0.01 ) ;
// Draw a blue triangle on the ground for the body yaw.
angles [ YAW ] = m_angRender [ YAW ] ;
AngleVectors ( angles , & vForward , & vRight , & vUp ) ;
debugoverlay - > AddTriangleOverlay ( vBasePos + vRight * flBaseSize / 2 , vBasePos - vRight * flBaseSize / 2 , vBasePos + vForward * flHeight , 0 , 0 , 255 , 255 , false , 0.01 ) ;
}
// Debug!
const char * s_aGestureSlotNames [ GESTURE_SLOT_COUNT ] =
{
" Attack and Reload " ,
" Grenade " ,
" Jump " ,
" Swim " ,
" Flinch " ,
" VCD " ,
" Custom "
} ;
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : DebugGestureInfo ( void )
{
CBasePlayer * pPlayer = GetBasePlayer ( ) ;
if ( ! pPlayer )
return ;
int iLine = ( pPlayer - > IsServer ( ) ? 12 : ( 14 + GESTURE_SLOT_COUNT ) ) ;
Anim_StatePrintf ( iLine + + , " %s \n " , ( pPlayer - > IsServer ( ) ? " Server " : " Client " ) ) ;
for ( int iGesture = 0 ; iGesture < GESTURE_SLOT_COUNT ; + + iGesture )
{
GestureSlot_t * pGesture = & m_aGestureSlots [ iGesture ] ;
if ( pGesture )
{
if ( pGesture - > m_bActive )
{
Anim_StatePrintf ( iLine + + , " Gesture Slot %d(%s): %s %s(A:%s, C:%f P:%f) \n " ,
iGesture ,
s_aGestureSlotNames [ iGesture ] ,
ActivityList_NameForIndex ( pGesture - > m_iActivity ) ,
GetSequenceName ( pPlayer - > GetModelPtr ( ) , pGesture - > m_pAnimLayer - > m_nSequence ) ,
( pGesture - > m_bAutoKill ? " true " : " false " ) ,
( float ) pGesture - > m_pAnimLayer - > m_flCycle , ( float ) pGesture - > m_pAnimLayer - > m_flPlaybackRate ) ;
}
else
{
Anim_StatePrintf ( iLine + + , " Gesture Slot %d(%s): NOT ACTIVE! \n " , iGesture , s_aGestureSlotNames [ iGesture ] ) ;
}
}
}
}
//-----------------------------------------------------------------------------
// Purpose: New Model, init the pose parameters
//-----------------------------------------------------------------------------
void CMultiPlayerAnimState : : OnNewModel ( void )
{
m_bPoseParameterInit = false ;
m_PoseParameterData . Init ( ) ;
ClearAnimationState ( ) ;
}