Исходник Akatsuki's Hitchance converted to LW

like amiri in my mind
Пользователь
Статус
Оффлайн
Регистрация
4 Дек 2022
Сообщения
308
Реакции[?]
54
Поинты[?]
1K
Хитчанс с этой темы - https://yougame.biz/threads/273111/#post-2774210
Credits: AkatsukiSun, me
пример использования в аиме:
is_valid_hitchance = g_hit_chance->can_hit(final_target.record , g_ctx.globals.weapon,aim_angle,final_target.data.hitbox);
коротко о нем: тестил недолго, но хитчанс оч понравился будет полюбе лучше других пабликов
hitchance.cpp:
#include "../../utils/math.hpp"
#include "../../lagcompensation/animation_system.h"
#include "hitchance_system.h"


void hit_chance::build_seed_table() {
    constexpr float pi_2 = 2.0f * (float)M_PI;
    for (size_t i = 0; i < 256; ++i) {
        math::random_seed(i);

        const float rand_a = math::random_float(0.0f, 1.0f);
        const float rand_pi_a = math::random_float(0.0f, pi_2);
        const float rand_b = math::random_float(0.0f, 1.0f);
        const float rand_pi_b = math::random_float(0.0f, pi_2);

        hit_chance_records[i] = {
            {  rand_a, rand_b                                 },
            {  std::cos(rand_pi_a), std::sin(rand_pi_a)     },
            {  std::cos(rand_pi_b), std::sin(rand_pi_b)     }
        };
    }
}

bool hit_chance::intersects_bb_hitbox(Vector start, Vector delta, Vector min, Vector max) {
    float d1, d2, f;
    auto start_solid = true;
    auto t1 = -1.0, t2 = 1.0;

    const float _start[3] = { start.x, start.y, start.z };
    const float _delta[3] = { delta.x, delta.y, delta.z };
    const float mins[3] = { min.x, min.y, min.z };
    const float maxs[3] = { max.x, max.y, max.z };

    for (auto i = 0; i < 6; ++i) {
        if (i >= 3) {
            const auto j = (i - 3);

            d1 = _start[j] - maxs[j];
            d2 = d1 + _delta[j];
        }
        else {
            d1 = -_start[i] + mins[i];
            d2 = d1 - _delta[i];
        }

        if (d1 > 0 && d2 > 0) {
            start_solid = false;
            return false;
        }

        if (d1 <= 0 && d2 <= 0)
            continue;

        if (d1 > 0)
            start_solid = false;

        if (d1 > d2) {
            f = d1;
            if (f < 0)
                f = 0;

            f /= d1 - d2;
            if (f > t1)
                t1 = f;
        }
        else {
            f = d1 / (d1 - d2);
            if (f < t2)
                t2 = f;
        }
    }

    return start_solid || (t1 < t2&& t1 >= 0.0f);
}

bool __vectorcall hit_chance::intersects_hitbox(Vector eye_pos, Vector end_pos, Vector min, Vector max, float radius) {
    auto dist = math::segment_to_segment(eye_pos, end_pos, min, max);

    return (dist < radius);
}

std::vector<hit_chance::hitbox_data_t> hit_chance::get_hitbox_data(adjust_data* log, int hitbox) {
    std::vector<hitbox_data_t> hitbox_data;
    auto target= static_cast<player_t*>(m_entitylist()->GetClientEntity(log->player->EntIndex()));

    const auto model = target->GetClientRenderable()->GetModel();

    if (!model)
        return {};


    auto hdr = m_modelinfo()->GetStudioModel(model);

    if (!hdr)
        return {};

    auto set = hdr->pHitboxSet(log->player->m_nHitboxSet());

    if (!set)
        return {};

    //we use 128 bones that not proper use aim matrix there
    auto bone_matrix = log->matrixes_data.main;

    Vector min, max;

    if (hitbox == -1) {
        for (int i = 0; i < set->numhitboxes; ++i) {
            const auto box = set->pHitbox(i);

            if (!box)
                continue;

            float radius = box->radius;
            const auto is_capsule = radius != -1.f;

            if (is_capsule) {
                math::VectorTransform(box->bbmin, bone_matrix[box->bone], min);
                math::VectorTransform(box->bbmax, bone_matrix[box->bone], max);
            }
            else {
                math::VectorTransform(math::vector_rotate(box->bbmin, box->rotation), bone_matrix[box->bone], min);
                math::VectorTransform(math::vector_rotate(box->bbmax, box->rotation), bone_matrix[box->bone], max);
                radius = min.DistTo(max);
            }

            hitbox_data.emplace_back(hitbox_data_t{ min, max, radius, box, box->bone, box->rotation });
        }
    }
    else {
        const auto box = set->pHitbox(hitbox);

        if (!box)
            return {};

        float radius = box->radius;
        const auto is_capsule = radius != -1.f;

        if (is_capsule) {
            math::VectorTransform(box->bbmin, bone_matrix[box->bone], min);
            math::VectorTransform(box->bbmax, bone_matrix[box->bone], max);
        }
        else {
            math::VectorTransform(math::vector_rotate(box->bbmin, box->rotation), bone_matrix[box->bone], min);
            math::VectorTransform(math::vector_rotate(box->bbmax, box->rotation), bone_matrix[box->bone], max);
            radius = min.DistTo(max);
        }

        hitbox_data.emplace_back(hitbox_data_t{ min, max, radius, box, box->bone, box->rotation });
    }

    return hitbox_data;
}

Vector hit_chance::get_spread_direction(weapon_t* weapon, Vector angles, int seed) {
    if (!weapon)
        return Vector();

    const int   rnsd = (seed & 0xFF);
    const auto* data = &hit_chance_records[rnsd];

    if (!data)
        return Vector();

    float rand_a = data->random[0];
    float rand_b = data->random[1];

    if (weapon->m_iItemDefinitionIndex() == WEAPON_NEGEV) {
        auto weapon_info = weapon ? g_ctx.globals.weapon->get_csweapon_info() : nullptr;

        if (weapon_info && weapon_info->iRecoilSeed < 3) {
            rand_a = 1.0f - std::pow(rand_a, static_cast<float>(3 - weapon_info->iRecoilSeed + 1));
            rand_b = 1.0f - std::pow(rand_b, static_cast<float>(3 - weapon_info->iRecoilSeed + 1));
        }
    }

    //must write from predition

    const float rand_inaccuracy = rand_a * g_ctx.globals.inaccuracy;
    const float rand_spread = rand_b * g_ctx.globals.spread;

    const float spread_x = data->inaccuracy[0] * rand_inaccuracy + data->spread[0] * rand_spread;
    const float spread_y = data->inaccuracy[1] * rand_inaccuracy + data->spread[1] * rand_spread;

    Vector forward, right, up;
    math::angle_vectors(angles, &forward, &right, &up);

    return forward + right * spread_x + up * spread_y;
}

bool hit_chance::can_intersect_hitbox(const Vector start, const Vector end, Vector spread_dir, adjust_data* log, int hitbox)
{
    const auto hitbox_data = get_hitbox_data(log, hitbox);

    if (hitbox_data.empty())
        return false;

    auto intersected = false;
    Vector delta;
    Vector start_scaled;

    for (const auto& it : hitbox_data) {
        const auto is_capsule = it.m_radius != -1.f;
        if (!is_capsule) {
            math::vector_i_transform(start, log->matrixes_data.main[it.m_bone], start_scaled);
            math::vector_i_rotate(spread_dir * 8192.f, log->matrixes_data.main[it.m_bone], delta);
            if (intersects_bb_hitbox(start_scaled, delta, it.m_min, it.m_max)) {
                intersected = true;
                break; //note - AkatsukiSun: cannot hit more than one hitbox.
            }
        }
        else if (intersects_hitbox(start, end, it.m_min, it.m_max, it.m_radius)) {
            intersected = true;
            break;//note - AkatsukiSun: cannot hit more than one hitbox.
        }
        else {
            intersected = false;
            break;
        }
    }

    return intersected;
}

bool hit_chance::can_hit(adjust_data* log, weapon_t* weapon, Vector angles, int hitbox) {

    auto target = static_cast<player_t*>(m_entitylist()->GetClientEntity(log->player->EntIndex()));

    if (!target || !weapon)
        return false;

    auto weapon_info = weapon ? g_ctx.globals.weapon->get_csweapon_info() : nullptr;

    if (!weapon_info)
        return false;

    build_seed_table();

    if ((weapon->m_iItemDefinitionIndex() == WEAPON_SSG08 || weapon->m_iItemDefinitionIndex() == WEAPON_REVOLVER) && !(g_ctx.local()->m_fFlags() & FL_ONGROUND)) {
        if ((g_ctx.globals.inaccuracy < 0.009f)) {
            return true;
        }
    }

    const Vector eye_pos = g_ctx.local()->get_eye_pos();
    Vector start_scaled = { };
    const auto hitchance_cfg = g_cfg.ragebot.weapon[g_ctx.globals.current_weapon].hitchance_amount;
    const int hits_needed = (hitchance_cfg * 256) / 100;
    int hits = 0;

    for (int i = 0; i < 256; ++i) {

        Vector spread_dir = get_spread_direction(weapon, angles, i);
        Vector end_pos = eye_pos + (spread_dir * 8192.f);

        if (can_intersect_hitbox(eye_pos, end_pos, spread_dir, log, hitbox))
            hits++;

        if (hits >= hits_needed)
            return true;
    }

    return false;
}
hitchance.h:
#pragma once

class hit_chance {
public:
    struct hit_chance_data_t {
        float random[2];
        float inaccuracy[2];
        float spread[2];
    };

    struct hitbox_data_t {
        hitbox_data_t(const Vector& min, const Vector& max, float radius,  mstudiobbox_t* hitbox, int bone, const Vector& rotation) {
            m_min = min;
            m_max = max;
            m_radius = radius;
            m_hitbox = hitbox;
            m_bone = bone;
            m_rotation = rotation;
        }

        Vector m_min{ };
        Vector m_max{ };
        float m_radius{ };
        mstudiobbox_t* m_hitbox{ };
        int m_bone{ };
        Vector m_rotation{ };
    };

    void build_seed_table();
    Vector get_spread_direction(weapon_t* weapon, Vector angles, int seed);
    bool can_intersect_hitbox(const Vector start, const Vector end, Vector spread_dir, adjust_data* log, int hitbox);
    std::vector<hitbox_data_t> get_hitbox_data(adjust_data* log, int hitbox);
    bool intersects_bb_hitbox(Vector start, Vector delta, Vector min, Vector max);
    bool __vectorcall intersects_hitbox(Vector eye_pos, Vector end_pos, Vector min, Vector max, float radius);
    bool can_hit(adjust_data* log, weapon_t* weapon, Vector angles, int hitbox);
private:
    std::array<hit_chance_data_t, 256> hit_chance_records = {};
};

inline hit_chance* g_hit_chance = new hit_chance();
 
Последнее редактирование:
Забаненный
Статус
Оффлайн
Регистрация
24 Июн 2021
Сообщения
26
Реакции[?]
4
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Че за дерьммо
 
Keep Ev0lving, Stay Fatal
Эксперт
Статус
Оффлайн
Регистрация
6 Фев 2018
Сообщения
1,543
Реакции[?]
583
Поинты[?]
99K
Дерьмо? Обоснуй.
Хотя, если уж вдаваться в подробности, то в хитшансе действительно есть проблемы.
Возможно, как-нибудь поправлю свою тему и расскажу что да как.
 
t.me/maj0rblog
Дизайнер
Статус
Оффлайн
Регистрация
6 Окт 2018
Сообщения
976
Реакции[?]
619
Поинты[?]
12K
Дерьмо? Обоснуй.
Хотя, если уж вдаваться в подробности, то в хитшансе действительно есть проблемы.
Возможно, как-нибудь поправлю свою тему и расскажу что да как.
Всё потому что это делал акатсука, не знаю зачем это в лв ну ладно, молодец
 
Эксперт
Статус
Оффлайн
Регистрация
30 Дек 2019
Сообщения
1,970
Реакции[?]
958
Поинты[?]
19K
Хотя, если уж вдаваться в подробности, то в хитшансе действительно есть проблемы.
знающий человек пофиксить на пару минут эти проблемы, сам по себе хитшанс более менее правильный, но легендвару это не поможет :roflanBuldiga:
 
Keep Ev0lving, Stay Fatal
Эксперт
Статус
Оффлайн
Регистрация
6 Фев 2018
Сообщения
1,543
Реакции[?]
583
Поинты[?]
99K
знающий человек пофиксить на пару минут эти проблемы, сам по себе хитшанс более менее правильный, но легендвару это не поможет :roflanBuldiga:
Да хз, в лв просто поменять анимки, чутка полностью переписать аимбот (а то какашка...) и получится +- хацк за 100 нормальный.
В хитшансе кое-что прям ОЧЕНЬ вронг, но да ладно :roflanBuldiga:
 
like amiri in my mind
Пользователь
Статус
Оффлайн
Регистрация
4 Дек 2022
Сообщения
308
Реакции[?]
54
Поинты[?]
1K
Да хз, в лв просто поменять анимки, чутка полностью переписать аимбот (а то какашка...) и получится +- хацк за 100 нормальный.
В хитшансе кое-что прям ОЧЕНЬ вронг, но да ладно :roflanBuldiga:
+если бы там все хуки правильно были установлены и тикбейз просчитывался правильно то все было бы очень неплохо
 
Начинающий
Статус
Оффлайн
Регистрация
15 Дек 2022
Сообщения
11
Реакции[?]
0
Поинты[?]
0
Сверху Снизу