add persist car (save / load json vehicles) (#366)

This commit is contained in:
Quentin E. / iDeath 2022-07-28 20:42:57 +02:00 committed by GitHub
parent 2d0079be69
commit 008d42ba9c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 664 additions and 1 deletions

View File

@ -0,0 +1,27 @@
#pragma once
#include "natives.hpp"
namespace big
{
struct model_attachment
{
Hash model_hash;
Vector3 position;
Vector3 rotation;
};
static void to_json(nlohmann::json& j, const model_attachment& attachment)
{
j = nlohmann::json{ {"model_hash", attachment.model_hash},
{"position_x", attachment.position.x}, {"position_y", attachment.position.y}, {"position_z", attachment.position.z},
{"rotation_x", attachment.rotation.x}, {"rotation_y", attachment.rotation.y}, {"rotation_z", attachment.rotation.z} };
}
static void from_json(const nlohmann::json& j, model_attachment& attachment)
{
j.at("model_hash").get_to(attachment.model_hash);
j.at("position_x").get_to(attachment.position.x); j.at("position_y").get_to(attachment.position.y); j.at("position_z").get_to(attachment.position.z);
j.at("rotation_x").get_to(attachment.rotation.x); j.at("rotation_y").get_to(attachment.rotation.y); j.at("rotation_z").get_to(attachment.rotation.z);
}
};

View File

@ -25,6 +25,7 @@ namespace big
SPAWN,
PV,
VEHICLE_FUN,
PERSIST_CAR,
SPOOFING,
TELEPORT,
VEHICLE,
@ -61,6 +62,7 @@ namespace big
{ tabs::SPAWN, { "Spawn", view::spawn }},
{ tabs::PV, { "Personal Vehicle", view::pv }},
{ tabs::VEHICLE_FUN, { "Fun Features", view::vehicle_fun }},
{ tabs::PERSIST_CAR, { "Persist Car", view::persist_car }},
}}},
{tabs::NETWORK, { "Network", nullptr, {
{ tabs::SPOOFING, { "Spoofing", view::spoofing }},

View File

@ -0,0 +1,466 @@
#include "persist_car_service.hpp"
#include "util/vehicle.hpp"
#include "pointers.hpp"
namespace big
{
void persist_car_service::save_vehicle(Vehicle vehicle, std::string_view file_name)
{
if (!ENTITY::DOES_ENTITY_EXIST(vehicle) ||
!ENTITY::IS_ENTITY_A_VEHICLE(vehicle))
{
g_notification_service->push_warning("Persist Car", "Tried to save a vehicle which does not exist");
return;
}
const auto file = check_vehicle_folder().get_file(file_name);
std::ofstream file_stream(file.get_path(), std::ios::out | std::ios::trunc);
file_stream << get_full_vehicle_json(vehicle).dump(4);
file_stream.close();
}
Vehicle persist_car_service::load_vehicle(std::string_view file_name)
{
const auto file = check_vehicle_folder().get_file(file_name);
std::ifstream file_stream(file.get_path());
nlohmann::json vehicle_json;
file_stream >> vehicle_json;
file_stream.close();
return spawn_vehicle_full(vehicle_json, self::ped);
}
std::vector<std::string> persist_car_service::list_files()
{
std::vector<std::string> file_paths;
const auto file_path = check_vehicle_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;
}
Vehicle persist_car_service::clone_ped_car(Ped ped, Vehicle vehicle)
{
return spawn_vehicle_full(get_full_vehicle_json(vehicle), ped);
}
Vehicle persist_car_service::spawn_vehicle_full(nlohmann::json vehicle_json, Ped ped)
{
const auto vehicle = spawn_vehicle(vehicle_json, ped);
if (!vehicle_json[tow_key].is_null())
{
const auto tow = spawn_vehicle(vehicle_json[tow_key], ped);
auto pos = ENTITY::GET_ENTITY_COORDS(tow, true);
pos.x -= 10;
ENTITY::SET_ENTITY_COORDS_NO_OFFSET(tow, pos.x, pos.y, 0.f, true, true, false);
VEHICLE::ATTACH_VEHICLE_TO_TOW_TRUCK(vehicle, tow, -1, 0.f, 0.5f, 0.f);
VEHICLE::SET_VEHICLE_TOW_TRUCK_ARM_POSITION(vehicle, 1.f);
const auto rotation = ENTITY::GET_ENTITY_ROTATION(tow, 2);
ENTITY::SET_ENTITY_ROTATION(tow, 0, 0, rotation.z, 2, true);
}
else if (!vehicle_json[trailer_key].is_null())
{
const auto trailer = spawn_vehicle(vehicle_json[trailer_key], ped);
VEHICLE::ATTACH_VEHICLE_TO_TRAILER(vehicle, trailer, 1.0f);
const auto rotation = ENTITY::GET_ENTITY_ROTATION(trailer, 2);
ENTITY::SET_ENTITY_ROTATION(trailer, 0, 0, rotation.z, 2, true);
}
const auto rotation = ENTITY::GET_ENTITY_ROTATION(vehicle, 2);
ENTITY::SET_ENTITY_ROTATION(vehicle, rotation.x, 0, rotation.z, 2, true);
return vehicle;
}
Vehicle persist_car_service::spawn_vehicle(nlohmann::json vehicle_json, Ped ped)
{
const auto vehicle = spawn_vehicle_json(vehicle_json, ped);
std::vector<nlohmann::json> model_attachments = vehicle_json[model_attachments_key];
for (const auto& j : model_attachments)
{
const auto attachment = j.get<model_attachment>();
STREAMING::REQUEST_MODEL(attachment.model_hash);
const auto object = OBJECT::CREATE_OBJECT(attachment.model_hash, 0, 0, 0, true, false, false);
ENTITY::ATTACH_ENTITY_TO_ENTITY(
object, vehicle,
0,
attachment.position.x, attachment.position.y, attachment.position.z,
attachment.rotation.x, attachment.rotation.y, attachment.rotation.z,
false, false, false, false, 0, true);
STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(attachment.model_hash);
}
std::vector<nlohmann::json> vehicle_attachments = vehicle_json[vehicle_attachments_key];
for (const auto& j : vehicle_attachments)
{
const auto vehicle_to_attach = spawn_vehicle_json(j[vehicle_key], ped);
auto attachment = j[model_attachment_key].get<big::model_attachment>();
ENTITY::ATTACH_ENTITY_TO_ENTITY(
vehicle_to_attach, vehicle,
0,
attachment.position.x, attachment.position.y, attachment.position.z,
attachment.rotation.x, attachment.rotation.y, attachment.rotation.z,
false, false, false, false, 0, true);
VEHICLE::SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(vehicle_to_attach, false);
}
return vehicle;
}
Vehicle persist_car_service::spawn_vehicle_json(nlohmann::json vehicle_json, Ped ped)
{
const Hash vehicle_hash = vehicle_json[vehicle_model_hash_key];
const auto pos = ENTITY::GET_ENTITY_COORDS(self::ped, true);
const auto vehicle = big::vehicle::spawn(vehicle_hash, pos, ENTITY::GET_ENTITY_HEADING(ped));
VEHICLE::SET_VEHICLE_DIRT_LEVEL(vehicle, 0.0f);
VEHICLE::SET_VEHICLE_MOD_KIT(vehicle, 0);
VEHICLE::SET_VEHICLE_TYRES_CAN_BURST(vehicle, false);
VEHICLE::SET_VEHICLE_COLOURS(vehicle, vehicle_json[primary_color_key], vehicle_json[secondary_color_key]);
if (!vehicle_json[custom_primary_color_key].is_null())
{
std::vector<int> primary_custom_color = vehicle_json[custom_primary_color_key];
VEHICLE::SET_VEHICLE_CUSTOM_PRIMARY_COLOUR(vehicle, primary_custom_color[0], primary_custom_color[1], primary_custom_color[2]);
}
if (!vehicle_json[custom_secondary_color_key].is_null())
{
std::vector<int> secondary_custom_color = vehicle_json[custom_secondary_color_key];
VEHICLE::SET_VEHICLE_CUSTOM_SECONDARY_COLOUR(vehicle, secondary_custom_color[0], secondary_custom_color[1], secondary_custom_color[2]);
}
VEHICLE::SET_VEHICLE_WINDOW_TINT(vehicle, vehicle_json[vehicle_window_tint_key]);
if (!vehicle_json[radio_station_key].is_null())
AUDIO::SET_VEH_RADIO_STATION(vehicle, vehicle_json[radio_station_key].get<std::string>().c_str());
VEHICLE::SET_VEHICLE_NUMBER_PLATE_TEXT(vehicle, vehicle_json[plate_text_key].get<std::string>().c_str());
VEHICLE::SET_VEHICLE_NUMBER_PLATE_TEXT_INDEX(vehicle, vehicle_json[plate_text_index_key]);
VEHICLE::SET_VEHICLE_EXTRA_COLOURS(vehicle, vehicle_json[pearlescent_color_key], vehicle_json[wheel_color_key]);
std::map<int, bool> vehicle_extras = vehicle_json[vehicle_extras_key];
for (int i = 0; i <= 20; i++)
{
if (VEHICLE::DOES_EXTRA_EXIST(vehicle, i))
VEHICLE::SET_VEHICLE_EXTRA(vehicle, i, vehicle_extras[i]);
}
if (!vehicle_json[vehicle_livery_key].is_null())
{
VEHICLE::SET_VEHICLE_LIVERY(vehicle, vehicle_json[vehicle_livery_key]);
}
if (VEHICLE::IS_THIS_MODEL_A_CAR(ENTITY::GET_ENTITY_MODEL(vehicle)) || VEHICLE::IS_THIS_MODEL_A_BIKE(ENTITY::GET_ENTITY_MODEL(vehicle)))
{
VEHICLE::SET_VEHICLE_WHEEL_TYPE(vehicle, vehicle_json[wheel_type_key]);
for (int i = MOD_SPOILERS; i <= MOD_LIGHTBAR; i++)
{
const bool has_mod = !vehicle_json[mod_names[i]].is_null();
if (has_mod)
{
if (i == MOD_TYRE_SMOKE)
{
std::vector<int> tire_smoke_color = vehicle_json[tire_smoke_color_key];
VEHICLE::SET_VEHICLE_TYRE_SMOKE_COLOR(vehicle, tire_smoke_color[0], tire_smoke_color[1], tire_smoke_color[2]);
VEHICLE::TOGGLE_VEHICLE_MOD(vehicle, MOD_TYRE_SMOKE, true);
}
else if (vehicle_json[mod_names[i]].is_array())
{
std::vector<int> mod = vehicle_json[mod_names[i]];
VEHICLE::SET_VEHICLE_MOD(vehicle, i, mod[0], mod[1]);
}
else
{
VEHICLE::TOGGLE_VEHICLE_MOD(vehicle, i, true);
}
}
}
std::vector<bool> neon_lights = vehicle_json[neon_lights_key];
for (int i = NEON_LEFT; i <= NEON_BACK; i++)
VEHICLE::SET_VEHICLE_NEON_LIGHT_ENABLED_(vehicle, i, neon_lights[i]);
std::vector<int> neon_color = vehicle_json[neon_color_key];
VEHICLE::SET_VEHICLE_NEON_LIGHTS_COLOUR_(vehicle, neon_color[0], neon_color[1], neon_color[2]);
if (VEHICLE::IS_VEHICLE_A_CONVERTIBLE(vehicle, 0))
{
int convertable_state = vehicle_json[convertable_state_key];
if (convertable_state == 0 || convertable_state == 3 || convertable_state == 5)
VEHICLE::RAISE_CONVERTIBLE_ROOF(vehicle, true);
else
VEHICLE::LOWER_CONVERTIBLE_ROOF(vehicle, true);
}
VEHICLE::SET_VEHICLE_INTERIOR_COLOR_(vehicle, vehicle_json[interior_color_key]);
VEHICLE::SET_VEHICLE_DASHBOARD_COLOR_(vehicle, vehicle_json[dash_color_key]);
const BOOL have_clan_logo = vehicle_json[clan_logo_key];
if (have_clan_logo)
vehicle_helper::add_clan_logo_to_vehicle(vehicle, ped);
VEHICLE::SET_VEHICLE_XENON_LIGHTS_COLOR_(vehicle, vehicle_json[headlight_color_key]);
}
return vehicle;
}
nlohmann::json persist_car_service::get_full_vehicle_json(Vehicle vehicle)
{
// The car needs to be rotated at (0, 0, 0) for the relative offset calculations to be accurate.
ENTITY::SET_ENTITY_ROTATION(vehicle, 0, 0, 0, 0, true);
script::get_current()->yield();
ENTITY::SET_ENTITY_ROTATION(vehicle, 0, 0, 0, 0, true);
nlohmann::json vehicle_json = get_vehicle_json(vehicle);
vehicle_json[model_attachments_key] = get_model_attachments(vehicle);
vehicle_json[vehicle_attachments_key] = get_vehicle_attachents(vehicle);
Vehicle tow = VEHICLE::GET_ENTITY_ATTACHED_TO_TOW_TRUCK(vehicle);
if (ENTITY::DOES_ENTITY_EXIST(tow))
{
vehicle_json[tow_key] = get_vehicle_json(tow);
vehicle_json[tow_key][model_attachments_key] = get_model_attachments(tow, true);
vehicle_json[tow_key][vehicle_attachments_key] = get_vehicle_attachents(tow);
}
if (VEHICLE::IS_VEHICLE_ATTACHED_TO_TRAILER(vehicle))
{
Vehicle trailer;
VEHICLE::GET_VEHICLE_TRAILER_VEHICLE(vehicle, &trailer);
vehicle_json[trailer_key] = get_vehicle_json(trailer);
vehicle_json[trailer_key][model_attachments_key] = get_model_attachments(trailer);
vehicle_json[trailer_key][vehicle_attachments_key] = get_vehicle_attachents(trailer);
}
return vehicle_json;
}
model_attachment persist_car_service::get_model_attachment(Vehicle vehicle, Object object)
{
const auto object_location = ENTITY::GET_ENTITY_COORDS(object, 0);
const auto location = ENTITY::GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(vehicle, object_location.x, object_location.y, object_location.z);
const auto object_rotation = ENTITY::GET_ENTITY_ROTATION(object, 0);
const auto vehicle_rotation = ENTITY::GET_ENTITY_ROTATION(vehicle, 0);
Vector3 rotation;
rotation.x = (object_rotation.x - vehicle_rotation.x);
rotation.y = (object_rotation.y - vehicle_rotation.y);
rotation.z = (object_rotation.z - vehicle_rotation.z);
model_attachment attachment = { ENTITY::GET_ENTITY_MODEL(object), location, rotation };
return attachment;
}
nlohmann::json persist_car_service::get_model_attachments(Vehicle vehicle, bool is_towed_vehicle)
{
const auto replay_interface = *g_pointers->m_replay_interface;
std::vector<nlohmann::json> attached_objects;
const auto object_interface = replay_interface->m_object_interface;
for (int i = 0; i < object_interface->m_max_objects; i++)
{
const auto object_ptr = object_interface->get_object(i);
if (!object_ptr)
continue;
const auto object = g_pointers->m_ptr_to_handle(object_ptr);
if (!object)
break;
if (!ENTITY::IS_ENTITY_ATTACHED_TO_ENTITY(vehicle, object))
continue;
// Don't save tow hook.
if (is_towed_vehicle && ENTITY::GET_ENTITY_MODEL(object) == 0xBC344305)
continue;
attached_objects.push_back(get_model_attachment(vehicle, object));
};
return attached_objects;
}
nlohmann::json persist_car_service::get_vehicle_attachents(Vehicle vehicle)
{
const auto replay_interface = *g_pointers->m_replay_interface;
const auto vehicle_interface = replay_interface->m_vehicle_interface;
std::vector<nlohmann::json> attached_vehicles;
Vehicle trailer;
VEHICLE::GET_VEHICLE_TRAILER_VEHICLE(vehicle, &trailer);
for (int i = 0; i < vehicle_interface->m_max_vehicles; i++)
{
const auto vehicle_ptr = vehicle_interface->get_vehicle(i);
if (!vehicle_ptr)
continue;
const auto object = g_pointers->m_ptr_to_handle(vehicle_ptr);
if (!object)
break;
if (!ENTITY::IS_ENTITY_ATTACHED_TO_ENTITY(vehicle, object))
continue;
if (object == VEHICLE::GET_ENTITY_ATTACHED_TO_TOW_TRUCK(vehicle) ||
VEHICLE::IS_VEHICLE_ATTACHED_TO_TOW_TRUCK(object, vehicle))
continue;
if (object == trailer ||
VEHICLE::IS_VEHICLE_ATTACHED_TO_TRAILER(object))
continue;
nlohmann::json model_attachment;
model_attachment[vehicle_key] = get_vehicle_json(object);
model_attachment[model_attachment_key] = get_model_attachment(vehicle, object);
attached_vehicles.push_back(model_attachment);
}
return attached_vehicles;
}
nlohmann::json persist_car_service::get_vehicle_json(Vehicle vehicle)
{
nlohmann::json vehicle_json;
vehicle_json[vehicle_model_hash_key] = ENTITY::GET_ENTITY_MODEL(vehicle);
int primary_color, secondary_color;
VEHICLE::GET_VEHICLE_COLOURS(vehicle, &primary_color, &secondary_color);
vehicle_json[primary_color_key] = primary_color;
vehicle_json[secondary_color_key] = secondary_color;
if (VEHICLE::GET_IS_VEHICLE_PRIMARY_COLOUR_CUSTOM(vehicle))
{
int custom_primary_color[3]{};
VEHICLE::GET_VEHICLE_CUSTOM_PRIMARY_COLOUR(vehicle, &custom_primary_color[0], &custom_primary_color[1], &custom_primary_color[2]);
vehicle_json[custom_primary_color_key] = custom_primary_color;
}
if (VEHICLE::GET_IS_VEHICLE_SECONDARY_COLOUR_CUSTOM(vehicle))
{
int custom_secondary_color[3]{};
VEHICLE::GET_VEHICLE_CUSTOM_SECONDARY_COLOUR(vehicle, &custom_secondary_color[0], &custom_secondary_color[1], &custom_secondary_color[2]);
vehicle_json[custom_secondary_color_key] = custom_secondary_color;
}
vehicle_json[vehicle_window_tint_key] = VEHICLE::GET_VEHICLE_WINDOW_TINT(vehicle);
auto radio_station = AUDIO::GET_PLAYER_RADIO_STATION_NAME();
if (!radio_station)
radio_station = "OFF";
vehicle_json[radio_station_key] = radio_station;
vehicle_json[plate_text_key] = VEHICLE::GET_VEHICLE_NUMBER_PLATE_TEXT(vehicle);
vehicle_json[plate_text_index_key] = VEHICLE::GET_VEHICLE_NUMBER_PLATE_TEXT_INDEX(vehicle);
int pearlescent_color, wheel_color;
VEHICLE::GET_VEHICLE_EXTRA_COLOURS(vehicle, &pearlescent_color, &wheel_color);
vehicle_json[pearlescent_color_key] = pearlescent_color;
vehicle_json[wheel_color_key] = wheel_color;
std::map<int, bool> vehicle_extras;
for (int i = 0; i <= 20; i++)
{
if (VEHICLE::DOES_EXTRA_EXIST(vehicle, i))
vehicle_extras[i] = !VEHICLE::IS_VEHICLE_EXTRA_TURNED_ON(vehicle, i);
}
vehicle_json[vehicle_extras_key] = vehicle_extras;
if ((VEHICLE::GET_VEHICLE_LIVERY_COUNT(vehicle) > 1) && VEHICLE::GET_VEHICLE_LIVERY(vehicle) >= 0)
{
vehicle_json[vehicle_livery_key] = VEHICLE::GET_VEHICLE_LIVERY(vehicle);
}
if (VEHICLE::IS_THIS_MODEL_A_CAR(ENTITY::GET_ENTITY_MODEL(vehicle)) ||
VEHICLE::IS_THIS_MODEL_A_BIKE(ENTITY::GET_ENTITY_MODEL(vehicle)))
{
vehicle_json[wheel_type_key] = VEHICLE::GET_VEHICLE_WHEEL_TYPE(vehicle);
for (int i = MOD_SPOILERS; i <= MOD_LIVERY; i++)
{
const auto is_mod_on = VEHICLE::IS_TOGGLE_MOD_ON(vehicle, i);
if (is_mod_on)
{
if (i == MOD_TYRE_SMOKE)
{
int tire_smoke_color[3]{};
VEHICLE::GET_VEHICLE_TYRE_SMOKE_COLOR(vehicle, &tire_smoke_color[0], &tire_smoke_color[1], &tire_smoke_color[2]);
vehicle_json[tire_smoke_color_key] = tire_smoke_color;
}
else
{
vehicle_json[mod_names[i]] = "TOGGLE";
}
}
if (VEHICLE::GET_VEHICLE_MOD(vehicle, i) != -1)
{
int vehicle_mod[2] = { VEHICLE::GET_VEHICLE_MOD(vehicle, i), VEHICLE::GET_VEHICLE_MOD_VARIATION(vehicle, i) };
vehicle_json[mod_names[i]] = vehicle_mod;
}
}
bool neon_lights[4]{};
for (int i = NEON_LEFT; i <= NEON_BACK; i++)
neon_lights[i] = VEHICLE::IS_VEHICLE_NEON_LIGHT_ENABLED_(vehicle, i);
int neon_color[3]{};
VEHICLE::GET_VEHICLE_NEON_LIGHTS_COLOUR_(vehicle, &neon_color[0], &neon_color[1], &neon_color[2]);
vehicle_json[neon_color_key] = neon_color;
vehicle_json[neon_lights_key] = neon_lights;
if (VEHICLE::IS_VEHICLE_A_CONVERTIBLE(vehicle, 0))
vehicle_json[convertable_state_key] = VEHICLE::GET_CONVERTIBLE_ROOF_STATE(vehicle);
int interior_color, dashboard_color;
VEHICLE::GET_VEHICLE_INTERIOR_COLOR_(vehicle, &interior_color);
VEHICLE::GET_VEHICLE_DASHBOARD_COLOR_(vehicle, &dashboard_color);
vehicle_json[interior_color_key] = interior_color;
vehicle_json[dash_color_key] = dashboard_color;
vehicle_json[clan_logo_key] = GRAPHICS::DOES_VEHICLE_HAVE_CREW_EMBLEM(vehicle, 0);
vehicle_json[headlight_color_key] = VEHICLE::GET_VEHICLE_XENON_LIGHTS_COLOR_(vehicle);
}
return vehicle_json;
}
big::folder persist_car_service::check_vehicle_folder()
{
const auto folder = g_file_manager->get_project_folder("./saved_json_vehicles");
return folder;
}
}

View File

@ -0,0 +1,80 @@
#pragma once
#include "natives.hpp"
#include "core/data/model_attachment.hpp"
namespace big
{
class persist_car_service
{
public:
static std::vector<std::string> list_files();
static Vehicle clone_ped_car(Ped ped, Vehicle vehicle);
static void save_vehicle(Vehicle vehicle, std::string_view file_name);
static Vehicle load_vehicle(std::string_view file_name);
private:
static constexpr auto model_attachment_key = "model_attachment";
static constexpr auto model_attachments_key = "model_attachments";
static constexpr auto vehicle_attachments_key = "vehicle_attachments";
static constexpr auto vehicle_model_hash_key = "vehicle_model_hash";
static constexpr auto vehicle_key = "vehicle";
static constexpr auto tow_key = "tow";
static constexpr auto trailer_key = "trailer";
static constexpr auto radio_station_key = "radio_station";
static constexpr auto plate_text_key = "plate_text";
static constexpr auto plate_text_index_key = "plate_text_index";
static constexpr auto vehicle_extras_key = "vehicle_extras";
static constexpr auto vehicle_livery_key = "vehicle_livery";
static constexpr auto wheel_type_key = "wheel_type";
static constexpr auto wheel_color_key = "wheel_color";
static constexpr auto tire_smoke_color_key = "tire_smoke_color";
static constexpr auto convertable_state_key = "convertable_state";
static constexpr auto vehicle_window_tint_key = "vehicle_window_tint";
static constexpr auto neon_lights_key = "neon_lights";
static constexpr auto neon_color_key = "neon_color";
static constexpr auto primary_color_key = "primary_color";
static constexpr auto custom_primary_color_key = "custom_primary_color";
static constexpr auto secondary_color_key = "secondary_color";
static constexpr auto custom_secondary_color_key = "custom_secondary_color";
static constexpr auto pearlescent_color_key = "pearlescent_color";
static constexpr auto headlight_color_key = "headlight_color";
static constexpr auto interior_color_key = "interior_color";
static constexpr auto dash_color_key = "dash_color";
static constexpr auto clan_logo_key = "clan_logo";
static Vehicle spawn_vehicle_full(nlohmann::json vehicle_json, Ped ped);
static Vehicle spawn_vehicle(nlohmann::json vehicle_json, Ped ped);
static Vehicle spawn_vehicle_json(nlohmann::json vehicle_json, Ped ped);
static nlohmann::json get_full_vehicle_json(Vehicle vehicle);
static model_attachment get_model_attachment(Vehicle vehicle, Object object);
static nlohmann::json get_model_attachments(Vehicle vehicle, bool is_towed_vehicle = false);
static nlohmann::json get_vehicle_attachents(Vehicle vehicle);
static nlohmann::json get_vehicle_json(Vehicle vehicle);
static big::folder check_vehicle_folder();
};
}

View File

@ -0,0 +1,87 @@
#include "fiber_pool.hpp"
#include "gui/handling/handling_tabs.hpp"
#include "script.hpp"
#include "util/vehicle.hpp"
#include "views/view.hpp"
#include "util/mobile.hpp"
#include "core/data/speed_units.hpp"
#include "services/vehicle/persist_car_service.hpp"
namespace big
{
static void save_vehicle(char* vehicle_file_name_input)
{
if (ENTITY::DOES_ENTITY_EXIST(self::veh))
{
const auto vehicle_file_name = std::string(vehicle_file_name_input).append(".json");
persist_car_service::save_vehicle(self::veh, vehicle_file_name);
ZeroMemory(vehicle_file_name_input, sizeof(vehicle_file_name_input));
}
}
static void load_vehicle(std::string& selected_vehicle_file)
{
if (!selected_vehicle_file.empty())
{
const auto vehicle = persist_car_service::load_vehicle(selected_vehicle_file);
if (!vehicle)
{
g_notification_service->push_warning("Persist Car", "Vehicle failed to spawn, there is most likely too many spawned vehicles in the area");
}
else if (g->spawn.spawn_inside)
teleport::into_vehicle(vehicle);
selected_vehicle_file.clear();
}
else
{
g_notification_service->push_warning("Persist Car", "Select a file first");
}
}
void view::persist_car()
{
static std::string selected_vehicle_file;
const auto vehicle_files = persist_car_service::list_files();
ImGui::PushItemWidth(250);
ImGui::Text("Saved Vehicles");
if (ImGui::ListBoxHeader("##empty", ImVec2(200, 200)))
{
for (const auto& pair : vehicle_files)
{
if (ImGui::Selectable(pair.c_str(), selected_vehicle_file == pair))
selected_vehicle_file = pair;
}
ImGui::ListBoxFooter();
}
ImGui::SameLine();
ImGui::BeginGroup();
static char vehicle_file_name_input[50]{};
ImGui::PushItemWidth(250);
components::input_text_with_hint(
"Vehicle File Name",
"Ex: My Cool Car",
vehicle_file_name_input, IM_ARRAYSIZE(vehicle_file_name_input));
ImGui::SameLine();
components::button("Save Vehicle", []
{
save_vehicle(vehicle_file_name_input);
});
components::button("Load Vehicle", []
{
load_vehicle(selected_vehicle_file);
});
ImGui::EndGroup();
}
}

View File

@ -35,6 +35,7 @@ namespace big
static void spawn();
static void pv();
static void vehicle_fun();
static void persist_car();
static void spoofing();
static void teleport();
static void vehicle();