General fixes (#1251)

This commit is contained in:
maybegreat48
2023-04-16 18:28:49 +00:00
committed by GitHub
parent 958463d5ff
commit 3c2245f780
46 changed files with 797 additions and 680 deletions

View File

@ -193,62 +193,52 @@ namespace big
void context_menu_service::get_entity_closest_to_screen_center()
{
m_pointer = nullptr;
if (const auto replay = *g_pointers->m_gta.m_replay_interface; replay)
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)
{
const auto veh_interface = replay->m_vehicle_interface;
const auto ped_interface = replay->m_ped_interface;
const auto obj_interface = replay->m_object_interface;
double distance = 1;
if (veh_interface && ped_interface && obj_interface)
const auto get_closest_to_center = [this, &distance](auto entity_getter_func) -> auto
{
double distance = 1;
const auto get_closest_to_center = [this, &distance](auto entity_list) -> auto
rage::fvector2 screen_pos{};
bool got_an_entity = false;
for (const auto entity : entity_getter_func())
{
rage::fvector2 screen_pos{};
bool got_an_entity = false;
for (const auto entity : *entity_list)
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)
{
const auto temp_pointer = entity.m_entity_ptr;
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;
}
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(veh_interface->m_vehicle_list);
got_an_entity |= get_closest_to_center(ped_interface->m_ped_list);
got_an_entity |= get_closest_to_center(obj_interface->m_object_list);
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();
}
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();
}
}
}

View File

@ -65,13 +65,12 @@ namespace big
return m_cache_header.m_data_size;
}
bool cache_file::up_to_date(std::uint32_t game_version, float online_version) const
bool cache_file::up_to_date(std::uint32_t file_version) const
{
if (!m_data)
return false;
return m_cache_version == m_cache_header.m_cache_version && game_version == m_cache_header.m_game_version
&& online_version == m_cache_header.m_online_version;
return m_cache_version == m_cache_header.m_cache_version && file_version == m_cache_header.m_file_version;
}
void cache_file::set_data(cache_data&& data, std::uint64_t data_size)
@ -80,11 +79,10 @@ namespace big
m_cache_header.m_data_size = data_size;
}
void cache_file::set_header_version(std::uint32_t game_version, float online_version)
void cache_file::set_header_version(std::uint32_t file_version)
{
m_cache_header.m_cache_version = m_cache_version;
m_cache_header.m_game_version = game_version;
m_cache_header.m_online_version = online_version;
m_cache_header.m_cache_version = m_cache_version;
m_cache_header.m_file_version = file_version;
}
void cache_file::set_cache_version(std::uint32_t cache_version)

View File

@ -7,8 +7,7 @@ namespace big
{
public:
std::uint32_t m_cache_version;
std::uint32_t m_game_version;
float m_online_version;
std::uint32_t m_file_version;
std::uint64_t m_data_size;
};
@ -55,7 +54,7 @@ namespace big
/// <param name="game_version">Current Game version</param>
/// <param name="online_version">Current Online version</param>
/// <returns>True if cache is up to date, false otherwise.</returns>
bool up_to_date(std::uint32_t game_version, float online_version) const;
bool up_to_date(std::uint32_t file_version) const;
void set_data(cache_data&& data, std::uint64_t data_size);
@ -64,7 +63,7 @@ namespace big
/// </summary>
/// <param name="game_version">Game Build</param>
/// <param name="online_version">Online Version</param>
void set_header_version(std::uint32_t game_version, float online_version);
void set_header_version(std::uint32_t file_version);
void set_cache_version(std::uint32_t cache_version);

View File

@ -15,6 +15,11 @@
namespace big
{
inline bool is_crash_ped(rage::joaat_t hash)
{
return hash == RAGE_JOAAT("slod_human") || hash == RAGE_JOAAT("slod_small_quadped") || hash == RAGE_JOAAT("slod_large_quadped");
}
bool add_if_not_exists(string_vec& vec, std::string str)
{
if (std::find(vec.begin(), vec.end(), str) != vec.end())
@ -25,9 +30,9 @@ namespace big
}
gta_data_service::gta_data_service() :
m_peds_cache(g_file_manager->get_project_file("./cache/peds.bin"), 2),
m_vehicles_cache(g_file_manager->get_project_file("./cache/vehicles.bin"), 1),
m_weapons_cache(g_file_manager->get_project_file("./cache/weapons.bin"), 2),
m_peds_cache(g_file_manager->get_project_file("./cache/peds.bin"), 3),
m_vehicles_cache(g_file_manager->get_project_file("./cache/vehicles.bin"), 2),
m_weapons_cache(g_file_manager->get_project_file("./cache/weapons.bin"), 3),
m_update_state(eGtaDataUpdateState::IDLE)
{
if (!is_cache_up_to_date())
@ -142,11 +147,9 @@ namespace big
m_vehicles_cache.load();
m_weapons_cache.load();
const auto game_version = g_pointers->m_game_version_uint32_t;
const auto online_version = g_pointers->m_online_version_float;
const auto file_version = memory::module("GTA5.exe").size();
return m_peds_cache.up_to_date(game_version, online_version) && m_vehicles_cache.up_to_date(game_version, online_version)
&& m_weapons_cache.up_to_date(game_version, online_version);
return m_peds_cache.up_to_date(file_version) && m_vehicles_cache.up_to_date(file_version) && m_weapons_cache.up_to_date(file_version);
}
void gta_data_service::load_data()
@ -223,6 +226,9 @@ namespace big
const auto name = item.child("Name").text().as_string();
const auto hash = rage::joaat(name);
if (is_crash_ped(hash))
continue;
if (std::find(mapped_peds.begin(), mapped_peds.end(), hash) != mapped_peds.end())
continue;
@ -411,6 +417,9 @@ namespace big
const auto name = file.stem().string();
const auto hash = rage::joaat(name);
if (is_crash_ped(hash))
continue;
if (std::find(mapped_peds.begin(), mapped_peds.end(), hash) != mapped_peds.end())
continue;
@ -484,15 +493,14 @@ namespace big
LOG(VERBOSE) << "Starting cache saving procedure...";
g_thread_pool->push([this, peds = std::move(peds), vehicles = std::move(vehicles), weapons = std::move(weapons)] {
const auto game_version = g_pointers->m_game_version_uint32_t;
const auto online_version = g_pointers->m_online_version_float;
const auto file_version = memory::module("GTA5.exe").size();
{
const auto data_size = sizeof(ped_item) * peds.size();
m_peds_cache.set_data(std::make_unique<std::uint8_t[]>(data_size), data_size);
std::memcpy(m_peds_cache.data(), peds.data(), data_size);
m_peds_cache.set_header_version(game_version, online_version);
m_peds_cache.set_header_version(file_version);
m_peds_cache.write();
}
@ -501,7 +509,7 @@ namespace big
m_vehicles_cache.set_data(std::make_unique<std::uint8_t[]>(data_size), data_size);
std::memcpy(m_vehicles_cache.data(), vehicles.data(), data_size);
m_vehicles_cache.set_header_version(game_version, online_version);
m_vehicles_cache.set_header_version(file_version);
m_vehicles_cache.write();
}
@ -510,7 +518,7 @@ namespace big
m_weapons_cache.set_data(std::make_unique<std::uint8_t[]>(data_size), data_size);
std::memcpy(m_weapons_cache.data(), weapons.data(), data_size);
m_weapons_cache.set_header_version(game_version, online_version);
m_weapons_cache.set_header_version(file_version);
m_weapons_cache.write();
}

View File

@ -6,35 +6,9 @@
namespace big
{
yim_fipackfile::yim_fipackfile(rage::fiPackfile* rpf, const std::string& mount_name)
yim_fipackfile::yim_fipackfile(rage::fiPackfile* rpf)
{
this->rpf = rpf;
this->mount_name = mount_name;
}
std::vector<std::string> yim_fipackfile::get_non_dlc_mounted_devices_names()
{
std::vector<std::string> non_dlc_mounted_devices_names;
uint16_t mounted_devices_len = *g_pointers->m_gta.m_fidevices_len;
if (mounted_devices_len)
{
auto devices_arr = *(uint64_t*)g_pointers->m_gta.m_fidevices;
uint8_t** current_device_mount_name_ptr = *(unsigned __int8***)g_pointers->m_gta.m_fidevices;
auto device_i = 0;
while (true)
{
non_dlc_mounted_devices_names.push_back(*(const char**)current_device_mount_name_ptr);
++device_i;
current_device_mount_name_ptr += 4;
if (device_i >= mounted_devices_len)
break;
}
}
return non_dlc_mounted_devices_names;
this->rpf = rpf;
}
void yim_fipackfile::add_wrapper_call_back(std::function<size_t(yim_fipackfile& rpf_wrapper)> cb)
@ -44,14 +18,6 @@ namespace big
void yim_fipackfile::for_each_fipackfile()
{
// the idea is to reuse existing mount points as much as possible because
// even when mounting / unmounting properly you'll get file errors
// and crashes if the rpf file was already mounted
// iterate the fidevice array which contains devices that are currently mounted
// the dlc devices are in another array
const auto non_dlc_mounted_devices_names = get_non_dlc_mounted_devices_names();
// for not hanging the game too much
constexpr auto yield_increment = 80;
@ -66,57 +32,11 @@ namespace big
break;
}
yim_fipackfile rpf_wrapper = yim_fipackfile(rpf, default_mount_name);
yim_fipackfile rpf_wrapper = yim_fipackfile(rpf);
auto already_mounted = false;
for (const auto& non_dlc_mounted_device_name : non_dlc_mounted_devices_names)
{
auto* non_dlc_mounted_device = rage::fiDevice::GetDevice(non_dlc_mounted_device_name.c_str(), true);
if (rpf == non_dlc_mounted_device)
{
rpf_wrapper.mount_name = non_dlc_mounted_device_name;
already_mounted = true;
}
}
if (!already_mounted)
{
size_t acc = 0;
static std::vector<std::string> mount_names = {"memory:/", "memory:", "dlc", "dlc:", "dlc:/", "dlcpacks:/", "common:/", "commoncrc:/", "update:/", "update2:/", "platform:/", "platformcrc:/", "gamecache:/"};
for (auto& mount_name : mount_names)
{
rpf_wrapper.mount_name = mount_name;
if (auto count = rpf_wrapper.get_file_paths().size())
{
acc += count;
std::for_each(m_wrapper_call_back.begin(), m_wrapper_call_back.end(), [&rpf_wrapper](std::function<size_t(yim_fipackfile & rpf_wrapper)> cb) {
cb(rpf_wrapper);
});
}
}
// if we got nothing with those mount points for this rpf, mount it
if (!acc)
{
rpf_wrapper.mount_name = default_mount_name;
rpf->Mount(default_mount_name);
std::for_each(m_wrapper_call_back.begin(), m_wrapper_call_back.end(), [&rpf_wrapper](std::function<size_t(yim_fipackfile & rpf_wrapper)> cb) {
cb(rpf_wrapper);
});
g_pointers->m_gta.m_fipackfile_unmount(default_mount_name);
}
}
else
{
std::for_each(m_wrapper_call_back.begin(), m_wrapper_call_back.end(), [&rpf_wrapper](std::function<size_t(yim_fipackfile & rpf_wrapper)> cb) {
cb(rpf_wrapper);
});
}
std::for_each(m_wrapper_call_back.begin(), m_wrapper_call_back.end(), [&rpf_wrapper](std::function<size_t(yim_fipackfile & rpf_wrapper)> cb) {
cb(rpf_wrapper);
});
if (i % yield_increment == 0)
script::get_current()->yield();
@ -127,7 +47,7 @@ namespace big
{
std::vector<std::filesystem::path> file_paths;
if (parent.empty())
parent = mount_name;
parent = "/";
std::vector<std::string> directories;
@ -137,7 +57,12 @@ namespace big
{
do
{
std::string fn = std::string(parent.c_str()) + std::string("/") + std::string(findData.fileName);
std::string fn;
if (parent == "/")
fn = std::string(parent.c_str()) + std::string(findData.fileName);
else
fn = std::string(parent.c_str()) + std::string("/") + std::string(findData.fileName);
if (findData.fileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{

View File

@ -4,15 +4,13 @@
namespace big
{
using file_contents_callback = std::function<void(const std::unique_ptr<std::uint8_t[]>& file_content, const int data_size)>;
class yim_fipackfile
{
static constexpr auto default_mount_name = "yimM:/";
rage::fiPackfile* rpf;
std::string mount_name;
public:
explicit yim_fipackfile(rage::fiPackfile* rpf, const std::string& mount_name);
explicit yim_fipackfile(rage::fiPackfile* rpf);
static std::vector<std::string> get_non_dlc_mounted_devices_names();
@ -29,7 +27,5 @@ namespace big
void read_file(const std::filesystem::path& path, file_contents_callback&& cb);
void read_xml_file(const std::filesystem::path& path, std::function<void(pugi::xml_document& doc)> cb);
private:
};
}

View File

@ -15,11 +15,11 @@ namespace big
register_hotkey("beastjump", g.settings.hotkeys.beastjump, RAGE_JOAAT("beastjump"));
register_hotkey("bringpv", g.settings.hotkeys.bringvehicle, RAGE_JOAAT("bringpv"));
register_hotkey("quicksearch", g.settings.hotkeys.cmd_excecutor, RAGE_JOAAT("cmdexecutor"));
register_hotkey("fastrun", g.settings.hotkeys.teleport_waypoint, RAGE_JOAAT("fastrun"));
register_hotkey("fastrun", g.settings.hotkeys.superrun, RAGE_JOAAT("fastrun"));
register_hotkey("fastquit", g.settings.hotkeys.fast_quit, RAGE_JOAAT("fastquit"));
register_hotkey("fillammo", g.settings.hotkeys.fill_ammo, RAGE_JOAAT("fillammo"));
register_hotkey("fillsnacks", g.settings.hotkeys.fill_inventory, RAGE_JOAAT("fillsnacks"));
register_hotkey("freecam", g.settings.hotkeys.teleport_waypoint, RAGE_JOAAT("freecam"));
register_hotkey("freecam", g.settings.hotkeys.freecam, RAGE_JOAAT("freecam"));
register_hotkey("heal", g.settings.hotkeys.heal, RAGE_JOAAT("heal"));
register_hotkey("invis", g.settings.hotkeys.invis, RAGE_JOAAT("invis"));
register_hotkey("invisveh", g.settings.hotkeys.invisveh, RAGE_JOAAT("invisveh"));

View File

@ -1,9 +1,9 @@
#include "locals_service.hpp"
#include "core/data/all_script_names.hpp"
#include "fiber_pool.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "fiber_pool.hpp"
namespace big
{
@ -19,12 +19,13 @@ namespace big
bool locals_service::does_script_exist(std::string script_name)
{
// TODO: find a better way to check script validity
for (auto s : all_script_names)
if (script_name == s)
return true;
bool script_exists = false;
g_fiber_pool->queue_job([&] {script_exists = SCRIPT::DOES_SCRIPT_EXIST(script_name.data());});
return script_exists;
return false;
}
std::filesystem::path locals_service::get_path()

View File

@ -65,7 +65,7 @@ namespace big
{
script_local actual_local = script_local(m_script_thread, m_base_address);
for (auto offset : m_offsets)
for (auto& offset : m_offsets)
{
if (offset.m_size > 0)
actual_local = actual_local.at(offset.m_offset, offset.m_size);

View File

@ -14,7 +14,7 @@
namespace big
{
bool_command g_orbital_drone("orbitaldrone", "Toggle orbital drone", "Enables/Disables the orbital drone.",
bool_command g_orbital_drone("orbitaldrone", "Toggle Orbital Drone", "Enables/Disables the orbital drone",
g.world.orbital_drone.enabled);
static bool nav_override;
@ -28,12 +28,10 @@ namespace big
return;
}
if (*g_pointers->m_gta.m_is_session_started && gta_util::get_network_player_mgr()->m_local_net_player
&& gta_util::get_network_player_mgr()->m_local_net_player->m_player_info->m_ped)
if (g_local_player)
{
scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[self::id].OrbitalBitset.Set(eOrbitalBitset::kOrbitalCannonActive);
const auto player_pos =
*gta_util::get_network_player_mgr()->m_local_net_player->m_player_info->m_ped->m_navigation->get_position();
const auto player_pos = *g_local_player->get_position();
m_start_pos = {player_pos.x, player_pos.y, player_pos.z};
@ -69,7 +67,7 @@ namespace big
{
m_initialized = false;
Entity self = PLAYER::PLAYER_PED_ID();
Entity self = self::ped;
if (PED::IS_PED_IN_ANY_VEHICLE(self, true))
self = PED::GET_VEHICLE_PED_IS_IN(self, false);
@ -102,7 +100,7 @@ namespace big
m_lock_ent = -1;
m_lock = false;
scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[PLAYER::PLAYER_ID()].OrbitalBitset.Clear(eOrbitalBitset::kOrbitalCannonActive);
scr_globals::globalplayer_bd.as<GlobalPlayerBD*>()->Entries[self::id].OrbitalBitset.Clear(eOrbitalBitset::kOrbitalCannonActive);
m_should_tp = false;
}
@ -292,7 +290,7 @@ namespace big
m_lock_ent = entity::get_entity_closest_to_middle_of_screen();
m_lock = true;
if (g.world.orbital_drone.detect_player)
if (*g_pointers->m_gta.m_is_session_started && g.world.orbital_drone.detect_player)
detect_player(m_lock_ent);
}
@ -378,8 +376,8 @@ namespace big
Vector3 campos = CAM::GET_CAM_COORD(m_cam);
Vector3 entpos = ENTITY::GET_ENTITY_COORDS(entity::get_entity_closest_to_middle_of_screen(), 0);
if (g_player_service->get_selected()->is_valid()
&&ENTITY::DOES_ENTITY_EXIST(g_pointers->m_gta.m_ptr_to_handle(g_player_service->get_selected()->get_ped())))
if (*g_pointers->m_gta.m_is_session_started && g_player_service->get_selected()->is_valid()
&& ENTITY::DOES_ENTITY_EXIST(g_pointers->m_gta.m_ptr_to_handle(g_player_service->get_selected()->get_ped())))
{
toxic::blame_explode_coord(g_player_service->get_selected(), m_ground_pos, eExplosionTag::EXP_TAG_ORBITAL_CANNON, 1.f, TRUE, TRUE, 1.f);
@ -388,9 +386,9 @@ namespace big
}
else
{
toxic::blame_explode_coord(g_player_service->get_self(), m_ground_pos, eExplosionTag::EXP_TAG_ORBITAL_CANNON, 1.f, TRUE, TRUE, 1.f);
toxic::blame_explode_coord(*g_pointers->m_gta.m_is_session_started ? g_player_service->get_self() : nullptr, m_ground_pos, eExplosionTag::EXP_TAG_ORBITAL_CANNON, 1.f, TRUE, TRUE, 1.f);
if (MISC::GET_DISTANCE_BETWEEN_COORDS(campos.x, campos.y, campos.z, entpos.x, entpos.y, entpos.z, false) < 10)
toxic::blame_explode_coord(g_player_service->get_self(), entpos, eExplosionTag::EXP_TAG_ORBITAL_CANNON, 1.f, TRUE, TRUE, 1.f);
toxic::blame_explode_coord(*g_pointers->m_gta.m_is_session_started ? g_player_service->get_self() : nullptr, entpos, eExplosionTag::EXP_TAG_ORBITAL_CANNON, 1.f, TRUE, TRUE, 1.f);
}

View File

@ -335,18 +335,11 @@ namespace big
nlohmann::json persist_car_service::get_model_attachments(Vehicle vehicle, bool is_towed_vehicle)
{
const auto replay_interface = *g_pointers->m_gta.m_replay_interface;
std::vector<nlohmann::json> attached_objects;
const auto object_interface = replay_interface->m_object_interface;
for (int i = 0; i < object_interface->m_max_objects; i++)
for (auto obj : pools::get_all_props())
{
const auto object_ptr = object_interface->get_object(i);
if (!object_ptr)
continue;
const auto object = g_pointers->m_gta.m_ptr_to_handle(object_ptr);
const auto object = g_pointers->m_gta.m_ptr_to_handle(obj);
if (!object)
break;
@ -354,7 +347,7 @@ namespace big
continue;
// Don't save tow hook.
if (is_towed_vehicle && ENTITY::GET_ENTITY_MODEL(object) == 0xBC344305)
if (is_towed_vehicle && ENTITY::GET_ENTITY_MODEL(object) == RAGE_JOAAT("prop_v_hook_s"))
continue;
attached_objects.push_back(get_model_attachment(vehicle, object));
@ -365,22 +358,14 @@ namespace big
nlohmann::json persist_car_service::get_vehicle_attachents(Vehicle vehicle)
{
const auto replay_interface = *g_pointers->m_gta.m_replay_interface;
const auto vehicle_interface = replay_interface->m_vehicle_interface;
std::vector<nlohmann::json> attached_vehicles;
Vehicle trailer;
VEHICLE::GET_VEHICLE_TRAILER_VEHICLE(vehicle, &trailer);
for (int i = 0; i < vehicle_interface->m_max_vehicles; i++)
for (auto veh : pools::get_all_vehicles())
{
const auto vehicle_ptr = vehicle_interface->get_vehicle(i);
if (!vehicle_ptr)
continue;
const auto object = g_pointers->m_gta.m_ptr_to_handle(vehicle_ptr);
const auto object = g_pointers->m_gta.m_ptr_to_handle(veh);
if (!object)
break;