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

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
15 Окт 2019
Сообщения
45
Реакции
8
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
 
right so you fixed all the things that have the least effect on the vertical position of the head bone.......... mr mercury997 my man,,,, animation fixes arent just to look pretty, youre supposed to rebuild anims to make sure your shoot pos isnt fucked after landing..... fix SetUpMovement if you are to fix anything bro....
 
Назад
Сверху Снизу