Example #1
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : actDesired - 
// Output : Activity
//-----------------------------------------------------------------------------
Activity CTFPlayerAnimState::TranslateActivity( Activity actDesired )
{
	Activity translateActivity = BaseClass::TranslateActivity( actDesired );

	if ( GetTFPlayer()->m_Shared.IsLoser() )
	{
		int actCount = ARRAYSIZE( m_acttableLoserState );
		for ( int i = 0; i < actCount; i++ )
		{
			const acttable_t& act = m_acttableLoserState[ i ];
			if ( actDesired == act.baseAct )
				return (Activity)act.weaponAct;
		}
	}

	if ( GetTFPlayer()->GetActiveWeapon() )
		translateActivity = GetTFPlayer()->GetActiveWeapon()->ActivityOverride( translateActivity, false );

	return translateActivity;
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : actDesired - 
// Output : Activity
//-----------------------------------------------------------------------------
Activity CTFPlayerAnimState::TranslateActivity( Activity actDesired )
{
	Activity translateActivity = BaseClass::TranslateActivity( actDesired );

	if ( GetTFPlayer()->m_Shared.IsLoser() )
	{
		int actCount = ARRAYSIZE( m_acttableLoserState );
		for ( int i = 0; i < actCount; i++ )
		{
			const acttable_t& act = m_acttableLoserState[i];
			if ( actDesired == act.baseAct)
				return (Activity)act.weaponAct;
		}
	}
	else if ( GetTFPlayer()->m_Shared.IsCarryingObject() )
	{
		int actCount = ARRAYSIZE( m_acttableBuildingDeployed );
		for ( int i = 0; i < actCount; i++ )
		{
			const acttable_t& act = m_acttableBuildingDeployed[i];
			if ( actDesired == act.baseAct )
				return (Activity)act.weaponAct;
		}
	}

	CBaseCombatWeapon *pWeapon = GetTFPlayer()->GetActiveWeapon();
	if ( pWeapon )
	{
		translateActivity = GetTFPlayer()->GetActiveWeapon()->ActivityOverride( translateActivity, false );

		// Live TF2 does this but is doing this after the above call correct?
		translateActivity = pWeapon->GetItem()->GetActivityOverride( GetTFPlayer()->GetTeamNumber(), translateActivity );
	}

	return translateActivity;
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CTFPlayerAnimState::Update( float eyeYaw, float eyePitch )
{
	// Profile the animation update.
	VPROF( "CMultiPlayerAnimState::Update" );

	// Get the TF player.
	CTFPlayer *pTFPlayer = GetTFPlayer();
	if ( !pTFPlayer )
		return;

	// Get the studio header for the player.
	CStudioHdr *pStudioHdr = pTFPlayer->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 ) && !pTFPlayer->m_Shared.InCond( TF_COND_TAUNTING ) )
	{
		// 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
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *idealActivity - 
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CTFPlayerAnimState::HandleDucking( Activity &idealActivity )
{
	if (GetBasePlayer()->GetFlags() & FL_DUCKING)
	{
		if ( GetOuterXYSpeed() < MOVING_MINIMUM_SPEED || m_pTFPlayer->m_Shared.IsLoser() )
		{
			idealActivity = ACT_MP_CROUCH_IDLE;		
			if ( m_pTFPlayer->m_Shared.InCond( TF_COND_AIMING ) || m_flHoldDeployedPoseUntilTime > gpGlobals->curtime )
			{
				idealActivity = ACT_MP_CROUCH_DEPLOYED_IDLE;
			}
		}
		else
		{
			idealActivity = ACT_MP_CROUCHWALK;		

			if ( m_pTFPlayer->m_Shared.InCond( TF_COND_AIMING ) )
			{
				// Don't do this for the heavy! we don't usually let him deployed crouch walk
				bool bIsMinigun = false;

				CTFPlayer *pPlayer = GetTFPlayer();
				if ( pPlayer && pPlayer->GetActiveTFWeapon() )
				{
					bIsMinigun = ( pPlayer->GetActiveTFWeapon()->GetWeaponID() == TF_WEAPON_MINIGUN );
				}

				if ( !bIsMinigun )
				{
					idealActivity = ACT_MP_CROUCH_DEPLOYED;
				}
			}
		}

		return true;
	}
	
	return false;
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : event - 
//-----------------------------------------------------------------------------
void CTFPlayerAnimState::DoAnimationEvent( PlayerAnimEvent_t event, int nData )
{
	Activity iGestureActivity = ACT_INVALID;

	switch( event )
	{
	case PLAYERANIMEVENT_ATTACK_PRIMARY:
		{
			CTFPlayer *pPlayer = GetTFPlayer();
			if ( !pPlayer )
				return;

			CTFWeaponBase *pWpn = pPlayer->GetActiveTFWeapon();
			bool bIsMinigun = ( pWpn && pWpn->GetWeaponID() == TF_WEAPON_MINIGUN );
			bool bIsSniperRifle = ( pWpn && pWpn->GetWeaponID() == TF_WEAPON_SNIPERRIFLE );

			// Heavy weapons primary fire.
			if ( bIsMinigun )
			{
				// Play standing primary fire.
				iGestureActivity = ACT_MP_ATTACK_STAND_PRIMARYFIRE;

				if ( m_bInSwim )
				{
					// Play swimming primary fire.
					iGestureActivity = ACT_MP_ATTACK_SWIM_PRIMARYFIRE;
				}
				else if ( GetBasePlayer()->GetFlags() & FL_DUCKING )
				{
					// Play crouching primary fire.
					iGestureActivity = ACT_MP_ATTACK_CROUCH_PRIMARYFIRE;
				}

				if ( !IsGestureSlotPlaying( GESTURE_SLOT_ATTACK_AND_RELOAD, TranslateActivity(iGestureActivity) ) )
				{
					RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, iGestureActivity );
				}
			}
			else if ( bIsSniperRifle && pPlayer->m_Shared.InCond( TF_COND_ZOOMED ) )
			{
				// Weapon primary fire, zoomed in
				if ( GetBasePlayer()->GetFlags() & FL_DUCKING )
				{
					RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_CROUCH_PRIMARYFIRE_DEPLOYED );
				}
				else
				{
					RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_STAND_PRIMARYFIRE_DEPLOYED );
				}

				iGestureActivity = ACT_VM_PRIMARYATTACK;

				// Hold our deployed pose for a few seconds
				m_flHoldDeployedPoseUntilTime = gpGlobals->curtime + 2.0;
			}
			else
			{
				// Weapon primary fire.
				if ( GetBasePlayer()->GetFlags() & FL_DUCKING )
				{
					RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_CROUCH_PRIMARYFIRE );
				}
				else
				{
					RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_STAND_PRIMARYFIRE );
				}

				iGestureActivity = ACT_VM_PRIMARYATTACK;
			}

			break;
		}

	case PLAYERANIMEVENT_VOICE_COMMAND_GESTURE:
		{
			if ( !IsGestureSlotActive( GESTURE_SLOT_ATTACK_AND_RELOAD ) )
			{
				RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, (Activity)nData );
			}
			break;
		}
	case PLAYERANIMEVENT_ATTACK_SECONDARY:
		{
			// Weapon secondary fire.
			if ( GetBasePlayer()->GetFlags() & FL_DUCKING )
			{
				RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_CROUCH_SECONDARYFIRE );
			}
			else
			{
				RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_STAND_SECONDARYFIRE );
			}

			iGestureActivity = ACT_VM_PRIMARYATTACK;
			break;
		}
	case PLAYERANIMEVENT_ATTACK_PRE:
		{
			CTFPlayer *pPlayer = GetTFPlayer();
			if ( !pPlayer )
				return;

			CTFWeaponBase *pWpn = pPlayer->GetActiveTFWeapon();
			bool bIsMinigun  = ( pWpn && pWpn->GetWeaponID() == TF_WEAPON_MINIGUN );

			bool bAutoKillPreFire = false;
			if ( bIsMinigun )
			{
				bAutoKillPreFire = true;
			}

			if ( m_bInSwim && bIsMinigun )
			{
				// Weapon pre-fire. Used for minigun windup while swimming
				iGestureActivity = ACT_MP_ATTACK_SWIM_PREFIRE;
			}
			else if ( GetBasePlayer()->GetFlags() & FL_DUCKING ) 
			{
				// Weapon pre-fire. Used for minigun windup, sniper aiming start, etc in crouch.
				iGestureActivity = ACT_MP_ATTACK_CROUCH_PREFIRE;
			}
			else
			{
				// Weapon pre-fire. Used for minigun windup, sniper aiming start, etc.
				iGestureActivity = ACT_MP_ATTACK_STAND_PREFIRE;
			}

			RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, iGestureActivity, bAutoKillPreFire );

			break;
		}
	case PLAYERANIMEVENT_ATTACK_POST:
		{
			CTFPlayer *pPlayer = GetTFPlayer();
			if ( !pPlayer )
				return;

			CTFWeaponBase *pWpn = pPlayer->GetActiveTFWeapon();
			bool bIsMinigun  = ( pWpn && pWpn->GetWeaponID() == TF_WEAPON_MINIGUN );

			if ( m_bInSwim && bIsMinigun )
			{
				// Weapon pre-fire. Used for minigun winddown while swimming
				iGestureActivity = ACT_MP_ATTACK_SWIM_POSTFIRE;
			}
			else if ( GetBasePlayer()->GetFlags() & FL_DUCKING ) 
			{
				// Weapon post-fire. Used for minigun winddown in crouch.
				iGestureActivity = ACT_MP_ATTACK_CROUCH_POSTFIRE;
			}
			else
			{
				// Weapon post-fire. Used for minigun winddown.
				iGestureActivity = ACT_MP_ATTACK_STAND_POSTFIRE;
			}

			RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, iGestureActivity );

			break;
		}

	case PLAYERANIMEVENT_RELOAD:
		{
			// Weapon reload.
			if ( m_bInAirWalk )
			{
				RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_AIRWALK );
			}
			else
			{
				BaseClass::DoAnimationEvent( event, nData );
			}
			break;
		}
	case PLAYERANIMEVENT_RELOAD_LOOP:
		{
			// Weapon reload.
			if ( m_bInAirWalk )
			{
				RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_AIRWALK_LOOP );
			}
			else
			{
				BaseClass::DoAnimationEvent( event, nData );
			}
			break;
		}
	case PLAYERANIMEVENT_RELOAD_END:
		{
			// Weapon reload.
			if ( m_bInAirWalk )
			{
				RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_AIRWALK_END );
			}
			else
			{
				BaseClass::DoAnimationEvent( event, nData );
			}
			break;
		}
	case PLAYERANIMEVENT_DOUBLEJUMP:
		{
			// Check to see if we are jumping!
			if ( !m_bJumping )
			{
				m_bJumping = true;
				m_bFirstJumpFrame = true;
				m_flJumpStartTime = gpGlobals->curtime;
				RestartMainSequence();
			}

			// Force the air walk off.
			m_bInAirWalk = false;

			// Player the air dash gesture.
			if (GetBasePlayer()->GetFlags() & FL_DUCKING)
			{
				RestartGesture( GESTURE_SLOT_JUMP, ACT_MP_DOUBLEJUMP_CROUCH );
			}
			else
			{
				RestartGesture( GESTURE_SLOT_JUMP, ACT_MP_DOUBLEJUMP );
			}
			break;
		}
	default:
		{
			BaseClass::DoAnimationEvent( event, nData );
			break;
		}
	}

#ifdef CLIENT_DLL
	// Make the weapon play the animation as well
	if (iGestureActivity != ACT_INVALID && GetBasePlayer() != C_BasePlayer::GetLocalPlayer())
	{
		CBaseCombatWeapon *pWeapon = GetTFPlayer()->GetActiveWeapon();
		if ( pWeapon )
		{
			pWeapon->SendWeaponAnim( iGestureActivity );
			pWeapon->DoAnimationEvents(pWeapon->GetModelPtr());
		}
	}
#endif
}