Persist Weapons (#1647)
This commit is contained in:
@ -127,17 +127,17 @@ namespace big
|
||||
|
||||
const weapon_component& gta_data_service::weapon_component_by_hash(std::uint32_t hash)
|
||||
{
|
||||
for (const auto& component : m_weapons_cache.weapon_components)
|
||||
if (component.second.m_hash == hash)
|
||||
return component.second;
|
||||
for (const auto& [name, component] : m_weapons_cache.weapon_components)
|
||||
if (component.m_hash == hash)
|
||||
return component;
|
||||
return gta_data_service::empty_component;
|
||||
}
|
||||
|
||||
const weapon_component& gta_data_service::weapon_component_by_name(std::string name)
|
||||
{
|
||||
for (const auto& component : m_weapons_cache.weapon_components)
|
||||
if (component.first == name)
|
||||
return component.second;
|
||||
for (const auto& [name_key, component] : m_weapons_cache.weapon_components)
|
||||
if (name_key == name)
|
||||
return component;
|
||||
return gta_data_service::empty_component;
|
||||
}
|
||||
|
||||
|
196
src/services/persist_weapons/persist_weapons.cpp
Normal file
196
src/services/persist_weapons/persist_weapons.cpp
Normal file
@ -0,0 +1,196 @@
|
||||
#include "persist_weapons.hpp"
|
||||
#include "services/gta_data/gta_data_service.hpp"
|
||||
#include "gta/weapons.hpp"
|
||||
#include "natives.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
static weaponloadout_json persist_weapon_loadout;
|
||||
|
||||
void persist_weapons::save_weapons(std::string loadout_name)
|
||||
{
|
||||
Player player = self::id;
|
||||
Ped player_ped = self::ped;
|
||||
weaponloadout_json weapon_json{};
|
||||
for (const auto& [name, weapon] : g_gta_data_service->weapons())
|
||||
{
|
||||
Hash weapon_hash = weapon.m_hash;
|
||||
if (weapon_hash != WEAPON_UNARMED && WEAPON::HAS_PED_GOT_WEAPON(player_ped, weapon_hash, FALSE))
|
||||
{
|
||||
weaponloadout_weapon_json weapon_loadout;
|
||||
weapon_loadout.weapon = weapon_hash;
|
||||
weapon_loadout.group = rage::joaat("GROUP_" + weapon.m_weapon_type);
|
||||
weapon_loadout.tint = WEAPON::GET_PED_WEAPON_TINT_INDEX(player_ped, weapon_hash);
|
||||
for (auto component : weapon.m_attachments)
|
||||
{
|
||||
Hash component_hash = rage::joaat(component);
|
||||
if (WEAPON::HAS_PED_GOT_WEAPON_COMPONENT(player_ped, weapon_hash, component_hash))
|
||||
weapon_loadout.component_array.push_back(component_hash);
|
||||
}
|
||||
weapon_json.weapons.push_back(weapon_loadout);
|
||||
}
|
||||
}
|
||||
if (WEAPON::HAS_PED_GOT_WEAPON(player_ped, GADGET_PARACHUTE, FALSE))
|
||||
{
|
||||
weapon_json.parachutes = 1;
|
||||
int parachute_tint, parachute_pack_tint, reserve_pack_tint, smoke_trail[3]{};
|
||||
bool hasReserve = PLAYER::GET_PLAYER_HAS_RESERVE_PARACHUTE(player);
|
||||
PLAYER::GET_PLAYER_PARACHUTE_TINT_INDEX(player, ¶chute_tint);
|
||||
PLAYER::GET_PLAYER_PARACHUTE_PACK_TINT_INDEX(player, ¶chute_pack_tint);
|
||||
weapon_json.parachute_tint = parachute_tint;
|
||||
weapon_json.parachute_pack_tint = parachute_pack_tint;
|
||||
if (hasReserve == true)
|
||||
{
|
||||
weapon_json.parachutes = 2;
|
||||
PLAYER::GET_PLAYER_RESERVE_PARACHUTE_TINT_INDEX(player, &reserve_pack_tint);
|
||||
weapon_json.reserve_pack_tint = reserve_pack_tint;
|
||||
}
|
||||
PLAYER::GET_PLAYER_PARACHUTE_SMOKE_TRAIL_COLOR(player,
|
||||
&weapon_json.smoke_trail[0],
|
||||
&weapon_json.smoke_trail[1],
|
||||
&weapon_json.smoke_trail[2]);
|
||||
}
|
||||
|
||||
nlohmann::json json_output_file = weapon_json;
|
||||
const auto file = get_weapon_config_folder().get_file(loadout_name + ".json");
|
||||
std::ofstream file_stream(file.get_path(), std::ios::out | std::ios::trunc);
|
||||
file_stream << json_output_file.dump(4);
|
||||
file_stream.close();
|
||||
}
|
||||
|
||||
void persist_weapons::set_weapon_loadout(std::string loadout_name)
|
||||
{
|
||||
if (loadout_name.empty())
|
||||
return;
|
||||
|
||||
g.persist_weapons.weapon_loadout_file = loadout_name;
|
||||
persist_weapon_loadout = get_loadout(loadout_name);
|
||||
}
|
||||
|
||||
void persist_weapons::check_player_has_weapons()
|
||||
{
|
||||
if (!g.persist_weapons.enabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (persist_weapon_loadout.weapons.empty())
|
||||
{
|
||||
if (g.persist_weapons.weapon_loadout_file.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
persist_weapon_loadout = get_loadout(g.persist_weapons.weapon_loadout_file);
|
||||
}
|
||||
|
||||
if (g_local_player == nullptr || g_local_player->m_player_info == nullptr || g_local_player->m_player_info->m_game_state == eGameState::InMPCutscene || STREAMING::IS_PLAYER_SWITCH_IN_PROGRESS() || DLC::GET_IS_LOADING_SCREEN_ACTIVE())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
give_Loadout(persist_weapon_loadout);
|
||||
}
|
||||
|
||||
void persist_weapons::give_player_loadout(std::string loadout_name)
|
||||
{
|
||||
give_Loadout(get_loadout(loadout_name));
|
||||
}
|
||||
|
||||
weaponloadout_json persist_weapons::get_loadout(std::string loadout_name)
|
||||
{
|
||||
auto file = get_weapon_config_folder().get_file(loadout_name);
|
||||
|
||||
if (file.exists())
|
||||
{
|
||||
std::ifstream file_stream(file.get_path());
|
||||
try
|
||||
{
|
||||
nlohmann::json json_input_file;
|
||||
|
||||
file_stream >> json_input_file;
|
||||
file_stream.close();
|
||||
|
||||
weaponloadout_json loadout = json_input_file;
|
||||
return loadout;
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
g_notification_service->push_warning("Persist Weapons", "Failed to load JSON file from disk.");
|
||||
LOG(WARNING) << "Persist Weapons failed to load JSON file: " << g.persist_weapons.weapon_loadout_file << " because " << e.what();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g.persist_weapons.weapon_loadout_file.clear();
|
||||
LOG(WARNING) << "persist_weapons cannot open file" << g.persist_weapons.weapon_loadout_file;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
big::folder persist_weapons::get_weapon_config_folder()
|
||||
{
|
||||
const auto folder = g_file_manager.get_project_folder("./weapon_loadouts");
|
||||
|
||||
return folder;
|
||||
}
|
||||
|
||||
std::vector<std::string> persist_weapons::list_weapon_loadouts()
|
||||
{
|
||||
std::vector<std::string> file_paths;
|
||||
|
||||
const auto file_path = get_weapon_config_folder();
|
||||
for (const auto& directory_entry : std::filesystem::directory_iterator(file_path.get_path()))
|
||||
if (directory_entry.path().extension() == ".json")
|
||||
file_paths.push_back(directory_entry.path().filename().generic_string());
|
||||
|
||||
return file_paths;
|
||||
}
|
||||
|
||||
void persist_weapons::give_Loadout(const weaponloadout_json& loadout)
|
||||
{
|
||||
Player player = self::id;
|
||||
Ped player_ped = self::ped;
|
||||
if (PED::IS_PED_DEAD_OR_DYING(player_ped, true))
|
||||
return;
|
||||
|
||||
for (auto weapon : loadout.weapons)
|
||||
{
|
||||
Hash weapon_hash = weapon.weapon;
|
||||
bool is_gun = (weapon.group != GROUP_MELEE);
|
||||
if (WEAPON::HAS_PED_GOT_WEAPON(player_ped, weapon_hash, FALSE) == false
|
||||
|| (is_gun && (WEAPON::GET_PED_WEAPON_TINT_INDEX(player_ped, weapon_hash) != weapon.tint || (WEAPON::GET_AMMO_IN_PED_WEAPON(player_ped, weapon_hash) == 0))))
|
||||
{
|
||||
int maxAmmo;
|
||||
if (WEAPON::GET_MAX_AMMO(player_ped, weapon_hash, &maxAmmo) == FALSE)
|
||||
maxAmmo = 9999;
|
||||
WEAPON::GIVE_WEAPON_TO_PED(player_ped, weapon_hash, maxAmmo, FALSE, FALSE);
|
||||
if (weapon.group != GROUP_MELEE)
|
||||
{
|
||||
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)
|
||||
WEAPON::REMOVE_WEAPON_COMPONENT_FROM_PED(player_ped, weapon_hash, rage::joaat(component));
|
||||
for (auto component : weapon.component_array)
|
||||
WEAPON::GIVE_WEAPON_COMPONENT_TO_PED(player_ped, weapon_hash, component);
|
||||
WEAPON::GIVE_WEAPON_TO_PED(player_ped, weapon_hash, (WEAPON::GET_MAX_AMMO(player_ped, weapon_hash, &maxAmmo) == TRUE) ? maxAmmo : 9999, FALSE, FALSE); //Mk II weapons require giving the weapon to the player twice for them to work, because reasons.
|
||||
}
|
||||
}
|
||||
}
|
||||
if (loadout.parachutes != 0)
|
||||
{
|
||||
WEAPON::GIVE_WEAPON_TO_PED(player_ped, GADGET_PARACHUTE, 1, FALSE, FALSE);
|
||||
PLAYER::SET_PLAYER_PARACHUTE_TINT_INDEX(player, loadout.parachute_tint);
|
||||
PLAYER::SET_PLAYER_PARACHUTE_PACK_TINT_INDEX(player, loadout.parachute_pack_tint);
|
||||
if (loadout.parachutes == 2)
|
||||
{
|
||||
PLAYER::SET_PLAYER_HAS_RESERVE_PARACHUTE(player);
|
||||
PLAYER::SET_PLAYER_RESERVE_PARACHUTE_TINT_INDEX(player, loadout.reserve_pack_tint);
|
||||
}
|
||||
auto smoke_trail = loadout.smoke_trail;
|
||||
if ((smoke_trail[0] + smoke_trail[1] + smoke_trail[2]) != 765) //255 + 255 + 255
|
||||
{
|
||||
PLAYER::SET_PLAYER_CAN_LEAVE_PARACHUTE_SMOKE_TRAIL(player, TRUE);
|
||||
PLAYER::SET_PLAYER_PARACHUTE_SMOKE_TRAIL_COLOR(player, smoke_trail[0], smoke_trail[1], smoke_trail[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
20
src/services/persist_weapons/persist_weapons.hpp
Normal file
20
src/services/persist_weapons/persist_weapons.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "weaponloadout_json.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
class persist_weapons
|
||||
{
|
||||
public:
|
||||
static void save_weapons(std::string loadout_name);
|
||||
static void set_weapon_loadout(std::string loadout_name);
|
||||
static std::vector<std::string> list_weapon_loadouts();
|
||||
static void check_player_has_weapons();
|
||||
static void give_player_loadout(std::string loadout_name);
|
||||
private:
|
||||
static weaponloadout_json get_loadout(std::string loadout_name);
|
||||
static big::folder get_weapon_config_folder();
|
||||
static void give_Loadout(const weaponloadout_json& loadout);
|
||||
};
|
||||
}
|
27
src/services/persist_weapons/weaponloadout_json.hpp
Normal file
27
src/services/persist_weapons/weaponloadout_json.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
namespace big
|
||||
{
|
||||
struct weaponloadout_weapon_json
|
||||
{
|
||||
Hash weapon;
|
||||
Hash group;
|
||||
std::vector<Hash> component_array;
|
||||
int tint;
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(weaponloadout_weapon_json, weapon, group, component_array, tint)
|
||||
};
|
||||
|
||||
|
||||
struct weaponloadout_json
|
||||
{
|
||||
std::vector<weaponloadout_weapon_json> weapons;
|
||||
int parachutes;
|
||||
int parachute_tint;
|
||||
int parachute_pack_tint;
|
||||
int reserve_pack_tint;
|
||||
int smoke_trail[3];
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(weaponloadout_json, weapons, parachutes, parachute_tint, parachute_pack_tint, reserve_pack_tint, smoke_trail)
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user