Исходник Supremacy Rebuilt Animations // supremacy c+p ready

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
15 Окт 2019
Сообщения
45
Реакции
6
supremacy full sdk rework oneday, inshalla
updateanimations() function:
Expand Collapse Copy
// 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:
Expand Collapse Copy
#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:
Expand Collapse Copy
#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;
}
 
supremacy full sdk rework oneday, inshalla
updateanimations() function:
Expand Collapse Copy
// 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:
Expand Collapse Copy
#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:
Expand Collapse Copy
#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;
}
wrong
just check how it game does
Пожалуйста, авторизуйтесь для просмотра ссылки.
 
supremacy full sdk rework oneday, inshalla
updateanimations() function:
Expand Collapse Copy
// 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:
Expand Collapse Copy
#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:
Expand Collapse Copy
#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;
}
this is wrong and also from airflow /del
 
Назад
Сверху Снизу