feat(Mobile): Added Mechanic personal vehicle summon

This commit is contained in:
Yimura
2022-01-08 05:42:36 +01:00
parent 0a16d73c1d
commit 9730c50d97
7 changed files with 227 additions and 4 deletions

View File

@ -15,7 +15,7 @@ namespace big
enum eVehicleFlags
{
UNK0 = 1 << 0,
ACTIVE = 1 << 0,
DESTROYED = 1 << 1,
HAS_INSURANCE = 1 << 2,
IMPOUNDED = 1 << 6,

View File

@ -3,6 +3,7 @@
#include "script.hpp"
#include "util/mobile.hpp"
#include "util/notify.hpp"
#include "services/mobile_service.hpp"
namespace big
{
@ -23,6 +24,78 @@ namespace big
}QUEUE_JOB_END_CLAUSE
}
ImGui::Separator();
if (ImGui::TreeNode("Lester"))
{
ImGui::Checkbox("Off Radar", &g.self.off_radar);
ImGui::TreePop();
}
ImGui::Separator();
if (ImGui::TreeNode("Mechanic - Personal Vehicles"))
{
static char search[64];
static std::string lower_search;
ImGui::BeginGroup();
ImGui::SetNextItemWidth(400.f);
if (ImGui::InputTextWithHint("##search_pv_list", "Search", search, sizeof(search)))
{
lower_search = search;
std::transform(lower_search.begin(), lower_search.end(), lower_search.begin(), tolower);
}
if (ImGui::ListBoxHeader("##personal_veh_list", { 400.f, 500.f }))
{
for (auto& it : g_mobile_service->m_personal_vehicles)
{
auto& personal_veh = it.second;
std::string lower = personal_veh.get_display_name().c_str();
std::transform(lower.begin(), lower.end(), lower.begin(), tolower);
if (lower.find(lower_search) != std::string::npos)
{
if (ImGui::Selectable(
personal_veh.get_display_name().c_str(),
personal_veh.get_id() == mobile::util::get_current_personal_vehicle()
))
{
strcpy(search, "");
lower_search = search;
QUEUE_JOB_BEGIN_CLAUSE(&personal_veh)
{
personal_veh.summon();
}QUEUE_JOB_END_CLAUSE
}
}
}
ImGui::ListBoxFooter();
}
ImGui::EndGroup();
ImGui::SameLine();
ImGui::BeginGroup();
if (ImGui::Button("Reload Vehicles"))
{
QUEUE_JOB_BEGIN_CLAUSE()
{
g_mobile_service->register_vehicles();
}QUEUE_JOB_END_CLAUSE
}
ImGui::TreePop();
}
ImGui::EndTabItem();
}
}

View File

@ -29,7 +29,7 @@ namespace big
if (!blip::get_blip_location(location, 225, 0) && !blip::get_blip_location(location, 226, 0)) return notify::above_map("No personal vehicle found, was it destroyed?");
Vehicle veh = vehicle::get_closest_to_location(location, 2.f);
if (veh == 0) return notify::above_map("Invalid vehicle handle...");
if (ENTITY::IS_ENTITY_DEAD(veh, false)) return notify::above_map("Invalid vehicle handle...");
location = ENTITY::GET_ENTITY_COORDS(PLAYER::PLAYER_PED_ID(), true);

View File

@ -57,6 +57,7 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
LOG(INFO) << "Registering service instances...";
auto globals_service_instace = std::make_unique<globals_service>();
auto mobile_service_instance = std::make_unique<mobile_service>();
auto vehicle_service_instance = std::make_unique<vehicle_service>();
while (g_running)
@ -66,6 +67,7 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
LOG(INFO) << "Serviceses uninitialized.";
vehicle_service_instance.reset();
mobile_service_instance.reset();
globals_service_instace.reset();
// Make sure that all threads created don't have any blocking loops

View File

@ -0,0 +1,68 @@
#include "mobile_service.hpp"
#include "fiber_pool.hpp"
#include "natives.hpp"
#include "script.hpp"
#include "thread_pool.hpp"
#include "util/mobile.hpp"
namespace big
{
PersonalVehicle::PersonalVehicle(int idx, script_global vehicle_idx)
{
m_id = idx;
m_hash = *vehicle_idx.at(66).as<Hash*>();
m_state_bitfield = vehicle_idx.at(103).as<int*>();
m_name = HUD::GET_LABEL_TEXT_(VEHICLE::GET_DISPLAY_NAME_FROM_VEHICLE_MODEL(m_hash));
}
std::string PersonalVehicle::get_display_name()
{
return m_name + "##" + std::to_string(m_id);
}
Hash PersonalVehicle::get_hash()
{
return m_hash;
}
int PersonalVehicle::get_id()
{
return m_id;
}
void PersonalVehicle::summon()
{
mobile::mechanic::summon_vehicle_by_index(m_id);
}
mobile_service::mobile_service()
{
g_mobile_service = this;
}
mobile_service::~mobile_service()
{
g_mobile_service = nullptr;
}
void mobile_service::register_vehicles()
{
for (int i = 0; i < *mobile::vehicle_global.as<int*>(); i++)
{
auto veh_idx_global = mobile::vehicle_global.at(i, 142);
Hash hash = *veh_idx_global.at(66).as<Hash*>();
if (STREAMING::IS_MODEL_A_VEHICLE(hash))
{
if (auto& it = m_personal_vehicles.find(i); it != m_personal_vehicles.end() && it->second.get_hash() != hash)
it->second = PersonalVehicle(i, veh_idx_global);
else
m_personal_vehicles.emplace(i, PersonalVehicle(i, veh_idx_global));
}
script::get_current()->yield();
}
}
}

View File

@ -0,0 +1,38 @@
#pragma once
namespace big
{
class script_global;
class PersonalVehicle
{
std::string m_name;
int m_id;
Hash m_hash;
int* m_state_bitfield;
public:
PersonalVehicle(int idx, script_global vehicle_idx);
std::string get_display_name();
Hash get_hash();
int get_id();
void summon();
};
class mobile_service
{
public:
mobile_service();
~mobile_service();
void register_vehicles();
std::map<int, PersonalVehicle> m_personal_vehicles;
};
class mobile_service;
inline mobile_service* g_mobile_service{};
}

View File

@ -1,14 +1,35 @@
#pragma once
#include "core/enums.hpp"
#include "script_global.hpp"
#include "gta_util.hpp"
#include "misc.hpp"
#include "natives.hpp"
#include "script.hpp"
#include "script_global.hpp"
#include "script_local.hpp"
namespace big::mobile
{
inline auto player_global = script_global(2689156);
inline auto mechanic_global = script_global(2810287);
inline auto vehicle_global = script_global(1585844);
namespace util
{
int get_current_personal_vehicle(); // forward declare
inline void despawn_current_personal_vehicle()
{
misc::clear_bits(
vehicle_global.at(get_current_personal_vehicle(), 142).at(103).as<int*>(),
eVehicleFlags::ACTIVE | eVehicleFlags::UNK2
);
}
inline int get_current_personal_vehicle()
{
return *script_global(2359296).at(0, 5559).at(675).at(2).as<int*>();
}
}
namespace lester
{
inline void off_radar(bool toggle)
@ -18,9 +39,30 @@ namespace big::mobile
}
}
namespace mors_mutual
{
bool fix_index(int veh_idx);
}
namespace mechanic
{
inline void summon_vehicle_by_index(int veh_idx)
{
// despawn current veh
util::despawn_current_personal_vehicle();
mors_mutual::fix_index(veh_idx);
script::get_current()->yield(100ms);
*mechanic_global.at(911).as<int*>() = 1;
*mechanic_global.at(961).as<int*>() = 0;
*mechanic_global.at(958).as<int*>() = veh_idx;
script::get_current()->yield(100ms);
GtaThread* freemode_thread = gta_util::find_script_thread(RAGE_JOAAT("freemode"));
if (freemode_thread)
*script_local(freemode_thread, 17437).at(176).as<int*>() = 0; // spawn vehicle instantly
}
}
namespace mors_mutual
@ -52,7 +94,7 @@ namespace big::mobile
);
misc::set_bits(
vehicle_global.at(veh_idx, 142).at(103).as<int*>(),
eVehicleFlags::UNK0 | eVehicleFlags::UNK2
eVehicleFlags::ACTIVE | eVehicleFlags::UNK2
);
}
return can_be_fixed;