fix(GtaDataService): Rebuild Cache button not working (#3411)

Changes:
- Switch from pointer singleton to pre-instanced singleton
- Added default constructor to cache_file object
- Fixed an issue where maps and vectors would not be cleared before (re)generating a cache.
This commit is contained in:
Andreas Maerten 2024-07-23 20:15:19 +02:00 committed by GitHub
parent f23078c9ea
commit 40bf403500
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 235 additions and 214 deletions

View File

@ -16,7 +16,7 @@ namespace big
virtual void execute(player_ptr player, const command_arguments& _args, const std::shared_ptr<command_context> ctx) override virtual void execute(player_ptr player, const command_arguments& _args, const std::shared_ptr<command_context> ctx) override
{ {
for (auto& weapon : g_gta_data_service->weapons()) for (auto& weapon : g_gta_data_service.weapons())
WEAPON::GIVE_WEAPON_TO_PED(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(player->id()), weapon.second.m_hash, 9999, FALSE, FALSE); WEAPON::GIVE_WEAPON_TO_PED(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(player->id()), weapon.second.m_hash, 9999, FALSE, FALSE);
} }
}; };
@ -33,7 +33,7 @@ namespace big
virtual void execute(const command_arguments& _args, const std::shared_ptr<command_context> ctx) override virtual void execute(const command_arguments& _args, const std::shared_ptr<command_context> ctx) override
{ {
g_player_service->iterate([](auto& plyr) { g_player_service->iterate([](auto& plyr) {
for (auto& weapon : g_gta_data_service->weapons()) for (auto& weapon : g_gta_data_service.weapons())
WEAPON::GIVE_WEAPON_TO_PED(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(plyr.second->id()), weapon.second.m_hash, 9999, FALSE, FALSE); WEAPON::GIVE_WEAPON_TO_PED(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(plyr.second->id()), weapon.second.m_hash, 9999, FALSE, FALSE);
script::get_current()->yield(500ms); script::get_current()->yield(500ms);
}); });
@ -42,4 +42,4 @@ namespace big
give_all_weapons g_give_all_weapons("giveweaps", "GIVE_WEAPONS", "GIVE_WEAPONS_DESC", 0, false); give_all_weapons g_give_all_weapons("giveweaps", "GIVE_WEAPONS", "GIVE_WEAPONS_DESC", 0, false);
give_all_weapons_all g_give_all_weapons_all("giveweapsall", "GIVE_WEAPONS", "GIVE_WEAPONS_ALL_DESC", 0); give_all_weapons_all g_give_all_weapons_all("giveweapsall", "GIVE_WEAPONS", "GIVE_WEAPONS_ALL_DESC", 0);
} }

View File

@ -42,7 +42,7 @@ namespace big
} }
else if (arg == 3) else if (arg == 3)
{ {
for (auto& item : g_gta_data_service->vehicles()) for (auto& item : g_gta_data_service.vehicles())
{ {
suggestions.push_back(item.second.m_name); suggestions.push_back(item.second.m_name);
} }
@ -92,7 +92,7 @@ namespace big
std::string item_name_lower, args_lower; std::string item_name_lower, args_lower;
args_lower = args[2]; args_lower = args[2];
string::operations::to_lower(args_lower); string::operations::to_lower(args_lower);
for (auto& item : g_gta_data_service->vehicles()) for (auto& item : g_gta_data_service.vehicles())
{ {
item_name_lower = item.second.m_name; item_name_lower = item.second.m_name;
string::operations::to_lower(item_name_lower); string::operations::to_lower(item_name_lower);

View File

@ -15,10 +15,10 @@ namespace big
virtual void execute(player_ptr player, const command_arguments& _args, const std::shared_ptr<command_context> ctx) override virtual void execute(player_ptr player, const command_arguments& _args, const std::shared_ptr<command_context> ctx) override
{ {
for (auto& [_, weapon] : g_gta_data_service->weapons()) for (auto& [_, weapon] : g_gta_data_service.weapons())
WEAPON::REMOVE_WEAPON_FROM_PED(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(player->id()), weapon.m_hash); WEAPON::REMOVE_WEAPON_FROM_PED(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(player->id()), weapon.m_hash);
} }
}; };
remove_all_weapons g_remove_all_weapons("remweaps", "REMOVE_ALL_WEAPONS", "REMOVE_ALL_WEAPONS_DESC", 0); remove_all_weapons g_remove_all_weapons("remweaps", "REMOVE_ALL_WEAPONS", "REMOVE_ALL_WEAPONS_DESC", 0);
} }

View File

@ -10,7 +10,7 @@ namespace big
virtual void execute(const command_arguments&, const std::shared_ptr<command_context> ctx) override virtual void execute(const command_arguments&, const std::shared_ptr<command_context> ctx) override
{ {
for (const auto& [_, weapon] : g_gta_data_service->weapons()) for (const auto& [_, weapon] : g_gta_data_service.weapons())
{ {
int ammo_in; int ammo_in;
WEAPON::GET_MAX_AMMO(self::ped, weapon.m_hash, &ammo_in); WEAPON::GET_MAX_AMMO(self::ped, weapon.m_hash, &ammo_in);
@ -19,4 +19,4 @@ namespace big
} }
}; };
fill_ammo g_fill_ammo("fillammo", "FILL_AMMO", "FILL_AMMO_DESC", 0); fill_ammo g_fill_ammo("fillammo", "FILL_AMMO", "FILL_AMMO_DESC", 0);
} }

View File

@ -17,7 +17,7 @@ namespace big
if (arg == 1) if (arg == 1)
{ {
std::vector<std::string> suggestions; std::vector<std::string> suggestions;
for (auto& item : g_gta_data_service->vehicles()) for (auto& item : g_gta_data_service.vehicles())
{ {
suggestions.push_back(item.second.m_name); suggestions.push_back(item.second.m_name);
} }
@ -31,13 +31,13 @@ namespace big
{ {
command_arguments result(1); command_arguments result(1);
if (g_gta_data_service->vehicle_by_hash(rage::joaat(args[0])).m_hash != 0) if (g_gta_data_service.vehicle_by_hash(rage::joaat(args[0])).m_hash != 0)
{ {
result.push(rage::joaat(args[0])); result.push(rage::joaat(args[0]));
return result; return result;
} }
for (auto& item : g_gta_data_service->vehicles()) for (auto& item : g_gta_data_service.vehicles())
{ {
std::string item_name_lower, args_lower; std::string item_name_lower, args_lower;
item_name_lower = item.second.m_name; item_name_lower = item.second.m_name;
@ -70,8 +70,7 @@ namespace big
auto id = ctx->get_sender()->id(); auto id = ctx->get_sender()->id();
const auto spawn_location = vehicle::get_spawn_location(id == self::id ? g.spawn_vehicle.spawn_inside : false, const auto spawn_location = vehicle::get_spawn_location(id == self::id ? g.spawn_vehicle.spawn_inside : false, hash, PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(id));
hash, PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(id));
const auto spawn_heading = ENTITY::GET_ENTITY_HEADING(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(id)); const auto spawn_heading = ENTITY::GET_ENTITY_HEADING(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(id));
auto veh = vehicle::spawn(hash, spawn_location, spawn_heading); auto veh = vehicle::spawn(hash, spawn_location, spawn_heading);

View File

@ -10,7 +10,7 @@ namespace big
static void resolve_weapon_hotkey(Hash weapon) static void resolve_weapon_hotkey(Hash weapon)
{ {
if (g_gta_data_service->weapon_by_hash(weapon).m_name.empty()) if (g_gta_data_service.weapon_by_hash(weapon).m_name.empty())
{ {
WEAPON::SET_CURRENT_PED_VEHICLE_WEAPON(self::ped, weapon); WEAPON::SET_CURRENT_PED_VEHICLE_WEAPON(self::ped, weapon);
} }
@ -61,4 +61,4 @@ namespace big
} }
} }
} }
} }

View File

@ -21,8 +21,8 @@
#include "netsync/nodes/ped/CPedCreationDataNode.hpp" #include "netsync/nodes/ped/CPedCreationDataNode.hpp"
#include "netsync/nodes/ped/CPedGameStateDataNode.hpp" #include "netsync/nodes/ped/CPedGameStateDataNode.hpp"
#include "netsync/nodes/ped/CPedHealthDataNode.hpp" #include "netsync/nodes/ped/CPedHealthDataNode.hpp"
#include "netsync/nodes/ped/CPedMovementGroupDataNode.hpp"
#include "netsync/nodes/ped/CPedMovementDataNode.hpp" #include "netsync/nodes/ped/CPedMovementDataNode.hpp"
#include "netsync/nodes/ped/CPedMovementGroupDataNode.hpp"
#include "netsync/nodes/ped/CPedOrientationDataNode.hpp" #include "netsync/nodes/ped/CPedOrientationDataNode.hpp"
#include "netsync/nodes/ped/CPedScriptCreationDataNode.hpp" #include "netsync/nodes/ped/CPedScriptCreationDataNode.hpp"
#include "netsync/nodes/ped/CPedTaskSequenceDataNode.hpp" #include "netsync/nodes/ped/CPedTaskSequenceDataNode.hpp"
@ -206,7 +206,7 @@ namespace big
if (info->m_model_type == eModelType::Vehicle) if (info->m_model_type == eModelType::Vehicle)
{ {
for (auto& [name, data] : g_gta_data_service->vehicles()) for (auto& [name, data] : g_gta_data_service.vehicles())
{ {
if (data.m_hash == model) if (data.m_hash == model)
{ {
@ -217,7 +217,7 @@ namespace big
} }
else if (info->m_model_type == eModelType::Ped || info->m_model_type == eModelType::OnlineOnlyPed) else if (info->m_model_type == eModelType::Ped || info->m_model_type == eModelType::OnlineOnlyPed)
{ {
for (auto& [name, data] : g_gta_data_service->peds()) for (auto& [name, data] : g_gta_data_service.peds())
{ {
if (data.m_hash == model) if (data.m_hash == model)
{ {
@ -1262,8 +1262,7 @@ namespace big
return true; return true;
} }
if (attach_node->m_attached if (attach_node->m_attached && object->m_object_type == (int16_t)eNetObjType::NET_OBJ_TYPE_TRAILER)
&& object->m_object_type == (int16_t)eNetObjType::NET_OBJ_TYPE_TRAILER)
{ {
if (auto net_obj = if (auto net_obj =
g_pointers->m_gta.m_get_net_object(*g_pointers->m_gta.m_network_object_mgr, attach_node->m_attached_to, false)) g_pointers->m_gta.m_get_net_object(*g_pointers->m_gta.m_network_object_mgr, attach_node->m_attached_to, false))
@ -1380,7 +1379,7 @@ namespace big
{ {
const auto game_state_node = (CPlayerGameStateDataNode*)(node); const auto game_state_node = (CPlayerGameStateDataNode*)(node);
if (game_state_node->m_is_overriding_population_control_sphere if (game_state_node->m_is_overriding_population_control_sphere
&& is_invalid_override_pos(game_state_node->m_population_control_sphere_x,game_state_node->m_population_control_sphere_y)) && is_invalid_override_pos(game_state_node->m_population_control_sphere_x, game_state_node->m_population_control_sphere_y))
{ {
if (gta_util::get_network()->m_game_session_ptr->is_host()) if (gta_util::get_network()->m_game_session_ptr->is_host())
notify::crash_blocked(sender, "invalid sector position (player game state node)"); notify::crash_blocked(sender, "invalid sector position (player game state node)");
@ -1573,7 +1572,7 @@ namespace big
} }
} }
} }
else if (veh_creation_model != std::nullopt) else if (veh_creation_model != std::nullopt)
{ {
// object hasn't been created yet, but we have the model hash from the creation node // object hasn't been created yet, but we have the model hash from the creation node
if (auto model_info = model_info::get_vehicle_model(veh_creation_model.value())) if (auto model_info = model_info::get_vehicle_model(veh_creation_model.value()))

View File

@ -52,7 +52,7 @@ namespace big
return false; return false;
} }
// Returns true if bad event // Returns true if bad event
bool scan_weapon_damage_event(rage::netEventMgr* event_manager, CNetGamePlayer* player, CNetGamePlayer* target_player, int event_index, int event_handled_bitset, rage::datBitBuffer* buffer) bool scan_weapon_damage_event(rage::netEventMgr* event_manager, CNetGamePlayer* player, CNetGamePlayer* target_player, int event_index, int event_handled_bitset, rage::datBitBuffer* buffer)
{ {
@ -103,7 +103,11 @@ namespace big
if (!is_valid_weapon(weaponType)) if (!is_valid_weapon(weaponType))
{ {
notify::crash_blocked(player, "invalid weapon type"); notify::crash_blocked(player, "invalid weapon type");
LOGF(stream::net_events, WARNING, "Blocked WEAPON_DAMAGE_EVENT from {} with invalid weapon hash {:X}", player->get_name(), weaponType); LOGF(stream::net_events,
WARNING,
"Blocked WEAPON_DAMAGE_EVENT from {} with invalid weapon hash {:X}",
player->get_name(),
weaponType);
g_pointers->m_gta.m_send_event_ack(event_manager, player, target_player, event_index, event_handled_bitset); g_pointers->m_gta.m_send_event_ack(event_manager, player, target_player, event_index, event_handled_bitset);
return true; return true;
} }
@ -424,7 +428,8 @@ namespace big
static const std::unordered_set<uint32_t> blocked_script_hashes = {"main_persistent"_J, "shop_controller"_J}; static const std::unordered_set<uint32_t> blocked_script_hashes = {"main_persistent"_J, "shop_controller"_J};
bool should_block = [&] { bool should_block = [&] {
if (blocked_ref_hashes.contains(ref_hash) || blocked_sound_hashes.contains(sound_hash) || blocked_script_hashes.contains(script_hash)) if (blocked_ref_hashes.contains(ref_hash) || blocked_sound_hashes.contains(sound_hash)
|| blocked_script_hashes.contains(script_hash))
return true; return true;
switch (sound_hash) switch (sound_hash)
@ -551,7 +556,7 @@ namespace big
else if (type == ScriptEntityChangeType::SetVehicleLockState) else if (type == ScriptEntityChangeType::SetVehicleLockState)
{ {
if (g_local_player && g_local_player->m_vehicle && g_local_player->m_vehicle->m_net_object if (g_local_player && g_local_player->m_vehicle && g_local_player->m_vehicle->m_net_object
&& g_local_player->m_vehicle->m_net_object->m_object_id == entity) && g_local_player->m_vehicle->m_net_object->m_object_id == entity)
{ {
g_pointers->m_gta.m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset); g_pointers->m_gta.m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset);
LOGF(stream::net_events, WARNING, "Blocked SCRIPT_ENTITY_STATE_CHANGE_EVENT of type SetVehicleLockState from {} on our local vehicle", plyr->get_name()); LOGF(stream::net_events, WARNING, "Blocked SCRIPT_ENTITY_STATE_CHANGE_EVENT of type SetVehicleLockState from {} on our local vehicle", plyr->get_name());
@ -673,8 +678,8 @@ namespace big
{ {
Vehicle personal_vehicle = mobile::mechanic::get_personal_vehicle(); Vehicle personal_vehicle = mobile::mechanic::get_personal_vehicle();
Vehicle veh = g_pointers->m_gta.m_ptr_to_handle(g_local_player->m_vehicle); Vehicle veh = g_pointers->m_gta.m_ptr_to_handle(g_local_player->m_vehicle);
if (!NETWORK::NETWORK_IS_ACTIVITY_SESSION() //If we're in Freemode. if (!NETWORK::NETWORK_IS_ACTIVITY_SESSION() //If we're in Freemode.
|| personal_vehicle == veh //Or we're in our personal vehicle. || personal_vehicle == veh //Or we're in our personal vehicle.
|| self::spawned_vehicles.contains(net_id)) // Or it's a vehicle we spawned. || self::spawned_vehicles.contains(net_id)) // Or it's a vehicle we spawned.
{ {
// Let trusted friends and players request control (e.g., they want to hook us to their tow-truck or something) // Let trusted friends and players request control (e.g., they want to hook us to their tow-truck or something)
@ -769,9 +774,9 @@ namespace big
if (g_local_player && g_local_player->m_net_object && g_local_player->m_net_object->m_object_id == net_id) if (g_local_player && g_local_player->m_net_object && g_local_player->m_net_object->m_object_id == net_id)
{ {
weapon_item weapon = g_gta_data_service->weapon_by_hash(hash); weapon_item weapon = g_gta_data_service.weapon_by_hash(hash);
g_notification_service.push_warning("PROTECTIONS"_T.data(), g_notification_service.push_warning("PROTECTIONS"_T.data(),
std::format("{} {} {}.", source_player->get_name(), "REMOVE_WEAPON_ATTEMPT_MESSAGE"_T, weapon.m_display_name)); std::format("{} {} {}.", source_player->get_name(), "REMOVE_WEAPON_ATTEMPT_MESSAGE"_T, weapon.m_display_name));
g_pointers->m_gta.m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset); g_pointers->m_gta.m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset);
return; return;
} }
@ -786,7 +791,7 @@ namespace big
if (g_local_player && g_local_player->m_net_object && g_local_player->m_net_object->m_object_id == net_id) if (g_local_player && g_local_player->m_net_object && g_local_player->m_net_object->m_object_id == net_id)
{ {
weapon_item weapon = g_gta_data_service->weapon_by_hash(hash); weapon_item weapon = g_gta_data_service.weapon_by_hash(hash);
g_notification_service.push_warning("PROTECTIONS"_T.data(), g_notification_service.push_warning("PROTECTIONS"_T.data(),
std::format("{} {} {}.", source_player->get_name(), "GIVE_WEAPON_ATTEMPT_MESSAGE"_T, weapon.m_display_name)); std::format("{} {} {}.", source_player->get_name(), "GIVE_WEAPON_ATTEMPT_MESSAGE"_T, weapon.m_display_name));
g_pointers->m_gta.m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset); g_pointers->m_gta.m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset);

View File

@ -18,7 +18,7 @@ namespace lua::vehicles
//``` //```
static std::string get_vehicle_display_name(Hash vehicle_hash) static std::string get_vehicle_display_name(Hash vehicle_hash)
{ {
return big::g_gta_data_service->vehicle_by_hash(vehicle_hash).m_display_name; return big::g_gta_data_service.vehicle_by_hash(vehicle_hash).m_display_name;
} }
// Lua API: Function // Lua API: Function
@ -32,7 +32,7 @@ namespace lua::vehicles
//``` //```
static std::string get_vehicle_display_name_string(std::string vehicle_name) static std::string get_vehicle_display_name_string(std::string vehicle_name)
{ {
return big::g_gta_data_service->vehicle_by_hash(rage::joaat(vehicle_name)).m_display_name; return big::g_gta_data_service.vehicle_by_hash(rage::joaat(vehicle_name)).m_display_name;
} }
// Lua API: Function // Lua API: Function
@ -50,7 +50,7 @@ namespace lua::vehicles
static std::vector<std::string> get_all_vehicles_by_class(std::string vehicle_class) static std::vector<std::string> get_all_vehicles_by_class(std::string vehicle_class)
{ {
std::vector<std::string> return_value; std::vector<std::string> return_value;
for (auto& [name, vehicle] : big::g_gta_data_service->vehicles()) for (auto& [name, vehicle] : big::g_gta_data_service.vehicles())
{ {
if (vehicle.m_vehicle_class == vehicle_class) if (vehicle.m_vehicle_class == vehicle_class)
{ {
@ -76,7 +76,7 @@ namespace lua::vehicles
static std::vector<std::string> get_all_vehicles_by_mfr(std::string manufacturer) static std::vector<std::string> get_all_vehicles_by_mfr(std::string manufacturer)
{ {
std::vector<std::string> return_value; std::vector<std::string> return_value;
for (auto& [name, vehicle] : big::g_gta_data_service->vehicles()) for (auto& [name, vehicle] : big::g_gta_data_service.vehicles())
{ {
if (vehicle.m_display_manufacturer == manufacturer) if (vehicle.m_display_manufacturer == manufacturer)
{ {
@ -88,9 +88,9 @@ namespace lua::vehicles
void bind(sol::state& state) void bind(sol::state& state)
{ {
auto ns = state["vehicles"].get_or_create<sol::table>(); auto ns = state["vehicles"].get_or_create<sol::table>();
ns["get_vehicle_display_name"] = sol::overload(get_vehicle_display_name, get_vehicle_display_name_string); ns["get_vehicle_display_name"] = sol::overload(get_vehicle_display_name, get_vehicle_display_name_string);
ns["get_all_vehicles_by_class"] = get_all_vehicles_by_class; ns["get_all_vehicles_by_class"] = get_all_vehicles_by_class;
ns["get_all_vehicles_by_mfr"] = get_all_vehicles_by_mfr; ns["get_all_vehicles_by_mfr"] = get_all_vehicles_by_mfr;
} }
} }

View File

@ -18,7 +18,7 @@ namespace lua::weapons
//``` //```
static std::string get_weapon_display_name(Hash weapon_hash) static std::string get_weapon_display_name(Hash weapon_hash)
{ {
return big::g_gta_data_service->weapon_by_hash(weapon_hash).m_display_name; return big::g_gta_data_service.weapon_by_hash(weapon_hash).m_display_name;
} }
// Lua API: Function // Lua API: Function
@ -32,7 +32,7 @@ namespace lua::weapons
//``` //```
static std::string get_weapon_display_name_string(std::string weapon_name) static std::string get_weapon_display_name_string(std::string weapon_name)
{ {
return big::g_gta_data_service->weapon_by_hash(rage::joaat(weapon_name)).m_display_name; return big::g_gta_data_service.weapon_by_hash(rage::joaat(weapon_name)).m_display_name;
} }
// Lua API: Function // Lua API: Function
@ -50,7 +50,7 @@ namespace lua::weapons
static std::vector<std::string> get_all_weapons_of_group_type(Hash group_hash) static std::vector<std::string> get_all_weapons_of_group_type(Hash group_hash)
{ {
std::vector<std::string> return_value; std::vector<std::string> return_value;
for (auto& [name, weapon] : big::g_gta_data_service->weapons()) for (auto& [name, weapon] : big::g_gta_data_service.weapons())
{ {
if (rage::joaat("GROUP_" + weapon.m_weapon_type) == group_hash) if (rage::joaat("GROUP_" + weapon.m_weapon_type) == group_hash)
{ {
@ -85,7 +85,7 @@ namespace lua::weapons
group_name.erase(0, 6); group_name.erase(0, 6);
} }
std::vector<std::string> return_value; std::vector<std::string> return_value;
for (auto& [name, weapon] : big::g_gta_data_service->weapons()) for (auto& [name, weapon] : big::g_gta_data_service.weapons())
{ {
if (weapon.m_weapon_type == group_name) if (weapon.m_weapon_type == group_name)
{ {
@ -109,7 +109,7 @@ namespace lua::weapons
//``` //```
static std::vector<std::string> get_all_weapon_components(Hash weapon_hash) static std::vector<std::string> get_all_weapon_components(Hash weapon_hash)
{ {
return big::g_gta_data_service->weapon_by_hash(weapon_hash).m_attachments; return big::g_gta_data_service.weapon_by_hash(weapon_hash).m_attachments;
} }
// Lua API: Function // Lua API: Function
@ -126,7 +126,7 @@ namespace lua::weapons
//``` //```
static std::vector<std::string> get_all_weapon_components_string(std::string weapon_name) static std::vector<std::string> get_all_weapon_components_string(std::string weapon_name)
{ {
return big::g_gta_data_service->weapon_by_hash(rage::joaat(weapon_name)).m_attachments; return big::g_gta_data_service.weapon_by_hash(rage::joaat(weapon_name)).m_attachments;
} }
// Lua API: Function // Lua API: Function
@ -140,7 +140,7 @@ namespace lua::weapons
//``` //```
static std::string get_weapon_component_display_name(Hash weapon_component_hash) static std::string get_weapon_component_display_name(Hash weapon_component_hash)
{ {
return big::g_gta_data_service->weapon_component_by_hash(weapon_component_hash).m_display_name; return big::g_gta_data_service.weapon_component_by_hash(weapon_component_hash).m_display_name;
} }
// Lua API: Function // Lua API: Function
@ -154,7 +154,7 @@ namespace lua::weapons
//``` //```
static std::string get_weapon_component_display_name_string(std::string weapon_component) static std::string get_weapon_component_display_name_string(std::string weapon_component)
{ {
return big::g_gta_data_service->weapon_component_by_hash(rage::joaat(weapon_component)).m_display_name; return big::g_gta_data_service.weapon_component_by_hash(rage::joaat(weapon_component)).m_display_name;
} }
// Lua API: Function // Lua API: Function
@ -168,7 +168,7 @@ namespace lua::weapons
//``` //```
static std::string get_weapon_component_display_desc(Hash weapon_component_hash) static std::string get_weapon_component_display_desc(Hash weapon_component_hash)
{ {
return big::g_gta_data_service->weapon_component_by_hash(weapon_component_hash).m_display_desc; return big::g_gta_data_service.weapon_component_by_hash(weapon_component_hash).m_display_desc;
} }
// Lua API: Function // Lua API: Function
@ -182,16 +182,16 @@ namespace lua::weapons
//``` //```
static std::string get_weapon_component_display_desc_string(std::string weapon_component) static std::string get_weapon_component_display_desc_string(std::string weapon_component)
{ {
return big::g_gta_data_service->weapon_component_by_hash(rage::joaat(weapon_component)).m_display_desc; return big::g_gta_data_service.weapon_component_by_hash(rage::joaat(weapon_component)).m_display_desc;
} }
void bind(sol::state& state) void bind(sol::state& state)
{ {
auto ns = state["weapons"].get_or_create<sol::table>(); auto ns = state["weapons"].get_or_create<sol::table>();
ns["get_weapon_display_name"] = sol::overload(get_weapon_display_name, get_weapon_display_name_string); ns["get_weapon_display_name"] = sol::overload(get_weapon_display_name, get_weapon_display_name_string);
ns["get_all_weapons_of_group_type"] = sol::overload(get_all_weapons_of_group_type, get_all_weapons_of_group_type_string); ns["get_all_weapons_of_group_type"] = sol::overload(get_all_weapons_of_group_type, get_all_weapons_of_group_type_string);
ns["get_all_weapon_components"] = sol::overload(get_all_weapon_components, get_all_weapon_components_string); ns["get_all_weapon_components"] = sol::overload(get_all_weapon_components, get_all_weapon_components_string);
ns["get_weapon_component_display_name"] = sol::overload(get_weapon_component_display_name, get_weapon_component_display_name_string); ns["get_weapon_component_display_name"] = sol::overload(get_weapon_component_display_name, get_weapon_component_display_name_string);
ns["get_weapon_component_display_desc"] = sol::overload(get_weapon_component_display_desc, get_weapon_component_display_desc_string); ns["get_weapon_component_display_desc"] = sol::overload(get_weapon_component_display_desc, get_weapon_component_display_desc_string);
} }
} }

View File

@ -204,12 +204,13 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
auto hooking_instance = std::make_unique<hooking>(); auto hooking_instance = std::make_unique<hooking>();
LOG(INFO) << "Hooking initialized."; LOG(INFO) << "Hooking initialized.";
g_gta_data_service.init();
auto context_menu_service_instance = std::make_unique<context_menu_service>(); auto context_menu_service_instance = std::make_unique<context_menu_service>();
auto custom_text_service_instance = std::make_unique<custom_text_service>(); auto custom_text_service_instance = std::make_unique<custom_text_service>();
auto mobile_service_instance = std::make_unique<mobile_service>(); auto mobile_service_instance = std::make_unique<mobile_service>();
auto pickup_service_instance = std::make_unique<pickup_service>(); auto pickup_service_instance = std::make_unique<pickup_service>();
auto player_service_instance = std::make_unique<player_service>(); auto player_service_instance = std::make_unique<player_service>();
auto gta_data_service_instance = std::make_unique<gta_data_service>();
auto model_preview_service_instance = std::make_unique<model_preview_service>(); auto model_preview_service_instance = std::make_unique<model_preview_service>();
auto handling_service_instance = std::make_unique<handling_service>(); auto handling_service_instance = std::make_unique<handling_service>();
auto gui_service_instance = std::make_unique<gui_service>(); auto gui_service_instance = std::make_unique<gui_service>();
@ -224,8 +225,8 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
auto xml_maps_service_instance = std::make_unique<xml_map_service>(); auto xml_maps_service_instance = std::make_unique<xml_map_service>();
LOG(INFO) << "Registered service instances..."; LOG(INFO) << "Registered service instances...";
g_notification_service.initialise(); g_notification_service.initialise();
LOG(INFO) << "Finished initialising services."; LOG(INFO) << "Finished initialising services.";
g_script_mgr.add_script(std::make_unique<script>(&gui::script_func, "GUI", false)); g_script_mgr.add_script(std::make_unique<script>(&gui::script_func, "GUI", false));
@ -300,8 +301,6 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
LOG(INFO) << "Script Patcher Service reset."; LOG(INFO) << "Script Patcher Service reset.";
gui_service_instance.reset(); gui_service_instance.reset();
LOG(INFO) << "Gui Service reset."; LOG(INFO) << "Gui Service reset.";
gta_data_service_instance.reset();
LOG(INFO) << "GTA Data Service reset.";
handling_service_instance.reset(); handling_service_instance.reset();
LOG(INFO) << "Vehicle Service reset."; LOG(INFO) << "Vehicle Service reset.";
model_preview_service_instance.reset(); model_preview_service_instance.reset();

View File

@ -3,11 +3,11 @@
#include "backend/player_command.hpp" #include "backend/player_command.hpp"
#include "natives.hpp" #include "natives.hpp"
#include "services/gta_data/gta_data_service.hpp" #include "services/gta_data/gta_data_service.hpp"
#include "services/ped_animations/ped_animations_service.hpp"
#include "services/vehicle/persist_car_service.hpp" #include "services/vehicle/persist_car_service.hpp"
#include "util/entity.hpp" #include "util/entity.hpp"
#include "util/ped.hpp" #include "util/ped.hpp"
#include "util/teleport.hpp" #include "util/teleport.hpp"
#include "services/ped_animations/ped_animations_service.hpp"
namespace big namespace big
@ -62,8 +62,7 @@ namespace big
s_context_menu vehicle_menu{ContextEntityType::VEHICLE, s_context_menu vehicle_menu{ContextEntityType::VEHICLE,
0, 0,
{}, {},
{ {{"KILL ENGINE",
{"KILL ENGINE",
[this] { [this] {
if (entity::take_control_of(m_handle)) if (entity::take_control_of(m_handle))
{ {
@ -72,19 +71,19 @@ namespace big
} }
else else
g_notification_service.push_warning("TOXIC"_T.data(), "VEHICLE_FAILED_CONTROL"_T.data()); g_notification_service.push_warning("TOXIC"_T.data(), "VEHICLE_FAILED_CONTROL"_T.data());
}}, }},
{"FIX VEHICLE", {"FIX VEHICLE",
[this] { [this] {
if (entity::take_control_of(m_handle)) if (entity::take_control_of(m_handle))
{ {
VEHICLE::SET_VEHICLE_ENGINE_HEALTH(m_handle, 1000.f); VEHICLE::SET_VEHICLE_ENGINE_HEALTH(m_handle, 1000.f);
VEHICLE::SET_VEHICLE_FIXED(m_handle); VEHICLE::SET_VEHICLE_FIXED(m_handle);
VEHICLE::SET_VEHICLE_DEFORMATION_FIXED(m_handle); VEHICLE::SET_VEHICLE_DEFORMATION_FIXED(m_handle);
VEHICLE::SET_VEHICLE_DIRT_LEVEL(m_handle, 0.f); VEHICLE::SET_VEHICLE_DIRT_LEVEL(m_handle, 0.f);
} }
else else
g_notification_service.push_warning("WARNING"_T.data(), "VEHICLE_FAILED_CONTROL"_T.data()); g_notification_service.push_warning("WARNING"_T.data(), "VEHICLE_FAILED_CONTROL"_T.data());
}}, }},
{"BURST TIRES", {"BURST TIRES",
[this] { [this] {
if (entity::take_control_of(m_handle)) if (entity::take_control_of(m_handle))
@ -98,7 +97,7 @@ namespace big
} }
else else
g_notification_service.push_warning("TOXIC"_T.data(), "VEHICLE_FAILED_CONTROL"_T.data()); g_notification_service.push_warning("TOXIC"_T.data(), "VEHICLE_FAILED_CONTROL"_T.data());
}}, }},
{"HALT", {"HALT",
[this] { [this] {
if (entity::take_control_of(m_handle)) if (entity::take_control_of(m_handle))
@ -107,27 +106,27 @@ namespace big
} }
else else
g_notification_service.push_warning("TOXIC"_T.data(), "VEHICLE_FAILED_CONTROL"_T.data()); g_notification_service.push_warning("TOXIC"_T.data(), "VEHICLE_FAILED_CONTROL"_T.data());
}}, }},
{"COPY VEHICLE", {"COPY VEHICLE",
[this] { [this] {
Vehicle v = persist_car_service::clone_ped_car(PLAYER::PLAYER_PED_ID(), m_handle); Vehicle v = persist_car_service::clone_ped_car(PLAYER::PLAYER_PED_ID(), m_handle);
script::get_current()->yield(); script::get_current()->yield();
PED::SET_PED_INTO_VEHICLE(PLAYER::PLAYER_PED_ID(), v, -1); PED::SET_PED_INTO_VEHICLE(PLAYER::PLAYER_PED_ID(), v, -1);
}}, }},
{"BOOST", {"BOOST",
[this] { [this] {
if (entity::take_control_of(m_handle)) if (entity::take_control_of(m_handle))
VEHICLE::SET_VEHICLE_FORWARD_SPEED(m_handle, 79); VEHICLE::SET_VEHICLE_FORWARD_SPEED(m_handle, 79);
else else
g_notification_service.push_warning("TOXIC"_T.data(), "VEHICLE_FAILED_CONTROL"_T.data()); g_notification_service.push_warning("TOXIC"_T.data(), "VEHICLE_FAILED_CONTROL"_T.data());
}}, }},
{"LAUNCH", {"LAUNCH",
[this] { [this] {
if (entity::take_control_of(m_handle)) if (entity::take_control_of(m_handle))
ENTITY::APPLY_FORCE_TO_ENTITY(m_handle, 1, 0.f, 0.f, 50000.f, 0.f, 0.f, 0.f, 0, 0, 1, 1, 0, 1); ENTITY::APPLY_FORCE_TO_ENTITY(m_handle, 1, 0.f, 0.f, 50000.f, 0.f, 0.f, 0.f, 0, 0, 1, 1, 0, 1);
else else
g_notification_service.push_warning("TOXIC"_T.data(), "VEHICLE_FAILED_CONTROL"_T.data()); g_notification_service.push_warning("TOXIC"_T.data(), "VEHICLE_FAILED_CONTROL"_T.data());
}}, }},
{"EJECT", {"EJECT",
[this] { [this] {
if (ped::get_player_from_ped(VEHICLE::GET_PED_IN_VEHICLE_SEAT(m_handle, -1, 0)) != NULL) if (ped::get_player_from_ped(VEHICLE::GET_PED_IN_VEHICLE_SEAT(m_handle, -1, 0)) != NULL)
@ -138,37 +137,35 @@ namespace big
TASK::CLEAR_PED_TASKS_IMMEDIATELY(VEHICLE::GET_PED_IN_VEHICLE_SEAT(m_handle, -1, 0)); TASK::CLEAR_PED_TASKS_IMMEDIATELY(VEHICLE::GET_PED_IN_VEHICLE_SEAT(m_handle, -1, 0));
TASK::CLEAR_PED_TASKS_IMMEDIATELY(m_handle); TASK::CLEAR_PED_TASKS_IMMEDIATELY(m_handle);
}}, }},
{"TP INTO", [this] { {"TP INTO", [this] {
teleport::into_vehicle(m_handle); teleport::into_vehicle(m_handle);
}} }}}};
}};
s_context_menu ped_menu{ContextEntityType::PED, s_context_menu ped_menu{ContextEntityType::PED,
0, 0,
{}, {},
{ {{"DISARM",
{"DISARM",
[this] { [this] {
for (auto& [_, weapon] : g_gta_data_service->weapons()) for (auto& [_, weapon] : g_gta_data_service.weapons())
WEAPON::REMOVE_WEAPON_FROM_PED(m_handle, weapon.m_hash); WEAPON::REMOVE_WEAPON_FROM_PED(m_handle, weapon.m_hash);
}}, }},
{"KILL", {"KILL",
[this] { [this] {
ped::kill_ped(m_handle); ped::kill_ped(m_handle);
}}, }},
{"RAGDOLL", {"RAGDOLL",
[this] { [this] {
PED::SET_PED_TO_RAGDOLL(m_handle, 2000, 2000, 0, 0, 0, 0); PED::SET_PED_TO_RAGDOLL(m_handle, 2000, 2000, 0, 0, 0, 0);
}}, }},
{"ANIMATION", {"ANIMATION",
[this] { [this] {
// TODO: maybe inform the user of this behavior // TODO: maybe inform the user of this behavior
if(STREAMING::DOES_ANIM_DICT_EXIST(g_ped_animation_service.current_animation.dict.data())) if (STREAMING::DOES_ANIM_DICT_EXIST(g_ped_animation_service.current_animation.dict.data()))
g_ped_animation_service.play_saved_ped_animation(g_ped_animation_service.current_animation, m_handle); g_ped_animation_service.play_saved_ped_animation(g_ped_animation_service.current_animation, m_handle);
else else
ped::ped_play_animation(m_handle, "mini@strip_club@private_dance@part1", "priv_dance_p1", 3.5f, -4.0f, -1, 1); ped::ped_play_animation(m_handle, "mini@strip_club@private_dance@part1", "priv_dance_p1", 3.5f, -4.0f, -1, 1);
}}, }},
{"RECRUIT", [this] { {"RECRUIT", [this] {
TASK::CLEAR_PED_TASKS(m_handle); TASK::CLEAR_PED_TASKS(m_handle);
PED::SET_PED_AS_GROUP_MEMBER(m_handle, PED::GET_PED_GROUP_INDEX(self::ped)); PED::SET_PED_AS_GROUP_MEMBER(m_handle, PED::GET_PED_GROUP_INDEX(self::ped));
@ -186,63 +183,60 @@ namespace big
WEAPON::GIVE_WEAPON_TO_PED(m_handle, "weapon_microsmg"_J, 9999, false, false); WEAPON::GIVE_WEAPON_TO_PED(m_handle, "weapon_microsmg"_J, 9999, false, false);
WEAPON::GIVE_WEAPON_TO_PED(m_handle, "weapon_carbinerifle"_J, 9999, false, true); WEAPON::GIVE_WEAPON_TO_PED(m_handle, "weapon_carbinerifle"_J, 9999, false, true);
TASK::TASK_COMBAT_HATED_TARGETS_AROUND_PED(self::ped, 100, 67108864); TASK::TASK_COMBAT_HATED_TARGETS_AROUND_PED(self::ped, 100, 67108864);
}} }}}};
}};
s_context_menu object_menu{ContextEntityType::OBJECT, 0, {}, {}}; s_context_menu object_menu{ContextEntityType::OBJECT, 0, {}, {}};
s_context_menu player_menu{ContextEntityType::PLAYER, s_context_menu player_menu{ContextEntityType::PLAYER,
0, 0,
{}, {},
{ {{"SET SELECTED",
{"SET SELECTED",
[this] { [this] {
g_player_service->set_selected(ped::get_player_from_ped(m_handle)); g_player_service->set_selected(ped::get_player_from_ped(m_handle));
}}, }},
{"STEAL OUTFIT", {"STEAL OUTFIT",
[this] { [this] {
ped::steal_outfit(m_handle); ped::steal_outfit(m_handle);
}}, }},
{"KICK", {"KICK",
[this] { [this] {
static player_command* command = player_command::get("smartkick"_J); static player_command* command = player_command::get("smartkick"_J);
command->call(ped::get_player_from_ped(m_handle), {}); command->call(ped::get_player_from_ped(m_handle), {});
script::get_current()->yield(500ms); script::get_current()->yield(500ms);
}}, }},
{"DISARM", {"DISARM",
[this] { [this] {
static player_command* command = player_command::get("remweaps"_J); static player_command* command = player_command::get("remweaps"_J);
command->call(ped::get_player_from_ped(m_handle), {}); command->call(ped::get_player_from_ped(m_handle), {});
}}, }},
{"RAGDOLL", [this] { {"RAGDOLL", [this] {
static player_command* command = player_command::get("ragdoll"_J); static player_command* command = player_command::get("ragdoll"_J);
command->call(ped::get_player_from_ped(m_handle), {}); command->call(ped::get_player_from_ped(m_handle), {});
}} }}}};
}};
s_context_menu shared_menu{ContextEntityType::SHARED, s_context_menu shared_menu{ContextEntityType::SHARED,
0, 0,
{}, {},
{ {{"COPY HASH",
{"COPY HASH", [this] { [this] {
ImGui::SetClipboardText(std::format("0x{:08X}", (rage::joaat_t)m_pointer->m_model_info->m_hash).c_str()); ImGui::SetClipboardText(std::format("0x{:08X}", (rage::joaat_t)m_pointer->m_model_info->m_hash).c_str());
g_notification_service.push("Context Menu", g_notification_service.push("Context Menu",
std::format("Copy hash 0x{:08X}", (rage::joaat_t)m_pointer->m_model_info->m_hash).c_str()); std::format("Copy hash 0x{:08X}", (rage::joaat_t)m_pointer->m_model_info->m_hash).c_str());
}}, }},
{"EXPLODE", {"EXPLODE",
[this] { [this] {
rage::fvector3 pos = *m_pointer->m_navigation->get_position(); rage::fvector3 pos = *m_pointer->m_navigation->get_position();
FIRE::ADD_EXPLOSION(pos.x, pos.y, pos.z, 1, 1000, 1, 0, 1, 0); FIRE::ADD_EXPLOSION(pos.x, pos.y, pos.z, 1, 1000, 1, 0, 1, 0);
}}, }},
{"TP TO", {"TP TO",
[this] { [this] {
rage::fvector3 pos = *m_pointer->m_navigation->get_position(); rage::fvector3 pos = *m_pointer->m_navigation->get_position();
teleport::to_coords({pos.x, pos.y, pos.z}); teleport::to_coords({pos.x, pos.y, pos.z});
}}, }},
{"TP ON TOP", {"TP ON TOP",
[this] { [this] {
teleport::tp_on_top(m_handle, true); teleport::tp_on_top(m_handle, true);
}}, }},
{"BRING", {"BRING",
[this] { [this] {
rage::fvector3 pos = *g_local_player->m_navigation->get_position(); rage::fvector3 pos = *g_local_player->m_navigation->get_position();
@ -261,22 +255,20 @@ namespace big
ENTITY::SET_ENTITY_COORDS(m_handle, pos.x, pos.y, pos.z, false, false, false, false); ENTITY::SET_ENTITY_COORDS(m_handle, pos.x, pos.y, pos.z, false, false, false, false);
} }
} }
}}, }},
{"ENFLAME", {"ENFLAME",
[this] { [this] {
Vector3 pos = ENTITY::GET_ENTITY_COORDS(m_handle, TRUE); Vector3 pos = ENTITY::GET_ENTITY_COORDS(m_handle, TRUE);
FIRE::START_ENTITY_FIRE(m_handle); FIRE::START_ENTITY_FIRE(m_handle);
FIRE::START_SCRIPT_FIRE(pos.x, pos.y, pos.z, 25, TRUE); FIRE::START_SCRIPT_FIRE(pos.x, pos.y, pos.z, 25, TRUE);
FIRE::ADD_EXPLOSION(pos.x, pos.y, pos.z, eExplosionTag::MOLOTOV, 1, false, false, 0, false); FIRE::ADD_EXPLOSION(pos.x, pos.y, pos.z, eExplosionTag::MOLOTOV, 1, false, false, 0, false);
}}, }},
{"DELETE", {"DELETE", [this] {
[this] { if (entity::take_control_of(m_handle))
if (entity::take_control_of(m_handle)) {
{ entity::delete_entity(m_handle);
entity::delete_entity(m_handle); }
} }}}};
}}
}};
std::unordered_map<ContextEntityType, s_context_menu> options = {{ContextEntityType::VEHICLE, vehicle_menu}, {ContextEntityType::PLAYER, player_menu}, {ContextEntityType::PED, ped_menu}, {ContextEntityType::SHARED, shared_menu}, {ContextEntityType::OBJECT, object_menu}}; std::unordered_map<ContextEntityType, s_context_menu> options = {{ContextEntityType::VEHICLE, vehicle_menu}, {ContextEntityType::PLAYER, player_menu}, {ContextEntityType::PED, ped_menu}, {ContextEntityType::SHARED, shared_menu}, {ContextEntityType::OBJECT, object_menu}};
}; };

View File

@ -15,6 +15,7 @@ namespace big
class cache_file final class cache_file final
{ {
public: public:
cache_file() = default;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>

View File

@ -28,21 +28,21 @@ namespace big
} }
gta_data_service::gta_data_service() : gta_data_service::gta_data_service() :
m_peds_cache(g_file_manager.get_project_file("./cache/peds.bin"), 5),
m_vehicles_cache(g_file_manager.get_project_file("./cache/vehicles.bin"), 6),
m_update_state(eGtaDataUpdateState::IDLE) m_update_state(eGtaDataUpdateState::IDLE)
{ {
}
bool gta_data_service::init()
{
m_peds_cache = {g_file_manager.get_project_file("./cache/peds.bin"), 5};
m_vehicles_cache = {g_file_manager.get_project_file("./cache/vehicles.bin"), 6};
if (!is_cache_up_to_date()) if (!is_cache_up_to_date())
m_update_state = eGtaDataUpdateState::NEEDS_UPDATE; m_update_state = eGtaDataUpdateState::NEEDS_UPDATE;
else else
load_data(); load_data();
g_gta_data_service = this; return true;
}
gta_data_service::~gta_data_service()
{
g_gta_data_service = nullptr;
} }
bool gta_data_service::cache_needs_update() const bool gta_data_service::cache_needs_update() const
@ -171,6 +171,10 @@ namespace big
const auto ped_count = m_peds_cache.data_size() / sizeof(ped_item); const auto ped_count = m_peds_cache.data_size() / sizeof(ped_item);
LOG(INFO) << "Loading " << ped_count << " peds from cache."; LOG(INFO) << "Loading " << ped_count << " peds from cache.";
m_ped_types.clear();
m_ped_types.reserve(ped_count);
m_peds.clear();
auto cached_peds = reinterpret_cast<const ped_item*>(m_peds_cache.data()); auto cached_peds = reinterpret_cast<const ped_item*>(m_peds_cache.data());
for (size_t i = 0; i < ped_count; i++) for (size_t i = 0; i < ped_count; i++)
{ {
@ -189,6 +193,10 @@ namespace big
const auto vehicle_count = m_vehicles_cache.data_size() / sizeof(vehicle_item); const auto vehicle_count = m_vehicles_cache.data_size() / sizeof(vehicle_item);
LOG(INFO) << "Loading " << vehicle_count << " vehicles from cache."; LOG(INFO) << "Loading " << vehicle_count << " vehicles from cache.";
m_vehicle_classes.clear();
m_vehicle_classes.reserve(vehicle_count);
m_vehicles.clear();
auto cached_vehicles = reinterpret_cast<const vehicle_item*>(m_vehicles_cache.data()); auto cached_vehicles = reinterpret_cast<const vehicle_item*>(m_vehicles_cache.data());
for (size_t i = 0; i < vehicle_count; i++) for (size_t i = 0; i < vehicle_count; i++)
{ {
@ -207,6 +215,9 @@ namespace big
LOG(INFO) << "Loading " << m_weapons_cache.weapon_map.size() << " weapons from cache."; LOG(INFO) << "Loading " << m_weapons_cache.weapon_map.size() << " weapons from cache.";
LOG(INFO) << "Loading " << m_weapons_cache.weapon_components.size() << " weapon components from cache."; LOG(INFO) << "Loading " << m_weapons_cache.weapon_components.size() << " weapon components from cache.";
m_weapon_types.clear();
m_weapon_types.reserve(m_weapons_cache.weapon_map.size());
for (const auto& [_, weapon] : m_weapons_cache.weapon_map) for (const auto& [_, weapon] : m_weapons_cache.weapon_map)
{ {
add_if_not_exists(m_weapon_types, weapon.m_weapon_type); add_if_not_exists(m_weapon_types, weapon.m_weapon_type);

View File

@ -22,7 +22,9 @@ namespace big
{ {
public: public:
gta_data_service(); gta_data_service();
~gta_data_service(); ~gta_data_service() = default;
bool init();
bool cache_needs_update() const; bool cache_needs_update() const;
eGtaDataUpdateState state() const; eGtaDataUpdateState state() const;
@ -88,5 +90,5 @@ namespace big
static constexpr weapon_component empty_component{}; static constexpr weapon_component empty_component{};
}; };
inline gta_data_service* g_gta_data_service{}; inline gta_data_service g_gta_data_service{};
} }

View File

@ -1,7 +1,8 @@
#include "persist_weapons.hpp" #include "persist_weapons.hpp"
#include "services/gta_data/gta_data_service.hpp"
#include "gta/weapons.hpp" #include "gta/weapons.hpp"
#include "natives.hpp" #include "natives.hpp"
#include "services/gta_data/gta_data_service.hpp"
namespace big namespace big
{ {
@ -9,10 +10,10 @@ namespace big
void persist_weapons::save_weapons(std::string loadout_name) void persist_weapons::save_weapons(std::string loadout_name)
{ {
Player player = self::id; Player player = self::id;
Ped player_ped = self::ped; Ped player_ped = self::ped;
weaponloadout_json weapon_json{}; weaponloadout_json weapon_json{};
for (const auto& [name, weapon] : g_gta_data_service->weapons()) for (const auto& [name, weapon] : g_gta_data_service.weapons())
{ {
Hash weapon_hash = weapon.m_hash; Hash weapon_hash = weapon.m_hash;
if (weapon_hash != WEAPON_UNARMED && WEAPON::HAS_PED_GOT_WEAPON(player_ped, weapon_hash, FALSE)) if (weapon_hash != WEAPON_UNARMED && WEAPON::HAS_PED_GOT_WEAPON(player_ped, weapon_hash, FALSE))
@ -167,7 +168,7 @@ namespace big
if (weapon.group != GROUP_MELEE) if (weapon.group != GROUP_MELEE)
{ {
WEAPON::SET_PED_WEAPON_TINT_INDEX(player_ped, weapon_hash, weapon.tint); WEAPON::SET_PED_WEAPON_TINT_INDEX(player_ped, weapon_hash, weapon.tint);
for (auto component : g_gta_data_service->weapon_by_hash(weapon_hash).m_attachments) for (auto component : g_gta_data_service.weapon_by_hash(weapon_hash).m_attachments)
WEAPON::REMOVE_WEAPON_COMPONENT_FROM_PED(player_ped, weapon_hash, rage::joaat(component)); WEAPON::REMOVE_WEAPON_COMPONENT_FROM_PED(player_ped, weapon_hash, rage::joaat(component));
for (auto component : weapon.component_array) for (auto component : weapon.component_array)
WEAPON::GIVE_WEAPON_COMPONENT_TO_PED(player_ped, weapon_hash, component); WEAPON::GIVE_WEAPON_COMPONENT_TO_PED(player_ped, weapon_hash, component);

View File

@ -39,7 +39,7 @@ namespace big
void pickup_service::give_ammo(const int targets) const void pickup_service::give_ammo(const int targets) const
{ {
for (const auto& [_, weapon] : g_gta_data_service->weapons()) for (const auto& [_, weapon] : g_gta_data_service.weapons())
{ {
if (weapon.m_reward_ammo_hash != 0 || weapon.m_throwable) if (weapon.m_reward_ammo_hash != 0 || weapon.m_throwable)
{ {
@ -65,7 +65,7 @@ namespace big
void pickup_service::give_weapons(const int targets) const void pickup_service::give_weapons(const int targets) const
{ {
for (const auto& [_, weapon] : g_gta_data_service->weapons()) for (const auto& [_, weapon] : g_gta_data_service.weapons())
{ {
if (weapon.m_reward_hash != 0) if (weapon.m_reward_hash != 0)
{ {

View File

@ -246,7 +246,7 @@ namespace big
if (CVehicleModelInfo* vehicle_model_info = static_cast<CVehicleModelInfo*>(vehicle->m_model_info)) if (CVehicleModelInfo* vehicle_model_info = static_cast<CVehicleModelInfo*>(vehicle->m_model_info))
{ {
vehicle_name = g_gta_data_service->vehicles()[vehicle_model_info->m_name].m_display_name; // TODO vehicle_name = g_gta_data_service.vehicles()[vehicle_model_info->m_name].m_display_name; // TODO
} }
if (veh_damage_bits & (uint32_t)eEntityProofs::GOD) if (veh_damage_bits & (uint32_t)eEntityProofs::GOD)

View File

@ -103,7 +103,7 @@ namespace big
components::command_checkbox<"nosway">(); components::command_checkbox<"nosway">();
components::button("GET_ALL_WEAPONS"_T, [] { components::button("GET_ALL_WEAPONS"_T, [] {
for (const auto& [_, weapon] : g_gta_data_service->weapons()) for (const auto& [_, weapon] : g_gta_data_service.weapons())
{ {
WEAPON::GIVE_DELAYED_WEAPON_TO_PED(self::ped, weapon.m_hash, 9999, false); WEAPON::GIVE_DELAYED_WEAPON_TO_PED(self::ped, weapon.m_hash, 9999, false);
} }
@ -236,7 +236,7 @@ namespace big
if (ImGui::BeginCombo("GUI_TAB_WEAPONS"_T.data(), selected_weapon.c_str())) if (ImGui::BeginCombo("GUI_TAB_WEAPONS"_T.data(), selected_weapon.c_str()))
{ {
std::map<std::string, weapon_item> sorted_map; std::map<std::string, weapon_item> sorted_map;
for (const auto& [_, weapon] : g_gta_data_service->weapons()) for (const auto& [_, weapon] : g_gta_data_service.weapons())
{ {
sorted_map.emplace(weapon.m_display_name, weapon); sorted_map.emplace(weapon.m_display_name, weapon);
} }
@ -270,14 +270,14 @@ namespace big
ImGui::PushItemWidth(250); ImGui::PushItemWidth(250);
if (ImGui::BeginCombo("VIEW_WEAPON_ATTACHMENTS"_T.data(), selected_weapon_attachment.c_str())) if (ImGui::BeginCombo("VIEW_WEAPON_ATTACHMENTS"_T.data(), selected_weapon_attachment.c_str()))
{ {
weapon_item weapon = g_gta_data_service->weapon_by_hash(selected_weapon_hash); weapon_item weapon = g_gta_data_service.weapon_by_hash(selected_weapon_hash);
if (!weapon.m_attachments.empty()) if (!weapon.m_attachments.empty())
{ {
for (std::string attachment : weapon.m_attachments) for (std::string attachment : weapon.m_attachments)
{ {
weapon_component attachment_component = g_gta_data_service->weapon_component_by_name(attachment); weapon_component attachment_component = g_gta_data_service.weapon_component_by_name(attachment);
std::string attachment_name = attachment_component.m_display_name; std::string attachment_name = attachment_component.m_display_name;
Hash attachment_hash = attachment_component.m_hash; Hash attachment_hash = attachment_component.m_hash;
if (attachment_hash == NULL) if (attachment_hash == NULL)
{ {
attachment_name = attachment; attachment_name = attachment;
@ -389,16 +389,16 @@ namespace big
for (auto& weapon_hash : g.weapons.weapon_hotkeys[selected_key]) for (auto& weapon_hash : g.weapons.weapon_hotkeys[selected_key])
{ {
ImGui::PushID(counter); ImGui::PushID(counter);
weapon_item weapon = g_gta_data_service->weapon_by_hash(weapon_hash); weapon_item weapon = g_gta_data_service.weapon_by_hash(weapon_hash);
ImGui::PushItemWidth(300); ImGui::PushItemWidth(300);
if (ImGui::BeginCombo("GUI_TAB_WEAPONS"_T.data(), weapon.m_display_name.c_str())) if (ImGui::BeginCombo("GUI_TAB_WEAPONS"_T.data(), weapon.m_display_name.c_str()))
{ {
std::map<std::string, weapon_item> sorted_map; std::map<std::string, weapon_item> sorted_map;
for (const auto& [_, weapon_iter] : g_gta_data_service->weapons()) for (const auto& [_, weapon_iter] : g_gta_data_service.weapons())
{ {
sorted_map.emplace(weapon_iter.m_display_name, weapon_iter); sorted_map.emplace(weapon_iter.m_display_name, weapon_iter);
} }
for (const auto& [_, weapon_iter] : g_gta_data_service->weapons()) for (const auto& [_, weapon_iter] : g_gta_data_service.weapons())
{ {
if (weapon_iter.m_display_name == "NULL") if (weapon_iter.m_display_name == "NULL")
{ {

View File

@ -5,17 +5,18 @@ namespace big
{ {
void view::gta_cache() void view::gta_cache()
{ {
auto ped_count = g_gta_data_service->peds().size(); auto ped_count = g_gta_data_service.peds().size();
auto veh_count = g_gta_data_service->vehicles().size(); auto veh_count = g_gta_data_service.vehicles().size();
auto wep_count = g_gta_data_service->weapons().size(); auto wep_count = g_gta_data_service.weapons().size();
auto wep_comp_count = g_gta_data_service->weapon_components().size(); auto wep_comp_count = g_gta_data_service.weapon_components().size();
ImGui::Text(std::format("{}: {}\n{}: {}\n{}: {}\n{}: {}", "VIEW_GTA_CACHE_PEDS_CACHED"_T, ped_count, "VIEW_GTA_CACHE_VEHICLES_CACHED"_T, veh_count, "VIEW_GTA_CACHE_WEAPONS_CACHED"_T, wep_count, "VIEW_GTA_CACHE_WEAPON_COMPONENTS_CACHED"_T, wep_comp_count).c_str()); ImGui::Text(std::format("{}: {}\n{}: {}\n{}: {}\n{}: {}", "VIEW_GTA_CACHE_PEDS_CACHED"_T, ped_count, "VIEW_GTA_CACHE_VEHICLES_CACHED"_T, veh_count, "VIEW_GTA_CACHE_WEAPONS_CACHED"_T, wep_count, "VIEW_GTA_CACHE_WEAPON_COMPONENTS_CACHED"_T, wep_comp_count)
.c_str());
if (components::button("VIEW_GTA_CACHE_REBUILD_CACHE"_T)) if (components::button("VIEW_GTA_CACHE_REBUILD_CACHE"_T))
{ {
g_gta_data_service->set_state(eGtaDataUpdateState::NEEDS_UPDATE); g_gta_data_service.set_state(eGtaDataUpdateState::NEEDS_UPDATE);
g_gta_data_service->update_now(); g_gta_data_service.update_now();
} }
} }
} }

View File

@ -55,7 +55,7 @@ namespace big
static int selected_class = -1; static int selected_class = -1;
const auto& class_arr = g_gta_data_service->vehicle_classes(); const auto& class_arr = g_gta_data_service.vehicle_classes();
ImGui::SetNextItemWidth(300.f); ImGui::SetNextItemWidth(300.f);
if (ImGui::BeginCombo("VEHICLE_CLASS"_T.data(), if (ImGui::BeginCombo("VEHICLE_CLASS"_T.data(),
@ -125,7 +125,7 @@ namespace big
{ {
const auto& label = it.first; const auto& label = it.first;
const auto& personal_veh = it.second; const auto& personal_veh = it.second;
const auto& item = g_gta_data_service->vehicle_by_hash(personal_veh->get_hash()); const auto& item = g_gta_data_service.vehicle_by_hash(personal_veh->get_hash());
std::string vehicle_class = item.m_vehicle_class; std::string vehicle_class = item.m_vehicle_class;
std::string display_name = label; std::string display_name = label;

View File

@ -32,7 +32,7 @@ namespace big
}); });
static int selected_class = -1; static int selected_class = -1;
const auto& class_arr = g_gta_data_service->vehicle_classes(); const auto& class_arr = g_gta_data_service.vehicle_classes();
ImGui::SetNextItemWidth(300.f); ImGui::SetNextItemWidth(300.f);
if (ImGui::BeginCombo("VEHICLE_CLASS"_T.data(), if (ImGui::BeginCombo("VEHICLE_CLASS"_T.data(),
@ -66,9 +66,9 @@ namespace big
vehicle_map calculated_map{}; vehicle_map calculated_map{};
if (g_gta_data_service->vehicles().size() > 0) if (g_gta_data_service.vehicles().size() > 0)
{ {
for (auto& item : g_gta_data_service->vehicles()) for (auto& item : g_gta_data_service.vehicles())
{ {
const auto& vehicle = item.second; const auto& vehicle = item.second;
@ -82,15 +82,16 @@ namespace big
std::string lower_search = search; std::string lower_search = search;
std::transform(lower_search.begin(), lower_search.end(), lower_search.begin(), tolower); std::transform(lower_search.begin(), lower_search.end(), lower_search.begin(), tolower);
if ((selected_class == -1 || class_arr[selected_class] == clazz) && (display_name.find(lower_search) != std::string::npos || display_manufacturer.find(lower_search) != std::string::npos)) if ((selected_class == -1 || class_arr[selected_class] == clazz)
&& (display_name.find(lower_search) != std::string::npos || display_manufacturer.find(lower_search) != std::string::npos))
{ {
calculated_map.emplace(item); calculated_map.emplace(item);
} }
} }
} }
static const auto over_30 = (30 * ImGui::GetTextLineHeightWithSpacing() + 2); static const auto over_30 = (30 * ImGui::GetTextLineHeightWithSpacing() + 2);
auto calculated_size = calculated_map.size(); auto calculated_size = calculated_map.size();
if (calculated_map.size() == 0) if (calculated_map.size() == 0)
{ {
calculated_size++; calculated_size++;
@ -112,7 +113,7 @@ namespace big
if (veh_hash) if (veh_hash)
{ {
const auto& item = g_gta_data_service->vehicle_by_hash(veh_hash); const auto& item = g_gta_data_service.vehicle_by_hash(veh_hash);
components::selectable(std::vformat("SPAWN_VEHICLE_CURRENT_VEHICLE"_T, std::make_format_args(item.m_display_name)), false, [] { components::selectable(std::vformat("SPAWN_VEHICLE_CURRENT_VEHICLE"_T, std::make_format_args(item.m_display_name)), false, [] {
if (self::veh) if (self::veh)
@ -166,8 +167,7 @@ namespace big
const auto& vehicle = item.second; const auto& vehicle = item.second;
ImGui::PushID(vehicle.m_hash); ImGui::PushID(vehicle.m_hash);
components::selectable(vehicle.m_display_name, false, [&vehicle] { components::selectable(vehicle.m_display_name, false, [&vehicle] {
const auto spawn_location = const auto spawn_location = vehicle::get_spawn_location(g.spawn_vehicle.spawn_inside, vehicle.m_hash);
vehicle::get_spawn_location(g.spawn_vehicle.spawn_inside, vehicle.m_hash);
const auto spawn_heading = ENTITY::GET_ENTITY_HEADING(self::ped); const auto spawn_heading = ENTITY::GET_ENTITY_HEADING(self::ped);
auto veh = vehicle::spawn(vehicle.m_hash, spawn_location, spawn_heading); auto veh = vehicle::spawn(vehicle.m_hash, spawn_location, spawn_heading);

View File

@ -6,10 +6,10 @@ namespace big
{ {
void view::gta_data() void view::gta_data()
{ {
if (!g_gta_data_service || !g.settings.onboarding_complete) if (!g.settings.onboarding_complete)
return; return;
if (g_gta_data_service->cache_needs_update()) if (g_gta_data_service.cache_needs_update())
{ {
g_gui->toggle(true); g_gui->toggle(true);
ImGui::OpenPopup("GAME_CACHE"_T.data()); ImGui::OpenPopup("GAME_CACHE"_T.data());
@ -19,7 +19,7 @@ namespace big
ImGui::SetNextWindowPos({200, 200}, ImGuiCond_FirstUseEver); ImGui::SetNextWindowPos({200, 200}, ImGuiCond_FirstUseEver);
if (ImGui::BeginPopupModal("GAME_CACHE"_T.data())) if (ImGui::BeginPopupModal("GAME_CACHE"_T.data()))
{ {
switch (g_gta_data_service->state()) switch (g_gta_data_service.state())
{ {
case eGtaDataUpdateState::NEEDS_UPDATE: case eGtaDataUpdateState::NEEDS_UPDATE:
{ {
@ -27,7 +27,7 @@ namespace big
if (ImGui::Button("GAME_CACHE_UPDATE_CACHE"_T.data())) if (ImGui::Button("GAME_CACHE_UPDATE_CACHE"_T.data()))
{ {
g_gta_data_service->update_now(); g_gta_data_service.update_now();
} }
break; break;

View File

@ -28,8 +28,8 @@ namespace big
return; return;
} }
const auto& weapon_type_arr = g_gta_data_service->weapon_types(); const auto& weapon_type_arr = g_gta_data_service.weapon_types();
for (auto& [_, weapon] : g_gta_data_service->weapons()) for (auto& [_, weapon] : g_gta_data_service.weapons())
{ {
if (selected_ped_weapon_type == SPAWN_PED_ALL_WEAPONS || weapon.m_weapon_type == weapon_type_arr[selected_ped_weapon_type]) if (selected_ped_weapon_type == SPAWN_PED_ALL_WEAPONS || weapon.m_weapon_type == weapon_type_arr[selected_ped_weapon_type])
{ {
@ -194,11 +194,11 @@ namespace big
static char ped_model_buf[64]; static char ped_model_buf[64];
static Player selected_ped_player_id = -1; static Player selected_ped_player_id = -1;
auto& ped_type_arr = g_gta_data_service->ped_types(); auto& ped_type_arr = g_gta_data_service.ped_types();
auto& ped_arr = g_gta_data_service->peds(); auto& ped_arr = g_gta_data_service.peds();
auto& weapon_type_arr = g_gta_data_service->weapon_types(); auto& weapon_type_arr = g_gta_data_service.weapon_types();
auto& weapon_arr = g_gta_data_service->weapons(); auto& weapon_arr = g_gta_data_service.weapons();
static Player selected_ped_for_player_id = -1; static Player selected_ped_for_player_id = -1;
auto& player_arr = g_player_service->players(); auto& player_arr = g_player_service->players();
@ -489,7 +489,7 @@ namespace big
"NO_WEAPONS"_T.data() : "NO_WEAPONS"_T.data() :
selected_ped_weapon_hash == 0 ? selected_ped_weapon_hash == 0 ?
"ALL"_T.data() : "ALL"_T.data() :
g_gta_data_service->weapon_by_hash(selected_ped_weapon_hash).m_display_name.c_str())) g_gta_data_service.weapon_by_hash(selected_ped_weapon_hash).m_display_name.c_str()))
{ {
if (selected_ped_weapon_type != SPAWN_PED_NO_WEAPONS) if (selected_ped_weapon_type != SPAWN_PED_NO_WEAPONS)
{ {

View File

@ -9,13 +9,19 @@ namespace big
void view::squad_spawner() void view::squad_spawner()
{ {
const char* const spawn_distance_modes[5]{"CUSTOM"_T.data(), "VIEW_SQUAD_SPAWNER_ON_TARGET"_T.data(), "VIEW_SQUAD_SPAWNER_NEARBY"_T.data(), "VIEW_SQUAD_SPAWNER_MODERATELY_DISTANCED"_T.data(), "VIEW_SQUAD_SPAWNER_FAR_AWAY"_T.data()}; const char* const spawn_distance_modes[5]{"CUSTOM"_T.data(),
const char* const combat_ability_levels[3]{"VIEW_SQUAD_SPAWNER_POOR"_T.data(), "VIEW_SQUAD_SPAWNER_AVERAGE"_T.data(), "VIEW_SQUAD_SPAWNER_PROFESSIONAL"_T.data()}; "VIEW_SQUAD_SPAWNER_ON_TARGET"_T.data(),
"VIEW_SQUAD_SPAWNER_NEARBY"_T.data(),
"VIEW_SQUAD_SPAWNER_MODERATELY_DISTANCED"_T.data(),
"VIEW_SQUAD_SPAWNER_FAR_AWAY"_T.data()};
const char* const combat_ability_levels[3]{"VIEW_SQUAD_SPAWNER_POOR"_T.data(),
"VIEW_SQUAD_SPAWNER_AVERAGE"_T.data(),
"VIEW_SQUAD_SPAWNER_PROFESSIONAL"_T.data()};
static squad new_template{}; static squad new_template{};
static player_ptr victim = g_player_service->get_selected(); static player_ptr victim = g_player_service->get_selected();
ImGui::SeparatorText("VIEW_SQUAD_SPAWNER_VICTIM"_T.data()); ImGui::SeparatorText("VIEW_SQUAD_SPAWNER_VICTIM"_T.data());
ImGui::SetNextItemWidth(200); ImGui::SetNextItemWidth(200);
if (ImGui::BeginCombo("##victim", victim->get_name())) if (ImGui::BeginCombo("##victim", victim->get_name()))
@ -102,7 +108,7 @@ namespace big
} }
ImGui::EndCombo(); ImGui::EndCombo();
} }
if(ImGui::IsItemHovered()) if (ImGui::IsItemHovered())
ImGui::SetTooltip("VIEW_SELF_ANIMATIONS_DOUBLE_SHIFT_CLICK_TO_DELETE"_T.data()); ImGui::SetTooltip("VIEW_SELF_ANIMATIONS_DOUBLE_SHIFT_CLICK_TO_DELETE"_T.data());
ImGui::SeparatorText("VIEW_SQUAD_SPAWNER_SQUAD_DETAILS"_T.data()); ImGui::SeparatorText("VIEW_SQUAD_SPAWNER_SQUAD_DETAILS"_T.data());
@ -115,15 +121,15 @@ namespace big
components::input_text_with_hint("##name", "NAME"_T, new_template.m_name); components::input_text_with_hint("##name", "NAME"_T, new_template.m_name);
components::input_text_with_hint("##pedmodel", "PED_MODEL"_T, new_template.m_ped_model); components::input_text_with_hint("##pedmodel", "PED_MODEL"_T, new_template.m_ped_model);
auto ped_found = std::find_if(g_gta_data_service->peds().begin(), g_gta_data_service->peds().end(), [=](const auto& pair) { auto ped_found = std::find_if(g_gta_data_service.peds().begin(), g_gta_data_service.peds().end(), [=](const auto& pair) {
return pair.second.m_name == new_template.m_ped_model; return pair.second.m_name == new_template.m_ped_model;
}); });
if (!new_template.m_ped_model.empty() && ped_found == g_gta_data_service->peds().end()) if (!new_template.m_ped_model.empty() && ped_found == g_gta_data_service.peds().end())
{ {
if (ImGui::BeginListBox("##pedlist", ImVec2(250, 200))) if (ImGui::BeginListBox("##pedlist", ImVec2(250, 200)))
{ {
for (auto& p : g_gta_data_service->peds() | std::ranges::views::values) for (auto& p : g_gta_data_service.peds() | std::ranges::views::values)
{ {
std::string p_model = p.m_name; std::string p_model = p.m_name;
std::string filter = new_template.m_ped_model; std::string filter = new_template.m_ped_model;
@ -143,15 +149,15 @@ namespace big
if (ImGui::IsItemHovered()) if (ImGui::IsItemHovered())
ImGui::SetTooltip("VIEW_SQUAD_SPAWNER_VEHICLE_TOOLTIP"_T.data()); ImGui::SetTooltip("VIEW_SQUAD_SPAWNER_VEHICLE_TOOLTIP"_T.data());
auto veh_found = std::find_if(g_gta_data_service->vehicles().begin(), g_gta_data_service->vehicles().end(), [=](const auto& pair) { auto veh_found = std::find_if(g_gta_data_service.vehicles().begin(), g_gta_data_service.vehicles().end(), [=](const auto& pair) {
return pair.second.m_name == new_template.m_vehicle_model; return pair.second.m_name == new_template.m_vehicle_model;
}); });
if (!new_template.m_vehicle_model.empty() && veh_found == g_gta_data_service->vehicles().end()) if (!new_template.m_vehicle_model.empty() && veh_found == g_gta_data_service.vehicles().end())
{ {
if (ImGui::BeginListBox("##vehlist", ImVec2(250, 200))) if (ImGui::BeginListBox("##vehlist", ImVec2(250, 200)))
{ {
for (auto& p : g_gta_data_service->vehicles() | std::ranges::views::values) for (auto& p : g_gta_data_service.vehicles() | std::ranges::views::values)
{ {
std::string p_model = p.m_name; std::string p_model = p.m_name;
std::string filter = new_template.m_vehicle_model; std::string filter = new_template.m_vehicle_model;
@ -171,15 +177,15 @@ namespace big
if (ImGui::IsItemHovered()) if (ImGui::IsItemHovered())
ImGui::SetTooltip("VIEW_SQUAD_SPAWNER_WEAPON_MODEL_TOOLTIP"_T.data()); ImGui::SetTooltip("VIEW_SQUAD_SPAWNER_WEAPON_MODEL_TOOLTIP"_T.data());
auto weap_found = std::find_if(g_gta_data_service->weapons().begin(), g_gta_data_service->weapons().end(), [=](const auto& pair) { auto weap_found = std::find_if(g_gta_data_service.weapons().begin(), g_gta_data_service.weapons().end(), [=](const auto& pair) {
return pair.second.m_name == new_template.m_weapon_model; return pair.second.m_name == new_template.m_weapon_model;
}); });
if (!new_template.m_weapon_model.empty() && weap_found == g_gta_data_service->weapons().end()) if (!new_template.m_weapon_model.empty() && weap_found == g_gta_data_service.weapons().end())
{ {
if (ImGui::BeginListBox("##weaplist", ImVec2(250, 200))) if (ImGui::BeginListBox("##weaplist", ImVec2(250, 200)))
{ {
for (auto& p : g_gta_data_service->weapons() | std::ranges::views::values) for (auto& p : g_gta_data_service.weapons() | std::ranges::views::values)
{ {
std::string p_model = p.m_name; std::string p_model = p.m_name;
std::string filter = new_template.m_weapon_model; std::string filter = new_template.m_weapon_model;
@ -216,9 +222,11 @@ namespace big
ImGui::Text("VIEW_SQUAD_SPAWNER_ACTIONS"_T.data()); ImGui::Text("VIEW_SQUAD_SPAWNER_ACTIONS"_T.data());
ImGui::Spacing(); ImGui::Spacing();
components::button(std::format("{} {} {}", "SETTINGS_NOTIFY_GTA_THREADS_TERMINATE"_T, g_squad_spawner_service.m_active_squads.size(), "VIEW_SQUAD_SPAWNER_SQUADS"_T), [] { components::button(
g_squad_spawner_service.terminate_squads(); std::format("{} {} {}", "SETTINGS_NOTIFY_GTA_THREADS_TERMINATE"_T, g_squad_spawner_service.m_active_squads.size(), "VIEW_SQUAD_SPAWNER_SQUADS"_T),
}); [] {
g_squad_spawner_service.terminate_squads();
});
components::button("VIEW_SQUAD_RESET_FIELDS"_T, [] { components::button("VIEW_SQUAD_RESET_FIELDS"_T, [] {
new_template.m_spawn_distance_mode = eSquadSpawnDistance::CLOSEBY; new_template.m_spawn_distance_mode = eSquadSpawnDistance::CLOSEBY;
@ -312,7 +320,8 @@ namespace big
ImGui::Text("VIEW_SQUAD_SPAWN_PERSISTENT_VEHICLE"_T.data()); ImGui::Text("VIEW_SQUAD_SPAWN_PERSISTENT_VEHICLE"_T.data());
if (ImGui::BeginCombo("##persistent_vehicle", new_template.m_persistent_vehicle.data())) if (ImGui::BeginCombo("##persistent_vehicle", new_template.m_persistent_vehicle.data()))
{ {
if (ImGui::Selectable("VIEW_SQUAD_SPAWN_PERSISTENT_VEHICLE_NONE"_T.data(), new_template.m_persistent_vehicle == "VIEW_SQUAD_SPAWN_PERSISTENT_VEHICLE_NONE"_T.data())) if (ImGui::Selectable("VIEW_SQUAD_SPAWN_PERSISTENT_VEHICLE_NONE"_T.data(),
new_template.m_persistent_vehicle == "VIEW_SQUAD_SPAWN_PERSISTENT_VEHICLE_NONE"_T.data()))
new_template.m_persistent_vehicle = "VIEW_SQUAD_SPAWN_PERSISTENT_VEHICLE_NONE"_T.data(); new_template.m_persistent_vehicle = "VIEW_SQUAD_SPAWN_PERSISTENT_VEHICLE_NONE"_T.data();
for (auto& p : persist_car_service::list_files()) for (auto& p : persist_car_service::list_files())
{ {
@ -324,7 +333,9 @@ namespace big
ImGui::PopItemWidth(); ImGui::PopItemWidth();
ImGui::EndGroup(); ImGui::EndGroup();
components::input_text_with_hint("##new_template.m_description", "VIEW_SQUAD_SPAWN_DESCRIPTION"_T, new_template.m_description); components::input_text_with_hint("##new_template.m_description",
"VIEW_SQUAD_SPAWN_DESCRIPTION"_T,
new_template.m_description);
ImGui::TreePop(); ImGui::TreePop();
} }
@ -364,27 +375,27 @@ namespace big
{ {
if (check_validity(false)) if (check_validity(false))
g_squad_spawner_service.spawn_squad({new_template.m_name, g_squad_spawner_service.spawn_squad({new_template.m_name,
new_template.m_ped_model, new_template.m_ped_model,
new_template.m_weapon_model, new_template.m_weapon_model,
new_template.m_vehicle_model, new_template.m_vehicle_model,
new_template.m_squad_size, new_template.m_squad_size,
new_template.m_ped_invincibility, new_template.m_ped_invincibility,
new_template.m_veh_invincibility, new_template.m_veh_invincibility,
new_template.m_ped_proofs, new_template.m_ped_proofs,
new_template.m_ped_health, new_template.m_ped_health,
new_template.m_ped_armor, new_template.m_ped_armor,
new_template.m_spawn_distance, new_template.m_spawn_distance,
new_template.m_ped_accuracy, new_template.m_ped_accuracy,
new_template.m_spawn_distance_mode, new_template.m_spawn_distance_mode,
new_template.m_combat_ability_level, new_template.m_combat_ability_level,
new_template.m_stay_in_veh, new_template.m_stay_in_veh,
new_template.m_spawn_behind_same_velocity, new_template.m_spawn_behind_same_velocity,
new_template.m_description, new_template.m_description,
new_template.m_disperse, new_template.m_disperse,
new_template.m_spawn_ahead, new_template.m_spawn_ahead,
new_template.m_favour_roads, new_template.m_favour_roads,
new_template.m_max_vehicle, new_template.m_max_vehicle,
new_template.m_persistent_vehicle}, new_template.m_persistent_vehicle},
victim, victim,
new_template.m_spawn_distance_mode == eSquadSpawnDistance::CUSTOM, new_template.m_spawn_distance_mode == eSquadSpawnDistance::CUSTOM,
g_orbital_drone_service.m_ground_pos); g_orbital_drone_service.m_ground_pos);