Custom teleport added euler angles and added persist outfit (#1743)
* Addressed #1694: Added Euler angles to telelocation JSON object. * Added Persist Outfits to resolve #1669
This commit is contained in:
parent
d1a8022eb7
commit
1d78388519
@ -54,6 +54,7 @@ namespace big
|
||||
looped::self_police();
|
||||
looped::self_hud();
|
||||
looped::self_dance_mode();
|
||||
looped::self_persist_outfit();
|
||||
|
||||
script::get_current()->yield();
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ namespace big
|
||||
static void self_police();
|
||||
static void self_hud();
|
||||
static void self_dance_mode();
|
||||
static void self_persist_outfit();
|
||||
|
||||
static void session_pop_multiplier_areas();
|
||||
static void session_force_thunder();
|
||||
|
37
src/backend/looped/self/persist_outfit.cpp
Normal file
37
src/backend/looped/self/persist_outfit.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
#include "backend/looped/looped.hpp"
|
||||
#include "services/outfit/outfit_service.hpp"
|
||||
#include "natives.hpp"
|
||||
#include "file_manager.hpp"
|
||||
#include "logger/logger.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
void looped::self_persist_outfit()
|
||||
{
|
||||
if (g.self.persist_outfit.empty())
|
||||
return; //Off
|
||||
|
||||
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; //Dead or Loading
|
||||
|
||||
if (PED::GET_PED_DRAWABLE_VARIATION(self::ped, 5) == 0 && PED::GET_PED_DRAWABLE_VARIATION(self::ped, 4) >= 14 && PED::GET_PED_DRAWABLE_VARIATION(self::ped, 4) <= 18)
|
||||
return; //Showering
|
||||
|
||||
if (g.self.persist_outfits_mis && NETWORK::NETWORK_IS_ACTIVITY_SESSION())
|
||||
return; //Missioning it up
|
||||
|
||||
static nlohmann::json outfit{};
|
||||
static std::string persisting_outfit = "";
|
||||
|
||||
if (persisting_outfit != g.self.persist_outfit)
|
||||
{
|
||||
persisting_outfit = g.self.persist_outfit;
|
||||
folder saved_outfit_path = g_file_manager.get_project_folder("saved_outfits");
|
||||
std::ifstream i(saved_outfit_path.get_file(persisting_outfit).get_path());
|
||||
outfit.clear();
|
||||
i >> outfit;
|
||||
}
|
||||
|
||||
outfit_service::apply_outfit(outfit, false);
|
||||
}
|
||||
}
|
@ -299,41 +299,43 @@ namespace big
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(ipls, select)
|
||||
} ipls{};
|
||||
|
||||
bool clean_player = false;
|
||||
bool force_wanted_level = false;
|
||||
bool free_cam = false;
|
||||
bool invisibility = false;
|
||||
bool local_visibility = true;
|
||||
bool never_wanted = false;
|
||||
bool no_ragdoll = false;
|
||||
bool noclip = false;
|
||||
bool off_radar = false;
|
||||
bool ghost_org = false;
|
||||
bool super_run = false;
|
||||
bool no_collision = false;
|
||||
bool unlimited_oxygen = false;
|
||||
bool no_water_collision = false;
|
||||
int wanted_level = 0;
|
||||
bool god_mode = false;
|
||||
bool part_water = false;
|
||||
bool proof_bullet = false;
|
||||
bool proof_fire = false;
|
||||
bool proof_collision = false;
|
||||
bool proof_melee = false;
|
||||
bool proof_explosion = false;
|
||||
bool proof_steam = false;
|
||||
bool proof_drown = false;
|
||||
bool proof_water = false;
|
||||
uint32_t proof_mask = 0;
|
||||
bool mobile_radio = false;
|
||||
bool fast_respawn = false;
|
||||
bool auto_tp = false;
|
||||
bool super_jump = false;
|
||||
bool beast_jump = false;
|
||||
bool healthregen = false;
|
||||
float healthregenrate = 1.0f;
|
||||
bool superman = false;
|
||||
bool custom_weapon_stop = true;
|
||||
bool clean_player = false;
|
||||
bool force_wanted_level = false;
|
||||
bool free_cam = false;
|
||||
bool invisibility = false;
|
||||
bool local_visibility = true;
|
||||
bool never_wanted = false;
|
||||
bool no_ragdoll = false;
|
||||
bool noclip = false;
|
||||
bool off_radar = false;
|
||||
bool ghost_org = false;
|
||||
bool super_run = false;
|
||||
bool no_collision = false;
|
||||
bool unlimited_oxygen = false;
|
||||
bool no_water_collision = false;
|
||||
int wanted_level = 0;
|
||||
bool god_mode = false;
|
||||
bool part_water = false;
|
||||
bool proof_bullet = false;
|
||||
bool proof_fire = false;
|
||||
bool proof_collision = false;
|
||||
bool proof_melee = false;
|
||||
bool proof_explosion = false;
|
||||
bool proof_steam = false;
|
||||
bool proof_drown = false;
|
||||
bool proof_water = false;
|
||||
uint32_t proof_mask = 0;
|
||||
bool mobile_radio = false;
|
||||
bool fast_respawn = false;
|
||||
bool auto_tp = false;
|
||||
bool super_jump = false;
|
||||
bool beast_jump = false;
|
||||
bool healthregen = false;
|
||||
float healthregenrate = 1.0f;
|
||||
bool superman = false;
|
||||
bool custom_weapon_stop = true;
|
||||
std::string persist_outfit = "";
|
||||
bool persist_outfits_mis = false;
|
||||
struct hud
|
||||
{
|
||||
bool color_override = false;
|
||||
@ -353,7 +355,7 @@ namespace big
|
||||
// do not save below entries
|
||||
bool dance_mode = false;
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(self, ipls, ptfx_effects, clean_player, force_wanted_level, free_cam, invisibility, local_visibility, never_wanted, no_ragdoll, noclip, off_radar, super_run, no_collision, unlimited_oxygen, no_water_collision, wanted_level, god_mode, part_water, proof_bullet, proof_fire, proof_collision, proof_melee, proof_explosion, proof_steam, proof_drown, proof_water, proof_mask, mobile_radio, fast_respawn, auto_tp, super_jump, beast_jump, healthregen, healthregenrate, hud, superman, custom_weapon_stop)
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(self, ipls, ptfx_effects, clean_player, force_wanted_level, free_cam, invisibility, local_visibility, never_wanted, no_ragdoll, noclip, off_radar, super_run, no_collision, unlimited_oxygen, no_water_collision, wanted_level, god_mode, part_water, proof_bullet, proof_fire, proof_collision, proof_melee, proof_explosion, proof_steam, proof_drown, proof_water, proof_mask, mobile_radio, fast_respawn, auto_tp, super_jump, beast_jump, healthregen, healthregenrate, hud, superman, custom_weapon_stop, persist_outfit)
|
||||
} self{};
|
||||
|
||||
struct session
|
||||
|
@ -7,9 +7,10 @@ namespace big
|
||||
{
|
||||
std::string name;
|
||||
float x, y, z;
|
||||
float yaw = 0.0f, pitch = 0.0f, roll = 0.0f;
|
||||
};
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(telelocation, name, x, y, z);
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(telelocation, name, x, y, z, yaw, pitch, roll);
|
||||
|
||||
class custom_teleport_service
|
||||
{
|
||||
|
115
src/services/outfit/outfit_service.cpp
Normal file
115
src/services/outfit/outfit_service.cpp
Normal file
@ -0,0 +1,115 @@
|
||||
#include "util/outfit.hpp"
|
||||
#include "outfit_service.hpp"
|
||||
#include "natives.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
void outfit_service::apply_outfit(nlohmann::json j, bool set_parachute)
|
||||
{
|
||||
bool was_components_set = false;
|
||||
for (auto& item : j["components"].items())
|
||||
{
|
||||
std::stringstream ss(item.key());
|
||||
int id = 0;
|
||||
ss >> id;
|
||||
|
||||
if (!set_parachute && id == 5)
|
||||
continue;
|
||||
|
||||
int drawable_id = item.value()["drawable_id"];
|
||||
int texture_id = item.value()["texture_id"];
|
||||
if (PED::GET_PED_DRAWABLE_VARIATION(self::ped, id) != drawable_id || PED::GET_PED_TEXTURE_VARIATION(self::ped, id) != texture_id)
|
||||
{
|
||||
was_components_set = true;
|
||||
PED::SET_PED_COMPONENT_VARIATION(self::ped, id, drawable_id, texture_id, PED::GET_PED_PALETTE_VARIATION(self::ped, id));
|
||||
if (PED::GET_PED_DRAWABLE_VARIATION(self::ped, id) != drawable_id || PED::GET_PED_TEXTURE_VARIATION(self::ped, id) != texture_id) //Run it again Tony to make sure it actually changed.
|
||||
was_components_set = false;
|
||||
}
|
||||
}
|
||||
for (auto& item : j["props"].items())
|
||||
{
|
||||
std::stringstream ss(item.key());
|
||||
int id = 0;
|
||||
ss >> id;
|
||||
int drawable_id = item.value()["drawable_id"];
|
||||
int texture_id = item.value()["texture_id"];
|
||||
if (drawable_id == -1 && PED::GET_PED_PROP_INDEX(self::ped, id, 1) != -1)
|
||||
PED::CLEAR_PED_PROP(self::ped, id, 1);
|
||||
else if (PED::GET_PED_PROP_INDEX(self::ped, id, 1) != drawable_id || PED::GET_PED_PROP_TEXTURE_INDEX(self::ped, id) != texture_id)
|
||||
{
|
||||
was_components_set = true;
|
||||
PED::SET_PED_PROP_INDEX(self::ped, id, drawable_id, texture_id, NETWORK::NETWORK_IS_GAME_IN_PROGRESS(), 1);
|
||||
if (id == 0)
|
||||
{
|
||||
//Prevent player ped from taking helmet off.
|
||||
PED::SET_PED_HELMET_PROP_INDEX(self::ped, drawable_id, 0);
|
||||
PED::SET_PED_HELMET_TEXTURE_INDEX(self::ped, texture_id);
|
||||
PED::SET_PED_CONFIG_FLAG(self::ped, 34, true);
|
||||
if (!PED::IS_PED_ON_ANY_BIKE(self::ped))
|
||||
PED::SET_PED_CONFIG_FLAG(self::ped, 36, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (j.contains("blend_data") && was_components_set)
|
||||
{
|
||||
head_blend_data blend_data = j["blend_data"];
|
||||
PED::SET_PED_HEAD_BLEND_DATA(self::ped, blend_data.shape_first_id, blend_data.shape_second_id,
|
||||
blend_data.shape_third_id, blend_data.skin_first_id, blend_data.skin_second_id, blend_data.skin_third_id,
|
||||
blend_data.shape_mix, blend_data.skin_mix, blend_data.third_mix, blend_data.is_parent);
|
||||
}
|
||||
}
|
||||
void outfit_service::save_outfit(std::string filename)
|
||||
{
|
||||
outfit::components_t components;
|
||||
outfit::props_t props;
|
||||
|
||||
for (auto& item : components.items)
|
||||
{
|
||||
item.drawable_id = PED::GET_PED_DRAWABLE_VARIATION(self::ped, item.id);
|
||||
item.drawable_id_max = PED::GET_NUMBER_OF_PED_DRAWABLE_VARIATIONS(self::ped, item.id) - 1;
|
||||
|
||||
item.texture_id = PED::GET_PED_TEXTURE_VARIATION(self::ped, item.id);
|
||||
item.texture_id_max = PED::GET_NUMBER_OF_PED_TEXTURE_VARIATIONS(self::ped, item.id, item.drawable_id) - 1;
|
||||
}
|
||||
|
||||
for (auto& item : props.items)
|
||||
{
|
||||
item.drawable_id = PED::GET_PED_PROP_INDEX(self::ped, item.id, 1);
|
||||
item.drawable_id_max = PED::GET_NUMBER_OF_PED_PROP_DRAWABLE_VARIATIONS(self::ped, item.id) - 1;
|
||||
|
||||
item.texture_id = PED::GET_PED_PROP_TEXTURE_INDEX(self::ped, item.id);
|
||||
item.texture_id_max = PED::GET_NUMBER_OF_PED_PROP_TEXTURE_VARIATIONS(self::ped, item.id, item.drawable_id) - 1;
|
||||
}
|
||||
|
||||
nlohmann::json j;
|
||||
nlohmann::json j_components;
|
||||
nlohmann::json j_props;
|
||||
|
||||
for (auto& item : components.items)
|
||||
{
|
||||
nlohmann::json tmp;
|
||||
tmp["drawable_id"] = item.drawable_id;
|
||||
tmp["texture_id"] = item.texture_id;
|
||||
j_components[std::to_string(item.id)] = tmp;
|
||||
}
|
||||
|
||||
for (auto& item : props.items)
|
||||
{
|
||||
nlohmann::json tmp;
|
||||
tmp["drawable_id"] = item.drawable_id;
|
||||
tmp["texture_id"] = item.texture_id;
|
||||
j_props[std::to_string(item.id)] = tmp;
|
||||
}
|
||||
|
||||
head_blend_data blend_data{};
|
||||
PED::GET_PED_HEAD_BLEND_DATA(self::ped, (Any*)&blend_data);
|
||||
|
||||
j["components"] = j_components;
|
||||
j["props"] = j_props;
|
||||
j["blend_data"] = blend_data;
|
||||
|
||||
static folder saved_outfit_path = g_file_manager.get_project_folder("saved_outfits");
|
||||
std::ofstream o(saved_outfit_path.get_file(filename).get_path());
|
||||
o << std::setw(4) << j << std::endl;
|
||||
}
|
||||
}
|
30
src/services/outfit/outfit_service.hpp
Normal file
30
src/services/outfit/outfit_service.hpp
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
namespace big
|
||||
{
|
||||
|
||||
class outfit_service
|
||||
{
|
||||
public:
|
||||
struct head_blend_data
|
||||
{
|
||||
public:
|
||||
alignas(8) int shape_first_id = -1;
|
||||
alignas(8) int shape_second_id = -1;
|
||||
alignas(8) int shape_third_id = -1;
|
||||
alignas(8) int skin_first_id = -1;
|
||||
alignas(8) int skin_second_id = -1;
|
||||
alignas(8) int skin_third_id = -1;
|
||||
alignas(8) float shape_mix = FLT_MAX;
|
||||
alignas(8) float skin_mix = FLT_MAX;
|
||||
alignas(8) float third_mix = FLT_MAX;
|
||||
alignas(8) BOOL is_parent = FALSE;
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(head_blend_data, shape_first_id, shape_second_id, shape_third_id, skin_first_id, skin_second_id, skin_third_id, shape_mix, skin_mix, third_mix, is_parent);
|
||||
};
|
||||
static_assert(sizeof(head_blend_data) == 0x50, "head_blend_data is not sized properly.");
|
||||
|
||||
static void apply_outfit(nlohmann::json, bool);
|
||||
static void save_outfit(std::string);
|
||||
};
|
||||
}
|
@ -8,7 +8,7 @@
|
||||
|
||||
namespace big::teleport
|
||||
{
|
||||
inline bool teleport_player_to_coords(player_ptr player, Vector3 coords)
|
||||
inline bool teleport_player_to_coords(player_ptr player, Vector3 coords, Vector3 euler = {0, 0, 0})
|
||||
{
|
||||
Entity ent;
|
||||
|
||||
@ -17,7 +17,9 @@ namespace big::teleport
|
||||
else
|
||||
ent = PLAYER::PLAYER_PED_ID();
|
||||
|
||||
if (ent == self::ped || ent == self::veh)
|
||||
bool is_local_player = (ent == self::ped || ent == self::veh);
|
||||
|
||||
if (is_local_player)
|
||||
PED::SET_PED_COORDS_KEEP_VEHICLE(ent, coords.x, coords.y, coords.z);
|
||||
|
||||
if (ENTITY::IS_ENTITY_DEAD(ent, true))
|
||||
@ -31,9 +33,22 @@ namespace big::teleport
|
||||
ent = PED::GET_VEHICLE_PED_IS_IN(ent, false);
|
||||
|
||||
if (entity::take_control_of(ent))
|
||||
ENTITY::SET_ENTITY_COORDS(ent, coords.x, coords.y, coords.z, 0, 0, 0, 0);
|
||||
{
|
||||
ENTITY::SET_ENTITY_COORDS_NO_OFFSET(ent, coords.x, coords.y, coords.z, TRUE, TRUE, TRUE);
|
||||
if (euler.x + euler.y + euler.z != 0.0f)
|
||||
{
|
||||
ENTITY::SET_ENTITY_HEADING(ent, euler.x);
|
||||
if (is_local_player)
|
||||
{
|
||||
CAM::SET_GAMEPLAY_CAM_RELATIVE_PITCH(euler.y, 1.f);
|
||||
CAM::SET_GAMEPLAY_CAM_RELATIVE_HEADING(euler.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_notification_service->push_warning("TELEPORT"_T.data(), "TELEPORT_FAILED_TO_TAKE_CONTROL"_T.data());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -49,6 +64,13 @@ namespace big::teleport
|
||||
|
||||
g.m_remote_player_teleports.emplace(g_pointers->m_gta.m_handle_to_ptr(hnd)->m_net_object->m_object_id, remote_tp);
|
||||
|
||||
if (is_local_player)
|
||||
{
|
||||
ENTITY::SET_ENTITY_HEADING(ent, euler.x);
|
||||
CAM::SET_GAMEPLAY_CAM_RELATIVE_PITCH(euler.y, 1.f);
|
||||
CAM::SET_GAMEPLAY_CAM_RELATIVE_HEADING(euler.z);
|
||||
}
|
||||
|
||||
if ((player->is_valid() && PED::IS_PED_IN_ANY_VEHICLE(PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(player->id()), false))
|
||||
|| PLAYER::IS_REMOTE_PLAYER_IN_NON_CLONED_VEHICLE(player->id()))
|
||||
g_pointers->m_gta.m_clear_ped_tasks_network(player->get_ped(), true);
|
||||
|
@ -77,8 +77,21 @@ namespace big
|
||||
if (g_custom_teleport_service.get_saved_location_by_name(new_location_name))
|
||||
g_notification_service->push_warning("Custom Teleport", std::format("Location with the name {} already exists", new_location_name));
|
||||
else
|
||||
g_custom_teleport_service.save_new_location(category,
|
||||
{new_location_name, self::pos.x, self::pos.y, self::pos.z});
|
||||
{
|
||||
telelocation teleport_location;
|
||||
Entity teleport_entity = self::ped;
|
||||
if (self::veh != 0)
|
||||
teleport_entity = self::veh;
|
||||
auto coords = ENTITY::GET_ENTITY_COORDS(teleport_entity, TRUE);
|
||||
teleport_location.name = new_location_name;
|
||||
teleport_location.x = coords.x;
|
||||
teleport_location.y = coords.y;
|
||||
teleport_location.z = coords.z;
|
||||
teleport_location.yaw = ENTITY::GET_ENTITY_HEADING(teleport_entity);
|
||||
teleport_location.pitch = CAM::GET_GAMEPLAY_CAM_RELATIVE_PITCH();
|
||||
teleport_location.roll = CAM::GET_GAMEPLAY_CAM_RELATIVE_HEADING();
|
||||
g_custom_teleport_service.save_new_location(category, teleport_location);
|
||||
}
|
||||
});
|
||||
|
||||
ImGui::Separator();
|
||||
@ -130,7 +143,7 @@ namespace big
|
||||
if (ImGui::IsMouseDoubleClicked(0))
|
||||
{
|
||||
g_fiber_pool->queue_job([l] {
|
||||
teleport::teleport_player_to_coords(g_player_service->get_self(), {l.x, l.y, l.z});
|
||||
teleport::teleport_player_to_coords(g_player_service->get_self(), {l.x, l.y, l.z}, {l.yaw, l.pitch, l.roll});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "util/outfit.hpp"
|
||||
#include "util/ped.hpp"
|
||||
#include "views/view.hpp"
|
||||
#include "services/outfit/outfit_service.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
@ -85,7 +86,18 @@ namespace big
|
||||
if (drawable_id == -1)
|
||||
PED::CLEAR_PED_PROP(self::ped, id, 1);
|
||||
else
|
||||
{
|
||||
PED::SET_PED_PROP_INDEX(self::ped, id, drawable_id, texture_id, TRUE, 1);
|
||||
if (id == 0)
|
||||
{
|
||||
//Prevent ped from taking helmet off.
|
||||
PED::SET_PED_HELMET_PROP_INDEX(self::ped, drawable_id, 0);
|
||||
PED::SET_PED_HELMET_TEXTURE_INDEX(self::ped, texture_id);
|
||||
PED::SET_PED_CONFIG_FLAG(self::ped, 34, true);
|
||||
if (!PED::IS_PED_ON_ANY_BIKE(self::ped))
|
||||
PED::SET_PED_CONFIG_FLAG(self::ped, 36, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -173,36 +185,12 @@ namespace big
|
||||
ImGui::SameLine();
|
||||
|
||||
components::button("OUTFIT_SAVE_CURRENT"_T, [] {
|
||||
nlohmann::json j;
|
||||
nlohmann::json j_components;
|
||||
nlohmann::json j_props;
|
||||
|
||||
for (auto& item : components.items)
|
||||
{
|
||||
nlohmann::json tmp;
|
||||
tmp["drawable_id"] = item.drawable_id;
|
||||
tmp["texture_id"] = item.texture_id;
|
||||
j_components[std::to_string(item.id)] = tmp;
|
||||
}
|
||||
|
||||
for (auto& item : props.items)
|
||||
{
|
||||
nlohmann::json tmp;
|
||||
tmp["drawable_id"] = item.drawable_id;
|
||||
tmp["texture_id"] = item.texture_id;
|
||||
j_props[std::to_string(item.id)] = tmp;
|
||||
}
|
||||
|
||||
j["components"] = j_components;
|
||||
j["props"] = j_props;
|
||||
|
||||
size_t index = 0;
|
||||
std::string str = outfit_name;
|
||||
while (saved_outfit_path.get_file(str + ".json").exists())
|
||||
str = std::format("{}({})", outfit_name, ++index);
|
||||
|
||||
std::ofstream o(saved_outfit_path.get_file(str + ".json").get_path());
|
||||
o << std::setw(4) << j << std::endl;
|
||||
outfit_service::save_outfit(str + ".json");
|
||||
});
|
||||
ImGui::SameLine();
|
||||
|
||||
@ -213,28 +201,7 @@ namespace big
|
||||
nlohmann::json j;
|
||||
i >> j;
|
||||
|
||||
for (auto& item : j["components"].items())
|
||||
{
|
||||
std::stringstream ss(item.key());
|
||||
int id = 0;
|
||||
ss >> id;
|
||||
int drawable_id = item.value()["drawable_id"];
|
||||
int texture_id = item.value()["texture_id"];
|
||||
PED::SET_PED_COMPONENT_VARIATION(self::ped, id, drawable_id, texture_id, PED::GET_PED_PALETTE_VARIATION(self::ped, id));
|
||||
}
|
||||
|
||||
for (auto& item : j["props"].items())
|
||||
{
|
||||
std::stringstream ss(item.key());
|
||||
int id = 0;
|
||||
ss >> id;
|
||||
int drawable_id = item.value()["drawable_id"];
|
||||
int texture_id = item.value()["texture_id"];
|
||||
if (drawable_id == -1)
|
||||
PED::CLEAR_PED_PROP(self::ped, id, 1);
|
||||
else
|
||||
PED::SET_PED_PROP_INDEX(self::ped, id, drawable_id, texture_id, TRUE, 1);
|
||||
}
|
||||
outfit_service::apply_outfit(j, true);
|
||||
}
|
||||
});
|
||||
ImGui::SameLine();
|
||||
@ -255,5 +222,20 @@ namespace big
|
||||
selected_index = i;
|
||||
ImGui::EndListBox();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginGroup();
|
||||
if (ImGui::Button("Set Persist Outfit"))
|
||||
{
|
||||
g.self.persist_outfit = saved_outfits[selected_index];
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Clear Persist Outfit"))
|
||||
{
|
||||
g.self.persist_outfit.clear();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Disable During Missions?", &g.self.persist_outfits_mis);
|
||||
ImGui::Text(std::format("Current Persisted Outfit: {}", g.self.persist_outfit).c_str());
|
||||
ImGui::EndGroup();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user