From 59f948c6fc92755d3f2a7e3ea00bd41ef9f4cd3c Mon Sep 17 00:00:00 2001 From: DayibBaba <79384354+DayibBaba@users.noreply.github.com> Date: Wed, 7 Jun 2023 23:56:43 +0200 Subject: [PATCH] fix(ContextMenu): entity detection (#1392) --- .../context_menu/context_menu_service.cpp | 52 +----------- src/util/entity.hpp | 81 ++++++++++++------- 2 files changed, 54 insertions(+), 79 deletions(-) diff --git a/src/services/context_menu/context_menu_service.cpp b/src/services/context_menu/context_menu_service.cpp index 07bbb9cf..6afad45e 100644 --- a/src/services/context_menu/context_menu_service.cpp +++ b/src/services/context_menu/context_menu_service.cpp @@ -192,55 +192,9 @@ namespace big void context_menu_service::get_entity_closest_to_screen_center() { - m_pointer = nullptr; - if (*g_pointers->m_gta.m_ped_pool && *g_pointers->m_gta.m_prop_pool && *g_pointers->m_gta.m_vehicle_pool - && **g_pointers->m_gta.m_vehicle_pool) - { - double distance = 1; - - const auto get_closest_to_center = [this, &distance](auto entity_getter_func) -> auto - { - rage::fvector2 screen_pos{}; - bool got_an_entity = false; - for (const auto entity : entity_getter_func()) - { - const auto temp_pointer = entity; - if (!temp_pointer || !temp_pointer->m_navigation) - continue; - const auto temp_handle = g_pointers->m_gta.m_ptr_to_handle(temp_pointer); - - const auto pos = temp_pointer->m_navigation->get_position(); - HUD::GET_HUD_SCREEN_POSITION_FROM_WORLD_POSITION(pos->x, pos->y, pos->z, &screen_pos.x, &screen_pos.y); - - const auto distance_from_middle = distance_to_middle_of_screen(screen_pos); - if (distance_from_middle < distance && ENTITY::HAS_ENTITY_CLEAR_LOS_TO_ENTITY(self::ped, temp_handle, 17) && temp_handle != self::ped) - { - m_handle = temp_handle; - m_pointer = temp_pointer; - distance = distance_from_middle; - got_an_entity = true; - } - } - return got_an_entity; - }; - - // I'm using bitwise OR instead or || to avoid compiler optimisation, all functions HAVE to execute - auto got_an_entity = get_closest_to_center(pools::get_all_vehicles); - got_an_entity |= get_closest_to_center(pools::get_all_peds); - got_an_entity |= get_closest_to_center(pools::get_all_props); - - if (got_an_entity) - { - // if the ped is driving a vehicle take their vehicle instead of the ped (aka. prevent jank) - if ((m_pointer->m_model_info->m_model_type == eModelType::Ped || m_pointer->m_model_info->m_model_type == eModelType::OnlineOnlyPed) - && reinterpret_cast(m_pointer)->m_vehicle) - { - m_pointer = reinterpret_cast(m_pointer)->m_vehicle; - m_handle = g_pointers->m_gta.m_ptr_to_handle(m_pointer); - } - fill_model_bounding_box_screen_space(); - } - } + m_handle = entity::get_entity_closest_to_middle_of_screen(&m_pointer); + if (ENTITY::DOES_ENTITY_EXIST(m_handle) && m_pointer) + fill_model_bounding_box_screen_space(); } void context_menu_service::load_shared() diff --git a/src/util/entity.hpp b/src/util/entity.hpp index 913882b3..38eb3079 100644 --- a/src/util/entity.hpp +++ b/src/util/entity.hpp @@ -6,6 +6,7 @@ #include "natives.hpp" #include "pools.hpp" #include "script.hpp" +#include "services/players/player_service.hpp" namespace big::entity { @@ -175,47 +176,67 @@ namespace big::entity return cumulative_distance; } - inline Entity get_entity_closest_to_middle_of_screen() + inline Entity get_entity_closest_to_middle_of_screen(rage::fwEntity** pointer = nullptr, std::vector ignore_entities = {}, bool include_veh = true, bool include_ped = true, bool include_prop = true, bool include_players = true) { Entity closest_entity{}; - float distance = 1; + rage::fwEntity* closest_entity_ptr = nullptr; + float distance = 1; - auto replayInterface = *g_pointers->m_gta.m_replay_interface; + auto ignored_entity = [=](Entity handle) -> bool { + if (handle == self::ped) + return true; - for (const auto veh : pools::get_all_vehicles()) - { - if (veh) + for (auto ent : ignore_entities) { - Vehicle handle = g_pointers->m_gta.m_ptr_to_handle(veh); - Vector3 pos = ENTITY::GET_ENTITY_COORDS(handle, 1); - rage::fvector2 screenpos; - HUD::GET_HUD_SCREEN_POSITION_FROM_WORLD_POSITION(pos.x, pos.y, pos.z, &screenpos.x, &screenpos.y); + if (handle == ent) + return true; + } - if (distance_to_middle_of_screen(screenpos) < distance && ENTITY::HAS_ENTITY_CLEAR_LOS_TO_ENTITY(PLAYER::PLAYER_PED_ID(), handle, 17)) + return false; + }; + + auto update_closest_entity = [&](Entity handle, rage::fwEntity* entity_ptr) { + Vector3 pos = ENTITY::GET_ENTITY_COORDS(handle, 1); + rage::fvector2 screenpos; + HUD::GET_HUD_SCREEN_POSITION_FROM_WORLD_POSITION(pos.x, pos.y, pos.z, &screenpos.x, &screenpos.y); + + if (distance_to_middle_of_screen(screenpos) < distance && ENTITY::HAS_ENTITY_CLEAR_LOS_TO_ENTITY(self::ped, handle, 17) && !ignored_entity(handle)) + { + closest_entity = handle; + closest_entity_ptr = entity_ptr; + distance = distance_to_middle_of_screen(screenpos); + } + }; + + auto include_pool = [&](auto& pool) { + for (const auto ptr : pool()) + if (ptr) + update_closest_entity(g_pointers->m_gta.m_ptr_to_handle(ptr), ptr); + }; + + if (include_veh) + include_pool(pools::get_all_vehicles); + + if (include_ped) + include_pool(pools::get_all_peds); + + if (include_prop) + include_pool(pools::get_all_props); + + if (include_players) + { + for (auto player : g_player_service->players() | std::ranges::views::values) + { + if (player->get_ped()) { - closest_entity = handle; - distance = distance_to_middle_of_screen(screenpos); + Ped handle = g_pointers->m_gta.m_ptr_to_handle(player->get_ped()); + update_closest_entity(handle, player->get_ped()); } } } - for (auto ped : pools::get_all_peds()) - { - if (ped) - { - Vehicle handle = g_pointers->m_gta.m_ptr_to_handle(ped); - Vector3 pos = ENTITY::GET_ENTITY_COORDS(handle, 1); - rage::fvector2 screenpos; - HUD::GET_HUD_SCREEN_POSITION_FROM_WORLD_POSITION(pos.x, pos.y, pos.z, &screenpos.x, &screenpos.y); - - if (distance_to_middle_of_screen(screenpos) < distance && ENTITY::HAS_ENTITY_CLEAR_LOS_TO_ENTITY(PLAYER::PLAYER_PED_ID(), handle, 17) && handle != PLAYER::PLAYER_PED_ID()) - { - closest_entity = handle; - distance = distance_to_middle_of_screen(screenpos); - } - } - } + *pointer = closest_entity_ptr; return closest_entity; } -} \ No newline at end of file +}