diff --git a/src/core/settings.hpp b/src/core/settings.hpp index 6be822ac..8e4def13 100644 --- a/src/core/settings.hpp +++ b/src/core/settings.hpp @@ -706,8 +706,9 @@ namespace big bool unlimited_weapons = false; bool siren_mute = false; bool all_vehs_in_heists = false; + std::string persist_vehicle_sub_folder = ""; - NLOHMANN_DEFINE_TYPE_INTRUSIVE(vehicle, speedo_meter, fly, rainbow_paint, speed_unit, god_mode, proof_bullet, proof_fire, proof_collision, proof_melee, proof_explosion, proof_steam, proof_water, proof_mask, auto_drive_destination, auto_drive_style, auto_drive_speed, auto_turn_signals, boost_behavior, drive_on_water, horn_boost, instant_brake, block_homing, seatbelt, turn_signals, vehicle_jump, keep_vehicle_repaired, no_water_collision, disable_engine_auto_start, change_engine_state_immediately, keep_engine_running, keep_vehicle_clean, vehinvisibility, localveh_visibility, keep_on_ground, no_collision, unlimited_weapons, siren_mute, all_vehs_in_heists) + NLOHMANN_DEFINE_TYPE_INTRUSIVE(vehicle, speedo_meter, fly, rainbow_paint, speed_unit, god_mode, proof_bullet, proof_fire, proof_collision, proof_melee, proof_explosion, proof_steam, proof_water, proof_mask, auto_drive_destination, auto_drive_style, auto_drive_speed, auto_turn_signals, boost_behavior, drive_on_water, horn_boost, instant_brake, block_homing, seatbelt, turn_signals, vehicle_jump, keep_vehicle_repaired, no_water_collision, disable_engine_auto_start, change_engine_state_immediately, keep_engine_running, keep_vehicle_clean, vehinvisibility, localveh_visibility, keep_on_ground, no_collision, unlimited_weapons, siren_mute, all_vehs_in_heists, persist_vehicle_sub_folder) } vehicle{}; struct weapons diff --git a/src/services/vehicle/persist_car_service.cpp b/src/services/vehicle/persist_car_service.cpp index e4ed834e..8b8c8491 100644 --- a/src/services/vehicle/persist_car_service.cpp +++ b/src/services/vehicle/persist_car_service.cpp @@ -9,7 +9,7 @@ namespace big { - void persist_car_service::save_vehicle(Vehicle vehicle, std::string_view file_name) + void persist_car_service::save_vehicle(Vehicle vehicle, std::string_view file_name, std::string folder_name) { if (!ENTITY::DOES_ENTITY_EXIST(vehicle) || !ENTITY::IS_ENTITY_A_VEHICLE(vehicle)) { @@ -18,7 +18,7 @@ namespace big return; } - const auto file = check_vehicle_folder().get_file(file_name); + const auto file = check_vehicle_folder(folder_name).get_file(file_name); std::ofstream file_stream(file.get_path(), std::ios::out | std::ios::trunc); @@ -27,9 +27,9 @@ namespace big file_stream.close(); } - Vehicle persist_car_service::load_vehicle(std::string_view file_name) + Vehicle persist_car_service::load_vehicle(std::string_view file_name, std::string folder_name) { - const auto file = check_vehicle_folder().get_file(file_name); + const auto file = check_vehicle_folder(folder_name).get_file(file_name); std::ifstream file_stream(file.get_path()); @@ -49,11 +49,11 @@ namespace big return spawn_vehicle_full(vehicle_json, self::ped); } - std::vector persist_car_service::list_files() + std::vector persist_car_service::list_files(std::string folder_name) { std::vector file_paths; - const auto file_path = check_vehicle_folder(); + const auto file_path = check_vehicle_folder(folder_name); 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()); @@ -61,6 +61,20 @@ namespace big return file_paths; } + std::vector persist_car_service::list_sub_folders() + { + std::vector folders; + + const auto file_path = check_vehicle_folder(); + for (const auto& directory_entry : std::filesystem::directory_iterator(file_path.get_path())) + if (directory_entry.is_directory()) + folders.push_back(directory_entry.path().filename().generic_string()); + + return folders; + } + + + Vehicle persist_car_service::clone_ped_car(Ped ped, Vehicle vehicle) { return spawn_vehicle_full(get_full_vehicle_json(vehicle), ped); @@ -513,10 +527,8 @@ namespace big return vehicle_json; } - big::folder persist_car_service::check_vehicle_folder() + big::folder persist_car_service::check_vehicle_folder(std::string folder_name) { - const auto folder = g_file_manager.get_project_folder("./saved_json_vehicles"); - - return folder; + return g_file_manager.get_project_folder("./saved_json_vehicles/" + folder_name); } } diff --git a/src/services/vehicle/persist_car_service.hpp b/src/services/vehicle/persist_car_service.hpp index b9490c46..c82dad2c 100644 --- a/src/services/vehicle/persist_car_service.hpp +++ b/src/services/vehicle/persist_car_service.hpp @@ -7,11 +7,12 @@ namespace big class persist_car_service { public: - static std::vector list_files(); + static std::vector list_files(std::string folder_name = ""); + static std::vector list_sub_folders(); 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); + static void save_vehicle(Vehicle vehicle, std::string_view file_name, std::string folder_name); + static Vehicle load_vehicle(std::string_view file_name, std::string folder_name = ""); private: static constexpr auto model_attachment_key = "model_attachment"; @@ -76,6 +77,6 @@ namespace big static nlohmann::json get_vehicle_json(Vehicle vehicle); - static big::folder check_vehicle_folder(); + static big::folder check_vehicle_folder(std::string folder_name = ""); }; } \ No newline at end of file diff --git a/src/views/vehicle/spawn/view_persist_car.cpp b/src/views/vehicle/spawn/view_persist_car.cpp index 6cae36ac..7c777812 100644 --- a/src/views/vehicle/spawn/view_persist_car.cpp +++ b/src/views/vehicle/spawn/view_persist_car.cpp @@ -8,12 +8,12 @@ namespace big { - static void save_vehicle(char* vehicle_file_name_input) + static void save_vehicle(char* vehicle_file_name_input, char* folder_name) { 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); + persist_car_service::save_vehicle(self::veh, vehicle_file_name, folder_name); ZeroMemory(vehicle_file_name_input, sizeof(vehicle_file_name_input)); } } @@ -22,7 +22,7 @@ namespace big { if (!selected_vehicle_file.empty()) { - const auto vehicle = persist_car_service::load_vehicle(selected_vehicle_file); + const auto vehicle = persist_car_service::load_vehicle(selected_vehicle_file, g.vehicle.persist_vehicle_sub_folder); if (!vehicle) { g_notification_service->push_warning("PERSIST_CAR"_T.data(), "PERSIST_CAR_TO_MANY_SPAWNED"_T.data()); @@ -42,19 +42,41 @@ namespace big { static std::string selected_vehicle_file; - const auto vehicle_files = persist_car_service::list_files(); + const auto vehicle_folders = persist_car_service::list_sub_folders(); + const auto vehicle_files = persist_car_service::list_files(g.vehicle.persist_vehicle_sub_folder); + + + auto folder_display = g.vehicle.persist_vehicle_sub_folder.empty() ? "ROOT"_T.data() : g.vehicle.persist_vehicle_sub_folder.c_str(); + if (ImGui::BeginCombo("FOLDER"_T.data(), folder_display)) + { + if (ImGui::Selectable("ROOT"_T.data(), g.vehicle.persist_vehicle_sub_folder == "")) + g.vehicle.persist_vehicle_sub_folder = ""; + + for (std::string folder_name : vehicle_folders) + { + if (ImGui::Selectable(folder_name.c_str(), g.vehicle.persist_vehicle_sub_folder == folder_name)) + g.vehicle.persist_vehicle_sub_folder = folder_name; + } + + ImGui::EndCombo(); + } ImGui::PushItemWidth(250); ImGui::Text("SAVED_VEHICLES"_T.data()); - if (ImGui::BeginListBox("##empty", ImVec2(200, 200))) + static const auto over_30 = (30 * ImGui::GetTextLineHeightWithSpacing() + 2); + const auto box_height = vehicle_files.size() <= 30 ? (vehicle_files.size() * ImGui::GetTextLineHeightWithSpacing() + 2) : over_30; + if (ImGui::BeginListBox("##empty", ImVec2(300, box_height))) { for (const auto& pair : vehicle_files) { if (ImGui::Selectable(pair.c_str(), selected_vehicle_file == pair)) - selected_vehicle_file = pair, g_fiber_pool->queue_job([] { + { + selected_vehicle_file = pair; + g_fiber_pool->queue_job([] { load_vehicle(selected_vehicle_file); }); + } } ImGui::EndListBox(); @@ -67,13 +89,24 @@ namespace big components::small_text("VEHICLE_FILE_NAME"_T); ImGui::PushItemWidth(250); - components::input_text_with_hint("##vehiclefilename", "VEHICLE_FILE_NAME_EXAMPLE"_T, vehicle_file_name_input, IM_ARRAYSIZE(vehicle_file_name_input)); + ImGui::InputText("##vehiclefilename", vehicle_file_name_input, IM_ARRAYSIZE(vehicle_file_name_input)); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("VEHICLE_FILE_NAME_EXAMPLE"_T.data()); + ImGui::PopItemWidth(); + + static char save_folder[50]{}; + components::small_text("VEHICLE_FOLDER_NAME"_T); + ImGui::PushItemWidth(250); + ImGui::InputText("##foldername", save_folder, IM_ARRAYSIZE(save_folder)); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("VEHICLE_FOLDER_NAME_EXAMPLE"_T.data()); + ImGui::PopItemWidth(); components::button("SAVE_VEHICLE"_T, [] { if (!self::veh) - return g_notification_service->push_warning("PERSIST_CAR"_T.data(), "You must be in a vehicle. Please enter a vehicle before using load."); + return g_notification_service->push_warning("PERSIST_CAR"_T.data(), "PERSIST_CAR_NOT_IN_VEHICLE"_T.data()); - save_vehicle(vehicle_file_name_input); + save_vehicle(vehicle_file_name_input, save_folder); }); ImGui::EndGroup();