Проблема с отображением Arrow Indicator Player в чите для Majestic RPg

BananovDev

Новичок
Автор темы
5
1
Здравствуйте!


В чите для Majestic RP функция draw_arrow_indicators работает некорректно: стрелки, указывающие на игроков, отображаются неправильно относительно их реального положения. Например, если игрок находится справа сверху экрана, стрелка может появиться слева снизу. В целом логика такая: игрок сзади — стрелка сверху, слева — стрелка справа и т.д., но позиционирование часто неверное, не всегда вниз. Так же стрелки не магнитятся на положение игроков при поворотах камерой , но реагируют на движение игроков + определение дистанции ( до игрока ) верное.

заранее извиняюсь за говнокод

Прилагаю скриншот для наглядности (см. вложение).
1757366298432.png



Вот код, связанный с этой функцией (из hacks.hpp и game.hpp):

Relevant includes and defines from hacks.hpp:
#include <cmath>
#include <algorithm>
#include "../includes/imgui/imgui.h"
#define M_PI 3.14159265358979323846
#define PI 3.14159265358979323846
#define M_PI_2 1.57079632679489661923

ImVec2 rotate_point(ImVec2 point, float cos_a, float sin_a) {
    return ImVec2(point.x * cos_a - point.y * sin_a, point.x * sin_a + point.y * cos_a);
}

void draw_arrow_indicators(Vector3 pedPos, CObject* ped) {
    Vector3 localpos = local.player->fPosition;
    float health = ped->HP;
    ImVec2 screen_size = ImGui::GetIO().DisplaySize;
    float screen_center_x = screen_size.x / 2.0f;
    float screen_center_y = screen_size.y / 2.0f;
    float radius = std::min(screen_size.x, screen_size.y) / 2.0f - 50.0f;
    float dx = pedPos.x - localpos.x;
    float dy = pedPos.y - localpos.y;
    float world_angle = atan2(dy, dx);
    float cam_rot_z_deg = native::cam::get_gameplay_cam_rot(2).z;
    float cam_rot_z = cam_rot_z_deg * M_PI / 180.0f;
    float rel_angle = world_angle - cam_rot_z + M_PI_2;
    while (rel_angle < -M_PI) rel_angle += 2 * M_PI;
    while (rel_angle > M_PI) rel_angle -= 2 * M_PI;
    float arrow_x = screen_center_x + cos(rel_angle) * radius;
    float arrow_y = screen_center_y + sin(rel_angle) * radius;
    ImColor arrow_color = ImColor(128, 0, 128, 140);
    float distance = sqrt(pow(pedPos.x - localpos.x, 2) + pow(pedPos.y - localpos.y, 2) + pow(pedPos.z - localpos.z, 2));
    if (health > 0) {
        float rot = rel_angle;
        float cos_r = cos(rot);
        float sin_r = sin(rot);
        ImVec2 center(arrow_x, arrow_y);
        ImVec2 base_p1(-15, -15);
        ImVec2 base_p2(-15, 15);
        ImVec2 base_p3(15, 0);
        ImVec2 p1 = rotate_point(base_p1, cos_r, sin_r) + center;
        ImVec2 p2 = rotate_point(base_p2, cos_r, sin_r) + center;
        ImVec2 p3 = rotate_point(base_p3, cos_r, sin_r) + center;
        ImGui::GetBackgroundDrawList()->AddTriangleFilled(p1, p2, p3, arrow_color);
        char dist_text[32];
        sprintf(dist_text, "%.0f m", distance);
        ImVec2 text_size = ImGui::CalcTextSize(dist_text);
        float inward_angle_rad = rot + M_PI;
        float text_offset = 20;
        float text_x = arrow_x + cos(inward_angle_rad) * text_offset - text_size.x / 2;
        float text_y = arrow_y + sin(inward_angle_rad) * text_offset - text_size.y / 2;
        ImGui::GetBackgroundDrawList()->AddText(ImVec2(text_x, text_y), ImColor(255, 255, 255, 200), dist_text);
    }
}

if (config::get("visual", "arrows", false)) {
    for (auto& entity : ped_list) {
        CObject* ped = entity.first;
        DataPed data = entity.second;
        if (IsValidPtr(ped) && game::isValidPlayer(ped->ModelInfo()->GetHash(), ped)) {
            Vector3 pedPos = ped->fPosition;
            float distance = get_distance(local.player->fPosition, pedPos);
            if (distance < 200.f && ped->HP > 0) {
                ImVec2 screen;
                if (WorldToScreen(pedPos, &screen) && isW2SValid(screen)) continue;
                hacks::draw_arrow_indicators(pedPos, ped);
            }
        }
    }
}