void C_CSGOPlayerAnimState::SetupVelocity()
{
MDLCACHE_CRITICAL_SECTION();
Vector velocity = m_vVelocity;
if (Interfaces::EngineClient->IsHLTV() || Interfaces::EngineClient->IsPlayingDemo())
pBaseEntity->GetAbsVelocity(velocity);
else
pBaseEntity->EstimateAbsVelocity(velocity);
float spd = velocity.LengthSqr();
if (spd > std::pow(1.2f * 260.0f, 2))
{
Vector velocity_normalized = velocity;
VectorNormalizeFast(velocity_normalized);
velocity = velocity_normalized * (1.2f * 260.0f);
}
m_flAbsVelocityZ = velocity.z;
velocity.z = 0.0f;
float leanspd = m_vecLastSetupLeanVelocity.LengthSqr();
m_bIsAccelerating = velocity.Length2DSqr() > leanspd;
m_vVelocity = GetSmoothedVelocity(m_flLastClientSideAnimationUpdateTimeDelta * 2000.0f, velocity, m_vVelocity);
m_vVelocityNormalized = VectorNormalizeReturn(m_vVelocity);
float speed = std::fmin(m_vVelocity.Length(), 260.0f);
m_flSpeed = speed;
if (speed > 0.0f)
m_vecLastAcceleratingVelocity = m_vVelocityNormalized;
CBaseCombatWeapon *weapon = pBaseEntity->GetWeapon();
pActiveWeapon = weapon;
float flMaxMovementSpeed = 260.0f;
if (weapon)
flMaxMovementSpeed = std::fmax(weapon->GetMaxSpeed(), 0.001f);
m_flSpeedNormalized = clamp(m_flSpeed / flMaxMovementSpeed, 0.0f, 1.0f);
m_flRunningSpeed = m_flSpeed / (flMaxMovementSpeed * 0.520f);
m_flDuckingSpeed = m_flSpeed / (flMaxMovementSpeed * 0.340f);
if (m_flRunningSpeed < 1.0f)
{
if (m_flRunningSpeed < 0.5f)
{
float vel = m_flVelocityUnknown;
float delta = m_flLastClientSideAnimationUpdateTimeDelta * 60.0f;
float newvel;
if ((80.0f - vel) <= delta)
{
if (-delta <= (80.0f - vel))
newvel = 80.0f;
else
newvel = vel - delta;
}
else
{
newvel = vel + delta;
}
m_flVelocityUnknown = newvel;
}
}
else
{
m_flVelocityUnknown = m_flSpeed;
}
bool bWasMovingLastUpdate = false;
bool bJustStartedMovingLastUpdate = false;
if (m_flSpeed <= 0.0f)
{
m_flTimeSinceStartedMoving = 0.0f;
bWasMovingLastUpdate = m_flTimeSinceStoppedMoving <= 0.0f;
m_flTimeSinceStoppedMoving += m_flLastClientSideAnimationUpdateTimeDelta;
}
else
{
m_flTimeSinceStoppedMoving = 0.0f;
bJustStartedMovingLastUpdate = m_flTimeSinceStartedMoving <= 0.0f;
m_flTimeSinceStartedMoving = m_flLastClientSideAnimationUpdateTimeDelta + m_flTimeSinceStartedMoving;
}
m_flCurrentFeetYaw = m_flGoalFeetYaw;
m_flGoalFeetYaw = clamp(m_flGoalFeetYaw, -360.0f, 360.0f);
float eye_feet_delta = AngleDiff(m_flEyeYaw, m_flGoalFeetYaw);
float flRunningSpeed = clamp(m_flRunningSpeed, 0.0f, 1.0f);
float flYawModifier = (((m_flGroundFraction * -0.3f) - 0.2f) * flRunningSpeed) + 1.0f;
if (m_fDuckAmount > 0.0f)
{
float flDuckingSpeed = clamp(m_flDuckingSpeed, 0.0f, 1.0f);
flYawModifier = flYawModifier + ((m_fDuckAmount * flDuckingSpeed) * (0.5f - flYawModifier));
}
float flMaxYawModifier = flYawModifier * m_flMaxYaw;
float flMinYawModifier = flYawModifier * m_flMinYaw;
if (eye_feet_delta <= flMaxYawModifier)
{
if (flMinYawModifier > eye_feet_delta)
m_flGoalFeetYaw = fabs(flMinYawModifier) + m_flEyeYaw;
}
else
{
m_flGoalFeetYaw = m_flEyeYaw - fabs(flMaxYawModifier);
}
NormalizeAngle(m_flGoalFeetYaw);
if (m_flSpeed > 0.1f || fabs(m_flAbsVelocityZ) > 100.0f)
{
m_flGoalFeetYaw = ApproachAngle(
m_flEyeYaw,
m_flGoalFeetYaw,
((m_flGroundFraction * 20.0f) + 30.0f)
* m_flLastClientSideAnimationUpdateTimeDelta);
}
else
{
m_flGoalFeetYaw = ApproachAngle(
pBaseEntity->GetLowerBodyYaw(),
m_flGoalFeetYaw,
m_flLastClientSideAnimationUpdateTimeDelta * 100.0f);
}
C_AnimationLayer *layer3 = pBaseEntity->GetAnimOverlay(3);
if (layer3 && layer3->m_flWeight > 0.0f)
{
IncrementLayerCycle(3, false);
LayerWeightAdvance(3);
}
if (m_flSpeed > 0.0f)
{
float velAngle = (atan2(-m_vVelocity.y, -m_vVelocity.x) * 180.0f) * (1.0f / M_PI);
if (velAngle < 0.0f)
velAngle += 360.0f;
m_flGoalMoveDirGoalFeetDelta = AngleNormalize(AngleDiff(velAngle, m_flGoalFeetYaw));
}
m_flFeetVelDirDelta = AngleNormalize(AngleDiff(m_flGoalMoveDirGoalFeetDelta, m_flCurrentMoveDirGoalFeetDelta));
if (bJustStartedMovingLastUpdate && m_flFeetYawRate <= 0.0f)
{
m_flCurrentMoveDirGoalFeetDelta = m_flGoalMoveDirGoalFeetDelta;
C_AnimationLayer *layer = pBaseEntity->GetAnimOverlay(6);
if (layer && layer->m_nSequence != -1)
{
if (*(DWORD*)((DWORD)pBaseEntity->pSeqdesc(layer->m_nSequence) + 0xC4) > 0)
{
int tag = ANIMTAG_UNINITIALIZED;
if (std::fabs(AngleDiff(m_flCurrentMoveDirGoalFeetDelta, 180.0f)) > 22.5f)
{
if (std::fabs(AngleDiff(m_flCurrentMoveDirGoalFeetDelta, 135.0f)) > 22.5f)
{
if (std::fabs(AngleDiff(m_flCurrentMoveDirGoalFeetDelta, 90.0f)) > 22.5f)
{
if (std::fabs(AngleDiff(m_flCurrentMoveDirGoalFeetDelta, 45.0f)) > 22.5f)
{
if (std::fabs(AngleDiff(m_flCurrentMoveDirGoalFeetDelta, 0.0f)) > 22.5f)
{
if (std::fabs(AngleDiff(m_flCurrentMoveDirGoalFeetDelta, -45.0f)) > 22.5f)
{
if (std::fabs(AngleDiff(m_flCurrentMoveDirGoalFeetDelta, -90.0f)) > 22.5f)
{
if (std::fabs(AngleDiff(m_flCurrentMoveDirGoalFeetDelta, -135.0f)) <= 22.5f)
tag = ANIMTAG_STARTCYCLE_NW;
}
else
{
tag = ANIMTAG_STARTCYCLE_W;
}
}
else
{
tag = ANIMTAG_STARTCYCLE_SW;
}
}
else
{
tag = ANIMTAG_STARTCYCLE_S;
}
}
else
{
tag = ANIMTAG_STARTCYCLE_SE;
}
}
else
{
tag = ANIMTAG_STARTCYCLE_E;
}
}
else
{
tag = ANIMTAG_STARTCYCLE_NE;
}
}
else
{
tag = ANIMTAG_STARTCYCLE_N;
}
m_flFeetCycle = pBaseEntity->GetFirstSequenceAnimTag(layer->m_nSequence, tag);
}
}
if (m_flDuckRate >= 1.0f && !clientpad[0] && std::fabs(m_flFeetVelDirDelta) > 45.0f)
{
if (m_bOnGround)
{
if (pBaseEntity->GetUnknownAnimationFloat() <= 0.0f)
pBaseEntity->DoUnknownAnimationCode(0.3f);
}
}
}
else
{
if (m_flDuckRate >= 1.0f
&& !clientpad[0]
&& std::fabs(m_flFeetVelDirDelta) > 100.0
&& m_bOnGround
&& pBaseEntity->GetUnknownAnimationFloat() <= 0.0)
{
pBaseEntity->DoUnknownAnimationCode(0.3f);
}
C_AnimationLayer *layer = pBaseEntity->GetAnimOverlay(6);
if (layer->m_flWeight >= 1.0f)
{
m_flCurrentMoveDirGoalFeetDelta = m_flGoalMoveDirGoalFeetDelta;
}
else
{
float flDuckSpeedClamp = clamp(m_flDuckingSpeed, 0.0f, 1.0f);
float flRunningSpeed = clamp(m_flRunningSpeed, 0.0f, 1.0f);
float flBiasMove = Bias(Lerp(m_fDuckAmount, flDuckSpeedClamp, flRunningSpeed), 0.18f);
m_flCurrentMoveDirGoalFeetDelta = AngleNormalize(((flBiasMove + 0.1f) * m_flFeetVelDirDelta) + m_flCurrentMoveDirGoalFeetDelta);
}
}
m_arrPoseParameters[4].SetValue(pBaseEntity, m_flCurrentMoveDirGoalFeetDelta);
float eye_goalfeet_delta = AngleDiff(m_flEyeYaw - m_flGoalFeetYaw, 360.0f);
float new_body_yaw_pose = 0.0f; //not initialized?
if (eye_goalfeet_delta < 0.0f || m_flMaxYaw == 0.0f)
{
if (m_flMinYaw != 0.0f)
new_body_yaw_pose = (eye_goalfeet_delta / m_flMinYaw) * -58.0f;
}
else
{
new_body_yaw_pose = (eye_goalfeet_delta / m_flMaxYaw) * 58.0f;
}
m_arrPoseParameters[6].SetValue(pBaseEntity, new_body_yaw_pose);
float eye_pitch_normalized = AngleNormalize(m_flPitch);
float new_body_pitch_pose;
if (eye_pitch_normalized <= 0.0f)
new_body_pitch_pose = (eye_pitch_normalized / m_flMaximumPitch) * -90.0f;
else
new_body_pitch_pose = (eye_pitch_normalized / m_flMinimumPitch) * 90.0f;
m_arrPoseParameters[7].SetValue(pBaseEntity, new_body_pitch_pose);
m_arrPoseParameters[1].SetValue(pBaseEntity, m_flRunningSpeed);
m_arrPoseParameters[9].SetValue(pBaseEntity, m_flDuckRate * m_fDuckAmount);
}