Начинающий
- Статус
- Оффлайн
- Регистрация
- 15 Окт 2019
- Сообщения
- 45
- Реакции
- 6
supremacy full sdk rework oneday, inshalla
updateanimations() function:
// replace your current anim update
// player->m_bClientSideAnimation() = true;
// player->UpdateClientSideAnimation();
// player->m_bClientSideAnimation() = false;
// with this
void UpdatePlayerAnimations(CCSGOPlayerAnimState* pState, Player* player) {
/* Force the owner of animation layers */
for (int iLayer = 0; iLayer < 13; iLayer++) {
C_AnimationLayer* m_Layer = &player->m_AnimOverlay()[iLayer];
if (!m_Layer)
continue;
m_Layer->m_owner = player;
m_Layer->studio_hdr = player->GetModelPtr();
}
player->m_bClientSideAnimation() = true;
player->UpdateClientSideAnimation();
player->m_bClientSideAnimation() = false;
auto animation_time = player->m_flOldSimulationTime() + g_csgo.m_globals->m_interval;
auto animation_ticks = game::TIME_TO_TICKS(animation_time);
auto& angles = player->m_angEyeAngles();
anims::rebuilt::update(player, pState, angles.y, angles.x, animation_time, animation_ticks);
}
rebuilt_animations.h:
#pragma once
#include <deque>
#include <array>
#include <optional>
#include <cmath>
#undef min
#undef max
#define CSGO_ANIM_LOWER_CATCHUP_IDLE 100.0f
#define CSGO_ANIM_AIM_NARROW_WALK 0.8f
#define CSGO_ANIM_AIM_NARROW_RUN 0.5f
#define CSGO_ANIM_AIM_NARROW_CROUCHMOVING 0.5f
#define CSGO_ANIM_LOWER_CATCHUP_WITHIN 3.0f
#define CSGO_ANIM_READJUST_THRESHOLD 120.0f
#define EIGHT_WAY_WIDTH 22.5f
#define FIRSTPERSON_TO_THIRDPERSON_VERTICAL_TOLERANCE_MIN 4.0f
#define FIRSTPERSON_TO_THIRDPERSON_VERTICAL_TOLERANCE_MAX 10.0f
#define CSGO_ANIM_WALK_TO_RUN_TRANSITION_SPEED 2.0f
#define CSGO_ANIM_ONGROUND_FUZZY_APPROACH 8.0f
#define CSGO_ANIM_ONGROUND_FUZZY_APPROACH_CROUCH 16.0f
#define CSGO_ANIM_LADDER_CLIMB_COVERAGE 100.0f
#define CSGO_ANIM_RUN_ANIM_PLAYBACK_MULTIPLIER 0.85f
#define MAX_ANIMSTATE_ANIMNAME_CHARS 64
#define ANIM_TRANSITION_WALK_TO_RUN 0
#define ANIM_TRANSITION_RUN_TO_WALK 1
#define CS_PLAYER_SPEED_DUCK_MODIFIER 0.34f
#define CS_PLAYER_SPEED_WALK_MODIFIER 0.52f
#define CS_PLAYER_SPEED_CLIMB_MODIFIER 0.34f
#define CS_PLAYER_HEAVYARMOR_FLINCH_MODIFIER 0.5f
#define CS_PLAYER_SPEED_RUN 260.0f
#define MOVESTATE_IDLE 0
#define MOVESTATE_WALK 1
#define MOVESTATE_RUN 2
constexpr auto CLIENT_DLL_ANIMS = 0;
//constexpr auto ANIMATION_LAYER_COUNT = 13;
constexpr auto CSGO_ANIM_DUCK_APPROACH_SPEED_DOWN = 3.1f;
constexpr auto CSGO_ANIM_DUCK_APPROACH_SPEED_UP = 6.0f;
namespace valve_math {
__forceinline float RemapValClamped(float val, float A, float B, float C, float D) {
if (A == B)
return val >= B ? D : C;
float cVal = (val - A) / (B - A);
cVal = std::clamp(cVal, 0.0f, 1.0f);
return C + (D - C) * cVal;
}
__forceinline float anglemod(float a) {
a = (360.f / 65536) * ((int)(a * (65536.f / 360.0f)) & 65535);
return a;
}
__forceinline float Approach(float target, float value, float speed) {
float delta = target - value;
if (delta > speed)
value += speed;
else if (delta < -speed)
value -= speed;
else
value = target;
return value;
}
__forceinline vec3_t ApproachVec(vec3_t target, vec3_t value, float speed) {
vec3_t diff = (target - value);
float delta = diff.length();
if (delta > speed)
value += diff.normalized() * speed;
else if (delta < -speed)
value -= diff.normalized() * speed;
else
value = target;
return value;
}
__forceinline float ApproachAngle(float target, float value, float speed) {
target = anglemod(target);
value = anglemod(value);
float delta = target - value;
// Speed is assumed to be positive
if (speed < 0.0f)
speed = -speed;
if (delta < -180.0f)
delta += 360.0f;
else if (delta > 180.0f)
delta -= 360.0f;
if (delta > speed)
value += speed;
else if (delta < -speed)
value -= speed;
else
value = target;
return value;
}
__forceinline float AngleDiff(float destAngle, float srcAngle) {
float delta;
delta = fmodf(destAngle - srcAngle, 360.0f);
if (destAngle > srcAngle)
{
if (delta >= 180)
delta -= 360;
}
else
{
if (delta <= -180)
delta += 360;
}
return delta;
}
__forceinline float AngleDistance(float next, float cur) {
float delta = next - cur;
if (delta < -180)
delta += 360;
else if (delta > 180)
delta -= 360;
return delta;
}
__forceinline float AngleNormalize(float angle) {
angle = fmodf(angle, 360.0f);
if (angle > 180)
{
angle -= 360;
}
if (angle < -180)
{
angle += 360;
}
return angle;
}
__forceinline float Bias(float x, float biasAmt) {
// WARNING: not thread safe
static float lastAmt = -1.0f;
static float lastExponent = 0.0f;
if (lastAmt != biasAmt)
lastExponent = log(biasAmt) * -1.4427f; // (-1.4427 = 1 / log(0.5))
return pow(x, lastExponent);
}
__forceinline float Gain(float x, float biasAmt) {
// WARNING: not thread safe
if (x < 0.5f)
return 0.5f * Bias(2.0f * x, 1.0f - biasAmt);
return 1.0f - 0.5f * Bias(2.0f - 2.0f * x, 1.0f - biasAmt);
}
__forceinline vec3_t ApproachVector(vec3_t& a, vec3_t& b, float rate) {
const auto delta = a - b;
const auto delta_len = delta.length();
if (delta_len <= rate) {
vec3_t result;
if (-rate <= delta_len) {
return a;
}
else {
const auto iradius = 1.0f / (delta_len + std::numeric_limits<float>::epsilon());
return b - ((delta * iradius) * rate);
}
}
else {
const auto iradius = 1.0f / (delta_len + std::numeric_limits<float>::epsilon());
return b + ((delta * iradius) * rate);
}
};
}
namespace anims::rebuilt {
void setup_velocity(CCSGOPlayerAnimState* anim_state, float curtime);
void setup_lean(CCSGOPlayerAnimState* anim_state, float curtime);
void setup_aim_matrix(CCSGOPlayerAnimState* anim_state, float curtime);
void update(Player* player, CCSGOPlayerAnimState* state, float yaw, float pitch, float curtime, int framecount);
}
rebuilt_animations.cpp:
#include "../../includes.h"
constexpr auto CSGO_ANIM_SPEED_TO_CHANGE_AIM_MATRIX = 0.8f;
constexpr auto CSGO_ANIM_SPEED_TO_CHANGE_AIM_MATRIX_SCOPED = 4.2f;
constexpr auto CSGO_ANIM_AIMMATRIX_DEFAULT_YAW_MAX = 58.0f;
constexpr auto CSGO_ANIM_AIMMATRIX_DEFAULT_YAW_MIN = -58.0f;
constexpr auto CSGO_ANIM_AIMMATRIX_DEFAULT_PITCH_MAX = 90.0f;
constexpr auto CSGO_ANIM_AIMMATRIX_DEFAULT_PITCH_MIN = -90.0f;
using ANIMSTATE_FUNC_FN = void(__thiscall*)(CCSGOPlayerAnimState*);
float get_sequence_animtag(CStudioHdr* hdr, int sequence, int tag) {
auto studiohdr = *reinterpret_cast<studiohdr_t**>(hdr);
if (!studiohdr)
return 0.f;
if (!studiohdr || sequence >= studiohdr->m_num_local_seq)
return 0.f;
auto& sequence_desc = hdr->get_sequence_desc(sequence);
int anim_tags = sequence_desc.num_animtags;
if (anim_tags == 0)
return 0.f;
for (int i = 0; i < anim_tags; ++i) {
auto anim_tag_ptr = sequence_desc.anim_tag(i);
auto anim_tag = *reinterpret_cast<int*>(anim_tag_ptr);
if (anim_tag == -1)
continue;
if (anim_tag == 0) {
auto anim_tag_name = reinterpret_cast<const char*>(anim_tag_ptr + *reinterpret_cast<int*>(anim_tag_ptr + 8));
auto func = g_csgo.index_from_anim_tag_name.as<int(__thiscall*)(const char*)>();
anim_tag = func(anim_tag_name);
}
if (anim_tag == tag) {
auto cycle = *reinterpret_cast<float*>(anim_tag_ptr + 4);
if (cycle >= 0.f && cycle < 1.f)
return cycle;
}
}
return 0.f;
}
float get_any_sequence_animtag(CStudioHdr* hdr, int sequence, int tag, float def_value) {
auto studiohdr = *reinterpret_cast<studiohdr_t**>(hdr);
if (!studiohdr)
return 0.f;
if (!studiohdr || sequence >= studiohdr->m_num_local_seq)
return def_value;
auto& sequence_desc = hdr->get_sequence_desc(sequence);
int anim_tags = sequence_desc.num_animtags;
if (anim_tags == 0)
return def_value;
for (int i = 0; i < anim_tags; ++i) {
auto anim_tag_ptr = sequence_desc.anim_tag(i);
auto anim_tag = *reinterpret_cast<int*>(anim_tag_ptr);
if (anim_tag == -1)
continue;
if (anim_tag == 0) {
auto anim_tag_name = reinterpret_cast<const char*>(anim_tag_ptr + *reinterpret_cast<int*>(anim_tag_ptr + 8));
auto func = g_csgo.index_from_anim_tag_name.as<int(__thiscall*)(const char*)>();
anim_tag = func(anim_tag_name);
}
if (anim_tag == tag) {
auto cycle = *reinterpret_cast<float*>(anim_tag_ptr + 4);
return cycle;
}
}
return def_value;
}
void anims::rebuilt::setup_velocity(CCSGOPlayerAnimState* anim_state, float curtime) {
auto player = reinterpret_cast<Player*>(anim_state->m_player);
auto hdr = player->GetModelPtr();
if (!hdr)
return;
auto weapon = player->GetActiveWeapon();
if (!weapon)
return;
auto weapon_info = weapon->GetWpnData();
if (!weapon_info)
return;
auto max_speed = weapon && weapon_info ?
std::max<float>((player->m_bIsScoped() ? weapon_info->m_max_player_speed_alt : weapon_info->m_max_player_speed), 0.001f)
: CS_PLAYER_SPEED_RUN;
auto abs_velocity = player->m_vecVelocity();
anim_state->m_velocity_length_z = abs_velocity.z;
abs_velocity.z = 0.f;
anim_state->m_player_is_accelerating = (anim_state->m_velocity_last.length_sqr() < abs_velocity.length_sqr());
anim_state->m_velocity = valve_math::ApproachVec(abs_velocity, anim_state->m_velocity, anim_state->m_last_update_increment * 2000);
anim_state->m_velocity_normalized = anim_state->m_velocity.normalized();
if (anim_state->m_velocity_length_xy > 0)
anim_state->m_velocity_normalized_non_zero = anim_state->m_velocity_normalized;
anim_state->m_speed_as_portion_of_run_top_speed = std::clamp<float>(anim_state->m_velocity_length_xy / max_speed, 0, 1);
anim_state->m_speed_as_portion_of_walk_top_speed = anim_state->m_velocity_length_xy / (max_speed * CS_PLAYER_SPEED_WALK_MODIFIER);
anim_state->m_speed_as_portion_of_crouch_top_speed = anim_state->m_velocity_length_xy / (max_speed * CS_PLAYER_SPEED_DUCK_MODIFIER);
if (anim_state->m_speed_as_portion_of_walk_top_speed >= 1)
anim_state->m_static_approach_speed = anim_state->m_velocity_length_xy;
else if (anim_state->m_speed_as_portion_of_walk_top_speed < 0.5f)
anim_state->m_static_approach_speed = valve_math::Approach(80, anim_state->m_static_approach_speed, anim_state->m_last_update_increment * 60);
bool started_moving_this_frame = false;
bool stopped_moving_this_frame = false;
if (anim_state->m_velocity_length_xy > 0) {
started_moving_this_frame = (anim_state->m_duration_moving <= 0);
anim_state->m_duration_still = 0;
anim_state->m_duration_moving += anim_state->m_last_update_increment;
}
else {
stopped_moving_this_frame = (anim_state->m_duration_still <= 0);
anim_state->m_duration_moving = 0;
anim_state->m_duration_still += anim_state->m_last_update_increment;
}
auto adjust = &player->m_AnimOverlay()[3];
if (!anim_state->m_adjust_started && stopped_moving_this_frame && anim_state->m_on_ground && !anim_state->m_on_ladder && !anim_state->m_landing && anim_state->m_stutter_step < 50.f) {
anim_state->SetLayerSequence(adjust, anim_state->SelectSequenceFromActivityModifier(ACT_CSGO_IDLE_ADJUST_STOPPEDMOVING));
anim_state->m_adjust_started = true;
}
int layer_activity = player->GetSequenceActivity(adjust->m_sequence);
if (layer_activity == ACT_CSGO_IDLE_ADJUST_STOPPEDMOVING || layer_activity == ACT_CSGO_IDLE_TURN_BALANCEADJUST) {
if (anim_state->m_adjust_started && anim_state->m_speed_as_portion_of_crouch_top_speed <= 0.25f) {
float previous_weight = adjust->m_weight;
anim_state->IncrementLayerCycle(adjust, false);
anim_state->SetLayerWeight(adjust, anim_state->GetLayerIdealWeightFromSeqCycle(adjust));
anim_state->SetLayerWeightRate(adjust, previous_weight);
anim_state->m_adjust_started = !(anim_state->IsLayerSequenceFinished(adjust, anim_state->m_last_update_increment));
}
else {
anim_state->m_adjust_started = false;
float previous_weight = adjust->m_weight;
anim_state->SetLayerWeight(adjust, valve_math::Approach(0, previous_weight, anim_state->m_last_update_increment * 5.f));
anim_state->SetLayerWeightRate(adjust, previous_weight);
}
}
anim_state->m_foot_yaw_last = anim_state->m_foot_yaw;
anim_state->m_foot_yaw = std::clamp<float>(anim_state->m_foot_yaw, -360, 360);
auto eye_delta = valve_math::AngleDiff(anim_state->m_eye_yaw, anim_state->m_foot_yaw);
auto speed_portion_walk = anim_state->m_speed_as_portion_of_walk_top_speed;
auto speed_portion_duck = anim_state->m_speed_as_portion_of_crouch_top_speed;
auto transition = anim_state->m_walk_to_run_transition;
auto duck_amount = anim_state->m_anim_duck_amount;
auto aim_matrix_width_range = math::lerp(std::clamp(speed_portion_walk, 0.f, 1.f), 1.f,
math::lerp(transition, 0.8f, 0.5f));
if (duck_amount > 0)
aim_matrix_width_range = math::lerp(duck_amount * std::clamp(speed_portion_duck, 0.f, 1.f),
aim_matrix_width_range, 0.5f);
auto yaw_max = anim_state->m_aim_yaw_max * aim_matrix_width_range;
auto yaw_min = anim_state->m_aim_yaw_min * aim_matrix_width_range;
if (eye_delta > yaw_max)
anim_state->m_foot_yaw = anim_state->m_eye_yaw - abs(yaw_max);
else if (eye_delta < yaw_min)
anim_state->m_foot_yaw = anim_state->m_eye_yaw + abs(yaw_min);
anim_state->m_foot_yaw = valve_math::AngleNormalize(anim_state->m_eye_yaw);
if (anim_state->m_on_ground) {
if (anim_state->m_velocity_length_xy > 0.1f) {
anim_state->m_foot_yaw = valve_math::ApproachAngle(anim_state->m_eye_yaw, anim_state->m_foot_yaw, anim_state->m_last_update_increment * (30.0f + 20.0f * anim_state->m_walk_to_run_transition));
}
else {
anim_state->m_foot_yaw = valve_math::ApproachAngle(player->m_flLowerBodyYawTarget(), anim_state->m_foot_yaw, anim_state->m_last_update_increment * 100.f);
}
}
if (anim_state->m_velocity_length_xy <= 1.f && anim_state->m_on_ground && !anim_state->m_on_ladder && !anim_state->m_landing
&& anim_state->m_last_update_increment > 0 && (std::abs(valve_math::AngleDiff(anim_state->m_foot_yaw_last, anim_state->m_foot_yaw)) / anim_state->m_last_update_increment) > 120.f) {
anim_state->SetLayerSequence(adjust, anim_state->SelectSequenceFromActivityModifier(ACT_CSGO_IDLE_TURN_BALANCEADJUST));
anim_state->m_adjust_started = true;
}
if (adjust->m_weight > 0) {
anim_state->IncrementLayerCycle(adjust, false);
anim_state->IncrementLayerWeight(adjust);
}
if (anim_state->m_velocity_length_xy > 0 && anim_state->m_on_ground) {
float raw_yaw_ideal = (std::atan2(-anim_state->m_velocity[1], -anim_state->m_velocity[0]) * 180 / 3.14159265358979323846);
if (raw_yaw_ideal < 0)
raw_yaw_ideal += 360;
anim_state->m_move_yaw_ideal = valve_math::AngleNormalize(valve_math::AngleDiff(raw_yaw_ideal, anim_state->m_foot_yaw));
}
anim_state->m_move_yaw_current_to_ideal = valve_math::AngleNormalize(valve_math::AngleDiff(anim_state->m_move_yaw_ideal, anim_state->m_move_yaw));
auto move = &player->m_AnimOverlay()[6];
auto strafe_change = &player->m_AnimOverlay()[7];
if (started_moving_this_frame && anim_state->m_move_weight <= 0.f) {
anim_state->m_move_yaw = anim_state->m_move_yaw_ideal;
auto move_sequence = move->m_sequence;
if (move_sequence != -1) {
auto& sequence_desc = hdr->get_sequence_desc(move->m_sequence);
auto anim_tags = sequence_desc.num_animtags;
if (anim_tags > 0) {
if (std::abs(valve_math::AngleDiff(anim_state->m_move_yaw, 180)) <= EIGHT_WAY_WIDTH) //N
anim_state->m_primary_cycle = get_sequence_animtag(hdr, move_sequence, ANIMTAG_STARTCYCLE_N);
else if (std::abs(valve_math::AngleDiff(anim_state->m_move_yaw, 135)) <= EIGHT_WAY_WIDTH) //NE
anim_state->m_primary_cycle = get_sequence_animtag(hdr, move_sequence, ANIMTAG_STARTCYCLE_NE);
else if (std::abs(valve_math::AngleDiff(anim_state->m_move_yaw, 90)) <= EIGHT_WAY_WIDTH) //E
anim_state->m_primary_cycle = get_sequence_animtag(hdr, move_sequence, ANIMTAG_STARTCYCLE_E);
else if (std::abs(valve_math::AngleDiff(anim_state->m_move_yaw, 45)) <= EIGHT_WAY_WIDTH) //SE
anim_state->m_primary_cycle = get_sequence_animtag(hdr, move_sequence, ANIMTAG_STARTCYCLE_SE);
else if (std::abs(valve_math::AngleDiff(anim_state->m_move_yaw, 0)) <= EIGHT_WAY_WIDTH) //S
anim_state->m_primary_cycle = get_sequence_animtag(hdr, move_sequence, ANIMTAG_STARTCYCLE_S);
else if (std::abs(valve_math::AngleDiff(anim_state->m_move_yaw, -45)) <= EIGHT_WAY_WIDTH) //SW
anim_state->m_primary_cycle = get_sequence_animtag(hdr, move_sequence, ANIMTAG_STARTCYCLE_SW);
else if (std::abs(valve_math::AngleDiff(anim_state->m_move_yaw, -90)) <= EIGHT_WAY_WIDTH) //W
anim_state->m_primary_cycle = get_sequence_animtag(hdr, move_sequence, ANIMTAG_STARTCYCLE_W);
else if (std::abs(valve_math::AngleDiff(anim_state->m_move_yaw, -135)) <= EIGHT_WAY_WIDTH) //NW
anim_state->m_primary_cycle = get_sequence_animtag(hdr, move_sequence, ANIMTAG_STARTCYCLE_NW);
}
}
}
else {
if (strafe_change->m_weight >= 1)
anim_state->m_move_yaw = anim_state->m_move_yaw_ideal;
else {
float move_weight = math::lerp(anim_state->m_anim_duck_amount,
std::clamp(anim_state->m_speed_as_portion_of_walk_top_speed, 0.f, 1.f),
std::clamp(anim_state->m_speed_as_portion_of_crouch_top_speed, 0.f, 1.f));
float ratio = valve_math::Bias(move_weight, 0.18f) + 0.1f;
anim_state->m_move_yaw = valve_math::AngleNormalize(anim_state->m_move_yaw + (anim_state->m_move_yaw_current_to_ideal * ratio));
}
}
anim_state->m_pose_param_mappings[PLAYER_POSE_PARAM_MOVE_YAW].SetValue(player, anim_state->m_move_yaw);
float aim_yaw = valve_math::AngleDiff(anim_state->m_eye_yaw, anim_state->m_foot_yaw);
if (aim_yaw >= 0 && anim_state->m_aim_yaw_max != 0)
aim_yaw = (aim_yaw / anim_state->m_aim_yaw_max) * 60.0f;
else if (anim_state->m_aim_yaw_min != 0)
aim_yaw = (aim_yaw / anim_state->m_aim_yaw_min) * -60.0f;
anim_state->m_pose_param_mappings[PLAYER_POSE_PARAM_BODY_YAW].SetValue(player, aim_yaw);
float pitch = valve_math::AngleDiff(anim_state->m_eye_pitch, 0);
if (pitch > 0)
pitch = (pitch / anim_state->m_aim_pitch_max) * 90.f;
else
pitch = (pitch / anim_state->m_aim_pitch_min) * -90.f;
anim_state->m_pose_param_mappings[PLAYER_POSE_PARAM_BODY_PITCH].SetValue(player, pitch);
anim_state->m_pose_param_mappings[PLAYER_POSE_PARAM_SPEED].SetValue(player, anim_state->m_speed_as_portion_of_walk_top_speed);
anim_state->m_pose_param_mappings[PLAYER_POSE_PARAM_STAND].SetValue(player, 1.0f - (anim_state->m_anim_duck_amount * anim_state->m_in_air_smooth_value));
}
void anims::rebuilt::setup_lean(CCSGOPlayerAnimState* anim_state, float curtime) {
auto player = reinterpret_cast<Player*>(anim_state->m_player);
auto lean = &player->m_AnimOverlay()[12];
lean->m_weight = lean->m_cycle = 0.f;
}
void anims::rebuilt::setup_aim_matrix(CCSGOPlayerAnimState* anim_state, float curtime) {
auto player = reinterpret_cast<Player*>(anim_state->m_player);
auto weapon = player->GetActiveWeapon();
if (!weapon)
return;
if (anim_state->m_anim_duck_amount <= 0 || anim_state->m_anim_duck_amount >= 1) {
bool bPlayerIsWalking = (player && player->m_bIsWalking());
bool bPlayerIsScoped = (player && player->m_bIsScoped());
float flTransitionSpeed = anim_state->m_last_update_increment * (bPlayerIsScoped ? CSGO_ANIM_SPEED_TO_CHANGE_AIM_MATRIX_SCOPED : CSGO_ANIM_SPEED_TO_CHANGE_AIM_MATRIX);
if (bPlayerIsScoped) {
anim_state->m_stand_walk_aim.m_duration_state_has_been_invalid = anim_state->m_stand_walk_aim.m_how_long_to_wait_until_transition_can_blend_out;
anim_state->m_stand_run_aim.m_duration_state_has_been_invalid = anim_state->m_stand_run_aim.m_how_long_to_wait_until_transition_can_blend_out;
anim_state->m_crouch_walk_aim.m_duration_state_has_been_invalid = anim_state->m_crouch_walk_aim.m_how_long_to_wait_until_transition_can_blend_out;
}
anim_state->m_stand_walk_aim.Update(bPlayerIsWalking && !bPlayerIsScoped && anim_state->m_speed_as_portion_of_walk_top_speed > 0.7f && anim_state->m_speed_as_portion_of_run_top_speed < 0.7,
anim_state->m_last_update_increment, flTransitionSpeed);
anim_state->m_stand_run_aim.Update(!bPlayerIsScoped && anim_state->m_speed_as_portion_of_run_top_speed >= 0.7,
anim_state->m_last_update_increment, flTransitionSpeed);
anim_state->m_crouch_walk_aim.Update(!bPlayerIsScoped && anim_state->m_speed_as_portion_of_crouch_top_speed >= 0.5,
anim_state->m_last_update_increment, flTransitionSpeed);
}
float flStandIdleWeight = 1;
float flStandWalkWeight = anim_state->m_stand_walk_aim.m_blend_value;
float flStandRunWeight = anim_state->m_stand_run_aim.m_blend_value;
float flCrouchIdleWeight = 1;
float flCrouchWalkWeight = anim_state->m_crouch_walk_aim.m_blend_value;
if (flStandWalkWeight >= 1)
flStandIdleWeight = 0;
if (flStandRunWeight >= 1) {
flStandIdleWeight = 0;
flStandWalkWeight = 0;
}
if (flCrouchWalkWeight >= 1)
flCrouchIdleWeight = 0;
if (anim_state->m_anim_duck_amount >= 1) {
flStandIdleWeight = 0;
flStandWalkWeight = 0;
flStandRunWeight = 0;
}
else if (anim_state->m_anim_duck_amount <= 0) {
flCrouchIdleWeight = 0;
flCrouchWalkWeight = 0;
}
float flOneMinusDuckAmount = 1.0f - anim_state->m_anim_duck_amount;
flCrouchIdleWeight *= anim_state->m_anim_duck_amount;
flCrouchWalkWeight *= anim_state->m_anim_duck_amount;
flStandWalkWeight *= flOneMinusDuckAmount;
flStandRunWeight *= flOneMinusDuckAmount;
if (flCrouchIdleWeight < 1 && flCrouchWalkWeight < 1 && flStandWalkWeight < 1 && flStandRunWeight < 1)
flStandIdleWeight = 1;
anim_state->m_pose_param_mappings[PLAYER_POSE_PARAM_AIM_BLEND_STAND_IDLE].SetValue(player, flStandIdleWeight);
anim_state->m_pose_param_mappings[PLAYER_POSE_PARAM_AIM_BLEND_STAND_WALK].SetValue(player, flStandWalkWeight);
anim_state->m_pose_param_mappings[PLAYER_POSE_PARAM_AIM_BLEND_STAND_RUN].SetValue(player, flStandRunWeight);
anim_state->m_pose_param_mappings[PLAYER_POSE_PARAM_AIM_BLEND_CROUCH_IDLE].SetValue(player, flCrouchIdleWeight);
anim_state->m_pose_param_mappings[PLAYER_POSE_PARAM_AIM_BLEND_CROUCH_WALK].SetValue(player, flCrouchWalkWeight);
static auto get_weapon_prefix = g_csgo.get_weapon_prefix.as<const char* (__thiscall*)(void*)>();
char szTransitionStandAimMatrix[64]{};
if (get_weapon_prefix && get_weapon_prefix(anim_state)) {
sprintf_s(szTransitionStandAimMatrix, xor_c("%s_aim"), get_weapon_prefix(anim_state));
}
int nSeqStand = player->lookup_sequence(szTransitionStandAimMatrix);
auto layer = &player->m_AnimOverlay()[0];
if (layer && weapon) {
auto aim_matrix_holder = player;
int nSeq = nSeqStand;
auto pWeaponWorldModel = (Player*)(g_csgo.m_entlist->GetClientEntityFromHandle(weapon->m_hWeaponWorldModel()));
if (pWeaponWorldModel && layer->dispatch_sequence != ACT_INVALID) {
aim_matrix_holder = pWeaponWorldModel;
nSeq = layer->dispatch_sequence;
}
if (nSeq > 0) {
auto hdr = aim_matrix_holder->GetModelPtr();
if (hdr) {
float flYawIdleMin = get_any_sequence_animtag(hdr, nSeq, ANIMTAG_AIMLIMIT_YAWMIN_IDLE, CSGO_ANIM_AIMMATRIX_DEFAULT_YAW_MIN);
float flYawIdleMax = get_any_sequence_animtag(hdr, nSeq, ANIMTAG_AIMLIMIT_YAWMAX_IDLE, CSGO_ANIM_AIMMATRIX_DEFAULT_YAW_MAX);
float flYawWalkMin = get_any_sequence_animtag(hdr, nSeq, ANIMTAG_AIMLIMIT_YAWMIN_WALK, flYawIdleMin);
float flYawWalkMax = get_any_sequence_animtag(hdr, nSeq, ANIMTAG_AIMLIMIT_YAWMAX_WALK, flYawIdleMax);
float flYawRunMin = get_any_sequence_animtag(hdr, nSeq, ANIMTAG_AIMLIMIT_YAWMIN_RUN, flYawWalkMin);
float flYawRunMax = get_any_sequence_animtag(hdr, nSeq, ANIMTAG_AIMLIMIT_YAWMAX_RUN, flYawWalkMax);
float flYawCrouchIdleMin = get_any_sequence_animtag(hdr, nSeq, ANIMTAG_AIMLIMIT_YAWMIN_CROUCHIDLE, CSGO_ANIM_AIMMATRIX_DEFAULT_YAW_MIN);
float flYawCrouchIdleMax = get_any_sequence_animtag(hdr, nSeq, ANIMTAG_AIMLIMIT_YAWMAX_CROUCHIDLE, CSGO_ANIM_AIMMATRIX_DEFAULT_YAW_MAX);
float flYawCrouchWalkMin = get_any_sequence_animtag(hdr, nSeq, ANIMTAG_AIMLIMIT_YAWMIN_CROUCHWALK, flYawCrouchIdleMin);
float flYawCrouchWalkMax = get_any_sequence_animtag(hdr, nSeq, ANIMTAG_AIMLIMIT_YAWMAX_CROUCHWALK, flYawCrouchIdleMax);
float flWalkAmt = anim_state->m_pose_param_mappings[PLAYER_POSE_PARAM_AIM_BLEND_STAND_WALK].GetValue(player);
float flRunAmt = anim_state->m_pose_param_mappings[PLAYER_POSE_PARAM_AIM_BLEND_STAND_RUN].GetValue(player);
float flCrouchWalkAmt = anim_state->m_pose_param_mappings[PLAYER_POSE_PARAM_AIM_BLEND_CROUCH_WALK].GetValue(player);
anim_state->m_aim_yaw_min = math::lerp(anim_state->m_anim_duck_amount,
math::lerp(flRunAmt, math::lerp(flWalkAmt, flYawIdleMin, flYawWalkMin), flYawRunMin),
math::lerp(flCrouchWalkAmt, flYawCrouchIdleMin, flYawCrouchWalkMin));
anim_state->m_aim_yaw_max = math::lerp(anim_state->m_anim_duck_amount,
math::lerp(flRunAmt, math::lerp(flWalkAmt, flYawIdleMax, flYawWalkMax), flYawRunMax),
math::lerp(flCrouchWalkAmt, flYawCrouchIdleMax, flYawCrouchWalkMax));
float flPitchIdleMin = get_any_sequence_animtag(hdr, nSeq, ANIMTAG_AIMLIMIT_PITCHMIN_IDLE, CSGO_ANIM_AIMMATRIX_DEFAULT_PITCH_MIN);
float flPitchIdleMax = get_any_sequence_animtag(hdr, nSeq, ANIMTAG_AIMLIMIT_PITCHMAX_IDLE, CSGO_ANIM_AIMMATRIX_DEFAULT_PITCH_MAX);
float flPitchWalkRunMin = get_any_sequence_animtag(hdr, nSeq, ANIMTAG_AIMLIMIT_PITCHMIN_WALKRUN, flPitchIdleMin);
float flPitchWalkRunMax = get_any_sequence_animtag(hdr, nSeq, ANIMTAG_AIMLIMIT_PITCHMAX_WALKRUN, flPitchIdleMax);
float flPitchCrouchMin = get_any_sequence_animtag(hdr, nSeq, ANIMTAG_AIMLIMIT_PITCHMIN_CROUCH, CSGO_ANIM_AIMMATRIX_DEFAULT_PITCH_MIN);
float flPitchCrouchMax = get_any_sequence_animtag(hdr, nSeq, ANIMTAG_AIMLIMIT_PITCHMAX_CROUCH, CSGO_ANIM_AIMMATRIX_DEFAULT_PITCH_MAX);
float flPitchCrouchWalkMin = get_any_sequence_animtag(hdr, nSeq, ANIMTAG_AIMLIMIT_PITCHMIN_CROUCHWALK, flPitchCrouchMin);
float flPitchCrouchWalkMax = get_any_sequence_animtag(hdr, nSeq, ANIMTAG_AIMLIMIT_PITCHMAX_CROUCHWALK, flPitchCrouchMax);
anim_state->m_aim_pitch_min = math::lerp(anim_state->m_anim_duck_amount, math::lerp(flWalkAmt, flPitchIdleMin, flPitchWalkRunMin), math::lerp(flCrouchWalkAmt, flPitchCrouchMin, flPitchCrouchWalkMin));
anim_state->m_aim_pitch_max = math::lerp(anim_state->m_anim_duck_amount, math::lerp(flWalkAmt, flPitchIdleMax, flPitchWalkRunMax), math::lerp(flCrouchWalkAmt, flPitchCrouchMax, flPitchCrouchWalkMax));
}
}
}
anim_state->UpdateLayer(layer, nSeqStand, 0.f, 0.f, 1.f, 0);
}
void anims::rebuilt::update(Player* player, CCSGOPlayerAnimState* state, float yaw, float pitch, float curtime, int framecount) {
state->m_player = player;
if (!g_csgo.cache_sequences.as<bool(__thiscall*)(CCSGOPlayerAnimState*)>()(state))
return;
pitch = valve_math::AngleNormalize(pitch + player->m_flThirdpersonRecoil());
state->m_last_update_increment = std::max<float>(0.f, curtime - state->m_last_update_time);
state->m_eye_yaw = valve_math::AngleNormalize(yaw);
state->m_eye_pitch = valve_math::AngleNormalize(pitch);
state->m_position_current = player->m_vecOrigin();
state->m_weapon = player->GetActiveWeapon();
if (state->m_weapon != state->m_weapon_last || state->m_first_run_since_init) {
for (int i = 0; i < 13; ++i) {
auto layer = &player->m_AnimOverlay()[i];
if (layer) {
layer->dispatch_sequence = -1;
layer->second_dispatch_sequence = -1;
}
}
}
state->m_anim_duck_amount = std::clamp<float>(valve_math::Approach(std::clamp<float>(player->m_flDuckAmount() + state->m_duck_additional, 0, 1),
state->m_anim_duck_amount, state->m_last_update_increment * 6.0f), 0, 1);
{
auto& new_seq = player->m_nPredictedViewModelSequence();
if (new_seq != 0) {
new_seq = 0;
}
*reinterpret_cast<float*>(reinterpret_cast<std::uintptr_t>(player) + 0xA18) = 0.f;
auto& cycle = *reinterpret_cast<float*>(reinterpret_cast<std::uintptr_t>(player) + 0xA14);
if (cycle != 0.f) {
cycle = 0;
}
}
{
setup_velocity(state, curtime);
setup_aim_matrix(state, curtime);
auto setup_weapon_action_fn = g_csgo.setup_weapon_action.as<ANIMSTATE_FUNC_FN>();
if (setup_weapon_action_fn)
setup_weapon_action_fn(state);
auto setup_movement_fn = g_csgo.setup_movement.as<ANIMSTATE_FUNC_FN>();
if (setup_movement_fn)
setup_movement_fn(state);
else
OutputDebugStringA("setup_movement function pointer is null!\n");
auto alive_loop = &player->m_AnimOverlay()[11];
state->IncrementLayerCycle(alive_loop, true);
auto whole_body = &player->m_AnimOverlay()[9];
if (whole_body->m_weight > 0) {
state->IncrementLayerCycle(whole_body, false);
state->IncrementLayerWeight(whole_body);
}
auto flashed = &player->m_AnimOverlay()[9];
if (flashed->m_weight > 0) {
if (flashed->m_weight_delta_rate < 0.f)
state->IncrementLayerWeight(flashed);
}
auto flinch = &player->m_AnimOverlay()[10];
state->IncrementLayerCycle(flinch, false);
setup_lean(state, curtime);
}
for (int i = 0; i < 13; ++i) {
auto layer = &player->m_AnimOverlay()[i];
if (layer->m_sequence == 0) {
layer->m_weight = 0.f;
}
}
player->SetAbsAngles({ 0.f, state->m_foot_yaw, 0.f });
state->m_weapon_last = state->m_weapon;
state->m_position_last = state->m_position_current;
state->m_first_run_since_init = false;
state->m_last_update_frame = framecount;
state->m_last_update_time = curtime;
}