add Vehicle Editor & persist car feature (#374)

* add VehicleEditor

- add VehicleEditorCategory in Vehicle Submenus
- add GetOwnedMods, GetVehicleFullname in Vehicle class
- add VehicleColorsChameleon in VehicleValues
- add VehicleHelper core/util
- add lscTypes in gta/data

* add persist car

* fix GetProjectFolderImpl

this will create saved_json_vehicles when does nt exist
This commit is contained in:
lonelybud authored and GitHub committed 2025-06-07 13:46:11 +00:00
1 parent 7c56a44fcf
commit 76bed308ae
17 files changed
+2209 -6

No files matched your search

+1 -1
View File
@@ -52,6 +52,6 @@ namespace YimMenu
if (folder.is_absolute())
throw std::invalid_argument("FileMgr::GetProjectFolder expects a relative path.");
return { m_RootFolder / folder };
return CreateFolderIfNotExists(m_RootFolder / folder);
}
}
+10
View File
@@ -8,4 +8,14 @@ namespace YimMenu
{
}
File Folder::GetFile(std::filesystem::path file_path) const
{
if (file_path.is_absolute())
throw std::invalid_argument("folder#get_file requires a relative path.");
if (file_path.string().contains(".."))
throw std::invalid_argument("Relative path traversal is not allowed, refrain from using \"..\" in file paths.");
return File(m_Path / file_path);
}
}
+7 -5
View File
@@ -3,10 +3,12 @@
namespace YimMenu
{
class Folder final : public BaseObj
{
public:
Folder(const std::filesystem::path& folder);
class File;
class Folder final : public BaseObj
{
public:
Folder(const std::filesystem::path& folder);
};
File GetFile(std::filesystem::path file_path) const;
};
}
+259
View File
@@ -0,0 +1,259 @@
#include "VehicleHelper.hpp"
#include "core/util/Joaat.hpp"
#include "game/gta/Natives.hpp"
#include "game/gta/data/VehicleValues.hpp"
namespace YimMenu
{
const char* VehicleHelper::GetModSlotName(Hash model, int vehicle, int mod_slot)
{
switch ((VehicleModType)mod_slot)
{
case VehicleModType::MOD_HOOD: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMOD_MOD_HOD");
case VehicleModType::MOD_ARMOR: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMOD_MOD_ARM");
case VehicleModType::MOD_BRAKES: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMOD_MOD_BRA");
case VehicleModType::MOD_ENGINE: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMOD_MOD_ENG");
case VehicleModType::MOD_SUSPENSION: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMOD_MOD_SUS");
case VehicleModType::MOD_TRANSMISSION: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMOD_MOD_TRN");
case VehicleModType::MOD_HORNS: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMOD_MOD_HRN");
case VehicleModType::MOD_FRONTWHEEL:
if (!VEHICLE::IS_THIS_MODEL_A_BIKE(model) && VEHICLE::IS_THIS_MODEL_A_BICYCLE(model))
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMOD_MOD_WHEM");
else
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMOD_WHE0_0");
case VehicleModType::MOD_REARWHEEL:
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMOD_WHE0_1");
//Bennys
case VehicleModType::MOD_PLATEHOLDER: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S0");
case VehicleModType::MOD_VANITYPLATES: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S1");
case VehicleModType::MOD_TRIMDESIGN:
if (model == "SULTANRS"_J)
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S2b");
else
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S2");
case VehicleModType::MOD_ORNAMENTS: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S3");
case VehicleModType::MOD_DASHBOARD: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S4");
case VehicleModType::MOD_DIALDESIGN: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S5");
case VehicleModType::MOD_DOORSPEAKERS: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S6");
case VehicleModType::MOD_SEATS: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S7");
case VehicleModType::MOD_STEERINGWHEELS: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S8");
case VehicleModType::MOD_COLUMNSHIFTERLEVERS: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S9");
case VehicleModType::MOD_PLAQUES: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S10");
case VehicleModType::MOD_SPEAKERS: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S11");
case VehicleModType::MOD_TRUNK: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S12");
case VehicleModType::MOD_HYDRO: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S13");
case VehicleModType::MOD_ENGINEBLOCK: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S14");
case VehicleModType::MOD_AIRFILTER:
if (model == "SULTANRS"_J)
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S15b");
else
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S15");
case VehicleModType::MOD_STRUTS:
if (model == "SULTANRS"_J || model == "BANSHEE2"_J)
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S16b");
else
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S16");
case VehicleModType::MOD_ARCHCOVER:
if (model == "SULTANRS"_J)
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S17b");
else
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S17");
case VehicleModType::MOD_AERIALS:
if (model == "SULTANRS"_J)
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S18b");
else if (model == "BTYPE3"_J)
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S18c");
else
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S18");
case VehicleModType::MOD_TRIM:
if (model == "SULTANRS"_J)
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S19b");
else if (model == "BTYPE3"_J)
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S19c");
else if (model == "VIRGO2"_J)
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S19d");
else
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S19");
case VehicleModType::MOD_TANK:
if (model == "SLAMVAN3"_J)
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S27");
else
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S20");
case VehicleModType::MOD_WINDOWS:
if (model == "BTYPE3"_J)
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S21b");
else
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S21");
case VehicleModType::MOD_DOORS:
if (model == "SLAMVAN3"_J)
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("SLVAN3_RDOOR");
else
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S22");
case VehicleModType::MOD_LIVERY: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMM_MOD_S23");
default:
auto name = VEHICLE::GET_MOD_SLOT_NAME(vehicle, mod_slot);
if (name == nullptr)
return "";
if (strstr(name, "_"))
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(name);
return name;
}
}
static const std::map<int, const char*> horn_map = {{-1, "CMOD_HRN_0"},
{0, "CMOD_HRN_TRK"},
{1, "CMOD_HRN_COP"},
{2, "CMOD_HRN_CLO"},
{3, "CMOD_HRN_MUS1"},
{4, "CMOD_HRN_MUS2"},
{5, "CMOD_HRN_MUS3"},
{6, "CMOD_HRN_MUS4"},
{7, "CMOD_HRN_MUS5"},
{8, "CMOD_HRN_SAD"},
{9, "HORN_CLAS1"},
{10, "HORN_CLAS2"},
{11, "HORN_CLAS3"},
{12, "HORN_CLAS4"},
{13, "HORN_CLAS5"},
{14, "HORN_CLAS6"},
{15, "HORN_CLAS7"},
{16, "HORN_CNOTE_C0"},
{17, "HORN_CNOTE_D0"},
{18, "HORN_CNOTE_E0"},
{19, "HORN_CNOTE_F0"},
{20, "HORN_CNOTE_G0"},
{21, "HORN_CNOTE_A0"},
{22, "HORN_CNOTE_B0"},
{23, "HORN_CNOTE_C1"},
{24, "HORN_HIPS1"},
{25, "HORN_HIPS2"},
{26, "HORN_HIPS3"},
{27, "HORN_HIPS4"},
{28, "HORN_INDI_1"},
{29, "HORN_INDI_2"},
{30, "HORN_INDI_3"},
{31, "HORN_INDI_4"},
{32, "HORN_LUXE2"},
{33, "HORN_LUXE1"},
{34, "HORN_LUXE3"}, /*{35, "HORN_LUXE2"},
{36, "HORN_LUXE1"}, {37, "HORN_LUXE3"},*/
{38, "HORN_HWEEN1"},
/*{39, "HORN_HWEEN1"},*/ {40, "HORN_HWEEN2"},
/*{41, "HORN_HWEEN2"},*/ {42, "HORN_LOWRDER1"},
/*{43, "HORN_LOWRDER1"},*/ {44, "HORN_LOWRDER2"}, /*{45, "HORN_LOWRDER2"},*/
{46, "HORN_XM15_1"},
{47, "HORN_XM15_2"},
{48, "HORN_XM15_3"}};
const char* VehicleHelper::GetModeName(Hash model, int vehicle, int mod_slot, int mod, int mod_count)
{
if (mod_count == 0)
return "";
if (mod < -1 || mod >= mod_count)
return "";
if (mod_slot == (int)VehicleModType::MOD_HORNS)
{
if (horn_map.find(mod) != horn_map.end())
{
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(horn_map.find(mod)->second);
}
return "";
}
if (mod_slot == (int)VehicleModType::MOD_FRONTWHEEL || mod_slot == (int)VehicleModType::MOD_REARWHEEL)
{
if (mod == -1)
{
if (!VEHICLE::IS_THIS_MODEL_A_BIKE(model) && VEHICLE::IS_THIS_MODEL_A_BICYCLE(model))
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMOD_WHE_0");
else
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMOD_WHE_B_0");
}
if (mod >= mod_count / 2)
//return std::format("{} {}", HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CHROME"), HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(VEHICLE::GET_MOD_TEXT_LABEL(vehicle, mod_slot, mod))).c_str(); //Bug with FMT library? Returns Chrome Chrome...
return std::format("Chrome {}", HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(VEHICLE::GET_MOD_TEXT_LABEL(vehicle, mod_slot, mod)))
.c_str();
else
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(VEHICLE::GET_MOD_TEXT_LABEL(vehicle, mod_slot, mod));
}
switch (mod_slot)
{
case (int)VehicleModType::MOD_ARMOR:
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(std::format("CMOD_ARM_{}", (mod + 1)).c_str());
case (int)VehicleModType::MOD_BRAKES:
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(std::format("CMOD_BRA_{}", (mod + 1)).c_str());
case (int)VehicleModType::MOD_ENGINE:
if (mod == -1)
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMOD_ARM_0");
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(std::format("CMOD_ENG_{}", (mod + 1)).c_str());
case (int)VehicleModType::MOD_SUSPENSION:
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(std::format("CMOD_SUS_{}", (mod + 1)).c_str());
case (int)VehicleModType::MOD_TRANSMISSION:
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(std::format("CMOD_GBX_{}", (mod + 1)).c_str());
}
if (mod > -1)
{
if (mod_slot == (int)VehicleModType::MOD_SIDESKIRT && VEHICLE::GET_NUM_VEHICLE_MODS(vehicle, (int)VehicleModType::MOD_SIDESKIRT) < 2)
{
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMOD_SKI_1");
}
auto label = VEHICLE::GET_MOD_TEXT_LABEL(vehicle, mod_slot, mod);
if (label == nullptr || strlen(label) == 0)
return "MISSING_LABEL";
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(label);
}
else
{
switch (mod_slot)
{
case (int)VehicleModType::MOD_AIRFILTER: break;
case (int)VehicleModType::MOD_STRUTS:
switch (model)
{
case "BANSHEE"_J:
case "BANSHEE2"_J :
case "SULTANRS"_J: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMOD_COL5_41");
}
break;
}
return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CMOD_DEF_0");
}
}
static const std::map<Hash, std::map<int, std::vector<int32_t>>> mod_blacklists = {
{"BANSHEE"_J, {{(int)VehicleModType::MOD_SPOILERS, {3, 4}}, {(int)VehicleModType::MOD_COLUMNSHIFTERLEVERS, {0, 1, 2, 3}}, {(int)VehicleModType::MOD_SPEAKERS, {0}}, {(int)VehicleModType::MOD_LIVERY, {15, 16}}}},
{"SENTINEL"_J, {{(int)VehicleModType::MOD_SPOILERS, {4, 5}}, {(int)VehicleModType::MOD_COLUMNSHIFTERLEVERS, {0, 1, 2, 3}}, {(int)VehicleModType::MOD_SPEAKERS, {0}}, {(int)VehicleModType::MOD_LIVERY, {0, 1}}}},
};
bool VehicleHelper::CheckModBlacklist(Hash model, int mod_slot, int mod)
{
if (mod_blacklists.find(model) == mod_blacklists.end())
{
return false;
}
auto veh_slot_blacklist = mod_blacklists.find(model)->second;
if (veh_slot_blacklist.find(mod_slot) == veh_slot_blacklist.end())
{
return false;
}
auto veh_mod_blacklist = veh_slot_blacklist.find(mod_slot)->second;
if (std::find(veh_mod_blacklist.begin(), veh_mod_blacklist.end(), mod) != veh_mod_blacklist.end())
{
return true;
}
return false;
}
bool VehicleHelper::IsBennys(int veh)
{
auto v = (WheelTypes)VEHICLE::GET_VEHICLE_WHEEL_TYPE(veh);
return v == WheelTypes::WHEEL_TYPE_BENNYS_ORIGINAL || v == WheelTypes::WHEEL_TYPE_BENNYS_BESPOKE || v == WheelTypes::WHEEL_TYPE_OPEN_WHEEL || v == WheelTypes::WHEEL_TYPE_STREET || v == WheelTypes::WHEEL_TYPE_TRACK;
}
}
+14
View File
@@ -0,0 +1,14 @@
#pragma once
#include "types/script/types.hpp"
namespace YimMenu
{
class VehicleHelper
{
public:
static bool CheckModBlacklist(Hash model, int mod_slot, int mod);
static const char* GetModSlotName(Hash model, int vehicle, int mod_slot);
static const char* GetModeName(Hash model, int vehicle, int mod_slot, int mod, int mod_count);
static bool IsBennys(int veh);
};
}
+43
View File
@@ -0,0 +1,43 @@
#pragma once
#include <iostream>
#include <string>
namespace YimMenu
{
// Function to trim leading and trailing whitespace from a string
inline std::string trimString(std::string& str)
{
auto start = str.begin();
auto end = str.end();
// Find the first non-whitespace character from the start
while (start != end && std::isspace(*start))
{
++start;
}
// Find the last non-whitespace character from the end
while (start != end && std::isspace(*(end - 1)))
{
--end;
}
return std::string(start, end);
}
inline void strcpy_safe(char* dest, const char* src, int dest_size)
{
auto len = dest_size - 1;
strncpy(dest, src, len);
if (strlen(src) > len)
dest[len] = '\0';
}
inline void replace_string(std::string& str, const char* str1, const char* str2)
{
size_t pos = 0;
while ((pos = str.find(str1, pos)) != std::string::npos)
str.replace(pos, strlen(str1), str2);
}
}
@@ -0,0 +1,282 @@
#include "PersistCarService.hpp"
#include "core/backend/FiberPool.hpp"
#include "core/backend/ScriptMgr.hpp"
#include "core/frontend/Notifications.hpp"
#include "core/util/VehicleHelper.hpp"
#include "game/backend/Self.hpp"
#include "game/gta/Natives.hpp"
#include "game/gta/Vehicle.hpp"
#include "game/gta/data/VehicleValues.hpp"
namespace YimMenu::Features
{
Folder PersistCarService::CheckFolder(std::string folderName)
{
return FileMgr::GetProjectFolder("./saved_json_vehicles/" + folderName);
}
void PersistCarService::RefreshList(std::string folderName, std::vector<std::string>& folders, std::vector<std::string>& files)
{
FiberPool::Push([folderName, &folders, &files] {
folders.clear();
const auto file_path = CheckFolder();
for (const auto& directory_entry : std::filesystem::directory_iterator(file_path.Path()))
if (directory_entry.is_directory())
folders.push_back(directory_entry.path().filename().generic_string());
files.clear();
const auto file_path2 = CheckFolder(folderName);
for (const auto& directory_entry : std::filesystem::directory_iterator(file_path2.Path()))
if (directory_entry.path().extension() == ".json")
files.push_back(directory_entry.path().filename().generic_string());
});
}
nlohmann::json PersistCarService::GetJson(Vehicle veh)
{
nlohmann::json vehicle_json;
int primary_color, secondary_color;
int pearlescent_color, wheel_color;
auto vehicle = veh.GetHandle();
Hash vehicle_hash = veh.GetModel();
std::map<int, int> vehicle_extras;
auto is_bennys = VehicleHelper::IsBennys(vehicle);
for (int slot = (int)VehicleModType::MOD_SPOILERS; slot <= (int)VehicleModType::MOD_LIGHTBAR; slot++)
if (VEHICLE::GET_NUM_VEHICLE_MODS(vehicle, slot) > 0)
{
auto wheel_custom = VEHICLE::GET_VEHICLE_MOD_VARIATION(vehicle, slot);
if (wheel_custom && is_bennys)
wheel_custom = 0;
int vehicle_mod[2] = {VEHICLE::GET_VEHICLE_MOD(vehicle, slot), wheel_custom};
vehicle_json[mod_names[slot]] = vehicle_mod;
}
else if (VEHICLE::IS_TOGGLE_MOD_ON(vehicle, slot))
{
vehicle_json[mod_names[slot]] = "TOGGLE";
if (slot == (int)VehicleModType::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 if (slot == (int)VehicleModType::MOD_XENON_LIGHTS)
vehicle_json[headlight_color_key] = VEHICLE::GET_VEHICLE_XENON_LIGHT_COLOR_INDEX(vehicle);
}
for (int extra = (int)CustomVehicleModType::MOD_EXTRA_14; extra <= (int)CustomVehicleModType::MOD_EXTRA_1; ++extra)
if (auto id = (extra - (int)CustomVehicleModType::MOD_EXTRA_1) * -1; VEHICLE::DOES_EXTRA_EXIST(vehicle, id))
vehicle_extras[id] = VEHICLE::IS_VEHICLE_EXTRA_TURNED_ON(vehicle, id);
VEHICLE::GET_VEHICLE_COLOURS(vehicle, &primary_color, &secondary_color);
VEHICLE::GET_VEHICLE_EXTRA_COLOURS(vehicle, &pearlescent_color, &wheel_color);
vehicle_json[vehicle_model_hash_key] = vehicle_hash;
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);
vehicle_json[pearlescent_color_key] = pearlescent_color;
vehicle_json[wheel_color_key] = wheel_color;
vehicle_json[tire_can_burst] = VEHICLE::GET_VEHICLE_TYRES_CAN_BURST(vehicle);
vehicle_json[vehicle_extras_key] = vehicle_extras;
vehicle_json[wheel_type_key] = VEHICLE::GET_VEHICLE_WHEEL_TYPE(vehicle);
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(vehicle_hash) || VEHICLE::IS_THIS_MODEL_A_BIKE(vehicle_hash))
{
bool neon_lights[4]{};
for (int i = (int)NeonLightLocations::NEON_LEFT; i <= (int)NeonLightLocations::NEON_BACK; i++)
neon_lights[i] = VEHICLE::GET_VEHICLE_NEON_ENABLED(vehicle, i);
int neon_color[3]{};
VEHICLE::GET_VEHICLE_NEON_COLOUR(vehicle, &neon_color[0], &neon_color[1], &neon_color[2]);
int interior_color, dashboard_color;
VEHICLE::GET_VEHICLE_EXTRA_COLOUR_5(vehicle, &interior_color);
VEHICLE::GET_VEHICLE_EXTRA_COLOUR_6(vehicle, &dashboard_color);
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);
vehicle_json[drift_tires] = VEHICLE::GET_DRIFT_TYRES_SET(vehicle);
vehicle_json[neon_color_key] = neon_color;
vehicle_json[neon_lights_key] = neon_lights;
vehicle_json[interior_color_key] = interior_color;
vehicle_json[dash_color_key] = dashboard_color;
}
return vehicle_json;
}
void PersistCarService::Save(std::string folderName, std::string fileName)
{
FiberPool::Push([folderName, fileName] {
if (auto veh = Self::GetVehicle(); veh && veh.IsValid())
{
const auto file = PersistCarService::CheckFolder(folderName).GetFile(fileName);
std::ofstream file_stream(file.Path(), std::ios::out | std::ios::trunc);
file_stream << PersistCarService::GetJson(veh).dump(4);
file_stream.close();
}
else
Notifications::Show("Persist Car", "Tried to save a vehicle which does not exist", NotificationType::Warning);
});
}
void PersistCarService::Load(std::string folderName, std::string fileName)
{
if (!fileName.empty())
FiberPool::Push([folderName, fileName] {
const auto file = CheckFolder(folderName).GetFile(fileName).Path();
if (!std::filesystem::exists(file))
{
Notifications::Show("Persist Car", "File does not exist.", NotificationType::Error);
return;
}
std::ifstream file_stream(file);
nlohmann::json vehicle_json;
try
{
file_stream >> vehicle_json;
if (SpawnFromJson(vehicle_json))
Notifications::Show("Persist Car", std::format("Spawned {}", fileName), NotificationType::Success);
else
Notifications::Show("Persist Car", std::format("Unable to spawn {}", fileName), NotificationType::Error);
}
catch (std::exception& e)
{
LOG(WARNING) << e.what();
}
file_stream.close();
});
else
Notifications::Show("Persist Car", "Select a file first", NotificationType::Warning);
}
bool PersistCarService::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());
if (veh != nullptr)
{
ScriptMgr::Yield();
auto vehicle = veh.GetHandle();
VEHICLE::SET_VEHICLE_MOD_KIT(vehicle, 0);
if (!(vehicle_json[primary_color_key].is_null() || vehicle_json[secondary_color_key].is_null()))
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]);
}
if (!vehicle_json[vehicle_window_tint_key].is_null())
VEHICLE::SET_VEHICLE_WINDOW_TINT(vehicle, vehicle_json[vehicle_window_tint_key]);
if (!(vehicle_json[pearlescent_color_key].is_null() || vehicle_json[wheel_color_key].is_null()))
VEHICLE::SET_VEHICLE_EXTRA_COLOURS(vehicle, vehicle_json[pearlescent_color_key], vehicle_json[wheel_color_key]);
if (!vehicle_json[tire_can_burst].is_null())
VEHICLE::SET_VEHICLE_TYRES_CAN_BURST(vehicle, vehicle_json[tire_can_burst]);
if (!vehicle_json[wheel_type_key].is_null())
VEHICLE::SET_VEHICLE_WHEEL_TYPE(vehicle, vehicle_json[wheel_type_key]);
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(vehicle_hash) || VEHICLE::IS_THIS_MODEL_A_BIKE(vehicle_hash))
{
if (!vehicle_json[neon_color_key].is_null())
{
std::vector<int> neon_color = vehicle_json[neon_color_key];
VEHICLE::SET_VEHICLE_NEON_COLOUR(vehicle, neon_color[0], neon_color[1], neon_color[2]);
}
if (!vehicle_json[neon_lights_key].is_null())
{
std::vector<bool> neon_lights = vehicle_json[neon_lights_key];
for (int i = (int)NeonLightLocations::NEON_LEFT; i <= (int)NeonLightLocations::NEON_BACK; i++)
VEHICLE::SET_VEHICLE_NEON_ENABLED(vehicle, i, neon_lights[i]);
}
if (!vehicle_json[plate_text_key].is_null())
VEHICLE::SET_VEHICLE_NUMBER_PLATE_TEXT(vehicle, vehicle_json[plate_text_key].get<std::string>().c_str());
if (!vehicle_json[plate_text_index_key].is_null())
VEHICLE::SET_VEHICLE_NUMBER_PLATE_TEXT_INDEX(vehicle, vehicle_json[plate_text_index_key]);
if (!vehicle_json[drift_tires].is_null())
VEHICLE::SET_DRIFT_TYRES(vehicle, vehicle_json[drift_tires]);
if (!vehicle_json[interior_color_key].is_null())
VEHICLE::SET_VEHICLE_EXTRA_COLOUR_5(vehicle, vehicle_json[interior_color_key]);
if (!vehicle_json[dash_color_key].is_null())
VEHICLE::SET_VEHICLE_EXTRA_COLOUR_6(vehicle, vehicle_json[dash_color_key]);
}
for (int i = (int)VehicleModType::MOD_SPOILERS; i < (int)VehicleModType::MOD_LIGHTBAR; i++)
if (!vehicle_json[mod_names[i]].is_null())
{
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
{
if (i == (int)VehicleModType::MOD_TYRE_SMOKE && !vehicle_json[tire_smoke_color_key].is_null())
{
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]);
}
else if (i == (int)VehicleModType::MOD_XENON_LIGHTS && !vehicle_json[headlight_color_key].is_null())
VEHICLE::SET_VEHICLE_XENON_LIGHT_COLOR_INDEX(vehicle, vehicle_json[headlight_color_key]);
VEHICLE::TOGGLE_VEHICLE_MOD(vehicle, i, TRUE);
}
}
if (!vehicle_json[vehicle_extras_key].is_null())
{
std::map<int, int> vehicle_extras = vehicle_json[vehicle_extras_key];
for (const auto& [extra, extra_enabled] : vehicle_extras)
VEHICLE::SET_VEHICLE_EXTRA(vehicle, extra, extra_enabled ? 0 : 1);
}
return true;
}
return false;
}
}
@@ -0,0 +1,43 @@
#pragma once
#include "core/filemgr/FileMgr.hpp"
#include "game/gta/Vehicle.hpp"
namespace YimMenu::Features
{
class PersistCarService
{
public:
static constexpr auto vehicle_model_hash_key = "vehicle_model_hash";
static void RefreshList(std::string folderName, std::vector<std::string>& folders, std::vector<std::string>& files);
static void Save(std::string folderName, std::string fileName);
static void Load(std::string folderName, std::string fileName);
private:
static nlohmann::json GetJson(Vehicle vehicle);
static Folder CheckFolder(std::string folderName = "");
static bool SpawnFromJson(nlohmann::json);
private:
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 tire_can_burst = "tire_can_burst";
static constexpr auto drift_tires = "drift_tires";
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";
};
}
+4
View File
@@ -1,6 +1,8 @@
#include "Vehicle.hpp"
#include "game/frontend/items/Items.hpp"
#include "game/frontend/submenus/Vehicle/SpawnVehicle.hpp"
#include "Vehicle/VehicleEditorCategory.hpp"
#include "Vehicle/PersistCarCategory.hpp"
namespace YimMenu::Submenus
{
@@ -37,5 +39,7 @@ namespace YimMenu::Submenus
AddCategory(std::move(main));
AddCategory(BuildSpawnVehicleMenu());
AddCategory(VehicleEditorCategory());
AddCategory(PersistCarCategory());
}
}
@@ -0,0 +1,149 @@
#include "PersistCarCategory.hpp"
#include "core/backend/FiberPool.hpp"
#include "core/frontend/Notifications.hpp"
#include "core/util/strings.hpp"
#include "game/backend/Self.hpp"
#include "game/features/vehicle/PersistCarService/PersistCarService.hpp"
#include "game/gta/Vehicle.hpp"
#include "misc/cpp/imgui_stdlib.h"
namespace YimMenu::Submenus
{
std::shared_ptr<Category> PersistCarCategory()
{
static std::string folder{}, file{};
static std::vector<std::string> folders{}, files{};
static char vehicle_file_name_input[64]{};
static char save_folder[50]{};
auto persistCar = std::make_shared<Category>("Persist Car");
persistCar->AddItem(std::make_unique<ImGuiItem>([] {
static auto drawSaveVehicleButton = [](const char* folderToSaveIn) {
if (!Self::GetVehicle() || !Self::GetVehicle().IsValid())
return;
if (ImGui::Button("Save Veh"))
{
std::string yo = vehicle_file_name_input;
ZeroMemory(vehicle_file_name_input, sizeof(vehicle_file_name_input));
if (!trimString(yo).size())
{
Notifications::Show("Persist Car", "Filename empty!", NotificationType::Warning);
return;
}
replace_string(yo, ".", ""); // so that .. does not throw error by custom file system when it sees say bob..json
yo += ".json";
Features::PersistCarService::Save(folderToSaveIn, yo);
Features::PersistCarService::RefreshList(folder, folders, files);
}
ImGui::SameLine();
if (ImGui::Button("Populate Name"))
FiberPool::Push([] {
std::string name = Self::GetVehicle().GetVehicleFullname();
strcpy(vehicle_file_name_input, name.c_str());
});
};
if (ImGui::Button("Refresh List"))
Features::PersistCarService::RefreshList(folder, folders, files);
ImGui::SetNextItemWidth(300.f);
auto folder_display = folder.empty() ? "Root" : folder.c_str();
if (ImGui::BeginCombo("Folder", folder_display))
{
if (ImGui::Selectable("Root", folder == ""))
{
folder.clear();
Features::PersistCarService::RefreshList(folder, folders, files);
}
for (std::string folder_name : folders)
if (ImGui::Selectable(folder_name.c_str(), folder == folder_name))
{
folder = folder_name;
Features::PersistCarService::RefreshList(folder, folders, files);
}
ImGui::EndCombo();
}
static bool open_modal = false;
static std::string search;
ImGui::SetNextItemWidth(300);
if (ImGui::InputTextWithHint("###veh_name", "Search", &search))
std::transform(search.begin(), search.end(), search.begin(), tolower);
ImGui::Text("Saved Vehicles");
static const auto over_30 = (30 * ImGui::GetTextLineHeightWithSpacing() + 2);
const auto box_height = files.size() <= 30 ? (files.size() * ImGui::GetTextLineHeightWithSpacing() + 2) : over_30;
ImGui::SetNextItemWidth(250);
if (ImGui::BeginListBox("##saved_vehs", ImVec2(300, box_height)))
{
for (const auto& pair : files)
{
std::string pair_lower = pair;
std::transform(pair_lower.begin(), pair_lower.end(), pair_lower.begin(), tolower);
if (pair_lower.contains(search))
{
auto file_name = pair.c_str();
if (ImGui::Selectable(file_name, file == pair, ImGuiSelectableFlags_AllowItemOverlap))
{
file = pair;
open_modal = true;
}
}
}
ImGui::EndListBox();
}
ImGui::SameLine();
ImGui::BeginGroup();
{
ImGui::Text("Vehicle File Name");
ImGui::SetNextItemWidth(250);
ImGui::InputText("##vehiclefilename", vehicle_file_name_input, IM_ARRAYSIZE(vehicle_file_name_input));
if (folder.empty())
{
ImGui::Text("Vehicle Folder Name");
ImGui::SetNextItemWidth(250);
ImGui::InputText("##foldername", save_folder, IM_ARRAYSIZE(save_folder));
drawSaveVehicleButton(save_folder);
}
else
drawSaveVehicleButton(folder.c_str());
}
ImGui::EndGroup();
if (open_modal)
ImGui::OpenPopup("##spawncarmodel2");
if (ImGui::BeginPopupModal("##spawncarmodel2", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove))
{
ImGui::Text("Are you sure you want to spawn %s", file.c_str());
ImGui::Spacing();
if (ImGui::Button("Yes"))
{
Features::PersistCarService::Load(folder, file);
open_modal = false;
ImGui::CloseCurrentPopup();
}
ImGui::SameLine();
if (ImGui::Button("No"))
{
open_modal = false;
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
}));
return persistCar;
}
}
@@ -0,0 +1,7 @@
#include "core/frontend/manager/Category.hpp"
#include "game/frontend/items/Items.hpp"
namespace YimMenu::Submenus
{
std::shared_ptr<Category> PersistCarCategory();
}
@@ -0,0 +1,882 @@
#include "VehicleEditorCategory.hpp"
#include "core/backend/FiberPool.hpp"
#include "core/backend/ScriptMgr.hpp"
#include "core/util/VehicleHelper.hpp"
#include "game/backend/Self.hpp"
#include "game/gta/Natives.hpp"
#include "game/gta/data/VehicleValues.hpp"
#include "game/gta/data/lscTypes.hpp"
namespace YimMenu::Submenus
{
std::shared_ptr<Category> VehicleEditorCategory()
{
static int currentVeh = 0;
static std::string vehName = "";
static bool preparingVehicle = false;
static bool isBennys = false;
static int selected_slot = -1;
static std::map<int, int32_t> owned_mods{};
static std::map<int, std::string> slot_display_names{};
static std::map<int, std::map<int, std::string>> mod_display_names{};
static std::map<std::string, std::vector<int>> front_wheel_map{};
static std::map<std::string, std::vector<int>> rear_wheel_map{};
static int front_wheel_stock_mod = -1;
static int rear_wheel_stock_mod = -1;
static auto prepareVehicle = [] {
if (currentVeh != -1) // when == -1 dont change selected slot
selected_slot = -1;
preparingVehicle = true;
FiberPool::Push([] {
currentVeh = Self::GetVehicle().GetHandle();
auto model = Self::GetVehicle().GetModel();
front_wheel_stock_mod = -1;
rear_wheel_stock_mod = -1;
if (!HUD::HAS_THIS_ADDITIONAL_TEXT_LOADED("MOD_MNU", 10))
{
HUD::CLEAR_ADDITIONAL_TEXT(10, TRUE);
HUD::REQUEST_ADDITIONAL_TEXT("MOD_MNU", 10);
ScriptMgr::Yield();
}
vehName = Self::GetVehicle().GetVehicleFullname();
owned_mods = Self::GetVehicle().GetOwnedMods();
isBennys = VehicleHelper::IsBennys(currentVeh);
VEHICLE::SET_VEHICLE_MOD_KIT(currentVeh, 0);
std::map<int, std::string> tmp_slot_display_names;
std::map<int, std::map<int, std::string>> tmp_mod_display_names;
std::map<std::string, std::vector<int>> tmp_front_wheel_map;
std::map<std::string, std::vector<int>> tmp_rear_wheel_map;
tmp_slot_display_names[(int)CustomVehicleModType::MOD_PLATE_STYLE] = "Plate Style";
tmp_slot_display_names[(int)CustomVehicleModType::MOD_WINDOW_TINT] = "Window Tint";
tmp_slot_display_names[(int)CustomVehicleModType::MOD_WHEEL_TYPE] = "Wheel Type";
tmp_mod_display_names[(int)CustomVehicleModType::MOD_PLATE_STYLE].insert(lscPlateStyles.begin(),
lscPlateStyles.end());
tmp_mod_display_names[(int)CustomVehicleModType::MOD_WINDOW_TINT].insert(lscWindowTintTypes.begin(),
lscWindowTintTypes.end());
tmp_mod_display_names[(int)CustomVehicleModType::MOD_WHEEL_TYPE].insert(lscWheelStyles.begin(),
lscWheelStyles.end());
for (int slot = (int)VehicleModType::MOD_SPOILERS; slot <= (int)VehicleModType::MOD_LIGHTBAR; slot++)
{
int count = VEHICLE::GET_NUM_VEHICLE_MODS(currentVeh, slot);
if (count > 0)
{
int owner_mod = owned_mods[slot];
std::string slot_name = VehicleHelper::GetModSlotName(model, currentVeh, slot);
if (slot_name.empty())
continue;
slot_name.append("##" + std::to_string(slot));
tmp_slot_display_names[slot] = slot_name;
std::map<int, std::string> mod_names;
for (int mod = -1; mod < count; mod++)
{
if (VehicleHelper::CheckModBlacklist(model, slot, mod))
continue;
bool is_repeated = false;
std::string mod_name = VehicleHelper::GetModeName(model, currentVeh, slot, mod, count);
if (mod_name.empty() || mod_name == "NULL")
continue;
if (slot == (int)VehicleModType::MOD_FRONTWHEEL)
{
if (isBennys && mod_name.rfind("Chrome ", 0) == 0)
{
std::string new_mod_name = mod_name.substr(7);
if (tmp_front_wheel_map[new_mod_name].size() > 0)
mod_name = new_mod_name;
}
tmp_front_wheel_map[mod_name].push_back(mod);
if (mod == owner_mod)
front_wheel_stock_mod = tmp_front_wheel_map[mod_name][0];
if (tmp_front_wheel_map[mod_name].size() > 1)
is_repeated = true;
}
else if (slot == (int)VehicleModType::MOD_REARWHEEL)
{
if (isBennys && mod_name.rfind("Chrome ", 0) == 0)
{
std::string new_mod_name = mod_name.substr(7);
if (tmp_rear_wheel_map[new_mod_name].size() > 0)
mod_name = new_mod_name;
}
tmp_rear_wheel_map[mod_name].push_back(mod);
if (mod == owner_mod)
rear_wheel_stock_mod = tmp_rear_wheel_map[mod_name][0];
if (tmp_rear_wheel_map[mod_name].size() > 1)
is_repeated = true;
}
if (!is_repeated)
mod_names[mod] = mod_name;
}
tmp_mod_display_names[slot] = mod_names;
}
}
if (tmp_mod_display_names.count((int)VehicleModType::MOD_HORNS) > 0)
tmp_mod_display_names[(int)VehicleModType::MOD_HORNS].insert(lscMissingHorns.begin(),
lscMissingHorns.end());
slot_display_names = tmp_slot_display_names;
mod_display_names = tmp_mod_display_names;
front_wheel_map = tmp_front_wheel_map;
rear_wheel_map = tmp_rear_wheel_map;
preparingVehicle = false;
});
};
auto vehicleEditor = std::make_shared<Category>("Vehicle Editor");
vehicleEditor->AddItem(std::make_unique<ImGuiItem>([] {
if (!Self::GetVehicle())
{
ImGui::Text("Please enter a vehicle.");
currentVeh = 0;
return;
}
if (currentVeh != Self::GetVehicle().GetHandle())
{
prepareVehicle();
return;
}
if (preparingVehicle)
return;
ImGui::BeginGroup();
{
ImGui::Text(vehName.c_str());
ImGui::SameLine();
if (ImGui::Button("Refresh Current Vehicle"))
FiberPool::Push([] {
currentVeh = -1;
});
ImGui::Spacing();
{
static char plate[9];
ImGui::SetNextItemWidth(150);
ImGui::InputTextWithHint("##plate", "Plate Number", plate, sizeof(plate), ImGuiInputTextFlags_None);
ImGui::SameLine();
if (ImGui::Button("Change Plate"))
FiberPool::Push([] {
Self::GetVehicle().SetPlateText(plate);
});
ImGui::SameLine();
if (ImGui::Button("Max Vehicle"))
FiberPool::Push([] {
Self::GetVehicle().Upgrade();
currentVeh = -1;
});
}
ImGui::SeparatorText("Mod Options");
{
if (ImGui::Checkbox("Burstible tires", (bool*)&owned_mods[(int)CustomVehicleModType::MOD_TIRE_CAN_BURST]))
FiberPool::Push([] {
VEHICLE::SET_VEHICLE_TYRES_CAN_BURST(currentVeh, owned_mods[(int)CustomVehicleModType::MOD_TIRE_CAN_BURST]);
});
ImGui::SameLine();
if (ImGui::Checkbox("Low Grip Tires", (bool*)&owned_mods[(int)CustomVehicleModType::MOD_DRIFT_TIRE]))
FiberPool::Push([] {
VEHICLE::SET_DRIFT_TYRES(currentVeh, owned_mods[(int)CustomVehicleModType::MOD_DRIFT_TIRE]);
});
ImGui::SameLine();
if (ImGui::Checkbox("Turbo", (bool*)&owned_mods[(int)VehicleModType::MOD_TURBO]))
FiberPool::Push([] {
VEHICLE::TOGGLE_VEHICLE_MOD(currentVeh, (int)VehicleModType::MOD_TURBO, owned_mods[(int)VehicleModType::MOD_TURBO]);
});
ImGui::SameLine();
if (ImGui::Checkbox("Tire Smoke", (bool*)&owned_mods[(int)VehicleModType::MOD_TYRE_SMOKE]))
FiberPool::Push([] {
VEHICLE::TOGGLE_VEHICLE_MOD(currentVeh, (int)VehicleModType::MOD_TYRE_SMOKE, owned_mods[(int)VehicleModType::MOD_TYRE_SMOKE]);
});
}
ImGui::SeparatorText("Mod Slots");
{
ImGui::BeginGroup();
{
ImGui::Text("Slot");
if (ImGui::BeginListBox("##slot", ImVec2(200, 200)))
{
for (const auto& [slot, name] : slot_display_names)
if (ImGui::Selectable(name.c_str(), slot == selected_slot))
selected_slot = slot;
ImGui::EndListBox();
}
}
ImGui::EndGroup();
if (selected_slot != -1)
{
auto wheel_stock_mod = &front_wheel_stock_mod;
auto wheel_custom = &owned_mods[(int)CustomVehicleModType::MOD_FRONTWHEEL_VAR];
bool is_wheel_mod = false;
if (selected_slot == (int)VehicleModType::MOD_FRONTWHEEL)
is_wheel_mod = true;
else if (selected_slot == (int)VehicleModType::MOD_REARWHEEL)
{
wheel_stock_mod = &rear_wheel_stock_mod;
wheel_custom = &owned_mods[(int)CustomVehicleModType::MOD_REARWHEEL_VAR];
is_wheel_mod = true;
}
else
is_wheel_mod = false;
ImGui::SameLine();
ImGui::BeginGroup();
{
ImGui::Text("Mod");
if (ImGui::BeginListBox("##mod", ImVec2(240, 200)))
{
for (const auto& it : mod_display_names[selected_slot])
{
const auto& mod = it.first;
const auto& name = it.second;
bool item_selected = mod == owned_mods[selected_slot];
if (is_wheel_mod)
item_selected = mod == *wheel_stock_mod;
if (ImGui::Selectable(name.c_str(), item_selected))
{
FiberPool::Push([&mod, is_wheel_mod, wheel_stock_mod, wheel_custom, name] {
if (selected_slot >= 0)
{
VEHICLE::SET_VEHICLE_MOD(currentVeh, selected_slot, mod, 0);
owned_mods[selected_slot] = mod;
if (is_wheel_mod)
{
*wheel_stock_mod = mod;
*wheel_custom = 0;
}
}
else if (selected_slot == (int)CustomVehicleModType::MOD_WINDOW_TINT)
{
VEHICLE::SET_VEHICLE_WINDOW_TINT(currentVeh, mod);
owned_mods[selected_slot] = mod;
}
else if (selected_slot == (int)CustomVehicleModType::MOD_WHEEL_TYPE)
{
VEHICLE::SET_VEHICLE_WHEEL_TYPE(currentVeh, mod);
VEHICLE::SET_VEHICLE_MOD(currentVeh, (int)VehicleModType::MOD_FRONTWHEEL, 0, 0);
VEHICLE::SET_VEHICLE_MOD(currentVeh, (int)VehicleModType::MOD_REARWHEEL, 0, 0);
currentVeh = -1;
}
else if (selected_slot == (int)CustomVehicleModType::MOD_PLATE_STYLE)
{
VEHICLE::SET_VEHICLE_NUMBER_PLATE_TEXT_INDEX(currentVeh, mod);
owned_mods[selected_slot] = mod;
}
});
}
}
ImGui::EndListBox();
}
}
ImGui::EndGroup();
if (is_wheel_mod && *wheel_stock_mod != -1)
{
ImGui::SameLine();
ImGui::BeginGroup();
{
auto wheel_map = selected_slot == (int)VehicleModType::MOD_REARWHEEL ? rear_wheel_map : front_wheel_map;
ImGui::Text("Style");
if (ImGui::BeginListBox("##style", ImVec2(200, 200)))
{
std::string mod_name = mod_display_names[selected_slot][*wheel_stock_mod];
auto wheel_mods = wheel_map[mod_name];
for (int i = 0; i < wheel_mods.size(); i++)
{
int& mod = wheel_mods[i];
int should_custom = 0;
// bennys fix
if (!isBennys)
{
if (i == 0 && ImGui::Selectable("Stock", mod == owned_mods[selected_slot] && *wheel_custom == 0))
FiberPool::Push([&mod] {
VEHICLE::SET_VEHICLE_MOD(currentVeh, selected_slot, mod, 0);
currentVeh = -1;
});
should_custom = 1;
}
if (ImGui::Selectable(("Style " + std::to_string(mod)).c_str(), mod == owned_mods[selected_slot] && *wheel_custom == should_custom))
FiberPool::Push([&mod, should_custom] {
VEHICLE::SET_VEHICLE_MOD(currentVeh, selected_slot, mod, should_custom);
currentVeh = -1;
});
}
ImGui::EndListBox();
}
}
ImGui::EndGroup();
}
}
}
ImGui::SeparatorText("Extras");
{
for (int extra = (int)CustomVehicleModType::MOD_EXTRA_1; extra >= (int)CustomVehicleModType::MOD_EXTRA_14; extra--)
if (owned_mods.find(extra) != owned_mods.end())
{
int id = (extra - (int)CustomVehicleModType::MOD_EXTRA_1) * -1;
bool is_extra_enabled = owned_mods[extra] == 1;
if (ImGui::Checkbox(std::format("{}###extra{}", id, id).c_str(), &is_extra_enabled))
{
owned_mods[extra] = is_extra_enabled;
FiberPool::Push([id, is_extra_enabled] {
VEHICLE::SET_VEHICLE_EXTRA(currentVeh, id, !is_extra_enabled);
});
}
ImGui::SameLine();
}
ImGui::NewLine();
}
ImGui::SeparatorText("Neon Light Options");
{
ImGui::PushID("##headlight_en");
if (ImGui::Checkbox("Headlight", (bool*)&owned_mods[(int)VehicleModType::MOD_XENON_LIGHTS]))
FiberPool::Push([] {
VEHICLE::TOGGLE_VEHICLE_MOD(currentVeh, (int)VehicleModType::MOD_XENON_LIGHTS, owned_mods[(int)VehicleModType::MOD_XENON_LIGHTS]);
});
ImGui::PopID();
ImGui::SameLine();
if (ImGui::Checkbox("Left", (bool*)&owned_mods[(int)CustomVehicleModType::MOD_NEON_LEFT_ON]))
FiberPool::Push([] {
VEHICLE::SET_VEHICLE_NEON_ENABLED(currentVeh, (int)NeonLightLocations::NEON_LEFT, owned_mods[(int)CustomVehicleModType::MOD_NEON_LEFT_ON]);
});
ImGui::SameLine();
if (ImGui::Checkbox("Right", (bool*)&owned_mods[(int)CustomVehicleModType::MOD_NEON_RIGHT_ON]))
FiberPool::Push([] {
VEHICLE::SET_VEHICLE_NEON_ENABLED(currentVeh, (int)NeonLightLocations::NEON_RIGHT, owned_mods[(int)CustomVehicleModType::MOD_NEON_RIGHT_ON]);
});
ImGui::SameLine();
if (ImGui::Checkbox("Front", (bool*)&owned_mods[(int)CustomVehicleModType::MOD_NEON_FRONT_ON]))
FiberPool::Push([] {
VEHICLE::SET_VEHICLE_NEON_ENABLED(currentVeh, (int)NeonLightLocations::NEON_FRONT, owned_mods[(int)CustomVehicleModType::MOD_NEON_FRONT_ON]);
});
ImGui::SameLine();
if (ImGui::Checkbox("Back", (bool*)&owned_mods[(int)CustomVehicleModType::MOD_NEON_BACK_ON]))
FiberPool::Push([] {
VEHICLE::SET_VEHICLE_NEON_ENABLED(currentVeh, (int)NeonLightLocations::NEON_BACK, owned_mods[(int)CustomVehicleModType::MOD_NEON_BACK_ON]);
});
}
ImGui::SeparatorText("Color Options");
{
static int color_to_change = 0;
static int color_type = 9;
if ((color_to_change == 7 && !owned_mods[(int)VehicleModType::MOD_XENON_LIGHTS]) || (color_to_change == 5 && !owned_mods[(int)VehicleModType::MOD_TYRE_SMOKE]))
{
color_to_change = 0;
color_type = 9;
}
if (ImGui::BeginListBox("##color_options", ImVec2(120, 254)))
{
if (ImGui::Selectable("Primary", color_to_change == 0))
color_to_change = 0;
if (ImGui::Selectable("Secondary", color_to_change == 1))
color_to_change = 1;
if (ImGui::Selectable("Pearlescent", color_to_change == 2))
{
color_to_change = 2;
color_type = 7;
}
if (ImGui::Selectable("Interior", color_to_change == 3))
{
color_to_change = 3;
color_type = 10;
}
if (ImGui::Selectable("Dashboard", color_to_change == 4))
{
color_to_change = 4;
color_type = 11;
}
if (!owned_mods[(int)VehicleModType::MOD_TYRE_SMOKE])
ImGui::BeginDisabled();
if (ImGui::Selectable("Tire Smoke", color_to_change == 5))
{
color_to_change = 5;
color_type = 9;
}
if (!owned_mods[(int)VehicleModType::MOD_TYRE_SMOKE])
ImGui::EndDisabled();
if (ImGui::Selectable("Wheel Color", color_to_change == 6))
{
color_to_change = 6;
color_type = 8;
}
if (!owned_mods[(int)VehicleModType::MOD_XENON_LIGHTS])
ImGui::BeginDisabled();
ImGui::PushID("##headlight_col");
if (ImGui::Selectable("Headlight", color_to_change == 7))
{
color_to_change = 7;
color_type = 12;
}
ImGui::PopID();
if (!owned_mods[(int)VehicleModType::MOD_XENON_LIGHTS])
ImGui::EndDisabled();
if (ImGui::Selectable("Neon", color_to_change == 8))
{
color_to_change = 8;
color_type = 9;
}
ImGui::EndListBox();
}
if (color_to_change == 0 || color_to_change == 1)
{
if (color_type > 6)
color_type = 9;
// primary and secondary color
ImGui::SameLine();
if (ImGui::BeginListBox("##colors", ImVec2(140, 254)))
{
if (ImGui::Selectable("Custom", color_type == 9))
color_type = 9;
if (ImGui::Selectable("Remove Custom", false))
FiberPool::Push([] {
if (color_to_change == 0)
VEHICLE::CLEAR_VEHICLE_CUSTOM_PRIMARY_COLOUR(currentVeh);
else
VEHICLE::CLEAR_VEHICLE_CUSTOM_SECONDARY_COLOUR(currentVeh);
VEHICLE::SET_VEHICLE_COLOURS(currentVeh, owned_mods[(int)CustomVehicleModType::MOD_PRIMARY_COL], owned_mods[(int)CustomVehicleModType::MOD_SECONDARY_COL]);
});
if (ImGui::Selectable("Chrome", color_type == 0))
color_type = 0;
if (ImGui::Selectable("Classic", color_type == 1))
color_type = 1;
if (ImGui::Selectable("Matte", color_type == 2))
color_type = 2;
if (ImGui::Selectable("Metals", color_type == 3))
color_type = 3;
if (ImGui::Selectable("Util", color_type == 4))
color_type = 4;
if (ImGui::Selectable("Worn", color_type == 5))
color_type = 5;
if (ImGui::Selectable("Chameleon", color_type == 6))
color_type = 6;
ImGui::EndListBox();
}
}
else if (color_to_change == 7)
ImGui::SameLine();
// **********************************************************************************************************************************
if (color_type == 9)
{
// custom color
static float color[3] = {1, 1, 1};
auto color_r = &owned_mods[(int)CustomVehicleModType::MOD_PRIMARY_COL_R];
auto color_g = &owned_mods[(int)CustomVehicleModType::MOD_PRIMARY_COL_G];
auto color_b = &owned_mods[(int)CustomVehicleModType::MOD_PRIMARY_COL_B];
if (color_to_change == 1)
{
color_r = &owned_mods[(int)CustomVehicleModType::MOD_SECONDARY_COL_R];
color_g = &owned_mods[(int)CustomVehicleModType::MOD_SECONDARY_COL_G];
color_b = &owned_mods[(int)CustomVehicleModType::MOD_SECONDARY_COL_B];
}
else if (color_to_change == 2)
{
color_r = &owned_mods[(int)CustomVehicleModType::MOD_TIRESMOKE_COL_R];
color_g = &owned_mods[(int)CustomVehicleModType::MOD_TIRESMOKE_COL_G];
color_b = &owned_mods[(int)CustomVehicleModType::MOD_TIRESMOKE_COL_B];
}
else if (color_to_change == 3)
{
color_r = &owned_mods[(int)CustomVehicleModType::MOD_NEON_COL_R];
color_g = &owned_mods[(int)CustomVehicleModType::MOD_NEON_COL_G];
color_b = &owned_mods[(int)CustomVehicleModType::MOD_NEON_COL_B];
}
color[0] = (float)*color_r / 255;
color[1] = (float)*color_g / 255;
color[2] = (float)*color_b / 255;
if (color_to_change == 5)
{
ImGui::SameLine();
if (ImGui::BeginListBox("##tire_smoke_rgb", ImVec2(140, 254)))
{
for (const auto& it : lscTireSmokeRgb)
{
auto& name = it.first;
auto& rgb = it.second;
if (ImGui::Selectable(name.c_str(), false))
{
FiberPool::Push([&rgb] {
VEHICLE::SET_VEHICLE_TYRE_SMOKE_COLOR(currentVeh, rgb[0], rgb[1], rgb[2]);
});
*color_r = rgb[0];
*color_g = rgb[1];
*color_b = rgb[2];
}
}
ImGui::EndListBox();
}
}
else if (color_to_change == 8)
{
ImGui::SameLine();
if (ImGui::BeginListBox("##neon_rgb", ImVec2(140, 254)))
{
for (const auto& it : lscNeonRgb)
{
auto& name = it.first;
auto& rgb = it.second;
if (ImGui::Selectable(name.c_str(), false))
{
FiberPool::Push([&rgb] {
VEHICLE::SET_VEHICLE_NEON_COLOUR(currentVeh, rgb[0], rgb[1], rgb[2]);
});
*color_r = rgb[0];
*color_g = rgb[1];
*color_b = rgb[2];
}
}
ImGui::EndListBox();
}
}
ImGui::SameLine();
ImGui::SetNextItemWidth(214);
if (ImGui::ColorPicker3("Custom Vehicle Color", color, ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoDragDrop | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHex))
{
*color_r = (int)(color[0] * 255);
*color_g = (int)(color[1] * 255);
*color_b = (int)(color[2] * 255);
FiberPool::Push([color_r, color_g, color_b] {
switch (color_to_change)
{
case 0:
VEHICLE::SET_VEHICLE_CUSTOM_PRIMARY_COLOUR(currentVeh, *color_r, *color_g, *color_b);
break;
case 1:
VEHICLE::SET_VEHICLE_CUSTOM_SECONDARY_COLOUR(currentVeh, *color_r, *color_g, *color_b);
break;
case 5:
VEHICLE::SET_VEHICLE_TYRE_SMOKE_COLOR(currentVeh, *color_r, *color_g, *color_b);
break;
case 8:
VEHICLE::SET_VEHICLE_NEON_COLOUR(currentVeh, *color_r, *color_g, *color_b);
break;
}
});
}
}
else
{
// standard color
int selected_color = 0;
switch (color_type)
{
case 7: selected_color = owned_mods[(int)CustomVehicleModType::MOD_PEARLESCENT_COL]; break;
case 8: selected_color = owned_mods[(int)CustomVehicleModType::MOD_WHEEL_COL]; break;
case 10: selected_color = owned_mods[(int)CustomVehicleModType::MOD_INTERIOR_COL]; break;
case 11: selected_color = owned_mods[(int)CustomVehicleModType::MOD_DASHBOARD_COL]; break;
case 12: selected_color = owned_mods[(int)CustomVehicleModType::MOD_XENON_COL]; break;
default:
selected_color = (color_to_change == 0) ? owned_mods[(int)CustomVehicleModType::MOD_PRIMARY_COL] : owned_mods[(int)CustomVehicleModType::MOD_SECONDARY_COL];
}
if (color_type != 12)
ImGui::SameLine();
if (ImGui::BeginListBox("##color", ImVec2(180, 254)))
{
switch (color_type)
{
case 0: //Chrome
{
if (ImGui::Selectable("Chrome", selected_color == (int)VehicleColorsChrome::COLOR_CHROME))
{
if (color_to_change == 0)
owned_mods[(int)CustomVehicleModType::MOD_PRIMARY_COL] = (int)VehicleColorsChrome::COLOR_CHROME;
else
owned_mods[(int)CustomVehicleModType::MOD_SECONDARY_COL] = (int)VehicleColorsChrome::COLOR_CHROME;
FiberPool::Push([] {
VEHICLE::SET_VEHICLE_COLOURS(currentVeh, owned_mods[(int)CustomVehicleModType::MOD_PRIMARY_COL], owned_mods[(int)CustomVehicleModType::MOD_SECONDARY_COL]);
});
}
break;
}
case 1: //Classic
{
for (const auto& [color, name] : lscClassicColors)
{
if (ImGui::Selectable(name.c_str(), selected_color == color))
{
selected_color = color;
if (color_to_change == 0)
owned_mods[(int)CustomVehicleModType::MOD_PRIMARY_COL] = color;
else
owned_mods[(int)CustomVehicleModType::MOD_SECONDARY_COL] = color;
FiberPool::Push([] {
VEHICLE::SET_VEHICLE_COLOURS(currentVeh, owned_mods[(int)CustomVehicleModType::MOD_PRIMARY_COL], owned_mods[(int)CustomVehicleModType::MOD_SECONDARY_COL]);
});
}
}
break;
}
case 2: //Matte
{
for (const auto& [color, name] : lscMatteColors)
{
if (ImGui::Selectable(name.c_str(), selected_color == color))
{
selected_color = color;
if (color_to_change == 0)
owned_mods[(int)CustomVehicleModType::MOD_PRIMARY_COL] = color;
else
owned_mods[(int)CustomVehicleModType::MOD_SECONDARY_COL] = color;
FiberPool::Push([] {
VEHICLE::SET_VEHICLE_COLOURS(currentVeh, owned_mods[(int)CustomVehicleModType::MOD_PRIMARY_COL], owned_mods[(int)CustomVehicleModType::MOD_SECONDARY_COL]);
});
}
}
break;
}
case 3: //Metals
{
for (const auto& [color, name] : lscMetalColors)
{
if (ImGui::Selectable(name.c_str(), selected_color == color))
{
selected_color = color;
if (color_to_change == 0)
owned_mods[(int)CustomVehicleModType::MOD_PRIMARY_COL] = color;
else
owned_mods[(int)CustomVehicleModType::MOD_SECONDARY_COL] = color;
FiberPool::Push([] {
VEHICLE::SET_VEHICLE_COLOURS(currentVeh, owned_mods[(int)CustomVehicleModType::MOD_PRIMARY_COL], owned_mods[(int)CustomVehicleModType::MOD_SECONDARY_COL]);
});
}
}
break;
}
case 4: //Util
{
for (const auto& [color, name] : lscUtilColors)
{
if (ImGui::Selectable(name.c_str(), selected_color == color))
{
selected_color = color;
if (color_to_change == 0)
owned_mods[(int)CustomVehicleModType::MOD_PRIMARY_COL] = color;
else
owned_mods[(int)CustomVehicleModType::MOD_SECONDARY_COL] = color;
FiberPool::Push([] {
VEHICLE::SET_VEHICLE_COLOURS(currentVeh, owned_mods[(int)CustomVehicleModType::MOD_PRIMARY_COL], owned_mods[(int)CustomVehicleModType::MOD_SECONDARY_COL]);
});
}
}
break;
}
case 5: //Worn
{
for (const auto& [color, name] : lscWornColors)
{
if (ImGui::Selectable(name.c_str(), selected_color == color))
{
selected_color = color;
if (color_to_change == 0)
owned_mods[(int)CustomVehicleModType::MOD_PRIMARY_COL] = color;
else
owned_mods[(int)CustomVehicleModType::MOD_SECONDARY_COL] = color;
FiberPool::Push([] {
VEHICLE::SET_VEHICLE_COLOURS(currentVeh, owned_mods[(int)CustomVehicleModType::MOD_PRIMARY_COL], owned_mods[(int)CustomVehicleModType::MOD_SECONDARY_COL]);
});
}
}
break;
}
case 6: //Chameleon
{
for (const auto& [color, name] : lscChameleonColors)
{
if (ImGui::Selectable(name.c_str(), selected_color == color))
{
selected_color = color;
if (color_to_change == 0)
owned_mods[(int)CustomVehicleModType::MOD_PRIMARY_COL] = color;
else
owned_mods[(int)CustomVehicleModType::MOD_SECONDARY_COL] = color;
FiberPool::Push([] {
VEHICLE::SET_VEHICLE_COLOURS(currentVeh, owned_mods[(int)CustomVehicleModType::MOD_PRIMARY_COL], owned_mods[(int)CustomVehicleModType::MOD_SECONDARY_COL]);
});
}
}
break;
}
case 7: //Pearlescent
{
for (const auto& [color, name] : lscClassicColors)
{
if (ImGui::Selectable(name.c_str(), selected_color == color))
{
selected_color = color;
owned_mods[(int)CustomVehicleModType::MOD_PEARLESCENT_COL] = color;
FiberPool::Push([] {
VEHICLE::SET_VEHICLE_EXTRA_COLOURS(currentVeh, owned_mods[(int)CustomVehicleModType::MOD_PEARLESCENT_COL], owned_mods[(int)CustomVehicleModType::MOD_WHEEL_COL]);
});
}
}
break;
}
case 8: //Wheel Color
{
constexpr auto alloy_color = 156;
if (ImGui::Selectable("Alloy", selected_color == alloy_color))
{
selected_color = alloy_color;
owned_mods[(int)CustomVehicleModType::MOD_WHEEL_COL] = alloy_color;
FiberPool::Push([] {
VEHICLE::SET_VEHICLE_EXTRA_COLOURS(currentVeh, owned_mods[(int)CustomVehicleModType::MOD_PEARLESCENT_COL], owned_mods[(int)CustomVehicleModType::MOD_WHEEL_COL]);
});
}
for (const auto& [color, name] : lscClassicColors)
{
if (ImGui::Selectable(name.c_str(), selected_color == color))
{
selected_color = color;
owned_mods[(int)CustomVehicleModType::MOD_WHEEL_COL] = color;
FiberPool::Push([] {
VEHICLE::SET_VEHICLE_EXTRA_COLOURS(currentVeh, owned_mods[(int)CustomVehicleModType::MOD_PEARLESCENT_COL], owned_mods[(int)CustomVehicleModType::MOD_WHEEL_COL]);
});
}
}
for (const auto& [color, name] : lscChameleonColors)
{
if (ImGui::Selectable(name.c_str(), selected_color == color))
{
selected_color = color;
owned_mods[(int)CustomVehicleModType::MOD_WHEEL_COL] = color;
FiberPool::Push([] {
VEHICLE::SET_VEHICLE_EXTRA_COLOURS(currentVeh, owned_mods[(int)CustomVehicleModType::MOD_PEARLESCENT_COL], owned_mods[(int)CustomVehicleModType::MOD_WHEEL_COL]);
});
}
}
break;
}
case 10: //Interior Color
{
for (const auto& [color, name] : lscClassicColors)
{
if (ImGui::Selectable(name.c_str(), selected_color == color))
{
selected_color = color;
owned_mods[(int)CustomVehicleModType::MOD_INTERIOR_COL] = color;
FiberPool::Push([] {
VEHICLE::SET_VEHICLE_EXTRA_COLOUR_5(currentVeh, owned_mods[(int)CustomVehicleModType::MOD_INTERIOR_COL]);
});
}
}
break;
}
case 11: //Dashboard Color
{
for (const auto& [color, name] : lscClassicColors)
{
if (ImGui::Selectable(name.c_str(), selected_color == color))
{
selected_color = color;
owned_mods[(int)CustomVehicleModType::MOD_DASHBOARD_COL] = color;
FiberPool::Push([] {
VEHICLE::SET_VEHICLE_EXTRA_COLOUR_6(currentVeh, owned_mods[(int)CustomVehicleModType::MOD_DASHBOARD_COL]);
});
}
}
break;
}
case 12: //Headlight Color
{
for (const auto& [color, name] : lscHeadlightColors)
{
if (ImGui::Selectable(name.c_str(), selected_color == color))
{
selected_color = color;
owned_mods[(int)CustomVehicleModType::MOD_XENON_COL] = color;
FiberPool::Push([] {
VEHICLE::SET_VEHICLE_XENON_LIGHT_COLOR_INDEX(currentVeh, owned_mods[(int)CustomVehicleModType::MOD_XENON_COL]);
});
}
}
break;
}
}
ImGui::EndListBox();
}
}
}
}
ImGui::EndGroup();
}));
return vehicleEditor;
}
}
@@ -0,0 +1,7 @@
#include "core/frontend/manager/Category.hpp"
#include "game/frontend/items/Items.hpp"
namespace YimMenu::Submenus
{
std::shared_ptr<Category> VehicleEditorCategory();
}
+88
View File
@@ -3,6 +3,7 @@
#include "core/backend/ScriptMgr.hpp"
#include "game/pointers/Pointers.hpp"
#include "game/gta/data/VehicleValues.hpp"
#include "game/gta/data/vehicles.hpp"
namespace YimMenu
{
@@ -145,4 +146,91 @@ namespace YimMenu
VEHICLE::SET_ROCKET_BOOST_FILL(GetHandle(), percentage);
}
std::string Vehicle::GetVehicleFullname()
{
auto model = ENTITY::GET_ENTITY_MODEL(GetHandle());
std::string gxt = VEHICLE::GET_DISPLAY_NAME_FROM_VEHICLE_MODEL(model);
std::string display = HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(gxt.c_str());
std::string finalName = display == "NULL" ? gxt : display;
std::string maker = HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(VEHICLE::GET_MAKE_NAME_FROM_VEHICLE_MODEL(model));
if (maker != "NULL")
finalName = maker + " " + finalName;
int id = VEHICLE::GET_VEHICLE_CLASS_FROM_NAME(model);
finalName = std::string(g_VehicleClassNames[id]) + " " + finalName;
return finalName;
}
std::map<int, int32_t> Vehicle::GetOwnedMods()
{
auto vehicle = GetHandle();
std::map<int, int32_t> ownedMods;
for (int i = (int)CustomVehicleModType::MOD_SECONDARY_CUSTOM; i <= (int)CustomVehicleModType::MOD_MODEL_HASH; i++)
{
ownedMods[i] = 0;
}
ownedMods[(int)CustomVehicleModType::MOD_MODEL_HASH] = ENTITY::GET_ENTITY_MODEL(vehicle);
ownedMods[(int)CustomVehicleModType::MOD_PLATE_STYLE] = VEHICLE::GET_VEHICLE_NUMBER_PLATE_TEXT_INDEX(vehicle);
ownedMods[(int)CustomVehicleModType::MOD_WINDOW_TINT] = VEHICLE::GET_VEHICLE_WINDOW_TINT(vehicle);
ownedMods[(int)CustomVehicleModType::MOD_WHEEL_TYPE] = VEHICLE::GET_VEHICLE_WHEEL_TYPE(vehicle);
VEHICLE::GET_VEHICLE_COLOURS(vehicle, &ownedMods[(int)CustomVehicleModType::MOD_PRIMARY_COL], &ownedMods[(int)CustomVehicleModType::MOD_SECONDARY_COL]);
VEHICLE::GET_VEHICLE_EXTRA_COLOURS(vehicle, &ownedMods[(int)CustomVehicleModType::MOD_PEARLESCENT_COL], &ownedMods[(int)CustomVehicleModType::MOD_WHEEL_COL]);
VEHICLE::GET_VEHICLE_EXTRA_COLOUR_5(vehicle, &ownedMods[(int)CustomVehicleModType::MOD_INTERIOR_COL]);
VEHICLE::GET_VEHICLE_EXTRA_COLOUR_6(vehicle, &ownedMods[(int)CustomVehicleModType::MOD_DASHBOARD_COL]);
ownedMods[(int)CustomVehicleModType::MOD_PRIMARY_CUSTOM] = VEHICLE::GET_IS_VEHICLE_PRIMARY_COLOUR_CUSTOM(vehicle);
if (ownedMods[(int)CustomVehicleModType::MOD_PRIMARY_CUSTOM])
{
VEHICLE::GET_VEHICLE_CUSTOM_PRIMARY_COLOUR(vehicle, &ownedMods[(int)CustomVehicleModType::MOD_PRIMARY_COL_R], &ownedMods[(int)CustomVehicleModType::MOD_PRIMARY_COL_G], &ownedMods[(int)CustomVehicleModType::MOD_PRIMARY_COL_B]);
}
ownedMods[(int)CustomVehicleModType::MOD_SECONDARY_CUSTOM] = VEHICLE::GET_IS_VEHICLE_SECONDARY_COLOUR_CUSTOM(vehicle);
if (ownedMods[(int)CustomVehicleModType::MOD_SECONDARY_CUSTOM])
{
VEHICLE::GET_VEHICLE_CUSTOM_SECONDARY_COLOUR(vehicle, &ownedMods[(int)CustomVehicleModType::MOD_SECONDARY_COL_R], &ownedMods[(int)CustomVehicleModType::MOD_SECONDARY_COL_G], &ownedMods[(int)CustomVehicleModType::MOD_SECONDARY_COL_B]);
}
ownedMods[(int)VehicleModType::MOD_TYRE_SMOKE] = VEHICLE::IS_TOGGLE_MOD_ON(vehicle, (int)VehicleModType::MOD_TYRE_SMOKE);
if (ownedMods[(int)VehicleModType::MOD_TYRE_SMOKE])
{
VEHICLE::GET_VEHICLE_TYRE_SMOKE_COLOR(vehicle, &ownedMods[(int)CustomVehicleModType::MOD_TIRESMOKE_COL_R], &ownedMods[(int)CustomVehicleModType::MOD_TIRESMOKE_COL_G], &ownedMods[(int)CustomVehicleModType::MOD_TIRESMOKE_COL_B]);
}
ownedMods[(int)VehicleModType::MOD_XENON_LIGHTS] = VEHICLE::IS_TOGGLE_MOD_ON(vehicle, (int)VehicleModType::MOD_XENON_LIGHTS);
if (ownedMods[(int)VehicleModType::MOD_XENON_LIGHTS])
{
ownedMods[(int)CustomVehicleModType::MOD_XENON_COL] = (int8_t)VEHICLE::GET_VEHICLE_XENON_LIGHT_COLOR_INDEX(vehicle);
}
ownedMods[(int)CustomVehicleModType::MOD_NEON_LEFT_ON] = VEHICLE::GET_VEHICLE_NEON_ENABLED(vehicle, (int)NeonLightLocations::NEON_LEFT);
ownedMods[(int)CustomVehicleModType::MOD_NEON_RIGHT_ON] = VEHICLE::GET_VEHICLE_NEON_ENABLED(vehicle, (int)NeonLightLocations::NEON_RIGHT);
ownedMods[(int)CustomVehicleModType::MOD_NEON_FRONT_ON] = VEHICLE::GET_VEHICLE_NEON_ENABLED(vehicle, (int)NeonLightLocations::NEON_FRONT);
ownedMods[(int)CustomVehicleModType::MOD_NEON_BACK_ON] = VEHICLE::GET_VEHICLE_NEON_ENABLED(vehicle, (int)NeonLightLocations::NEON_BACK);
VEHICLE::GET_VEHICLE_NEON_COLOUR(vehicle, &ownedMods[(int)CustomVehicleModType::MOD_NEON_COL_R], &ownedMods[(int)CustomVehicleModType::MOD_NEON_COL_G], &ownedMods[(int)CustomVehicleModType::MOD_NEON_COL_B]);
ownedMods[(int)CustomVehicleModType::MOD_TIRE_CAN_BURST] = VEHICLE::GET_VEHICLE_TYRES_CAN_BURST(vehicle);
ownedMods[(int)CustomVehicleModType::MOD_DRIFT_TIRE] = VEHICLE::GET_DRIFT_TYRES_SET(vehicle);
ownedMods[(int)VehicleModType::MOD_TURBO] = VEHICLE::IS_TOGGLE_MOD_ON(vehicle, (int)VehicleModType::MOD_TURBO);
ownedMods[(int)CustomVehicleModType::MOD_FRONTWHEEL_VAR] = VEHICLE::GET_VEHICLE_MOD_VARIATION(vehicle, (int)VehicleModType::MOD_FRONTWHEEL);
ownedMods[(int)CustomVehicleModType::MOD_REARWHEEL_VAR] = VEHICLE::GET_VEHICLE_MOD_VARIATION(vehicle, (int)VehicleModType::MOD_REARWHEEL);
for (int slot = (int)VehicleModType::MOD_SPOILERS; slot <= (int)VehicleModType::MOD_LIGHTBAR; slot++)
if (VEHICLE::GET_NUM_VEHICLE_MODS(vehicle, slot) > 0)
ownedMods[slot] = VEHICLE::GET_VEHICLE_MOD(vehicle, slot);
for (int extra = (int)CustomVehicleModType::MOD_EXTRA_14; extra <= (int)CustomVehicleModType::MOD_EXTRA_1; ++extra)
if (auto id = (extra - (int)CustomVehicleModType::MOD_EXTRA_1) * -1; VEHICLE::DOES_EXTRA_EXIST(vehicle, id))
ownedMods[extra] = VEHICLE::IS_VEHICLE_EXTRA_TURNED_ON(vehicle, id);
return ownedMods;
}
}
+3
View File
@@ -22,6 +22,7 @@ namespace YimMenu
// mods
void Upgrade();
void SetPlateText(std::string_view text);
std::map<int, int32_t> GetOwnedMods();
// seats
bool IsSeatFree(int seat);
@@ -30,5 +31,7 @@ namespace YimMenu
bool SupportsBoost();
bool IsBoostActive();
void SetBoostCharge(int percentage = 100);
std::string GetVehicleFullname();
};
}
+66
View File
@@ -629,6 +629,72 @@ enum class VehicleColorsClassic
COLOR_CLASSIC_SECRET_GOLD = 160
};
enum class VehicleColorsChameleon
{
ANOD_RED = 161,
ANOD_WINE = 162,
ANOD_PURPLE = 163,
ANOD_BLUE = 164,
ANOD_GREEN = 165,
ANOD_LIME = 166,
ANOD_COPPER = 167,
ANOD_BRONZE = 168,
ANOD_CHAMPAGNE = 169,
ANOD_GOLD = 170,
GREEN_BLUE_FLIP = 171,
GREEN_RED_FLIP = 172,
GREEN_BROW_FLIP = 173,
GREEN_TURQ_FLIP = 174,
GREEN_PURP_FLIP = 175,
TEAL_PURP_FLIP = 176,
TURQ_RED_FLIP = 177,
TURQ_PURP_FLIP = 178,
CYAN_PURP_FLIP = 179,
BLUE_PINK_FLIP = 180,
BLUE_GREEN_FLIP = 181,
PURP_RED_FLIP = 182,
PURP_GREEN_FLIP = 183,
MAGEN_GREE_FLIP = 184,
MAGEN_YELL_FLIP = 185,
BURG_GREEN_FLIP = 186,
MAGEN_CYAN_FLIP = 187,
COPPE_PURP_FLIP = 188,
MAGEN_ORAN_FLIP = 189,
RED_ORANGE_FLIP = 190,
ORANG_PURP_FLIP = 191,
ORANG_BLUE_FLIP = 192,
WHITE_PURP_FLIP = 193,
RED_RAINBO_FLIP = 194,
BLU_RAINBO_FLIP = 195,
DARKGREENPEARL = 196,
DARKTEALPEARL = 197,
DARKBLUEPEARL = 198,
DARKPURPLEPEARL = 199,
OIL_SLICK_PEARL = 200,
LIT_GREEN_PEARL = 201,
LIT_BLUE_PEARL = 202,
LIT_PURP_PEARL = 203,
LIT_PINK_PEARL = 204,
OFFWHITE_PRISMA = 205,
PINK_PEARL = 206,
YELLOW_PEARL = 207,
GREEN_PEARL = 208,
BLUE_PEARL = 209,
CREAM_PEARL = 210,
WHITE_PRISMA = 211,
GRAPHITE_PRISMA = 212,
DARKBLUEPRISMA = 213,
DARKPURPPRISMA = 214,
HOT_PINK_PRISMA = 215,
RED_PRISMA = 216,
GREEN_PRISMA = 217,
BLACK_PRISMA = 218,
OIL_SLIC_PRISMA = 219,
RAINBOW_PRISMA = 220,
BLACK_HOLO = 221,
WHITE_HOLO = 222
};
enum class VehicleColorsMatte
{
COLOR_MATTE_BLACK = 12,
+344
View File
@@ -0,0 +1,344 @@
#pragma once
#include "VehicleValues.hpp"
inline const std::map<int, std::string> lscPlateStyles = {
{(int)PlateTextIndexs::PLATE_BLUEONWHITE1, "Blue on White 1"},
{(int)PlateTextIndexs::PLATE_YELLOWONBLACK, "Yellow on Black"},
{(int)PlateTextIndexs::PLATE_YELLOWONBLUE, "Yellow on Blue"},
{(int)PlateTextIndexs::PLATE_BLUEONWHITE2, "Blue on White 2"},
{(int)PlateTextIndexs::PLATE_BLUEONWHITE3, "Blue on White 3"},
{(int)PlateTextIndexs::PLATE_YANKTON, "Yankton"},
{(int)PlateTextIndexs::PLATE_ECOLA, "Ecola"},
{(int)PlateTextIndexs::PLATE_LASVENTURAS, "Las Venturas"},
{(int)PlateTextIndexs::PLATE_LIBERTYCITY, "Liberty City"},
{(int)PlateTextIndexs::PLATE_LOSSANTOSCARMEET, "Los Santos Car Meet"},
{(int)PlateTextIndexs::PLATE_LOSSANTOSPANIC, "Los Santos Panicc"},
{(int)PlateTextIndexs::PLATE_LOSSANTOSPOUNDERS, "Los Santos Pounders"},
{(int)PlateTextIndexs::PLATE_SPRUNK, "Sprunk"},
};
inline const std::map<int, std::string> lscWheelStyles = {
{(int)WheelTypes::WHEEL_TYPE_SPORT, "Sport"},
{(int)WheelTypes::WHEEL_TYPE_MUSCLE, "Muscle"},
{(int)WheelTypes::WHEEL_TYPE_LOWRIDER, "Lowrider"},
{(int)WheelTypes::WHEEL_TYPE_SUV, "SUV"},
{(int)WheelTypes::WHEEL_TYPE_OFFROAD, "Offroad"},
{(int)WheelTypes::WHEEL_TYPE_TUNER, "Tuner"},
{(int)WheelTypes::WHEEL_TYPE_BIKEWHEELS, "Bike Wheels"},
{(int)WheelTypes::WHEEL_TYPE_HIGHEND, "High End"},
{(int)WheelTypes::WHEEL_TYPE_BENNYS_ORIGINAL, "Bennys Original"},
{(int)WheelTypes::WHEEL_TYPE_BENNYS_BESPOKE, "Bennys Bespoke"},
{(int)WheelTypes::WHEEL_TYPE_OPEN_WHEEL, "Open Wheel"},
{(int)WheelTypes::WHEEL_TYPE_STREET, "Street"},
{(int)WheelTypes::WHEEL_TYPE_TRACK, "Track"},
};
inline const std::map<int, std::string> lscWindowTintTypes = {
{(int)WindowTints::WINDOWTINT_NONE, "None"},
{(int)WindowTints::WINDOWTINT_BLACK, "Black"},
{(int)WindowTints::WINDOWTINT_DARKSMOKE, "Dark"},
{(int)WindowTints::WINDOWTINT_LIGHTSMOKE, "Light"},
{(int)WindowTints::WINDOWTINT_STOCK, "Stock"},
{(int)WindowTints::WINDOWTINT_LIMO, "Limo"},
{(int)WindowTints::WINDOWTINT_GREEN, "Green"},
};
inline const std::map<int, std::string> lscClassicColors = {
{(int)VehicleColorsClassic::COLOR_CLASSIC_BLACK, "Black"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_CARBON_BLACK, "Carbon Black"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_GRAPHITE, "Graphite"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_ANTHRACITE_BLACK, "Anthracite Black"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_BLACK_STEEL, "Black Steel"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_DARK_STEEL, "Dark Steel"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_SILVER, "Silver"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_BLUISH_SILVER, "Bluish Silver"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_ROLLED_STEEL, "Rolled Steel"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_SHADOW_SILVER, "Shadow SIlver"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_STONE_SILVER, "Stone Silver"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_MIDNIGHT_SILVER, "Midnight Silver"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_CAST_IRON_SILVER, "Cast Iron Silver"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_RED, "Red"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_TORINO_RED, "Torino Red"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_FORMULA_RED, "Formula Red"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_LAVA_RED, "Lava Red"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_BLAZE_RED, "Blaze Red"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_GRACE_RED, "Grace Red"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_GARNET_RED, "Garnet Red"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_SUNSET_RED, "Sunset Red"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_CABERNET_RED, "Cabernet Red"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_WINE_RED, "Wine Red"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_CANDY_RED, "Candy Red"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_HOT_PINK, "Hot Pink"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_PFSITER_PINK, "Pfister Pink"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_SALMON_PINK, "Salmon Pink"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_SUNRISE_ORANGE, "Sunrise Orange"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_ORANGE, "Orange"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_BRIGHT_ORANGE, "Bright Orange"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_GOLD, "Gold"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_BRONZE, "Bronze"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_YELLOW, "Yellow"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_RACE_YELLOW, "Race Yellow"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_DEW_YELLOW, "Dew Yellow"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_DARK_GREEN, "Dark Green"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_RACING_GREEN, "Racing Green"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_SEA_GREEN, "Sea Green"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_OLIVE_GREEN, "Olive Green"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_BRIGHT_GREEN, "Bright Green"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_GASOLINE_GREEN, "Gasoline Green"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_LIME_GREEN, "Lime Green"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_MIDNIGHT_BLUE, "Midnight Blue"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_GALAXY_BLUE, "Galaxy Blue"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_DARK_BLUE, "Dark Blue"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_SAXON_BLUE, "Saxon Blue"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_BLUE, "Blue"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_MARINER_BLUE, "Mariner Blue"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_HARBOR_BLUE, "Harbor Blue"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_DIAMOND_BLUE, "Diamond Blue"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_SURF_BLUE, "Surf Blue"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_NAUTICAL_BLUE, "Nautical Blue"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_RACING_BLUE, "Racing Blue"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_ULTRA_BLUE, "Ultra Blue"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_LIGHT_BLUE, "Light Blue"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_CHOCOLATE_BROWN, "Chocolate Brown"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_BISON_BROWN, "Bison Brown"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_CREEK_BROWN, "Creek Brown"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_FELTZER_BROWN, "Feltzer Brown"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_MAPLE_BROWN, "Maple Brown"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_BEECHWOOD_BROWN, "Beechwood Brown"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_SIENNA_BROWN, "Sienna Brown"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_SADDLE_BROWN, "Saddle Brown"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_MOSS_BROWN, "Moss Brown"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_WOODBEECH_BROWN, "Woodbeech Brown"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_STRAW_BROWN, "Straw Brown"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_SANDY_BROWN, "Sandy Brown"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_BLEACHED_BROWN, "Bleached Brown"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_SCHAFTER_PURPLE, "Schafter Purple"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_SPINNAKER_PURPLE, "Spinnaker Purple"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_MIDNIGHT_PURPLE, "Midnight Purple"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_BRIGHT_PURPLE, "Bright Purple"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_CREAM, "Cream"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_ICE_WHITE, "Ice White"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_FROST_WHITE, "Frost White"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_CLASSIC_GOLD, "Classic Gold"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_GREEN, "Green"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_HUNTER_GREEN, "Hunter Green"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_SECURICOR_GREEN, "Securicor Green"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_EPSILON_BLUE, "Epsilon Blue"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_FLOURESCENT_BLUE, "Flourescent Blue"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_V_DARK_BLUE, "V Dark Blue"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_POLICE_BLUE, "Police Blue"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_CHAMPAGNE, "Champagne"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_PURE_WHITE, "Pure White"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_DEFAULT_ALLOY, "Default Alloy"},
{(int)VehicleColorsClassic::COLOR_CLASSIC_SECRET_GOLD, "Secret Gold"},
};
inline const std::map<int, std::string> lscMatteColors = {
{(int)VehicleColorsMatte::COLOR_MATTE_BLACK, "Black"},
{(int)VehicleColorsMatte::COLOR_MATTE_GRAY, "Gray"},
{(int)VehicleColorsMatte::COLOR_MATTE_LIGHT_GRAY, "Light Gray"},
{(int)VehicleColorsMatte::COLOR_MATTE_ICE_WHITE, "Ice White"},
{(int)VehicleColorsMatte::COLOR_MATTE_BLUE, "Blue"},
{(int)VehicleColorsMatte::COLOR_MATTE_DARK_BLUE, "Dark Blue"},
{(int)VehicleColorsMatte::COLOR_MATTE_MIDNIGHT_BLUE, "Midnight Blue"},
{(int)VehicleColorsMatte::COLOR_MATTE_MIDNIGHT_PURPLE, "Midnight Purple"},
{(int)VehicleColorsMatte::COLOR_MATTE_SCHAFTER_PURPLE, "Shafter Purple"},
{(int)VehicleColorsMatte::COLOR_MATTE_RED, "Red"},
{(int)VehicleColorsMatte::COLOR_MATTE_DARK_RED, "Dark Red"},
{(int)VehicleColorsMatte::COLOR_MATTE_ORANGE, "Orange"},
{(int)VehicleColorsMatte::COLOR_MATTE_YELLOW, "Yellow"},
{(int)VehicleColorsMatte::COLOR_MATTE_LIME_GREEN, "Lime Green"},
{(int)VehicleColorsMatte::COLOR_MATTE_GREEN, "Green"},
{(int)VehicleColorsMatte::COLOR_MATTE_FOREST_GREEN, "Forest Green"},
{(int)VehicleColorsMatte::COLOR_MATTE_FOLIAGE_GREEN, "Foliage Green"},
{(int)VehicleColorsMatte::COLOR_MATTE_OLIVE_DRAB, "Olive Drab"},
{(int)VehicleColorsMatte::COLOR_MATTE_DARK_EARTH, "Dark Earth"},
{(int)VehicleColorsMatte::COLOR_MATTE_DESERT_TAN, "Desert Tan"},
{(int)VehicleColorsMatte::COLOR_MATTE_BROWN, "Brown"},
};
inline const std::map<int, std::string> lscChameleonColors = {
{(int)VehicleColorsChameleon::ANOD_RED , "Anodized Red"},
{(int)VehicleColorsChameleon::ANOD_WINE , "Anodized Wine"},
{(int)VehicleColorsChameleon::ANOD_PURPLE , "Anodized Purple"},
{(int)VehicleColorsChameleon::ANOD_BLUE , "Anodized Blue"},
{(int)VehicleColorsChameleon::ANOD_GREEN , "Anodized Green"},
{(int)VehicleColorsChameleon::ANOD_LIME , "Anodized Lime"},
{(int)VehicleColorsChameleon::ANOD_COPPER , "Anodized Copper"},
{(int)VehicleColorsChameleon::ANOD_BRONZE , "Anodized Bronze"},
{(int)VehicleColorsChameleon::ANOD_CHAMPAGNE , "Anodized Champagne"},
{(int)VehicleColorsChameleon::ANOD_GOLD , "Anodized Gold"},
{(int)VehicleColorsChameleon::GREEN_BLUE_FLIP , "Green Blue Flip"},
{(int)VehicleColorsChameleon::GREEN_RED_FLIP , "Green Red Flip"},
{(int)VehicleColorsChameleon::GREEN_BROW_FLIP , "Green Brown Flip"},
{(int)VehicleColorsChameleon::GREEN_TURQ_FLIP , "Green Turqoise Flip"},
{(int)VehicleColorsChameleon::GREEN_PURP_FLIP , "Green Purple Flip"},
{(int)VehicleColorsChameleon::TEAL_PURP_FLIP , "Teal Purple Flip"},
{(int)VehicleColorsChameleon::TURQ_RED_FLIP , "Turqoise Red Flip"},
{(int)VehicleColorsChameleon::TURQ_PURP_FLIP , "Turquoise Purple Flip"},
{(int)VehicleColorsChameleon::CYAN_PURP_FLIP , "Cyan Purple Flip"},
{(int)VehicleColorsChameleon::BLUE_PINK_FLIP , "Blue Pink Flip"},
{(int)VehicleColorsChameleon::BLUE_GREEN_FLIP , "Blue Green Flip"},
{(int)VehicleColorsChameleon::PURP_RED_FLIP , "Purple Red Flip"},
{(int)VehicleColorsChameleon::PURP_GREEN_FLIP , "Purple Green Flip"},
{(int)VehicleColorsChameleon::MAGEN_GREE_FLIP , "Magenta Green Flip"},
{(int)VehicleColorsChameleon::MAGEN_YELL_FLIP , "Magenta Yellow Flip"},
{(int)VehicleColorsChameleon::BURG_GREEN_FLIP , "Burgundy Green Flip"},
{(int)VehicleColorsChameleon::MAGEN_CYAN_FLIP , "Magenta Cyan Flip"},
{(int)VehicleColorsChameleon::COPPE_PURP_FLIP , "Copper Purple Flip"},
{(int)VehicleColorsChameleon::MAGEN_ORAN_FLIP , "Magenta Orange Flip"},
{(int)VehicleColorsChameleon::RED_ORANGE_FLIP , "Red Orange Flip"},
{(int)VehicleColorsChameleon::ORANG_PURP_FLIP , "Orange Purple Flip"},
{(int)VehicleColorsChameleon::ORANG_BLUE_FLIP , "Orange Blue Flip"},
{(int)VehicleColorsChameleon::WHITE_PURP_FLIP , "White Purple Flip"},
{(int)VehicleColorsChameleon::RED_RAINBO_FLIP , "Red Rainbow Flip"},
{(int)VehicleColorsChameleon::BLU_RAINBO_FLIP , "Blue Rainbow Flip"},
{(int)VehicleColorsChameleon::DARKGREENPEARL , "Dark Green Pearl"},
{(int)VehicleColorsChameleon::DARKTEALPEARL , "Dark Teal Pearl"},
{(int)VehicleColorsChameleon::DARKBLUEPEARL , "Dark Blue Pearl"},
{(int)VehicleColorsChameleon::DARKPURPLEPEARL , "Dark Purple Pearl"},
{(int)VehicleColorsChameleon::OIL_SLICK_PEARL , "Oil Slick Pearl"},
{(int)VehicleColorsChameleon::LIT_GREEN_PEARL , "Light Green Pearl"},
{(int)VehicleColorsChameleon::LIT_BLUE_PEARL , "Light Blue Pearl"},
{(int)VehicleColorsChameleon::LIT_PURP_PEARL , "Light Purple Pearl"},
{(int)VehicleColorsChameleon::LIT_PINK_PEARL , "Light Pink Pearl"},
{(int)VehicleColorsChameleon::OFFWHITE_PRISMA , "Off White Pearl"},
{(int)VehicleColorsChameleon::PINK_PEARL , "Pink Pearl"},
{(int)VehicleColorsChameleon::YELLOW_PEARL , "Yellow Pearl"},
{(int)VehicleColorsChameleon::GREEN_PEARL , "Green Pearl"},
{(int)VehicleColorsChameleon::BLUE_PEARL , "Blue Pearl"},
{(int)VehicleColorsChameleon::CREAM_PEARL , "Cream Pearl"},
{(int)VehicleColorsChameleon::WHITE_PRISMA , "White Prismatic"},
{(int)VehicleColorsChameleon::GRAPHITE_PRISMA , "Graphite Prismatic"},
{(int)VehicleColorsChameleon::DARKBLUEPRISMA , "Dark Blue Prismatic"},
{(int)VehicleColorsChameleon::DARKPURPPRISMA , "Dark Purple Prismatic"},
{(int)VehicleColorsChameleon::HOT_PINK_PRISMA , "Hot Pink Prismatic"},
{(int)VehicleColorsChameleon::RED_PRISMA , "Dark Red Prismatic"},
{(int)VehicleColorsChameleon::GREEN_PRISMA , "Dark Green Prismatic"},
{(int)VehicleColorsChameleon::BLACK_PRISMA , "Black Prismatic"},
{(int)VehicleColorsChameleon::OIL_SLIC_PRISMA , "Black Oil Spill"},
{(int)VehicleColorsChameleon::RAINBOW_PRISMA , "Black Rainbow"},
{(int)VehicleColorsChameleon::BLACK_HOLO , "Black Holographic"},
{(int)VehicleColorsChameleon::WHITE_HOLO , "White Holographic"},
};
inline const std::map<int, std::string> lscMetalColors = {
{(int)VehicleColorsMetals::COLOR_METALS_BRUSHED_STEEL, "Brushed Steel"},
{(int)VehicleColorsMetals::COLOR_METALS_BRUSHED_BLACK_STEEL, "Brushed Black Steel"},
{(int)VehicleColorsMetals::COLOR_METALS_BRUSHED_ALUMINUM, "Brushed Aluminium"},
{(int)VehicleColorsMetals::COLOR_METALS_PURE_GOLD, "Pure Gold"},
{(int)VehicleColorsMetals::COLOR_METALS_BRUSHED_GOLD, "Brushed Gold"},
};
inline const std::map<int, std::string> lscUtilColors = {
{(int)VehicleColorsUtil::COLOR_UTIL_BLACK, "Black"},
{(int)VehicleColorsUtil::COLOR_UTIL_BLACK_POLY, "Black Poly"},
{(int)VehicleColorsUtil::COLOR_UTIL_DARK_SILVER, "Dark Silver"},
{(int)VehicleColorsUtil::COLOR_UTIL_SILVER, "Silver"},
{(int)VehicleColorsUtil::COLOR_UTIL_GUN_METAL, "Gun Metal"},
{(int)VehicleColorsUtil::COLOR_UTIL_SHADOW_SILVER, "Shadow Silver"},
{(int)VehicleColorsUtil::COLOR_UTIL_RED, "Red"},
{(int)VehicleColorsUtil::COLOR_UTIL_BRIGHT_RED, "Bright Red"},
{(int)VehicleColorsUtil::COLOR_UTIL_GARNET_RED, "Garnet Red"},
{(int)VehicleColorsUtil::COLOR_UTIL_DARK_GREEN, "Dark Green"},
{(int)VehicleColorsUtil::COLOR_UTIL_GREEN, "Green"},
{(int)VehicleColorsUtil::COLOR_UTIL_DARK_BLUE, "Dark Blue"},
{(int)VehicleColorsUtil::COLOR_UTIL_MIDNIGHT_BLUE, "Midnight Blue"},
{(int)VehicleColorsUtil::COLOR_UTIL_BLUE, "Blue"},
{(int)VehicleColorsUtil::COLOR_UTIL_SEA_FOAM_BLUE, "Sea Foam Blue"},
{(int)VehicleColorsUtil::COLOR_UTIL_LIGHTNING_BLUE, "Lightning Blue"},
{(int)VehicleColorsUtil::COLOR_UTIL_MAUI_BLUE_POLY, "Maui Blue Poly"},
{(int)VehicleColorsUtil::COLOR_UTIL_BRIGHT_BLUE, "Bright Blue"},
{(int)VehicleColorsUtil::COLOR_UTIL_BROWN, "Brown"},
{(int)VehicleColorsUtil::COLOR_UTIL_MEDIUM_BROWN, "Medium Brown"},
{(int)VehicleColorsUtil::COLOR_UTIL_LIGHT_BROWN, "Light Brown"},
{(int)VehicleColorsUtil::COLOR_UTIL_OFF_WHITE, "Off White"},
};
inline const std::map<int, std::string> lscWornColors = {
{(int)VehicleColorsWorn::COLOR_WORN_BLACK, "Black"},
{(int)VehicleColorsWorn::COLOR_WORN_GRAPHITE, "Graphite"},
{(int)VehicleColorsWorn::COLOR_WORN_SILVER_GREY, "Silver Grey"},
{(int)VehicleColorsWorn::COLOR_WORN_SILVER, "Silver"},
{(int)VehicleColorsWorn::COLOR_WORN_BLUE_SILVER, "Blue Silver"},
{(int)VehicleColorsWorn::COLOR_WORN_SHADOW_SILVER, "Shadow Silver"},
{(int)VehicleColorsWorn::COLOR_WORN_RED, "Red"},
{(int)VehicleColorsWorn::COLOR_WORN_GOLDEN_RED, "Golden Red"},
{(int)VehicleColorsWorn::COLOR_WORN_DARK_RED, "Dark Red"},
{(int)VehicleColorsWorn::COLOR_WORN_DARK_GREEN, "Dark Green"},
{(int)VehicleColorsWorn::COLOR_WORN_GREEN, "Green"},
{(int)VehicleColorsWorn::COLOR_WORN_SEA_WASH, "Sea Wash"},
{(int)VehicleColorsWorn::COLOR_WORN_DARK_BLUE, "Dark blue"},
{(int)VehicleColorsWorn::COLOR_WORN_BLUE, "Blue"},
{(int)VehicleColorsWorn::COLOR_WORN_BABY_BLUE, "Light blue"},
{(int)VehicleColorsWorn::COLOR_WORN_HONEY_BEIGE, "Honey Beige"},
{(int)VehicleColorsWorn::COLOR_WORN_BROWN, "Brown"},
{(int)VehicleColorsWorn::COLOR_WORN_DARK_BROWN, "Dark Brown"},
{(int)VehicleColorsWorn::COLOR_WORN_STRAW_BEIGE, "straw beige"},
{(int)VehicleColorsWorn::COLOR_WORN_OFF_WHITE, "Off White"},
{(int)VehicleColorsWorn::COLOR_WORN_ORANGE, "Orange"},
{(int)VehicleColorsWorn::COLOR_WORN_LIGHT_ORANGE, "Light Orange"},
{(int)VehicleColorsWorn::COLOR_WORN_TAXI_YELLOW, "Taxi Yellow"},
{(int)VehicleColorsWorn::COLOR_WORN_PALE_ORANGE, "Pale Orange"},
{(int)VehicleColorsWorn::COLOR_WORN_WHITE, "White"},
{(int)VehicleColorsWorn::COLOR_WORN_OLIVE_ARMY_GREEN, "Olive Army Green"},
};
inline const std::map<int, std::string> lscHeadlightColors = {
{(int)HeadlightColors::XENON_DEFAULT, "Default"},
{(int)HeadlightColors::XENON_WHITE, "White"},
{(int)HeadlightColors::XENON_BLUE, "Blue"},
{(int)HeadlightColors::XENON_ELECTRIC_BLUE, "Electric Blue"},
{(int)HeadlightColors::XENON_MINT_GREEN, "Mint Green"},
{(int)HeadlightColors::XENON_LIME_GREEN, "Lime Green"},
{(int)HeadlightColors::XENON_YELLOW, "Yellow"},
{(int)HeadlightColors::XENON_GOLDEN_SHOWER, "Golden Shower"},
{(int)HeadlightColors::XENON_ORANGE, "Orange"},
{(int)HeadlightColors::XENON_RED, "Red"},
{(int)HeadlightColors::XENON_PONY_PINK, "Pony Pink"},
{(int)HeadlightColors::XENON_HOT_PINK, "Hot Pink"},
{(int)HeadlightColors::XENON_PURPLE, "Purple"},
{(int)HeadlightColors::XENON_BLACKLIGHT, "Blacklight"},
};
inline const std::map<int, std::string> lscMissingHorns = {
{(int)VehicleModHorns::HORN_XMAS_BACKGROUND, "Festival Loop 1 Bg"},
{(int)VehicleModHorns::HORN_XMAS2_BACKGROUND, "Festival Loop 2 Bg"},
{(int)VehicleModHorns::HORN_XMAS3_BACKGROUND, "Festival Loop 3 Bg"},
{(int)VehicleModHorns::HORN_LOW_LONG, "Low (Long)"},
{(int)VehicleModHorns::HORN_LOW_SHORT, "Low (Short)"},
{(int)VehicleModHorns::HORN_MID_LONG, "Mid (Long)"},
{(int)VehicleModHorns::HORN_MID_SHORT, "Mid (Short)"},
{(int)VehicleModHorns::HORN_HIGH_LONG, "High (Long)"},
{(int)VehicleModHorns::HORN_HIGH_SHORT, "High (Short)"},
};
inline const std::map<std::string, std::vector<int>> lscTireSmokeRgb = {
{"White", {TIRESMOKE_COLOR_WHITE}},
{"Black", {TIRESMOKE_COLOR_BLACK}},
{"Blue", {TIRESMOKE_COLOR_BLUE}},
{"Yellow", {TIRESMOKE_COLOR_YELLOW}},
{"Purple", {TIRESMOKE_COLOR_PURPLE}},
{"Orange", {TIRESMOKE_COLOR_ORANGE}},
{"Green", {TIRESMOKE_COLOR_GREEN}},
{"Red", {TIRESMOKE_COLOR_RED}},
{"Pink", {TIRESMOKE_COLOR_PINK}},
{"Brown", {TIRESMOKE_COLOR_BROWN}},
{"Patriot", {TIRESMOKE_COLOR_PATRIOT}},
};
inline const std::map<std::string, std::vector<int>> lscNeonRgb = {
{"White", {NEON_COLOR_WHITE}},
{"Blue", {NEON_COLOR_BLUE}},
{"Electro Blue", {NEON_COLOR_ELECTRICBLUE}},
{"Mint Green", {NEON_COLOR_MINTGREEN}},
{"Lime Green", {NEON_COLOR_LIMEGREEN}},
{"Yellow", {NEON_COLOR_YELLOW}},
{"Golden Shower", {NEON_COLOR_GOLDENSHOWER}},
{"Orange", {NEON_COLOR_ORANGE}},
{"Red", {NEON_COLOR_RED}},
{"Pony Pink", {NEON_COLOR_PONYPINK}},
{"Hot Pink", {NEON_COLOR_HOTPINK}},
{"Purple", {NEON_COLOR_PURPLE}},
{"Blacklight", {NEON_COLOR_BLACKLIGHT}},
};