From e5dc61111b39e31c3ca1e921709b95df9b80e6b6 Mon Sep 17 00:00:00 2001 From: lonelybud <139460769+lonelybud@users.noreply.github.com> Date: Fri, 4 Jul 2025 00:30:49 +0530 Subject: [PATCH] refractor savedvehicles & vehicle spawn (#604) - add checkbox in savedvehicles to spawninside - use shared logic to get spawn location for a given vehicle model for saved veh, cloned pv veh & spawned veh --- src/game/backend/SavedVehicles.cpp | 20 +++++++++------- src/game/backend/SavedVehicles.hpp | 4 ++-- .../submenus/Vehicle/SavedVehicles.cpp | 8 +++++-- .../submenus/Vehicle/SpawnVehicle.cpp | 23 ++----------------- src/game/gta/Vehicle.cpp | 7 ++++++ src/game/gta/Vehicle.hpp | 10 ++++++-- 6 files changed, 37 insertions(+), 35 deletions(-) diff --git a/src/game/backend/SavedVehicles.cpp b/src/game/backend/SavedVehicles.cpp index 7776141..047cfff 100644 --- a/src/game/backend/SavedVehicles.cpp +++ b/src/game/backend/SavedVehicles.cpp @@ -145,10 +145,10 @@ namespace YimMenu }); } - void SavedVehicles::Load(std::string folderName, std::string fileName) + void SavedVehicles::Load(std::string folderName, std::string fileName, bool spawnInside) { if (!fileName.empty()) - FiberPool::Push([folderName, fileName] { + FiberPool::Push([folderName, fileName, spawnInside] { const auto file = CheckFolder(folderName).GetFile(fileName).Path(); if (!std::filesystem::exists(file)) @@ -163,8 +163,14 @@ namespace YimMenu try { file_stream >> vehicle_json; - if (SpawnFromJson(vehicle_json)) + auto veh = SpawnFromJson(vehicle_json); + + if (veh) + { + if (spawnInside) + Self::GetPed().SetInVehicle(veh.GetHandle()); Notifications::Show("Persist Car", std::format("Spawned {}", fileName), NotificationType::Success); + } else Notifications::Show("Persist Car", std::format("Unable to spawn {}", fileName), NotificationType::Error); } @@ -179,10 +185,10 @@ namespace YimMenu Notifications::Show("Persist Car", "Select a file first", NotificationType::Warning); } - bool SavedVehicles::SpawnFromJson(nlohmann::json vehicle_json) + Vehicle SavedVehicles::SpawnFromJson(nlohmann::json vehicle_json) { const Hash vehicle_hash = vehicle_json[vehicle_model_hash_key]; - auto veh = Vehicle::Create(vehicle_hash, Self::GetPed().GetPosition(), Self::GetPed().GetHeading()); + auto veh = Vehicle::Create(vehicle_hash, Vehicle::GetSpawnLocRelToPed(Self::GetPed().GetHandle(), vehicle_hash), Self::GetPed().GetHeading()); if (veh != nullptr) { @@ -273,10 +279,8 @@ namespace YimMenu for (const auto& [extra, extra_enabled] : vehicle_extras) VEHICLE::SET_VEHICLE_EXTRA(vehicle, extra, extra_enabled ? 0 : 1); } - - return true; } - return false; + return veh; } } diff --git a/src/game/backend/SavedVehicles.hpp b/src/game/backend/SavedVehicles.hpp index 095bc9e..47dd3f6 100644 --- a/src/game/backend/SavedVehicles.hpp +++ b/src/game/backend/SavedVehicles.hpp @@ -11,12 +11,12 @@ namespace YimMenu static void RefreshList(std::string folderName, std::vector& folders, std::vector& files); static void Save(std::string folderName, std::string fileName); - static void Load(std::string folderName, std::string fileName); + static void Load(std::string folderName, std::string fileName, bool spawnInside); private: static nlohmann::json GetJson(Vehicle vehicle); static Folder CheckFolder(std::string folderName = ""); - static bool SpawnFromJson(nlohmann::json); + static Vehicle SpawnFromJson(nlohmann::json); private: static constexpr auto plate_text_key = "plate_text"; diff --git a/src/game/frontend/submenus/Vehicle/SavedVehicles.cpp b/src/game/frontend/submenus/Vehicle/SavedVehicles.cpp index 71bb0d1..9d09686 100644 --- a/src/game/frontend/submenus/Vehicle/SavedVehicles.cpp +++ b/src/game/frontend/submenus/Vehicle/SavedVehicles.cpp @@ -1,5 +1,5 @@ #include "SavedVehicles.hpp" - +#include "core/commands/BoolCommand.hpp" #include "core/backend/FiberPool.hpp" #include "core/backend/ScriptMgr.hpp" #include "core/frontend/Notifications.hpp" @@ -11,6 +11,8 @@ namespace YimMenu::Submenus { + static BoolCommand spawnInsideSavedVehicle{"spawninsidesavedveh", "Spawn Inside", "Spawn inside the vehicle."}; + std::shared_ptr BuildSavedVehiclesMenu() { static std::string folder{}, file{}; @@ -20,6 +22,8 @@ namespace YimMenu::Submenus auto persistCar = std::make_shared("Saved Vehicles"); + persistCar->AddItem(std::make_shared("spawninsidesavedveh"_J)); + persistCar->AddItem(std::make_unique([] { static auto drawSaveVehicleButton = [](bool saveToNewFolder) { if (!Self::GetVehicle() || !Self::GetVehicle().IsValid()) @@ -140,7 +144,7 @@ namespace YimMenu::Submenus ImGui::Spacing(); if (ImGui::Button("Yes")) { - SavedVehicles::Load(folder, file); + SavedVehicles::Load(folder, file, spawnInsideSavedVehicle.GetState()); open_modal = false; ImGui::CloseCurrentPopup(); } diff --git a/src/game/frontend/submenus/Vehicle/SpawnVehicle.cpp b/src/game/frontend/submenus/Vehicle/SpawnVehicle.cpp index 7737b63..50b53f5 100644 --- a/src/game/frontend/submenus/Vehicle/SpawnVehicle.cpp +++ b/src/game/frontend/submenus/Vehicle/SpawnVehicle.cpp @@ -15,25 +15,6 @@ namespace YimMenu::Submenus static BoolCommand spawnInsidePersonalVehicle{"spawninsidepv", "Spawn Inside", "Spawn inside the personal vehicle."}; static BoolCommand spawnClonePersonalVehicle{"spawnclonepv", "Spawn Clone", "Spawn a clone of the persone vehicle."}; - static Vector3 GetVehicleSpawnLoc(joaat_t hash, bool spawnInside) - { - float y_offset = 0; - - if (Self::GetVehicle().IsValid()) - { - Vector3 min, max, result; - MISC::GET_MODEL_DIMENSIONS(hash, &min, &max); - result = max - min; - y_offset = result.y; - } - else if (!spawnInside) - { - y_offset = 5.f; - } - - return ENTITY::GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(Self::GetPed().GetHandle(), 0.f, y_offset, 0.f); - } - std::shared_ptr RenderSpawnNewVehicle() { auto tab = std::make_shared("New Vehicle"); @@ -129,7 +110,7 @@ namespace YimMenu::Submenus if (ImGui::Selectable(name.c_str())) { FiberPool::Push([hash] { - auto handle = Vehicle::Create(hash, GetVehicleSpawnLoc(hash, spawnInsideVehicle.GetState()), Self::GetPed().GetHeading()); + auto handle = Vehicle::Create(hash, Vehicle::GetSpawnLocRelToPed(Self::GetPed().GetHandle(), hash), Self::GetPed().GetHeading()); if (spawnInsideVehicle.GetState()) Self::GetPed().SetInVehicle(handle); @@ -222,7 +203,7 @@ namespace YimMenu::Submenus FiberPool::Push([&personalVeh] { if (spawnClonePersonalVehicle.GetState()) { - auto coords = GetVehicleSpawnLoc(personalVeh->GetModel(), spawnInsidePersonalVehicle.GetState()); + auto coords = Vehicle::GetSpawnLocRelToPed(Self::GetPed().GetHandle(), personalVeh->GetModel()); auto heading = Self::GetPed().GetHeading(); auto handle = personalVeh->Clone(coords, heading); diff --git a/src/game/gta/Vehicle.cpp b/src/game/gta/Vehicle.cpp index 3413b22..968a7bb 100644 --- a/src/game/gta/Vehicle.cpp +++ b/src/game/gta/Vehicle.cpp @@ -274,4 +274,11 @@ namespace YimMenu return ownedMods; } + + Vector3 Vehicle::GetSpawnLocRelToPed(int ped, joaat_t hash) + { + Vector3 min, max; + MISC::GET_MODEL_DIMENSIONS(hash, &min, &max); + return ENTITY::GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(ped, 0.f, (max - min).y, 0.f); + } } \ No newline at end of file diff --git a/src/game/gta/Vehicle.hpp b/src/game/gta/Vehicle.hpp index a8e17de..cc1b043 100644 --- a/src/game/gta/Vehicle.hpp +++ b/src/game/gta/Vehicle.hpp @@ -1,5 +1,7 @@ #pragma once #include "Entity.hpp" +#include "types/script/types.hpp" +#include "core/util/Joaat.hpp" namespace YimMenu { @@ -10,14 +12,16 @@ namespace YimMenu static Vehicle Create(std::uint32_t model, rage::fvector3 coords, float heading = 0.0f); + // health void Fix(); // gears int GetGear(); float GetRevRatio(); - // speed + // motion float GetMaxSpeed(); + void BringToHalt(float distance = 1.0f, int duration = 1); // mods void Upgrade(); @@ -36,9 +40,11 @@ namespace YimMenu // stance void LowerStance(bool lower); - void BringToHalt(float distance = 1.0f, int duration = 1); + // position bool SetOnGroundProperly(); + static Vector3 GetSpawnLocRelToPed(int ped, joaat_t hash); + // description std::string GetFullName(); }; } \ No newline at end of file