fix(ContextMenu): entity detection (#1392)

This commit is contained in:
DayibBaba 2023-06-07 23:56:43 +02:00 committed by GitHub
parent 34481918d1
commit 9b5bd2ee4d
2 changed files with 54 additions and 79 deletions

View File

@ -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<CPed*>(m_pointer)->m_vehicle)
{
m_pointer = reinterpret_cast<CPed*>(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()

View File

@ -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<Entity> 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;
}
}
}