refactor(HandlingService): Use JSON to store profiles (#711)

* fix(HandlingService): Correctly apply profile from storage
* fix(HandlingService): Name inconsistency in UI
* feat(HandlingService): Convert old handling profiles
This commit is contained in:
Yimura 2022-12-17 15:11:36 +01:00 committed by GitHub
parent d728fabe14
commit 7da9427128
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 74 additions and 16 deletions

View File

@ -20,11 +20,11 @@ namespace big
if (ImGui::ListBoxHeader("##handling_profiles")) if (ImGui::ListBoxHeader("##handling_profiles"))
{ {
for (const auto& [name, profile] : g_handling_service->profiles()) for (auto& [name, profile] : g_handling_service->profiles())
{ {
if (components::selectable(name, profile.get() == g_handling_service->active_profile())) if (components::selectable(name, &profile == g_handling_service->active_profile()))
{ {
g_handling_service->apply_profile(profile.get()); g_handling_service->apply_profile(&profile);
} }
} }
ImGui::EndListBox(); ImGui::EndListBox();

View File

@ -13,7 +13,10 @@ namespace big
const auto hash = vehicle->m_handling_data->m_model_hash; const auto hash = vehicle->m_handling_data->m_model_hash;
vehicle->m_gravity = m_gravity; vehicle->m_gravity = m_gravity;
*vehicle->m_handling_data = m_handling_data;
// cursed but works perfectly without overriding members that we shouldn't override
nlohmann::json j = m_handling_data; // exports our binary object so we can apply it field by field instead of copying the whole object
from_json(j, *vehicle->m_handling_data); // macro is defined in global scope of which CHandlingData is part of
if (restore_hash) if (restore_hash)
vehicle->m_handling_data->m_model_hash = hash; vehicle->m_handling_data->m_model_hash = hash;

View File

@ -1,6 +1,25 @@
#pragma once #pragma once
#include "vehicle/CVehicle.hpp" #include "vehicle/CVehicle.hpp"
// Register to_json/from_json for these GTA classes
namespace rage
{
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(rage::fvector3, x, y, z)
}
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CHandlingData,
m_mass, m_initial_drag_coeff, m_downforce_multiplier, m_centre_of_mass, m_inertia_mult,
m_buoyancy, m_drive_bias_rear, m_drive_bias_front, m_acceleration, m_initial_drive_gears,
m_drive_inertia, m_upshift, m_downshift, m_initial_drive_force, m_drive_max_flat_velocity,
m_initial_drive_max_flat_vel, m_brake_force, m_brake_bias_front, m_brake_bias_rear,
m_handbrake_force, m_steering_lock, m_steering_lock_ratio, m_traction_curve_max,
m_traction_curve_lateral, m_traction_curve_min, m_traction_curve_ratio, m_curve_lateral,
m_curve_lateral_ratio, m_traction_spring_delta_max, m_traction_spring_delta_max_ratio,
m_low_speed_traction_loss_mult, m_camber_stiffness, m_traction_bias_front, m_traction_bias_rear,
m_traction_loss_mult, m_suspension_force, m_suspension_comp_damp, m_suspension_rebound_damp,
m_suspension_upper_limit, m_suspension_lower_limit, m_suspension_raise, m_suspension_bias_front,
m_suspension_bias_rear, m_anti_rollbar_force, m_anti_rollbar_bias_front, m_anti_rollbar_bias_rear,
m_roll_centre_height_front, m_roll_centre_height_rear, m_collision_damage_mult)
namespace big namespace big
{ {
class handling_profile final class handling_profile final
@ -11,6 +30,9 @@ namespace big
void apply_to(CVehicle* vehicle, bool restore_hash = true) const; void apply_to(CVehicle* vehicle, bool restore_hash = true) const;
public:
NLOHMANN_DEFINE_TYPE_INTRUSIVE(handling_profile, m_gravity, m_handling_data)
private: private:
float m_gravity; float m_gravity;
CHandlingData m_handling_data; CHandlingData m_handling_data;

View File

@ -19,19 +19,47 @@ namespace big
std::size_t handling_service::load_files() std::size_t handling_service::load_files()
{ {
std::size_t files_loaded{}; std::size_t files_loaded{};
m_handling_profiles.clear();
for (const auto& item : std::filesystem::directory_iterator(m_profiles_folder.get_path())) for (const auto& item : std::filesystem::directory_iterator(m_profiles_folder.get_path()))
{ {
if (!item.is_regular_file()) if (!item.is_regular_file())
continue; continue;
if (auto file_path = item.path(); file_path.extension() == ".bin")
auto file_path = item.path();
if (file_path.extension() == ".json")
{ {
auto profile = std::make_unique<handling_profile>();
auto profile_file = std::ifstream(file_path, std::ios::binary); auto profile_file = std::ifstream(file_path, std::ios::binary);
profile_file.read(reinterpret_cast<char*>(profile.get()), sizeof(handling_profile)); nlohmann::json j;
profile_file >> j;
profile_file.close(); profile_file.close();
m_handling_profiles.emplace(file_path.stem().string(), std::move(profile)); m_handling_profiles.emplace(file_path.stem().string(), j.get<handling_profile>());
++files_loaded;
}
// deprecate this
else if (file_path.extension() == ".bin")
{
LOG(WARNING) << "Attempting to convert old handling files, this feature will be removed in the future.";
auto profile_file = std::ifstream(file_path, std::ios::binary);
auto profile = handling_profile();
profile_file.read(reinterpret_cast<char*>(&profile), 328); // hardcoded old size to prevent overreading
profile_file.close();
const auto new_save = file_path.stem().string();
// this will make sure we only copy the fields we want to copy
nlohmann::json j = profile;
const auto save_file_path = m_profiles_folder.get_file("./" + new_save + ".json");
auto save_file = std::ofstream(save_file_path.get_path(), std::ios::binary);
save_file << j.dump(4);
// remove old file
std::filesystem::remove(file_path);
m_handling_profiles.emplace(new_save, j.get<handling_profile>());
++files_loaded; ++files_loaded;
} }
@ -65,16 +93,21 @@ namespace big
if (!vehicle) if (!vehicle)
return false; return false;
name += ".bin"; name += ".json";
const auto save = m_profiles_folder.get_file(name); const auto save = m_profiles_folder.get_file(name);
auto profile = std::make_unique<handling_profile>(vehicle); auto profile = handling_profile(vehicle);
auto save_file = std::ofstream(save.get_path(), std::ios::binary); auto save_file = std::ofstream(save.get_path(), std::ios::binary);
save_file.write(reinterpret_cast<const char*>(profile.get()), sizeof(handling_profile)); nlohmann::json j = profile;
save_file << j.dump(4);
save_file.close(); save_file.close();
m_handling_profiles.emplace(name, std::move(profile)); // reset our profile to prevent copying members we don't want to exist
profile = handling_profile();
profile = j.get<handling_profile>();
m_handling_profiles.emplace(save.get_path().stem().string(), std::move(profile));
return true; return true;
} }
@ -89,7 +122,7 @@ namespace big
if (const auto& it = m_vehicle_backups.find(hash); it != m_vehicle_backups.end()) if (const auto& it = m_vehicle_backups.find(hash); it != m_vehicle_backups.end())
return false; return false;
m_vehicle_backups.emplace(hash, std::make_unique<handling_profile>(vehicle)); m_vehicle_backups.emplace(hash, handling_profile(vehicle));
return true; return true;
} }
@ -102,7 +135,7 @@ namespace big
if (const auto& it = m_vehicle_backups.find(vehicle->m_handling_data->m_model_hash); it != m_vehicle_backups.end()) if (const auto& it = m_vehicle_backups.find(vehicle->m_handling_data->m_model_hash); it != m_vehicle_backups.end())
{ {
it->second->apply_to(vehicle); it->second.apply_to(vehicle);
} }
} }
} }

View File

@ -3,7 +3,7 @@
namespace big namespace big
{ {
using handling_profiles = std::map<std::string, std::unique_ptr<handling_profile>>; using handling_profiles = std::map<std::string, handling_profile>;
class handling_service final class handling_service final
{ {
public: public:
@ -32,7 +32,7 @@ namespace big
handling_profiles m_handling_profiles; handling_profiles m_handling_profiles;
// contains the handling profiles of a vehicles before they're been modified // contains the handling profiles of a vehicles before they're been modified
std::unordered_map<std::uint32_t, std::unique_ptr<handling_profile>> m_vehicle_backups; std::unordered_map<std::uint32_t, handling_profile> m_vehicle_backups;
}; };