From 9aebeaed17f7c61e3cf3c3eb269831ec1f9d1eab Mon Sep 17 00:00:00 2001 From: LiamD-Flop <40887493+LiamD-Flop@users.noreply.github.com> Date: Sun, 22 May 2022 16:38:28 +0200 Subject: [PATCH] F.A.R.T. Interface (#104) Co-authored-by: Yimura --- BigBaseV2/src/backend/backend.cpp | 2 + .../src/backend/looped/hud/context_menu.cpp | 48 ++++++ BigBaseV2/src/backend/looped/looped.hpp | 1 + BigBaseV2/src/core/enums.hpp | 11 ++ BigBaseV2/src/core/globals.hpp | 13 +- BigBaseV2/src/function_types.hpp | 2 +- BigBaseV2/src/gta/replay.hpp | 29 ++-- BigBaseV2/src/main.cpp | 6 +- .../src/services/context_menu_service.cpp | 141 ++++++++++++++++++ .../src/services/context_menu_service.hpp | 117 +++++++++++++++ BigBaseV2/src/util/math.hpp | 11 +- BigBaseV2/src/views/esp/view_esp.cpp | 10 +- BigBaseV2/src/views/esp/view_esp.hpp | 1 - BigBaseV2/src/views/view.hpp | 2 + BigBaseV2/src/views/view_context_menu.cpp | 44 ++++++ vendor/GTAV-Classes | 2 +- vendor/ImGui | 2 +- 17 files changed, 413 insertions(+), 29 deletions(-) create mode 100644 BigBaseV2/src/backend/looped/hud/context_menu.cpp create mode 100644 BigBaseV2/src/services/context_menu_service.cpp create mode 100644 BigBaseV2/src/services/context_menu_service.hpp create mode 100644 BigBaseV2/src/views/view_context_menu.cpp diff --git a/BigBaseV2/src/backend/backend.cpp b/BigBaseV2/src/backend/backend.cpp index 683fee0c..7b4a7c93 100644 --- a/BigBaseV2/src/backend/backend.cpp +++ b/BigBaseV2/src/backend/backend.cpp @@ -21,6 +21,8 @@ namespace big }); } + looped::context_menu(); + QUEUE_JOB_BEGIN_CLAUSE() { looped::hud_transition_state(); diff --git a/BigBaseV2/src/backend/looped/hud/context_menu.cpp b/BigBaseV2/src/backend/looped/hud/context_menu.cpp new file mode 100644 index 00000000..2430075c --- /dev/null +++ b/BigBaseV2/src/backend/looped/hud/context_menu.cpp @@ -0,0 +1,48 @@ +#include "services/context_menu_service.hpp" +#include "backend/looped/looped.hpp" +#include "gta/enums.hpp" +#include "natives.hpp" + +namespace big +{ + void looped::context_menu() + { + if (PAD::IS_DISABLED_CONTROL_JUST_RELEASED(0, (int)ControllerInputs::INPUT_VEH_DUCK)) + { + g_context_menu_service->enabled = !g_context_menu_service->enabled; + } + + if (g_context_menu_service->enabled) + { + PAD::DISABLE_CONTROL_ACTION(0, (int)ControllerInputs::INPUT_NEXT_WEAPON, true); + PAD::DISABLE_CONTROL_ACTION(0, (int)ControllerInputs::INPUT_PREV_WEAPON, true); + PAD::DISABLE_CONTROL_ACTION(0, (int)ControllerInputs::INPUT_VEH_NEXT_RADIO, true); + PAD::DISABLE_CONTROL_ACTION(0, (int)ControllerInputs::INPUT_VEH_SELECT_NEXT_WEAPON, true); + PAD::DISABLE_CONTROL_ACTION(0, (int)ControllerInputs::INPUT_SELECT_NEXT_WEAPON, true); + PAD::DISABLE_CONTROL_ACTION(0, (int)ControllerInputs::INPUT_SELECT_PREV_WEAPON, true); + PAD::DISABLE_CONTROL_ACTION(0, (int)ControllerInputs::INPUT_WEAPON_WHEEL_NEXT, true); + PAD::DISABLE_CONTROL_ACTION(0, (int)ControllerInputs::INPUT_WEAPON_WHEEL_PREV, true); + PAD::DISABLE_CONTROL_ACTION(0, (int)ControllerInputs::INPUT_ATTACK, true); + PAD::DISABLE_CONTROL_ACTION(0, (int)ControllerInputs::INPUT_SPECIAL_ABILITY, true); + PAD::DISABLE_CONTROL_ACTION(0, (int)ControllerInputs::INPUT_VEH_MOUSE_CONTROL_OVERRIDE, true); + + g_context_menu_service->get_entity_closest_to_screen_center(); + + const auto cm = g_context_menu_service->get_context_menu(); + if (cm == nullptr) + return; + + if (PAD::IS_DISABLED_CONTROL_JUST_PRESSED(0, (int)ControllerInputs::INPUT_WEAPON_WHEEL_NEXT)) + cm->current_option = cm->options.size() <= cm->current_option + 1 ? 0 : cm->current_option + 1; + if (PAD::IS_DISABLED_CONTROL_JUST_PRESSED(0, (int)ControllerInputs::INPUT_WEAPON_WHEEL_PREV)) + cm->current_option = 0 > cm->current_option - 1 ? static_cast(cm->options.size()) - 1 : cm->current_option - 1; + if (PAD::IS_DISABLED_CONTROL_JUST_PRESSED(0, (int)ControllerInputs::INPUT_ATTACK) || + PAD::IS_DISABLED_CONTROL_JUST_PRESSED(0, (int)ControllerInputs::INPUT_SPECIAL_ABILITY)) + { + if (!g_context_menu_service->m_pointer) + return; + cm->options.at(cm->current_option).command(); + } + } + } +} diff --git a/BigBaseV2/src/backend/looped/looped.hpp b/BigBaseV2/src/backend/looped/looped.hpp index b7c60df3..760fcc5a 100644 --- a/BigBaseV2/src/backend/looped/looped.hpp +++ b/BigBaseV2/src/backend/looped/looped.hpp @@ -7,6 +7,7 @@ namespace big public: static void api_login_session(); + static void context_menu(); static void hud_transition_state(); static void rgb_synced_fade(); diff --git a/BigBaseV2/src/core/enums.hpp b/BigBaseV2/src/core/enums.hpp index cd8ef9e2..3dc42fe3 100644 --- a/BigBaseV2/src/core/enums.hpp +++ b/BigBaseV2/src/core/enums.hpp @@ -13,6 +13,17 @@ namespace big VEHICLE_GUN }; + enum class eEntityType + { + UNK_0, + UNK_1, + UNK_2, + UNK_3, + UNK_4, + VEHICLE, + PED, + }; + enum class eTransitionState { TRANSITION_STATE_EMPTY, diff --git a/BigBaseV2/src/core/globals.hpp b/BigBaseV2/src/core/globals.hpp index 74492a4d..2a8fd568 100644 --- a/BigBaseV2/src/core/globals.hpp +++ b/BigBaseV2/src/core/globals.hpp @@ -13,15 +13,11 @@ namespace big nlohmann::json default_options; nlohmann::json options; - struct debug { + struct debug + { bool script_event_logging = false; }; - struct tunables { - bool disable_phone = false; - bool no_idle_kick = false; - }; - struct notifications { struct pair @@ -184,6 +180,11 @@ namespace big uint64_t rockstar_id = 0; }; + struct tunables { + bool disable_phone = false; + bool no_idle_kick = false; + }; + struct vehicle { struct speedo_meter { SpeedoMeter type = SpeedoMeter::DISABLED; diff --git a/BigBaseV2/src/function_types.hpp b/BigBaseV2/src/function_types.hpp index 2531e28a..c3956f5c 100644 --- a/BigBaseV2/src/function_types.hpp +++ b/BigBaseV2/src/function_types.hpp @@ -17,7 +17,7 @@ namespace big::functions using increment_stat_event = bool(uint64_t net_event_struct, int64_t sender, int64_t a3); - using ptr_to_handle = Object(rage::CObject* object); + using ptr_to_handle = Entity(void* entity); using get_screen_coords_for_world_coords = bool(float* world_coords, float* out_x, float* out_y); diff --git a/BigBaseV2/src/gta/replay.hpp b/BigBaseV2/src/gta/replay.hpp index d8aa67a4..22d6b3bb 100644 --- a/BigBaseV2/src/gta/replay.hpp +++ b/BigBaseV2/src/gta/replay.hpp @@ -45,6 +45,15 @@ namespace rage class CPed* m_local_ped; //0x0008 }; //Size: 0x0010 + //CUSTOM CLASS TO IMPROVE R* SHIT CLASS STRUCTURE + class CEntityHandle { + public: + class fwEntity* m_entity_ptr; //0x0000 + int32_t m_handle; //0x0008 + char pad_000C[4]; //0x000C + }; //Size: 0x0010 + static_assert(sizeof(CEntityHandle) == 0x10, "CEntityHandle is not properly sized"); + class CObjectHandle { public: @@ -57,7 +66,7 @@ namespace rage class CObjectList { public: - class CObjectHandle m_objects[2300]; //0x0000 + class CEntityHandle m_objects[2300]; //0x0000 }; //Size: 0x8FC0 class CObjectInterface @@ -69,10 +78,10 @@ namespace rage char pad_0164[4]; //0x0164 int32_t m_cur_objects; //0x0168 - rage::CObject* get_object(const int& index) + rage::fwEntity* get_object(const int& index) { if (index < m_max_objects) - return m_object_list->m_objects[index].m_object; + return m_object_list->m_objects[index].m_entity_ptr; return nullptr; } }; //Size: 0x016C @@ -89,7 +98,8 @@ namespace rage class CPedList { public: - class CPedHandle m_peds[256]; //0x0000 + //CHANGED FROM CPedHandle + class CEntityHandle m_peds[256]; //0x0000 }; //Size: 0x1000 class CPedInterface @@ -101,10 +111,10 @@ namespace rage char pad_010C[4]; //0x010C int32_t m_cur_peds; //0x0110 - CPed* get_ped(const int& index) + fwEntity* get_ped(const int& index) { if (index < m_max_peds) - return m_ped_list->m_peds[index].m_ped; + return m_ped_list->m_peds[index].m_entity_ptr; return nullptr; } }; //Size: 0x0114 @@ -121,7 +131,8 @@ namespace rage class CVehicleList { public: - class CVehicleHandle m_vehicles[300]; //0x0000 + //CHANGED FROM CVehicleHandle + class CEntityHandle m_vehicles[300]; //0x0000 }; //Size: 0x12C0 class CVehicleInterface @@ -133,10 +144,10 @@ namespace rage char pad_018C[4]; //0x018C int32_t m_cur_vehicles; //0x0190 - CVehicle* get_vehicle(const int& index) + fwEntity* get_vehicle(const int& index) { if (index < m_max_vehicles) - return m_vehicle_list->m_vehicles[index].m_vehicle; + return m_vehicle_list->m_vehicles[index].m_entity_ptr; return nullptr; } }; //Size: 0x0194 diff --git a/BigBaseV2/src/main.cpp b/BigBaseV2/src/main.cpp index 31e3fad9..33ae5bc1 100644 --- a/BigBaseV2/src/main.cpp +++ b/BigBaseV2/src/main.cpp @@ -11,6 +11,7 @@ #include "thread_pool.hpp" #include "native_hooks/native_hooks.hpp" +#include "services/context_menu_service.hpp" #include "services/globals_service.hpp" #include "services/gui_service.hpp" #include "services/player_service.hpp" @@ -53,7 +54,7 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID) auto renderer_instance = std::make_unique(); LOG(INFO) << "Renderer initialized."; - auto fiber_pool_instance = std::make_unique(10); + auto fiber_pool_instance = std::make_unique(11); LOG(INFO) << "Fiber pool initialized."; auto hooking_instance = std::make_unique(); @@ -65,6 +66,7 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID) auto thread_pool_instance = std::make_unique(); LOG(INFO) << "Thread pool initialized."; + auto context_menu_service_instance = std::make_unique(); auto globals_service_instace = std::make_unique(); auto mobile_service_instance = std::make_unique(); auto notification_service_instance = std::make_unique(); @@ -110,6 +112,8 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID) LOG(INFO) << "Player Service reset."; globals_service_instace.reset(); LOG(INFO) << "Globals Service reset."; + context_menu_service_instance.reset(); + LOG(INFO) << "Context Service reset."; LOG(INFO) << "Services uninitialized."; // Make sure that all threads created don't have any blocking loops diff --git a/BigBaseV2/src/services/context_menu_service.cpp b/BigBaseV2/src/services/context_menu_service.cpp new file mode 100644 index 00000000..7589a983 --- /dev/null +++ b/BigBaseV2/src/services/context_menu_service.cpp @@ -0,0 +1,141 @@ +#include "context_menu_service.hpp" +#include "natives.hpp" +#include "pointers.hpp" +#include "gta/replay.hpp" + +namespace big +{ + context_menu_service::context_menu_service() + { + g_context_menu_service = this; + load_shared(); + } + + context_menu_service::~context_menu_service() + { + g_context_menu_service = nullptr; + } + + double context_menu_service::distance_to_middle_of_screen(const rage::vector2& screen_pos) + { + double cumulative_distance{}; + + if (screen_pos.x > 0.5) + cumulative_distance += screen_pos.x - 0.5; + else + cumulative_distance += 0.5 - screen_pos.x; + + if (screen_pos.y > 0.5) + cumulative_distance += screen_pos.y - 0.5; + else + cumulative_distance += 0.5 - screen_pos.y; + + return cumulative_distance; + } + + s_context_menu* context_menu_service::get_context_menu() + { + if (m_pointer && m_pointer->m_model_info) + { + switch (m_pointer->m_model_info->m_model_type) + { + case eModelType::Object: // Object + { + return &options.at(ContextEntityType::OBJECT); + } + case eModelType::Ped: + { + if (const auto ped = reinterpret_cast(m_pointer); ped) + { + if (ped->m_ped_task_flag & static_cast(ePedTask::TASK_DRIVING) && + ped->m_vehicle) + { + m_pointer = ped->m_vehicle; + return &options.at(ContextEntityType::VEHICLE); + } + if (ped->m_player_info) + return &options.at(ContextEntityType::PLAYER); + } + return &options.at(ContextEntityType::PED); + } + case eModelType::Vehicle: + { + return &options.at(ContextEntityType::VEHICLE); + } + default: + break; + } + } + return nullptr; + } + + void context_menu_service::get_entity_closest_to_screen_center() + { + if (const auto replay = *g_pointers->m_replay_interface; replay) + { + const auto veh_interface = replay->m_vehicle_interface; + const auto ped_interface = replay->m_ped_interface; + const auto obj_interface = replay->m_object_interface; + + if (veh_interface && ped_interface && obj_interface) + { + const auto veh_interface_size = veh_interface->m_max_vehicles; + const auto ped_interface_size = ped_interface->m_max_peds; + const auto obj_interface_size = obj_interface->m_max_objects; + const auto all_entities = std::make_unique(veh_interface_size + ped_interface_size + obj_interface_size); + + const auto ptr = all_entities.get(); + std::uint32_t offset = 0; + std::copy(ped_interface->m_ped_list->m_peds, ped_interface->m_ped_list->m_peds + ped_interface_size,ptr); + offset += ped_interface_size; + + std::copy(veh_interface->m_vehicle_list->m_vehicles, veh_interface->m_vehicle_list->m_vehicles + veh_interface_size, ptr + offset); + offset += veh_interface_size; + + std::copy(obj_interface->m_object_list->m_objects, obj_interface->m_object_list->m_objects + obj_interface_size, ptr + offset); + offset += obj_interface_size; + + double distance = 1; + rage::vector2 screen_pos{}; + for (std::uint32_t i = 0; i < offset; i++) + { + if (!all_entities[i].m_entity_ptr) + continue; + + const auto temp_pointer = all_entities[i].m_entity_ptr; + const auto temp_handle = g_pointers->m_ptr_to_handle(temp_pointer); + if (!temp_pointer->m_navigation) + continue; + + const auto pos = temp_pointer->m_navigation->m_position; + HUD::GET_HUD_SCREEN_POSITION_FROM_WORLD_POSITION(pos.x, pos.y, pos.z, &screen_pos.x, &screen_pos.y); + if (distance_to_middle_of_screen(screen_pos) < distance && + ENTITY::HAS_ENTITY_CLEAR_LOS_TO_ENTITY(PLAYER::PLAYER_PED_ID(), temp_handle, 17) && + temp_handle != PLAYER::PLAYER_PED_ID()) { + m_handle = temp_handle; + m_pointer = temp_pointer; + distance = distance_to_middle_of_screen(screen_pos); + } + } + } + } + } + + void context_menu_service::load_shared() + { + for (auto& [type, menu] : options) + { + if (type == ContextEntityType::SHARED) + continue; + menu.options.insert(menu.options.end(), options.at(ContextEntityType::SHARED).options.begin(), options.at(ContextEntityType::SHARED).options.end()); + + std::uint32_t max_size = 0; + for (auto& [name, _] : menu.options) + { + max_size = static_cast(max_size < name.length() ? name.length() : max_size); + } + + menu.menu_size = { (10.f * static_cast(max_size)) + 10.f , 2 * (10.f * static_cast(menu.options.size())) + 10.f }; + } + } +} diff --git a/BigBaseV2/src/services/context_menu_service.hpp b/BigBaseV2/src/services/context_menu_service.hpp new file mode 100644 index 00000000..a207c15d --- /dev/null +++ b/BigBaseV2/src/services/context_menu_service.hpp @@ -0,0 +1,117 @@ +#pragma once +#include "natives.hpp" +#include "util/entity.hpp" +#include "util/ped.hpp" +#include "util/teleport.hpp" + +namespace big +{ + enum class ContextEntityType + { + PED, + PLAYER, + VEHICLE, + OBJECT, + SHARED + }; + + struct context_option + { + std::string name; + std::function command; + }; + + struct s_context_menu + { + ContextEntityType type; + int current_option = 0; + ImVec2 menu_size = {}; + std::vector options; + }; + + class context_menu_service final + { + private: + static double distance_to_middle_of_screen(const rage::vector2& screen_pos); + + public: + context_menu_service(); + ~context_menu_service(); + + context_menu_service(const context_menu_service&) = delete; + context_menu_service(context_menu_service&&) noexcept = delete; + context_menu_service& operator=(const context_menu_service&) = delete; + context_menu_service& operator=(context_menu_service&&) noexcept = delete; + + bool enabled = false; + s_context_menu* get_context_menu(); + void get_entity_closest_to_screen_center(); + void load_shared(); + + Entity m_handle; + rage::fwEntity* m_pointer; + + s_context_menu vehicle_menu{ + ContextEntityType::VEHICLE, + 0,{}, { + {"KILL ENGINE", [this] { + if (entity::take_control_of(m_handle)) + { + VEHICLE::SET_VEHICLE_ENGINE_HEALTH(m_handle, 0.f); + VEHICLE::SET_VEHICLE_ENGINE_ON(m_handle, false, true, false); + } + }}, + {"DELETE", [this] { + if (entity::take_control_of(m_handle)) + { + entity::delete_entity(m_handle); + } + }}, + { "TP INTO", [this] { + teleport::into_vehicle(m_handle); + }} + } }; + + s_context_menu ped_menu{ + ContextEntityType::PED, + 0,{}, {}}; + + s_context_menu object_menu{ + ContextEntityType::OBJECT, + 0,{}, {}}; + + s_context_menu player_menu{ + ContextEntityType::PLAYER, + 0,{}, { + {"STEAL IDENTITY", [this] + { + ped::steal_identity(m_handle); + }} + } }; + + s_context_menu shared_menu{ + ContextEntityType::SHARED, + 0, + {}, { + {"EXPLODE", [this] { + rage::fvector3 pos = m_pointer->m_navigation->m_position; + FIRE::ADD_EXPLOSION(pos.x, pos.y, pos.z, 1, 1000, 1, 0, 1, 0); + }}, + {"TP TO", [this] { + rage::fvector3 pos = m_pointer->m_navigation->m_position; + teleport::to_coords({ pos.x, pos.y, pos.z }); + }}, + } + }; + + std::unordered_map options = { + {ContextEntityType::VEHICLE, vehicle_menu}, + {ContextEntityType::PLAYER, player_menu}, + {ContextEntityType::PED, ped_menu}, + {ContextEntityType::SHARED, shared_menu}, + {ContextEntityType::OBJECT, object_menu} + }; + }; + + inline context_menu_service* g_context_menu_service{}; +} diff --git a/BigBaseV2/src/util/math.hpp b/BigBaseV2/src/util/math.hpp index 8f5a3792..0154e134 100644 --- a/BigBaseV2/src/util/math.hpp +++ b/BigBaseV2/src/util/math.hpp @@ -1,4 +1,5 @@ #pragma once +#include "pointers.hpp" namespace big::math { @@ -27,4 +28,12 @@ namespace big::math sin(x) }; } -} \ No newline at end of file + + inline float calculate_distance_from_game_cam (rage::fvector3 player_position) + { + const Vector3 plyr_coords = { player_position.x, player_position.y, player_position.z }; + const Vector3 cam_coords = g_pointers->m_get_gamplay_cam_coords(); + + return (float)distance_between_vectors(plyr_coords, cam_coords); + } +} diff --git a/BigBaseV2/src/views/esp/view_esp.cpp b/BigBaseV2/src/views/esp/view_esp.cpp index 58195344..66cdc3e8 100644 --- a/BigBaseV2/src/views/esp/view_esp.cpp +++ b/BigBaseV2/src/views/esp/view_esp.cpp @@ -4,16 +4,10 @@ #include "util/math.hpp" #include "gta_util.hpp" #include "util/misc.hpp" +#include "services/context_menu_service.hpp" namespace big { - float esp::calculate_distance(rage::fvector3 player_position) - { - const Vector3 plyr_coords = { player_position.x, player_position.y, player_position.z }; - const Vector3 cam_coords = g_pointers->m_get_gamplay_cam_coords(); - - return (float)math::distance_between_vectors(plyr_coords, cam_coords); - } void esp::draw() { if (!g->esp.enabled) return; @@ -43,7 +37,7 @@ namespace big float screen_x, screen_y; - const float distance = calculate_distance(player_pos); + const float distance = math::calculate_distance_from_game_cam(player_pos); const float multplr = distance > g->esp.global_render_distance[1] ? -1.f : 6.17757f / distance; if (multplr == -1.f || g->esp.global_render_distance[0] > distance) continue; diff --git a/BigBaseV2/src/views/esp/view_esp.hpp b/BigBaseV2/src/views/esp/view_esp.hpp index eacbfb64..a94875a8 100644 --- a/BigBaseV2/src/views/esp/view_esp.hpp +++ b/BigBaseV2/src/views/esp/view_esp.hpp @@ -6,7 +6,6 @@ namespace big class esp { - static float calculate_distance(rage::fvector3); public: static void draw(); }; diff --git a/BigBaseV2/src/views/view.hpp b/BigBaseV2/src/views/view.hpp index 618cfae7..eba92363 100644 --- a/BigBaseV2/src/views/view.hpp +++ b/BigBaseV2/src/views/view.hpp @@ -43,10 +43,12 @@ namespace big static void view_player(); static void players(); static void weapons(); + static void context_menu(); static void always() { esp::draw(); + context_menu(); notifications(); } }; diff --git a/BigBaseV2/src/views/view_context_menu.cpp b/BigBaseV2/src/views/view_context_menu.cpp new file mode 100644 index 00000000..bb70ca8e --- /dev/null +++ b/BigBaseV2/src/views/view_context_menu.cpp @@ -0,0 +1,44 @@ +#include "view.hpp" +#include "services/context_menu_service.hpp" + +namespace big +{ + void view::context_menu() + { + if (const auto draw_list = ImGui::GetBackgroundDrawList(); draw_list) + { + if (g_context_menu_service->enabled && + g_context_menu_service->m_pointer && + g_context_menu_service->m_pointer->m_navigation) + { + float context_screen_x; + float context_screen_y; + + auto& context_target_pos = g_context_menu_service->m_pointer->m_navigation->m_position; + + const auto context_target_distance = math::calculate_distance_from_game_cam(context_target_pos); + const auto context_target_multplr = context_target_distance > g->esp.global_render_distance[1] ? -1.f : 6.17757f / context_target_distance; + + if (g_pointers->m_get_screen_coords_for_world_coords(context_target_pos.data, &context_screen_x, &context_screen_y)) + { + const auto cm = g_context_menu_service->get_context_menu(); + if (cm == nullptr) + return; + + const auto cm_start_x = static_cast(*g_pointers->m_resolution_x) * context_screen_x + (67.5f * context_target_multplr); + const auto cm_start_y = static_cast(*g_pointers->m_resolution_y) * context_screen_y - (175.f * context_target_multplr); + + const auto cm_col = ImGui::ColorConvertFloat4ToU32({ 0.549f, 0.639f, 0.710f, 0.3f }); + + draw_list->AddRectFilled({ cm_start_x - 2.f , cm_start_y }, { cm_start_x + 2.f + cm->menu_size.x, cm_start_y + cm->menu_size.y }, cm_col, 5.f); + + for (std::uint32_t i = 0; i < cm->options.size(); i++) + { + const auto co = cm->options.at(i); + draw_list->AddText({ cm_start_x + 7.f, cm_start_y + (20.f * static_cast(i)) + 5.f }, cm->current_option == i ? ImGui::ColorConvertFloat4ToU32({ 0.f, 1.f, 0.f, 1.f }) : ImGui::ColorConvertFloat4ToU32({ 1.f, 1.f, 1.f, 1.f }), co.name.c_str()); + } + } + } + } + } +} \ No newline at end of file diff --git a/vendor/GTAV-Classes b/vendor/GTAV-Classes index f27b0ed1..49916757 160000 --- a/vendor/GTAV-Classes +++ b/vendor/GTAV-Classes @@ -1 +1 @@ -Subproject commit f27b0ed16ade185464e6c0be45f92869fdb43d81 +Subproject commit 49916757dffe36b22422c1e7d6ec1487e8619bda diff --git a/vendor/ImGui b/vendor/ImGui index ced3b84d..afffcd58 160000 --- a/vendor/ImGui +++ b/vendor/ImGui @@ -1 +1 @@ -Subproject commit ced3b84d96256d66711a7a347968a023ebf04a3e +Subproject commit afffcd5810d030e24056c1a61f27a6eb632f50ed