From 6495b36952c2d7eb743bbbc4e3530cdb89d193f6 Mon Sep 17 00:00:00 2001 From: Grinch_ Date: Sat, 20 Aug 2022 08:56:05 +0600 Subject: [PATCH] Refactor code more & fix issue with clothes --- src/cheatmenu.cpp | 8 - src/custom/animation.h | 2 +- src/custom/autodrive.cpp | 126 ++++++ src/custom/autodrive.h | 26 ++ src/custom/customskins_sa.cpp | 76 ++++ src/custom/customskins_sa.h | 34 ++ src/custom/cutscene_sa.h | 2 +- src/custom/freecam_sa.h | 2 +- src/custom/neon_sa.h | 2 +- src/custom/particle_sa.h | 2 +- src/custom/randomcheats_sa.h | 2 +- src/custom/topdowncam_sa.h | 2 +- src/custom/vehmod_sa.cpp | 255 +++++++++++++ src/custom/vehmod_sa.h | 34 ++ src/custom/vehpaint.cpp | 287 ++++++++++++++ src/custom/vehpaint.h | 42 ++ src/defines.h | 2 +- src/interface/icheat.hpp | 9 +- src/interface/ifeature.hpp | 12 + src/interface/ipage.cpp | 12 +- src/interface/ipage.h | 33 +- src/pages/anniversary.h | 2 +- src/pages/game.cpp | 1 - src/pages/game.h | 2 +- src/pages/menu.cpp | 8 +- src/pages/menu.h | 2 +- src/pages/ped.cpp | 92 ++--- src/pages/ped.h | 56 +-- src/pages/player.cpp | 138 ++----- src/pages/player.h | 55 ++- src/pages/scene.h | 2 +- src/pages/teleport.h | 2 +- src/pages/update.h | 2 +- src/pages/vehicle.cpp | 696 +++------------------------------- src/pages/vehicle.h | 123 ++---- src/pages/visual.cpp | 66 ++-- src/pages/visual.h | 47 +-- src/pages/weapon.cpp | 34 +- src/pages/weapon.h | 84 ++-- src/pages/welcome.h | 2 +- src/pch.cpp | 2 +- src/pch.h | 22 +- src/utils/d3dhook.cpp | 14 +- src/utils/overlay.cpp | 10 +- src/utils/rpc.cpp | 2 +- src/utils/util.cpp | 36 +- src/utils/util.h | 23 +- src/utils/widget.cpp | 2 +- 48 files changed, 1353 insertions(+), 1142 deletions(-) create mode 100644 src/custom/autodrive.cpp create mode 100644 src/custom/autodrive.h create mode 100644 src/custom/customskins_sa.cpp create mode 100644 src/custom/customskins_sa.h create mode 100644 src/custom/vehmod_sa.cpp create mode 100644 src/custom/vehmod_sa.h create mode 100644 src/custom/vehpaint.cpp create mode 100644 src/custom/vehpaint.h create mode 100644 src/interface/ifeature.hpp diff --git a/src/cheatmenu.cpp b/src/cheatmenu.cpp index 4b0aeec..f3cbe8b 100644 --- a/src/cheatmenu.cpp +++ b/src/cheatmenu.cpp @@ -127,14 +127,6 @@ void CheatMenu::Init() ApplyStyle(); Locale::Init(FILE_NAME "/locale/", "English", "English"); - // GenHeaderList(); - - // Init menu parts - Player::Init(); - Ped::Init(); - Vehicle::Init(); - Visual::Init(); - WeaponPage::Init(); Overlay::Init(); Events::processScriptsEvent += []() diff --git a/src/custom/animation.h b/src/custom/animation.h index 4c21c13..25aa802 100644 --- a/src/custom/animation.h +++ b/src/custom/animation.h @@ -11,7 +11,7 @@ class AnimationMgr : public ICheat private: CPed *m_pTarget = nullptr; // target ped pointer - friend class ICheat; + friend class IFeature; AnimationMgr(); AnimationMgr(const AnimationMgr&); diff --git a/src/custom/autodrive.cpp b/src/custom/autodrive.cpp new file mode 100644 index 0000000..75b153c --- /dev/null +++ b/src/custom/autodrive.cpp @@ -0,0 +1,126 @@ +#include "pch.h" +#include "autodrive.h" +#include "utils/widget.h" +#include "pages/teleport.h" + +AutoDriveMgr& AutoDrive = AutoDriveMgr::Get(); + +void AutoDriveMgr::StartDrive(CVehicle *pVeh, const char *buf) +{ + int hVeh = CPools::GetVehicleRef(pVeh); + CVector pos; + + if (buf == nullptr) + { +#ifdef GTASA + tRadarTrace targetBlip = CRadar::ms_RadarTrace[LOWORD(FrontEndMenuManager.m_nTargetBlipIndex)]; + pos = targetBlip.m_vecPos; + if (targetBlip.m_nRadarSprite != RADAR_SPRITE_WAYPOINT) + { + Util::SetMessage(TEXT("Teleport.TargetBlipText")); + return; + } +#else + return; +#endif + } + else + { + if (sscanf(buf, "%f,%f,%f", &pos.x, &pos.y, &pos.z) != 3) + { + int dim; + sscanf(buf, "%d,%f,%f,%f", &dim, &pos.x, &pos.y, &pos.z); + } + } + + int model = pVeh->m_nModelIndex; + if (CModelInfo::IsBoatModel(model)) + { + Command(hVeh, pos.x, pos.y, pos.z); + } + else if (CModelInfo::IsPlaneModel(model)) + { + CVector p = pVeh->GetPosition(); + p.z = 300.0f; +#ifdef GTASA + pVeh->SetPosn(p); +#elif GTAVC + pVeh->SetPosition(p); +#else + pVeh->SetPos(p); +#endif + Command(hVeh, pos.x, pos.y, 300.0f, 30, 200); + } + else if (CModelInfo::IsHeliModel(model)) + { + CVector p = pVeh->GetPosition(); + p.z = 300.0f; +#ifdef GTASA + pVeh->SetPosn(p); +#elif GTAVC + pVeh->SetPosition(p); +#else + pVeh->SetPos(p); +#endif + Command(hVeh, pos.x, pos.y, 300.0f, 30, 200); + } +#ifdef GTASA + else if (CModelInfo::IsTrainModel(model)) + { + return; + } +#endif + else + { + Command(hVeh, pos.x, pos.y, pos.z); + } +} + +void AutoDriveMgr::Draw() +{ + CPlayerPed* pPlay = FindPlayerPed(); + CVehicle* pVeh = BY_GAME(FindPlayerVehicle(-1, false), FindPlayerVehicle(), FindPlayerVehicle());; + int hPlayer = CPools::GetPedRef(pPlay); + int hVeh = CPools::GetVehicleRef(pVeh); + + if (ImGui::Button(TEXT("Vehicle.AutoDriveStop"), Widget::CalcSize(1))) + { + Command(hPlayer, hVeh); + } + ImGui::Spacing(); + if (ImGui::BeginTabBar("PassTabaBar")) + { + if (ImGui::BeginTabItem(TEXT("Teleport.Coordinates"))) + { + static char buf[INPUT_BUFFER_SIZE]; + ImGui::Spacing(); + ImGui::TextWrapped(TEXT("Vehicle.AutoDriveInfo")); + ImGui::Spacing(); + ImGui::InputTextWithHint(TEXT("Teleport.Coordinates"), "x, y, z", buf, IM_ARRAYSIZE(buf)); + ImGui::Spacing(); + if (ImGui::Button(TEXT("Vehicle.AutoDriveCoord"), Widget::CalcSize(BY_GAME(2,1,1)))) + { + StartDrive(pVeh, buf); + } +#ifdef GTASA + ImGui::SameLine(); + if (ImGui::Button(TEXT("Vehicle.AutoDriveMarker"), Widget::CalcSize(2))) + { + StartDrive(pVeh); + } +#endif + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem(TEXT("Teleport.Location"))) + { + ImGui::Spacing(); + Widget::DataList(teleportPage.m_locData, + [this, pVeh](std::string& rootkey, std::string& bLocName, std::string& loc) + { + StartDrive(pVeh, loc.c_str()); + }); + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); + } +} \ No newline at end of file diff --git a/src/custom/autodrive.h b/src/custom/autodrive.h new file mode 100644 index 0000000..c089494 --- /dev/null +++ b/src/custom/autodrive.h @@ -0,0 +1,26 @@ +#pragma once +#include "utils/resourcestore.h" +#include "interface/icheat.hpp" + + +/* + AutoDriveMgr Class + Automatically drives vehicle to marker/ coord +*/ +class AutoDriveMgr : public ICheat +{ +private: + + friend class IFeature; + AutoDriveMgr(){}; + AutoDriveMgr(const AutoDriveMgr&); + + void StartDrive(CVehicle *pVeh, const char *buf = nullptr); + +public: + + // Draw custom skins handler code + void Draw(); +}; + +extern AutoDriveMgr& AutoDrive; \ No newline at end of file diff --git a/src/custom/customskins_sa.cpp b/src/custom/customskins_sa.cpp new file mode 100644 index 0000000..86fbbbc --- /dev/null +++ b/src/custom/customskins_sa.cpp @@ -0,0 +1,76 @@ +#include "pch.h" +#include "customskins_sa.h" +#include "utils/widget.h" + +CustomSkinsMgr& CustomSkins = CustomSkinsMgr::Get(); +CustomSkinsMgr::CustomSkinsMgr() +{ + std::string path = GAME_PATH((char*)"modloader/"); + if (GetModuleHandle("modloader.asi") && std::filesystem::is_directory(path)) + { + path += "CustomSkins/"; + if (std::filesystem::is_directory(path)) + { + for (auto& p : std::filesystem::recursive_directory_iterator(path)) + { + if (p.path().extension() == ".dff") + { + std::string file_name = p.path().stem().string(); + + if (file_name.size() < 9) + { + m_List.push_back(file_name); + } + else + { + Log::Print("Custom Skin longer than 8 characters {}", file_name); + } + } + } + } + else + { + std::filesystem::create_directory(path); + } + m_bInit = true; + } +} + +void CustomSkinsMgr::SetSkin(const std::string& name) +{ + CStreaming::RequestSpecialChar(1, name.c_str(), PRIORITY_REQUEST); + CStreaming::LoadAllRequestedModels(true); + FindPlayerPed()->SetModelIndex(291); + CStreaming::SetSpecialCharIsDeletable(291); +} + +void CustomSkinsMgr::Draw() +{ + if (m_bInit) + { + Widget::Filter(TEXT("Window.Search"), m_Filter, std::format("{}{}", TEXT("Player.TotalSkins"), m_List.size()).c_str()); + Widget::Tooltip(TEXT("Player.CustomSkinsDirTip")); + ImGui::Spacing(); + ImGui::TextWrapped(TEXT("Player.CustomSkinsTip")); + ImGui::Spacing(); + for (std::string name : m_List) + { + if (m_Filter.PassFilter(name.c_str())) + { + if (ImGui::MenuItem(name.c_str())) + { + SetSkin(name); + } + } + } + } + else + { + ImGui::TextWrapped(TEXT("Player.CustomSkinTutorial")); + ImGui::Spacing(); + if (ImGui::Button(TEXT("Player.DownloadModloader"), ImVec2(Widget::CalcSize(1)))) + { + OPEN_LINK("https://gtaforums.com/topic/669520-mod-loader/"); + } + } +} \ No newline at end of file diff --git a/src/custom/customskins_sa.h b/src/custom/customskins_sa.h new file mode 100644 index 0000000..4119062 --- /dev/null +++ b/src/custom/customskins_sa.h @@ -0,0 +1,34 @@ +#pragma once +#include "utils/resourcestore.h" +#include "interface/icheat.hpp" + + +/* + CustomSkins Class for SA + Adds ability to use skins without replacing + Requires modloader installed + + There are certain limitations, + 1. Skin names can't be longer than 8 chars + 2. Skins can't be removed while the game is running +*/ +class CustomSkinsMgr : public ICheat +{ +private: + ImGuiTextFilter m_Filter; + std::vector m_List; + bool m_bInit; + + friend class IFeature; + CustomSkinsMgr(); + CustomSkinsMgr(const CustomSkinsMgr&); + + // Change player to custom skin + void SetSkin(const std::string& name); +public: + + // Draw custom skins handler code + void Draw(); +}; + +extern CustomSkinsMgr& CustomSkins; \ No newline at end of file diff --git a/src/custom/cutscene_sa.h b/src/custom/cutscene_sa.h index 9cd6e8f..f0a3b61 100644 --- a/src/custom/cutscene_sa.h +++ b/src/custom/cutscene_sa.h @@ -17,7 +17,7 @@ private: CVehicle *m_pLastVeh; // vehicle player was in int m_nVehSeat; // seat id of player vehicle - friend class ICheat; + friend class IFeature; CutsceneMgr(); CutsceneMgr(const CutsceneMgr&); diff --git a/src/custom/freecam_sa.h b/src/custom/freecam_sa.h index 09f7d8d..148b2e6 100644 --- a/src/custom/freecam_sa.h +++ b/src/custom/freecam_sa.h @@ -14,7 +14,7 @@ private: bool m_bHudState; // backup of the prev game hud state bool m_bRadarState; // backup of the prev game radar state - friend ICheat; + friend class IFeature; FreecamMgr(); FreecamMgr(const FreecamMgr&); diff --git a/src/custom/neon_sa.h b/src/custom/neon_sa.h index 0ca1c3d..a110d87 100644 --- a/src/custom/neon_sa.h +++ b/src/custom/neon_sa.h @@ -31,7 +31,7 @@ private: RwTexture* m_pNeonTexture = nullptr; // pointer to the neon mask texture VehicleExtendedData m_VehNeon; - friend ICheat; + friend class IFeature; NeonMgr(); NeonMgr(NeonMgr&); ~NeonMgr(); diff --git a/src/custom/particle_sa.h b/src/custom/particle_sa.h index faf4004..0522806 100644 --- a/src/custom/particle_sa.h +++ b/src/custom/particle_sa.h @@ -11,7 +11,7 @@ class ParticleMgr : public ICheat private: std::vector m_nList; - friend class ICheat; + friend class IFeature; ParticleMgr(){}; ParticleMgr(const ParticleMgr&); diff --git a/src/custom/randomcheats_sa.h b/src/custom/randomcheats_sa.h index b133f92..b8f3d56 100644 --- a/src/custom/randomcheats_sa.h +++ b/src/custom/randomcheats_sa.h @@ -12,7 +12,7 @@ private: std::string m_EnabledCheats[92][2]; DataStore m_pData {"cheats"}; - friend ICheat; + friend class IFeature; RandomCheatsMgr(); RandomCheatsMgr(const RandomCheatsMgr&); diff --git a/src/custom/topdowncam_sa.h b/src/custom/topdowncam_sa.h index fc923ad..dafa11c 100644 --- a/src/custom/topdowncam_sa.h +++ b/src/custom/topdowncam_sa.h @@ -9,7 +9,7 @@ class TopDownCamera : public ICheat { private: - friend ICheat; + friend class IFeature; TopDownCamera(); TopDownCamera(const TopDownCamera&); diff --git a/src/custom/vehmod_sa.cpp b/src/custom/vehmod_sa.cpp new file mode 100644 index 0000000..942c96e --- /dev/null +++ b/src/custom/vehmod_sa.cpp @@ -0,0 +1,255 @@ +#include "pch.h" +#include "vehmod_sa.h" +#include "utils/widget.h" +#include "filehandler.h" + +static std::vector m_HandlingFlagNames = // 32 flags +{ + "1G_BOOST", "2G_BOOST", "NPC_ANTI_ROLL", "NPC_NEUTRAL_HANDL", "NO_HANDBRAKE", "STEER_REARWHEELS", + "HB_REARWHEEL_STEER", "ALT_STEER_OPT", + "WHEEL_F_NARROW2", "WHEEL_F_NARROW", "WHEEL_F_WIDE", "WHEEL_F_WIDE2", "WHEEL_R_NARROW2", "WHEEL_R_NARROW", + "WHEEL_R_WIDE", "WHEEL_R_WIDE2", + "HYDRAULIC_GEOM", "HYDRAULIC_INST", "HYDRAULIC_NONE", "NOS_INST", "OFFROAD_ABILITY", "OFFROAD_ABILITY2", + "HALOGEN_LIGHTS", "PROC_REARWHEEL_1ST", + "USE_MAXSP_LIMIT", "LOW_RIDER", "STREET_RACER", "SWINGING_CHASSIS", "Unused 1", "Unused 2", "Unused 3", + "Unused 4" +}; + +static std::vector m_ModelFlagNames = // 32 flags +{ + "IS_VAN", "IS_BUS", "IS_LOW", "IS_BIG", "REVERSE_BONNET", "HANGING_BOOT", "TAILGATE_BOOT", "NOSWING_BOOT", + "NO_DOORS", "TANDEM_SEATS", + "SIT_IN_BOAT", "CONVERTIBLE", "NO_EXHAUST", "DOUBLE_EXHAUST", "NO1FPS_LOOK_BEHIND", "FORCE_DOOR_CHECK", + "AXLE_F_NOTILT", "AXLE_F_SOLID", "AXLE_F_MCPHERSON", + "AXLE_F_REVERSE", "AXLE_R_NOTILT", "AXLE_R_SOLID", "AXLE_R_MCPHERSON", "AXLE_R_REVERSE", "IS_BIKE", "IS_HELI", + "IS_PLANE", "IS_BOAT", "BOUNCE_PANELS", + "DOUBLE_RWHEELS", "FORCE_GROUND_CLEARANCE", "IS_HATCHBAC1K" +}; + +VehModMgr& VehMod = VehModMgr::Get(); + +VehModMgr::VehModMgr() +{ + FileHandler::FetchHandlingID(m_VehicleIDE); + + Events::processScriptsEvent += [this]() + { + if (m_Nitro.m_bEnabled && FindPlayerVehicle(-1, false)->m_nVehicleSubClass == VEHICLE_AUTOMOBILE) + { + patch::Set(0x969165, 0, true); // All cars have nitro + patch::Set(0x96918B, 0, true); // All taxis have nitro + + if (KeyPressed(VK_LBUTTON)) + { + if (!m_Nitro.m_bCompAdded) + { + AddComponent("1010", false); + m_Nitro.m_bCompAdded = true; + } + } + else + { + if (m_Nitro.m_bCompAdded) + { + RemoveComponent("1010", false); + m_Nitro.m_bCompAdded = false; + } + } + } + }; +} + +void VehModMgr::AddComponent(const std::string& component, const bool display_message) +{ + try + { + CPlayerPed* player = FindPlayerPed(); + int icomp = std::stoi(component); + int hveh = CPools::GetVehicleRef(player->m_pVehicle); + + CStreaming::RequestModel(icomp, eStreamingFlags::PRIORITY_REQUEST); + CStreaming::LoadAllRequestedModels(true); + player->m_pVehicle->AddVehicleUpgrade(icomp); + CStreaming::SetModelIsDeletable(icomp); + + if (display_message) + { + Util::SetMessage("Component added"); + } + } + catch (...) + { + Log::Print("Failed to add component to vehicle {}", component); + } +} + + +void VehModMgr::RemoveComponent(const std::string& component, const bool display_message) +{ + try + { + CPlayerPed* player = FindPlayerPed(); + int icomp = std::stoi(component); + int hveh = CPools::GetVehicleRef(player->m_pVehicle); + + player->m_pVehicle->RemoveVehicleUpgrade(icomp); + + if (display_message) + { + Util::SetMessage("Component removed"); + } + } + catch (...) + { + Log::Print("Failed to remove component from vehicle {}", component); + } +} + +void VehModMgr::Draw() +{ + if (ImGui::BeginTabItem(TEXT("Vehicle.TuneTab"))) + { + ImGui::Spacing(); + Widget::ImageList(m_TuneData, + [this](std::string& str) + { + AddComponent(str); + }, + // [](std::string& str) + // { + // RemoveComponent(str); + // }, + [](std::string& str) + { + return str; + }, + [](std::string& str) + { + return ((bool(*)(int, CVehicle*))0x49B010)(std::stoi(str), FindPlayerPed()->m_pVehicle); + }); + + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem(TEXT("Vehicle.HandlingTab"))) + { + ImGui::Spacing(); + // https://github.com/multitheftauto/mtasa-blue/blob/16769b8d1c94e2b9fe6323dcba46d1305f87a190/Client/game_sa/CModelInfoSA.h#L213 + CBaseModelInfo* pInfo = CModelInfo::GetModelInfo(FindPlayerVehicle(-1, false)->m_nModelIndex); + int handlingID = patch::Get((int)pInfo + 74, false); // CBaseModelInfo + 74 = handlingID + tHandlingData *pHandlingData = reinterpret_cast(0xC2B9DC + (handlingID * 224)); // sizeof(tHandlingData) = 224 + + if (ImGui::Button(TEXT("Vehicle.ResetHandling"), ImVec2(Widget::CalcSize(3)))) + { + gHandlingDataMgr.LoadHandlingData(); + Util::SetMessage(TEXT("Vehicle.ResetHandlingMSG")); + } + + ImGui::SameLine(); + + if (ImGui::Button(TEXT("Vehicle.SaveFile"), ImVec2(Widget::CalcSize(3)))) + { + FileHandler::GenerateHandlingFile(pHandlingData, m_VehicleIDE); + Util::SetMessage(TEXT("Vehicle.SaveFileMSG")); + } + + ImGui::SameLine(); + + if (ImGui::Button(TEXT("Vehicle.ReadMore"), ImVec2(Widget::CalcSize(3)))) + { + ShellExecute(NULL, "open", "https://projectcerbera.com/gta/sa/tutorials/handling", NULL, NULL, + SW_SHOWNORMAL); + } + + ImGui::Spacing(); + + ImGui::BeginChild("HandlingChild"); + + std::vector abs{ {TEXT("Vehicle.On"), 1}, {TEXT("Vehicle.Off"), 0} }; + Widget::EditRadioBtnAddr(TEXT("Vehicle.Abs"), (int)&pHandlingData->m_bABS, abs); + + Widget::EditAddr(TEXT("Vehicle.ADM"), (int)&pHandlingData->m_fSuspensionAntiDiveMultiplier, 0.0f, 0.0f, 1.0f); + Widget::EditAddr(TEXT("Vehicle.AnimGroup"), (int)&pHandlingData->m_nAnimGroup, 0, 0, 20); + Widget::EditAddr(TEXT("Vehicle.BrakeBias"), (int)&pHandlingData->m_fBrakeBias, 0.0f, 0.0f, 1.0f); + + // Brake deceleration calculation + float BrakeDeceleration = pHandlingData->m_fBrakeDeceleration * 2500; + Widget::EditAddr(TEXT("Vehicle.BrakeDecel"), (int)&pHandlingData->m_fBrakeDeceleration, 0.0f, 0.0f, 20.0f, 2500.0f); + pHandlingData->m_fBrakeDeceleration = BrakeDeceleration / 2500; + + Widget::EditAddr(TEXT("Vehicle.CemterMassX"), (int)&pHandlingData->m_vecCentreOfMass.x, -10.0f, -10.0f, 10.0f); + Widget::EditAddr(TEXT("Vehicle.CemterMassY"), (int)&pHandlingData->m_vecCentreOfMass.y, -10.0f, -10.0f, 10.0f); + Widget::EditAddr(TEXT("Vehicle.CemterMassZ"), (int)&pHandlingData->m_vecCentreOfMass.z, -10.0f, -10.0f, 10.0f); + + // CDM calculations + float factor = (1.0 / pHandlingData->m_fMass); + float fCDM = pHandlingData->m_fCollisionDamageMultiplier / (2000.0f * factor); + Widget::EditAddr(TEXT("Vehicle.CDM"), (int)&fCDM, 0.0f, 0.0f, 1.0f, 0.3381f); + pHandlingData->m_fCollisionDamageMultiplier = factor * fCDM * 2000.0f; + + Widget::EditAddr(TEXT("Vehicle.DampingLvl"), (int)&pHandlingData->m_fSuspensionDampingLevel, -10.0f, -10.0f, 10.0f); // test later + Widget::EditAddr(TEXT("Vehicle.DragMult"), (int)&pHandlingData->m_fDragMult, 0.0f, 0.0f, 30.0f); + + std::vector drive_type + { + {TEXT("Vehicle.FrontWheelDrive"), 70}, + {TEXT("Vehicle.RearWheelDrive"), 82}, + {TEXT("Vehicle.FourWheelDrive"), 52} + }; + Widget::EditRadioBtnAddr(TEXT("Vehicle.DriveType"), (int)&pHandlingData->m_transmissionData.m_nDriveType, drive_type); + + // Engine acceleration calculation + float fEngineAcceleration = pHandlingData->m_transmissionData.m_fEngineAcceleration * 12500; + Widget::EditAddr(TEXT("Vehicle.EngineAccel"), (int)&fEngineAcceleration, 0.0f, 0.0f, 49.0f, 12500.0f); + pHandlingData->m_transmissionData.m_fEngineAcceleration = fEngineAcceleration / 12500; + + + Widget::EditAddr(TEXT("Vehicle.EngineInertia"), (int)&pHandlingData->m_transmissionData.m_fEngineInertia, 0.1f, 0.1f, 400.0f); + + std::vector engine_type + { + {TEXT("Vehicle.Petrol"), 80}, {TEXT("Vehicle.Diseal"), 68}, {TEXT("Vehicle.Electric"), 69} + }; + Widget::EditRadioBtnAddr(TEXT("Vehicle.EngineType"), (int)&pHandlingData->m_transmissionData.m_nEngineType, engine_type); + + std::vector lights + { + {TEXT("Vehicle.Long"), 0}, {TEXT("Vehicle.Small"), 1}, + {TEXT("Vehicle.Big"), 2}, {TEXT("Vehicle.Tall"), 3} + }; + Widget::EditRadioBtnAddr(TEXT("Vehicle.FrontLights"), (int)&pHandlingData->m_nFrontLights, lights); + + Widget::EditAddr(TEXT("Vehicle.ForceLevel"), (int)&pHandlingData->m_fSuspensionForceLevel, -10.0f, -10.0f, 10.0f); // test later + + Widget::EditBits(TEXT("Vehicle.HandlingFlags"), (int)&pHandlingData->m_nHandlingFlags, m_HandlingFlagNames); + + Widget::EditAddr(TEXT("Vehicle.HighSpeedDamping"), (int)&pHandlingData->m_fSuspensionDampingLevel, -10.0f, -10.0f, 10.0f); // test later + Widget::EditAddr(TEXT("Vehicle.LowerKimit"), (int)&pHandlingData->m_fSuspensionLowerLimit, -10.0f, -10.0f, 10.0f); // test later + Widget::EditAddr(TEXT("Vehicle.Mass"), (int)&pHandlingData->m_fMass, 1.0f, 1.0f, 50000.0f); + + // Max Velocity calculation + int MaxVelocity = pHandlingData->m_transmissionData.m_fMaxGearVelocity / *(float*)0xC2B9BC; + Widget::EditAddr(TEXT("Vehicle.MaxVelocity"), (int)&MaxVelocity, 1.0f, 1.0f, 1000.0f); + pHandlingData->m_transmissionData.m_fMaxGearVelocity = MaxVelocity * (*(float*)0xC2B9BC); + + Widget::EditBits(TEXT("Vehicle.ModelFlags"), (int)&pHandlingData->m_nModelFlags, m_ModelFlagNames); + + Widget::EditAddr(TEXT("Vehicle.MonValue"), (int)&pHandlingData->m_nMonetaryValue, 1, 1, 100000); + Widget::EditAddr(TEXT("Vehicle.NumGears"), (int)&pHandlingData->m_transmissionData.m_nNumberOfGears, 1, 1, 10); + Widget::EditAddr(TEXT("Vehicle.PercentSubmerged"), (int)&pHandlingData->m_nPercentSubmerged, 10, 10, 120); + + Widget::EditRadioBtnAddr(TEXT("Vehicle.RearLights"), (int)&pHandlingData->m_nRearLights, lights); + + Widget::EditAddr(TEXT("Vehicle.SeatOffset"), (int)&pHandlingData->m_fSeatOffsetDistance, 0.0f, 0.0f, 1.0f); + Widget::EditAddr(TEXT("Vehicle.SteeringLock"), (int)&pHandlingData->m_fSteeringLock, 10.0f, 10.0f, 50.0f); + Widget::EditAddr(TEXT("Vehicle.SuspensionBias"), (int)&pHandlingData->m_fSuspensionBiasBetweenFrontAndRear, 0.0f, 0.0f, 1.0f); + Widget::EditAddr(TEXT("Vehicle.TractionBias"), (int)&pHandlingData->m_fTractionBias, 0.0f, 0.0f, 1.0f); + Widget::EditAddr(TEXT("Vehicle.TractionLoss"), (int)&pHandlingData->m_fTractionLoss, 0.0f, 0.0f, 1.0f); + Widget::EditAddr(TEXT("Vehicle.TractionMul"), (int)&pHandlingData->m_fTractionMultiplier, 0.5f, 0.5f, 2.0f); + Widget::EditAddr(TEXT("Vehicle.TurnMass"), (int)&pHandlingData->m_fTurnMass, 20.0f, 20.0f, 1000.0f); // test later + Widget::EditAddr(TEXT("Vehicle.UpperLimit"), (int)&pHandlingData->m_fSuspensionUpperLimit, -1.0f, -1.0f, 1.0f); + + ImGui::EndChild(); + + ImGui::EndTabItem(); + } +} \ No newline at end of file diff --git a/src/custom/vehmod_sa.h b/src/custom/vehmod_sa.h new file mode 100644 index 0000000..d5eed5e --- /dev/null +++ b/src/custom/vehmod_sa.h @@ -0,0 +1,34 @@ +#pragma once +#include "pch.h" +#include "interface/ifeature.hpp" + +/* + VehModMgr Class + Handles tunes & handling +*/ +class VehModMgr : public IFeature +{ +private: + ResourceStore m_TuneData { "components", eResourceType::TYPE_IMAGE_TEXT, ImVec2(100, 80) }; + std::map m_VehicleIDE; + + // Add/ Remove vehicle mod + void AddComponent(const std::string& component, bool displayMessage = true); + void RemoveComponent(const std::string& component, bool displayMessage = true); + + friend class IFeature; + VehModMgr(); + VehModMgr(const VehModMgr&); + +public: + struct + { + bool m_bEnabled; + bool m_bCompAdded; + } m_Nitro; + + // Draw custom skins handler code + void Draw(); +}; + +extern VehModMgr& VehMod; \ No newline at end of file diff --git a/src/custom/vehpaint.cpp b/src/custom/vehpaint.cpp new file mode 100644 index 0000000..c274ddb --- /dev/null +++ b/src/custom/vehpaint.cpp @@ -0,0 +1,287 @@ +#include "pch.h" +#include "vehpaint.h" +#include "utils/widget.h" +#include "custom/filehandler.h" + +#ifdef GTASA +#include "custom/neon_sa.h" +#include "custom/paint_sa.h" +#endif + +VehPaintMgr& VehPaint = VehPaintMgr::Get(); + +VehPaintMgr::VehPaintMgr() +{ + FileHandler::FetchColorData(m_ColorData); + +#ifdef GTASA + Paint::InjectHooks(); + + Events::processScriptsEvent += [this] + { + uint timer = CTimer::m_snTimeInMilliseconds; + CPlayerPed* pPlayer = FindPlayerPed(); + CVehicle* pVeh = BY_GAME(FindPlayerVehicle(-1, false), FindPlayerVehicle(), FindPlayerVehicle()); + + if (pPlayer && Util::IsInCar()) + { + if (m_Neon.m_bRainbowEffect && timer - m_Neon.m_nRainbowTimer > 50) + { + int red, green, blue; + + Util::RainbowValues(red, green, blue, 0.25); + Neon.Install(pVeh, red, green, blue); + m_Neon.m_nRainbowTimer = timer; + } + } + + // Traffic neons + if (m_Neon.m_bApplyOnTraffic && timer - m_Neon.m_nTrafficTimer > 1000) + { + for (CVehicle* veh : CPools::ms_pVehiclePool) + { + int chance = 0; + + if (veh->m_nVehicleClass == CLASS_NORMAL) // Normal + { + chance = Random(1, 20); + } + + if (veh->m_nVehicleClass == CLASS_RICHFAMILY) // Rich family + { + chance = Random(1, 4); + } + + if (veh->m_nVehicleClass == CLASS_EXECUTIVE) // Executive + { + chance = Random(1, 3); + } + + if (chance == 1 && !Neon.IsInstalled(veh) && veh->m_pDriver != pPlayer) + { + Neon.Install(veh, Random(0, 255), Random(0, 255), Random(0, 255)); + } + } + m_Neon.m_nTrafficTimer = timer; + } + }; +#endif +} + +void VehPaintMgr::Draw() +{ + CVehicle* pVeh = BY_GAME(FindPlayerVehicle(-1, false), FindPlayerVehicle(), FindPlayerVehicle()); + int hVeh = CPools::GetVehicleRef(pVeh); + + if (ImGui::BeginTabItem(TEXT("Vehicle.Color"))) + { +#ifdef GTASA + Paint::GenerateNodeList(pVeh, m_Paint.m_vecNames, m_Paint.m_Selected); + + ImGui::Spacing(); + if (ImGui::Button(TEXT("Vehicle.ResetColor"), ImVec2(Widget::CalcSize()))) + { + Paint::ResetNodeColor(pVeh, m_Paint.m_Selected); + Util::SetMessage(TEXT("Vehicle.ResetColorMSG")); + } + ImGui::Spacing(); + + Widget::ListBox(TEXT("Vehicle.Component"), m_Paint.m_vecNames, m_Paint.m_Selected); + + if (ImGui::ColorEdit3(TEXT("Vehicle.ColorPicker"), m_Paint.m_fColorPicker)) + { + uchar r = m_Paint.m_fColorPicker[0] * 255; + uchar g = m_Paint.m_fColorPicker[1] * 255; + uchar b = m_Paint.m_fColorPicker[2] * 255; + Paint::SetNodeColor(pVeh, m_Paint.m_Selected, { r, g, b, 255 }, m_Paint.m_bMatFilter); + } +#endif + + ImGui::Spacing(); + ImGui::Columns(2, NULL, false); + +#ifdef GTASA + ImGui::Checkbox(TEXT("Vehicle.MatFilter"), &m_Paint.m_bMatFilter); + ImGui::RadioButton(TEXT("Vehicle.Primary"), &m_Paint.m_nRadioButton, 1); + ImGui::RadioButton(TEXT("Vehicle.Secondary"), &m_Paint.m_nRadioButton, 2); + ImGui::NextColumn(); + ImGui::NewLine(); + ImGui::RadioButton(TEXT("Vehicle.Tertiary"), &m_Paint.m_nRadioButton, 3); + ImGui::RadioButton(TEXT("Vehicle.Quaternary"), &m_Paint.m_nRadioButton, 4); +#else + ImGui::RadioButton(TEXT("Vehicle.Primary"), &m_Paint.m_nRadioButton, 1); + ImGui::NextColumn(); + ImGui::RadioButton(TEXT("Vehicle.Secondary"), &m_Paint.m_nRadioButton, 2); +#endif + ImGui::Spacing(); + ImGui::Columns(1); + ImGui::Text(TEXT("Vehicle.SelectPreset")); + ImGui::Spacing(); + + int count = (int)m_ColorData.size(); + + ImVec2 size = Widget::CalcSize(); + int btnsInRow = ImGui::GetWindowContentRegionWidth() / (size.y * 2); + int btnSize = (ImGui::GetWindowContentRegionWidth() - int(ImGuiStyleVar_ItemSpacing) * (btnsInRow - + 0.6 * btnsInRow)) / btnsInRow; + + ImGui::BeginChild("Colorss"); + + for (int colorId = 0; colorId < count; ++colorId) + { + if (Widget::ColorBtn(colorId, m_ColorData[colorId], ImVec2(btnSize, btnSize))) + { + *(uint8_replacement*)(int(pVeh) + BY_GAME(0x433, 0x19F, 0x19B) + m_Paint.m_nRadioButton) = colorId; + } + + if ((colorId + 1) % btnsInRow != 0) + { + ImGui::SameLine(0.0, 4.0); + } + } + + ImGui::EndChild(); + ImGui::EndTabItem(); + } + +#ifdef GTASA + if (gRenderer != eRenderer::DirectX11) + { + CVehicle* pVeh = BY_GAME(FindPlayerVehicle(-1, false), FindPlayerVehicle(), FindPlayerVehicle()); + + if (ImGui::BeginTabItem(TEXT("Vehicle.NeonsTab"))) + { + int model = pVeh->m_nModelIndex; + ImGui::Spacing(); + if (ImGui::Button(TEXT("Vehicle.RemoveNeon"), ImVec2(Widget::CalcSize()))) + { + Neon.Remove(pVeh); + Util::SetMessage(TEXT("Vehicle.RemoveNeonMSG")); + } + + ImGui::Spacing(); + ImGui::Columns(2, NULL, false); + + bool pulsing = Neon.IsPulsingEnabled(pVeh); + if (Widget::Checkbox(TEXT("Vehicle.PulsingNeon"), &pulsing)) + { + Neon.SetPulsing(pVeh, pulsing); + } + + Widget::Checkbox(TEXT("Vehicle.RainbowNeon"), &m_Neon.m_bRainbowEffect, TEXT("Vehicle.RainbowNeonMSG")); + ImGui::NextColumn(); + Widget::Checkbox(TEXT("Vehicle.TrafficNeon"), &m_Neon.m_bApplyOnTraffic, TEXT("Vehicle.TrafficNeonMSG")); + ImGui::Columns(1); + + ImGui::Spacing(); + + if (ImGui::ColorEdit3(TEXT("Vehicle.ColorPicker"), m_Neon.m_fColorPicker)) + { + int r = static_cast(m_Neon.m_fColorPicker[0] * 255); + int g = static_cast(m_Neon.m_fColorPicker[1] * 255); + int b = static_cast(m_Neon.m_fColorPicker[2] * 255); + + Neon.Install(pVeh, r, g, b); + } + + + ImGui::Spacing(); + ImGui::Text(TEXT("Vehicle.SelectPreset")); + + int count = (int)m_ColorData.size(); + ImVec2 size = Widget::CalcSize(); + int btnsInRow = ImGui::GetWindowContentRegionWidth() / (size.y * 2); + int btnSize = (ImGui::GetWindowContentRegionWidth() - int(ImGuiStyleVar_ItemSpacing) * (btnsInRow - + 0.6 * btnsInRow)) / btnsInRow; + + ImGui::BeginChild("Neonss"); + + for (int color_id = 0; color_id < count; ++color_id) + { + auto& color = m_ColorData[color_id]; + if (Widget::ColorBtn(color_id, color, ImVec2(btnSize, btnSize))) + { + int r = static_cast(color[0] * 255); + int g = static_cast(color[1] * 255); + int b = static_cast(color[2] * 255); + + Neon.Install(pVeh, r, g, b); + } + + if ((color_id + 1) % btnsInRow != 0) + { + ImGui::SameLine(0.0, 4.0); + } + } + + ImGui::EndChild(); + ImGui::EndTabItem(); + } + + if (ImGui::BeginTabItem(TEXT("Vehicle.TextureTab"))) + { + Paint::GenerateNodeList(pVeh, m_Paint.m_vecNames, m_Paint.m_Selected); + + ImGui::Spacing(); + if (ImGui::Button(TEXT("Vehicle.ResetTexture"), ImVec2(Widget::CalcSize()))) + { + Paint::ResetNodeTexture(pVeh, m_Paint.m_Selected); + Util::SetMessage(TEXT("Vehicle.ResetTextureMSG")); + } + ImGui::Spacing(); + + Widget::ListBox(TEXT("Vehicle.Component"), m_Paint.m_vecNames, m_Paint.m_Selected); + ImGui::Spacing(); + + ImGui::Columns(2, NULL, false); + ImGui::Checkbox(TEXT("Vehicle.MatFilter"), &m_Paint.m_bMatFilter); + ImGui::NextColumn(); + int maxpjob, curpjob; + Command(hVeh, &maxpjob); + + if (maxpjob > 0) + { + Command(hVeh, &curpjob); + + if (ImGui::ArrowButton("Left", ImGuiDir_Left)) + { + curpjob -= 1; + if (curpjob < -1) + { + curpjob = maxpjob - 1; + } + Command(hVeh, curpjob); + } + ImGui::SameLine(); + ImGui::Text("%s: %d",TEXT("Vehicle.Paintjob"), curpjob+2); + ImGui::SameLine(); + if (ImGui::ArrowButton("Right", ImGuiDir_Right)) + { + curpjob += 1; + if (curpjob > maxpjob) + { + curpjob = -1; + } + Command(hVeh, curpjob); + } + + ImGui::Spacing(); + } + ImGui::Columns(1); + ImGui::Spacing(); + Widget::ImageList(Paint::m_TextureData, + [this](std::string& str) + { + Paint::SetNodeTexture(FindPlayerPed()->m_pVehicle, m_Paint.m_Selected, str, + m_Paint.m_bMatFilter); + }, + [](std::string& str) + { + return str; + }, nullptr, [](){}); + + ImGui::EndTabItem(); + } + } +#endif +} \ No newline at end of file diff --git a/src/custom/vehpaint.h b/src/custom/vehpaint.h new file mode 100644 index 0000000..eeab1bc --- /dev/null +++ b/src/custom/vehpaint.h @@ -0,0 +1,42 @@ +#pragma once +#include "interface/ifeature.hpp" + +/* + VehPaintMgr Class + Handles neon, textures for vehicle +*/ +class VehPaintMgr : public IFeature +{ +private: + std::vector> m_ColorData; // vehicle color data from carcols.dat + + struct + { + float m_fColorPicker[3] { 0, 0, 0 }; + bool m_bRainbowEffect; + unsigned int m_nRainbowTimer; + bool m_bApplyOnTraffic; + unsigned int m_nTrafficTimer; + } m_Neon; + + struct + { + bool m_bMatFilter = true; + int m_nRadioButton = 1; + float m_fColorPicker[3] { 0, 0, 0 }; + std::vector m_vecNames{"Default"}; + std::string m_Selected = "Default"; + } m_Paint; + + + friend class IFeature; + VehPaintMgr(); + VehPaintMgr(const VehPaintMgr&); + +public: + + // Draw color, neon & texture tabs + void Draw(); +}; + +extern VehPaintMgr& VehPaint; \ No newline at end of file diff --git a/src/defines.h b/src/defines.h index 4ec5e53..108667c 100644 --- a/src/defines.h +++ b/src/defines.h @@ -10,7 +10,7 @@ #define MENU_NAME "Cheat Menu" #define MENU_VERSION_NUMBER "3.3" #define MENU_VERSION MENU_VERSION_NUMBER"-beta" -#define BUILD_NUMBER "20220810" +#define BUILD_NUMBER "20220820" #define MENU_TITLE MENU_NAME " v" MENU_VERSION #ifdef GTASA diff --git a/src/interface/icheat.hpp b/src/interface/icheat.hpp index 631fb93..64ead7b 100644 --- a/src/interface/icheat.hpp +++ b/src/interface/icheat.hpp @@ -1,7 +1,8 @@ #pragma once +#include "ifeature.hpp" template -class ICheat +class ICheat : public IFeature { protected: bool m_bEnabled = false; @@ -20,12 +21,6 @@ public: m_bEnabled = true; } - static T &Get() - { - static T _instance; - return _instance; - } - // Returns the current stae of the cheat virtual const bool GetState() final { diff --git a/src/interface/ifeature.hpp b/src/interface/ifeature.hpp new file mode 100644 index 0000000..48d1a8a --- /dev/null +++ b/src/interface/ifeature.hpp @@ -0,0 +1,12 @@ +#pragma once + +template +class IFeature +{ +public: + static T &Get() + { + static T _instance; + return _instance; + } +}; \ No newline at end of file diff --git a/src/interface/ipage.cpp b/src/interface/ipage.cpp index 186876a..e992662 100644 --- a/src/interface/ipage.cpp +++ b/src/interface/ipage.cpp @@ -5,9 +5,17 @@ #include "imgui/imgui_internal.h" #include "pages/welcome.h" -void PageHandler::AddPage(PagePtr page) +void PageHandler::AddPage(PagePtr page, size_t index) { - m_PageList.push_back(page); + static size_t size = static_cast(ePageID::None); + if (index <= size) + { + if (m_PageList.size() < size) + { + m_PageList.resize(size); + } + m_PageList[index] = page; + } } void PageHandler::SetCurrentPage(PagePtr page) diff --git a/src/interface/ipage.h b/src/interface/ipage.h index d154c70..acbb5c9 100644 --- a/src/interface/ipage.h +++ b/src/interface/ipage.h @@ -1,21 +1,24 @@ #pragma once #include +#include "ifeature.hpp" enum class ePageID { - Anniversary, - Game, - Menu, - None, - Ped, + Teleport, Player, + Ped, Scene, - Teleport, - Update, Vehicle, - Visual, Weapon, - Welcome + Game, + Visual, + Menu, + + // Pages without headers + None, + Anniversary, + Update, + Welcome, }; /* @@ -38,7 +41,7 @@ public: static void DrawPages(); // Add a new page - static void AddPage(PagePtr page); + static void AddPage(PagePtr page, size_t index); static void SetCurrentPage(PagePtr page); }; @@ -47,7 +50,7 @@ public: Every page must inherit this */ template -class IPage +class IPage : public IFeature { private: ePageID m_eID; // Menu page ID @@ -58,18 +61,12 @@ public: IPage(ePageID page, const std::string& key, bool header) : m_eID(page), m_NameKey(key), m_bHasHeader(header) { - PageHandler::AddPage(reinterpret_cast(this)); + PageHandler::AddPage(reinterpret_cast(this), static_cast(m_eID)); } // Page drawing code goes here virtual void Draw() = 0; - static T &Get() - { - static T _instance; - return _instance; - } - // Returns the ID of the page virtual ePageID GetPageID() final { diff --git a/src/pages/anniversary.h b/src/pages/anniversary.h index 489ef0d..4a903f0 100644 --- a/src/pages/anniversary.h +++ b/src/pages/anniversary.h @@ -5,7 +5,7 @@ class AnniversaryPage : public IPage { private: - friend IPage; + friend class IFeature; AnniversaryPage() : IPage(ePageID::Anniversary, "Anniversary", false){} AnniversaryPage(const AnniversaryPage&); diff --git a/src/pages/game.cpp b/src/pages/game.cpp index acc3cb9..b51e62d 100644 --- a/src/pages/game.cpp +++ b/src/pages/game.cpp @@ -175,7 +175,6 @@ void SetPlayerMission(std::string& rootkey, std::string& name, std::string& id) void GamePage::Draw() { - ImGui::Spacing(); CPlayerPed* pPlayer = FindPlayerPed(); int hplayer = CPools::GetPedRef(pPlayer); diff --git a/src/pages/game.h b/src/pages/game.h index 281c6f9..5c6feb5 100644 --- a/src/pages/game.h +++ b/src/pages/game.h @@ -28,7 +28,7 @@ private: ResourceStore m_StatData{ "stats", eResourceType::TYPE_TEXT }; #endif - friend IPage; + friend class IFeature; GamePage(); GamePage(const GamePage&); diff --git a/src/pages/menu.cpp b/src/pages/menu.cpp index 58eab6d..01065ca 100644 --- a/src/pages/menu.cpp +++ b/src/pages/menu.cpp @@ -104,7 +104,7 @@ void MenuPage::Draw() } ImGui::NextColumn(); - if (gRenderer == Render_DirectX9 + if (gRenderer == eRenderer::DirectX9 && Widget::Checkbox(TEXT("Menu.TextOnlyMode"), &m_bTextOnlyMode, TEXT("Menu.TextOnlyModeHint"))) { gConfig.Set("Menu.TextOnlyMode", m_bTextOnlyMode); @@ -380,6 +380,12 @@ void MenuPage::Draw() ImGui::TableNextColumn(); ImGui::Text("MinHook"); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::Text("_AG & jeremii"); + ImGui::TableNextColumn(); + ImGui::Text("Radar code"); + ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text(TEXT("Main.TranslatorName")); diff --git a/src/pages/menu.h b/src/pages/menu.h index 1375186..d1cd352 100644 --- a/src/pages/menu.h +++ b/src/pages/menu.h @@ -8,7 +8,7 @@ public: bool m_bDiscordRPC; // Is the discord rich presence enabled bool m_bTextOnlyMode; // Hide all menu images mode - friend IPage; + friend class IFeature; MenuPage(); MenuPage(const MenuPage&); diff --git a/src/pages/ped.cpp b/src/pages/ped.cpp index 497c6dd..bb721bd 100644 --- a/src/pages/ped.cpp +++ b/src/pages/ped.cpp @@ -23,14 +23,17 @@ static const char* pedTypeList = "Civ Male\0Civ Female\0Cop\0Leones\0Triads\0Dia #endif -void Ped::Init() +PedPage &pedPage = PedPage::Get(); + +PedPage::PedPage() + : IPage(ePageID::Ped, "Window.PedPage", true) { /* Taken from gta chaos mod by Lordmau5 & _AG TODO: Implement in VC too */ #ifdef GTASA - Events::pedRenderEvent += [](CPed *ped) + Events::pedRenderEvent += [this](CPed *ped) { if (m_bBigHead)// || m_bThinBody) @@ -86,7 +89,7 @@ void Ped::Init() #endif } -void Ped::AddNewPed() +void PedPage::AddNewPed() { static char name[8]; static int model = 0; @@ -118,12 +121,12 @@ void Ped::AddNewPed() } } #ifdef GTASA -void Ped::SpawnPed(std::string& model) +void PedPage::SpawnPed(std::string& model) #else -void Ped::SpawnPed(std::string& cat, std::string& name, std::string& model) +void PedPage::SpawnPed(std::string& cat, std::string& name, std::string& model) #endif { - if (Spawner::m_List.size() == SPAWN_PED_LIMIT) + if (m_Spawner.m_List.size() == SPAWN_PED_LIMIT) { Util::SetMessage(TEXT("Ped.MaxLimit")); return; @@ -155,7 +158,7 @@ void Ped::SpawnPed(std::string& cat, std::string& name, std::string& model) CStreaming::RequestSpecialChar(currentSlot, name.c_str(), PRIORITY_REQUEST); CStreaming::LoadAllRequestedModels(true); - Command(Spawner::m_nSelectedPedType + 4, 290 + currentSlot, pos.x, pos.y, pos.z + 1, &hplayer); + Command(m_Spawner.m_nSelectedPedType + 4, 290 + currentSlot, pos.x, pos.y, pos.z + 1, &hplayer); CStreaming::SetSpecialCharIsDeletable(290 + currentSlot); // SA has 10 slots @@ -175,7 +178,7 @@ void Ped::SpawnPed(std::string& cat, std::string& name, std::string& model) Command(currentSlot, model.c_str()); Command(); - Command(Spawner::m_nSelectedPedType + 4, 108+currentSlot, pos.x, pos.y, pos.z + 1, &hplayer); + Command(m_Spawner.m_nSelectedPedType + 4, 108+currentSlot, pos.x, pos.y, pos.z + 1, &hplayer); Command(currentSlot); ++currentSlot; @@ -192,37 +195,37 @@ void Ped::SpawnPed(std::string& cat, std::string& name, std::string& model) CStreaming::RequestModel(iModel, eStreamingFlags::PRIORITY_REQUEST); CStreaming::LoadAllRequestedModels(false); - Command(Spawner::m_nSelectedPedType + 4, iModel, pos.x, pos.y, pos.z + 1, &hplayer); + Command(m_Spawner.m_nSelectedPedType + 4, iModel, pos.x, pos.y, pos.z + 1, &hplayer); CStreaming::SetModelIsDeletable(iModel); } ped = CPools::GetPed(hplayer); - if (Spawner::m_bPedMove) + if (m_Spawner.m_bPedMove) { - Spawner::m_List.push_back(ped); + m_Spawner.m_List.push_back(ped); } else { Command(hplayer); } - ped->m_nPedFlags.bPedIsBleeding = Spawner::m_bPedBleed; - ped->m_nWeaponAccuracy = Spawner::m_nAccuracy; - ped->m_fHealth = Spawner::m_nPedHealth; + ped->m_nPedFlags.bPedIsBleeding = m_Spawner.m_bPedBleed; + ped->m_nWeaponAccuracy = m_Spawner.m_nAccuracy; + ped->m_fHealth = m_Spawner.m_nPedHealth; #ifdef GTASA - if (Spawner::m_nWeaponId != 0) + if (m_Spawner.m_nWeaponId != 0) { int model = 0; - Command(Spawner::m_nWeaponId, &model); + Command(m_Spawner.m_nWeaponId, &model); CStreaming::RequestModel(model, PRIORITY_REQUEST); CStreaming::LoadAllRequestedModels(false); - Command(hplayer, Spawner::m_nWeaponId, 999); + Command(hplayer, m_Spawner.m_nWeaponId, 999); } #endif } } -void Ped::ShowPage() +void PedPage::Draw() { if (ImGui::BeginTabBar("Ped", ImGuiTabBarFlags_NoTooltip + ImGuiTabBarFlags_FittingPolicyScroll)) { @@ -320,12 +323,12 @@ void Ped::ShowPage() ImGui::Spacing(); if (ImGui::Button(TEXT("Ped.RemoveFrozen"), Widget::CalcSize(1))) { - for (CPed* ped : Spawner::m_List) + for (CPed* ped : m_Spawner.m_List) { CWorld::Remove(ped); ped->Remove(); } - Spawner::m_List.clear(); + m_Spawner.m_List.clear(); } ImGui::Spacing(); if (ImGui::BeginTabBar("SpawnPedBar")) @@ -336,12 +339,14 @@ void Ped::ShowPage() { ImGui::Spacing(); #ifdef GTASA - Widget::ImageList(m_PedData, SpawnPed, - [](std::string& str){ - return m_PedData.m_pData->Get(str.c_str(), "Unknown"); - }, nullptr, AddNewPed); + Widget::ImageList(m_PedData, fArgWrapper(pedPage.SpawnPed), + [this](str &text) + { + return m_PedData.m_pData->Get(text.c_str(), "Unknown"); + }, + nullptr, fArgNoneWrapper(pedPage.AddNewPed)); #else - Widget::DataList(m_PedData, SpawnPed, AddNewPed); + Widget::DataList(m_PedData, fArg3Wrapper(pedPage.SpawnPed), fArgNoneWrapper(pedPage.AddNewPed)); #endif ImGui::EndTabItem(); } @@ -350,26 +355,26 @@ void Ped::ShowPage() ImGui::Spacing(); ImGui::BeginChild("PedCOnfig"); ImGui::Columns(2, 0, false); - Widget::Checkbox(TEXT("Ped.NoMove"), &Spawner::m_bPedMove); + Widget::Checkbox(TEXT("Ped.NoMove"), &m_Spawner.m_bPedMove); ImGui::NextColumn(); - Widget::Checkbox(TEXT("Ped.PedBleed"), &Spawner::m_bPedBleed); + Widget::Checkbox(TEXT("Ped.PedBleed"), &m_Spawner.m_bPedBleed); ImGui::Columns(1); ImGui::Spacing(); - ImGui::SliderInt(TEXT("Ped.Accuracy"), &Spawner::m_nAccuracy, 0.0, 100.0); - if (ImGui::InputInt(TEXT("Ped.Health"), &Spawner::m_nPedHealth)) + ImGui::SliderInt(TEXT("Ped.Accuracy"), &m_Spawner.m_nAccuracy, 0.0, 100.0); + if (ImGui::InputInt(TEXT("Ped.Health"), &m_Spawner.m_nPedHealth)) { - if (Spawner::m_nPedHealth > 1000) + if (m_Spawner.m_nPedHealth > 1000) { - Spawner::m_nPedHealth = 1000; + m_Spawner.m_nPedHealth = 1000; } - if (Spawner::m_nPedHealth < 0) + if (m_Spawner.m_nPedHealth < 0) { - Spawner::m_nPedHealth = 0; + m_Spawner.m_nPedHealth = 0; } } - ImGui::Combo(TEXT("Ped.PedType"), &Spawner::m_nSelectedPedType, pedTypeList); + ImGui::Combo(TEXT("Ped.PedType"), &m_Spawner.m_nSelectedPedType, pedTypeList); ImGui::EndChild(); ImGui::EndTabItem(); } @@ -380,25 +385,25 @@ void Ped::ShowPage() ImGui::Text(TEXT("Ped.SelectedWeapon"), weaponName.c_str()); ImGui::Spacing(); #ifdef GTASA - Widget::ImageList(WeaponPage::m_WeaponData, - [](std::string& str) + Widget::ImageList(weaponPage.m_WeaponData, + [this](std::string& str) { - Spawner::m_nWeaponId = std::stoi(str); - weaponName = WeaponPage::m_WeaponData.m_pData->Get(str.c_str(), "Unknown"); + m_Spawner.m_nWeaponId = std::stoi(str); + weaponName = weaponPage.m_WeaponData.m_pData->Get(str.c_str(), "Unknown"); }, [](std::string& str) { - return WeaponPage::m_WeaponData.m_pData->Get(str.c_str(), "Unknown"); + return weaponPage.m_WeaponData.m_pData->Get(str.c_str(), "Unknown"); }, [](std::string& str) { return str != "-1"; /*Jetpack*/ }); #else - Widget::DataList(Weapon::m_WeaponData, - [](std::string& root, std::string& key, std::string& id) + Widget::DataList(weaponPage.m_WeaponData, + [this](std::string& root, std::string& key, std::string& id) { - Spawner::m_nWeaponId = std::stoi(id); + m_Spawner.m_nWeaponId = std::stoi(id); weaponName = key; }); #endif @@ -462,8 +467,7 @@ void Ped::ShowPage() ImGui::Spacing(); if (ImGui::Button(TEXT("Ped.DownloadExGangWars"), Widget::CalcSize(1))) { - ShellExecute(NULL, "open", "https://gtaforums.com/topic/682194-extended-gang-wars/", NULL, NULL, - SW_SHOWNORMAL); + OPEN_LINK("https://gtaforums.com/topic/682194-extended-gang-wars/"); } } diff --git a/src/pages/ped.h b/src/pages/ped.h index 769f516..504c82b 100644 --- a/src/pages/ped.h +++ b/src/pages/ped.h @@ -1,41 +1,47 @@ #pragma once #include "pch.h" +#include "interface/ipage.h" -class Ped +class PedPage : public IPage { private: - static inline bool m_bBigHead; - static inline bool m_bThinBody; - - struct Spawner + bool m_bBigHead; + bool m_bThinBody; + struct { - static inline std::vector m_List; - static inline int m_nAccuracy = 50; - static inline int m_nPedHealth = 100; - static inline bool m_bPedMove; - static inline bool m_bPedBleed; - static inline int m_nSelectedPedType; - static inline int m_nWeaponId; - }; + std::vector m_List; + int m_nAccuracy = 50; + int m_nPedHealth = 100; + bool m_bPedMove; + bool m_bPedBleed; + int m_nSelectedPedType; + int m_nWeaponId; + } m_Spawner; - static void AddNewPed(); + + friend class IFeature; + PedPage(); + PedPage(const PedPage&); + + // Add new ped to data file + void AddNewPed(); + + // Spawn a ped with specified model #ifdef GTASA - static void SpawnPed(std::string& model); + void SpawnPed(str& model); #else - static void SpawnPed(std::string& cat, std::string& name, std::string& model); + void SpawnPed(str& cat, str& name, str& model); #endif - + public: #ifdef GTASA - static inline DataStore m_SpecialPedData {"special_peds"}; - static inline ResourceStore m_PedData{"peds", eResourceType::TYPE_IMAGE_TEXT, ImVec2(65, 110)}; + DataStore m_SpecialPedData {"special_peds"}; + ResourceStore m_PedData{"peds", eResourceType::TYPE_IMAGE_TEXT, ImVec2(65, 110)}; #else - static inline ResourceStore m_PedData {"peds", eResourceType::TYPE_TEXT}; + ResourceStore m_PedData {"peds", eResourceType::TYPE_TEXT}; #endif - Ped() = delete; - Ped(const Ped&) = delete; - - static void Init(); - static void ShowPage(); + void Draw(); }; + +extern PedPage &pedPage; diff --git a/src/pages/player.cpp b/src/pages/player.cpp index 1e884dc..604e1bc 100644 --- a/src/pages/player.cpp +++ b/src/pages/player.cpp @@ -8,6 +8,7 @@ #ifdef GTASA #include "ped.h" #include "custom/topdowncam_sa.h" +#include "custom/customskins_sa.h" static inline const char* clothNameList[18] = { @@ -28,7 +29,9 @@ static inline void PlayerModelBrokenFix() } #endif -void Player::Init() +PlayerPage &playerPage = PlayerPage::Get(); +PlayerPage::PlayerPage() + : IPage(ePageID::Player, "Window.PlayerPage", true) { #ifdef GTASA // Fix player model being broken after rebuild @@ -36,42 +39,7 @@ void Player::Init() m_bAimSkinChanger = gConfig.Get("Features.AimSkinChanger", false); #endif - - // Custom skins setup - std::string path = GAME_PATH((char*)"modloader/"); - if (GetModuleHandle("modloader.asi") && std::filesystem::is_directory(path)) - { -#ifdef GTASA - path += "CustomSkins/"; - if (std::filesystem::is_directory(path)) - { - for (auto& p : std::filesystem::recursive_directory_iterator(path)) - { - if (p.path().extension() == ".dff") - { - std::string file_name = p.path().stem().string(); - - if (file_name.size() < 9) - { - CustomSkins::m_List.push_back(file_name); - } - else - { - Log::Print("Custom Skin longer than 8 characters {}", file_name); - } - } - } - } - else - { - std::filesystem::create_directory(path); - } -#endif - - m_bModloaderInstalled = true; - } - - Events::processScriptsEvent += [] + Events::processScriptsEvent += [this] { uint timer = CTimer::m_snTimeInMilliseconds; CPlayerPed* player = FindPlayerPed(); @@ -123,22 +91,22 @@ void Player::Init() } } - if (KeepPosition::m_bEnabled) + if (m_RespawnDieLoc.m_bEnabled) { if (Command(hplayer)) { - KeepPosition::m_fPos = player->GetPosition(); + m_RespawnDieLoc.m_fPos = player->GetPosition(); } else { CVector cur_pos = player->GetPosition(); - if (KeepPosition::m_fPos.x != 0 && KeepPosition::m_fPos.x != cur_pos.x - && KeepPosition::m_fPos.y != 0 && KeepPosition::m_fPos.y != cur_pos.y) + if (m_RespawnDieLoc.m_fPos.x != 0 && m_RespawnDieLoc.m_fPos.x != cur_pos.x + && m_RespawnDieLoc.m_fPos.y != 0 && m_RespawnDieLoc.m_fPos.y != cur_pos.y) { - BY_GAME(player->Teleport(KeepPosition::m_fPos, false) - , player->Teleport(KeepPosition::m_fPos), player->Teleport(KeepPosition::m_fPos)); - KeepPosition::m_fPos = CVector(0, 0, 0); + BY_GAME(player->Teleport(m_RespawnDieLoc.m_fPos, false) + , player->Teleport(m_RespawnDieLoc.m_fPos), player->Teleport(m_RespawnDieLoc.m_fPos)); + m_RespawnDieLoc.m_fPos = CVector(0, 0, 0); } } } @@ -179,7 +147,7 @@ void Player::Init() if (targetPed) { player->SetModelIndex(targetPed->m_nModelIndex); - Util::ClearCharTasksVehCheck(player); + Util::ClearCharTasksCarCheck(player); } } #endif @@ -221,7 +189,7 @@ void Player::Init() } #ifdef GTASA -void Player::ChangePlayerCloth(std::string& name) +void PlayerPage::SetCloth(std::string& name) { int bodyPart; char model[16], tex[16]; @@ -259,47 +227,32 @@ void Player::ChangePlayerCloth(std::string& name) #endif #ifdef GTASA -void Player::ChangePlayerModel(std::string& model) +void PlayerPage::SetModel(std::string& model) { - bool custom_skin = std::find(CustomSkins::m_List.begin(), CustomSkins::m_List.end(), model) != - CustomSkins::m_List.end(); - - if (Ped::m_PedData.m_pData->Contains(model.c_str()) || custom_skin) + if (pedPage.m_PedData.m_pData->Contains(model.c_str())) { CPlayerPed* player = FindPlayerPed(); - if (Ped::m_SpecialPedData.Contains(model.c_str()) || custom_skin) + if (pedPage.m_SpecialPedData.Contains(model.c_str())) { - std::string name; - if (Ped::m_SpecialPedData.Contains(model.c_str())) - { - name = Ped::m_SpecialPedData.Get(model.c_str(), "Unknown"); - } - else - { - name = model; - } - + std::string name = pedPage.m_SpecialPedData.Get(model.c_str(), "Unknown"); CStreaming::RequestSpecialChar(1, name.c_str(), PRIORITY_REQUEST); CStreaming::LoadAllRequestedModels(true); - player->SetModelIndex(291); - CStreaming::SetSpecialCharIsDeletable(291); } else { int imodel = std::stoi(model); - CStreaming::RequestModel(imodel, eStreamingFlags::PRIORITY_REQUEST); CStreaming::LoadAllRequestedModels(false); player->SetModelIndex(imodel); CStreaming::SetModelIsDeletable(imodel); } - Util::ClearCharTasksVehCheck(player); + Util::ClearCharTasksCarCheck(player); } } #else -void Player::ChangePlayerModel(std::string& cat, std::string& key, std::string& val) +void PlayerPage::ChangePlayerModel(std::string& cat, std::string& key, std::string& val) { CPlayerPed* player = FindPlayerPed(); @@ -329,7 +282,7 @@ void Player::ChangePlayerModel(std::string& cat, std::string& key, std::string& } #endif -void Player::ShowPage() +void PlayerPage::Draw() { CPlayerPed* pPlayer = FindPlayerPed(); int hplayer = CPools::GetPedRef(pPlayer); @@ -574,7 +527,7 @@ void Player::ShowPage() #endif Widget::CheckboxAddr(TEXT("Player.NoFee"), (int)&pInfo->m_bGetOutOfJailFree); - Widget::Checkbox(TEXT("Player.RespawnDieLoc"), &KeepPosition::m_bEnabled, TEXT("Player.RespawnDieLocTip")); + Widget::Checkbox(TEXT("Player.RespawnDieLoc"), &m_RespawnDieLoc.m_bEnabled, TEXT("Player.RespawnDieLocTip")); Widget::Checkbox(TEXT("Player.PlayerRegen"), &m_bPlayerRegen, TEXT("Player.PlayerRegenTip")); #ifdef GTASA static bool sprintInt = false; @@ -684,7 +637,7 @@ void Player::ShowPage() if (ImGui::Button(TEXT("Player.ChangeToCJ"), ImVec2(Widget::CalcSize(1)))) { pPlayer->SetModelIndex(0); - Util::ClearCharTasksVehCheck(pPlayer); + Util::ClearCharTasksCarCheck(pPlayer); } } ImGui::Spacing(); @@ -806,7 +759,8 @@ void Player::ShowPage() { if (pPlayer->m_nModelIndex == 0) { - Widget::ImageList(m_ClothData, ChangePlayerCloth, [](std::string& str) + Widget::ImageList(m_ClothData, fArgWrapper(playerPage.SetCloth), + [](std::string& str) { std::stringstream ss(str); std::string temp; @@ -825,7 +779,7 @@ void Player::ShowPage() if (ImGui::Button(TEXT("Player.ChangeToCJ"), ImVec2(Widget::CalcSize(1)))) { pPlayer->SetModelIndex(0); - Util::ClearCharTasksVehCheck(pPlayer); + Util::ClearCharTasksCarCheck(pPlayer); } } ImGui::EndTabItem(); @@ -837,7 +791,6 @@ void Player::ShowPage() ImGui::Spacing(); ImGui::BeginChild("ClothesRemove"); - size_t count = 0; if (ImGui::Button(TEXT("Player.RemoveAll"), ImVec2(Widget::CalcSize(2)))) { CPlayerPed* player = FindPlayerPed(); @@ -848,12 +801,13 @@ void Player::ShowPage() CClothes::RebuildPlayer(player, false); } ImGui::SameLine(); + size_t count = 0; for (auto [k, v] : m_ClothData.m_pData->Items()) { if (ImGui::Button(std::string(k.str()).c_str(), ImVec2(Widget::CalcSize(2)))) { CPlayerPed* player = FindPlayerPed(); - player->m_pPlayerData->m_pPedClothesDesc->SetTextureAndModel(0u, 0u, count); + player->m_pPlayerData->m_pPedClothesDesc->SetTextureAndModel(0u, 0u, std::stoi(v.value_or("0"))); CClothes::RebuildPlayer(player, false); } @@ -869,45 +823,17 @@ void Player::ShowPage() } if (ImGui::BeginTabItem(TEXT("Player.PedSkinsTab"))) { - Widget::ImageList(Ped::m_PedData, ChangePlayerModel, + Widget::ImageList(pedPage.m_PedData, fArgWrapper(playerPage.SetModel), [](std::string& str) { - return Ped::m_PedData.m_pData->Get(str.c_str(), "Unknown"); + return pedPage.m_PedData.m_pData->Get(str.c_str(), "Unknown"); }); ImGui::EndTabItem(); } if (ImGui::BeginTabItem(TEXT("Player.CustomSkinsTab"))) { ImGui::Spacing(); - - if (m_bModloaderInstalled) - { - Widget::Filter(TEXT("Window.Search"), m_ClothData.m_Filter, - std::string(TEXT("Player.TotalSkins") + std::to_string(CustomSkins::m_List.size())) - .c_str()); - Widget::Tooltip(TEXT("Player.CustomSkinsDirTip")); - ImGui::Spacing(); - ImGui::TextWrapped(TEXT("Player.CustomSkinsTip")); - ImGui::Spacing(); - for (std::string name : CustomSkins::m_List) - { - if (CustomSkins::m_Filter.PassFilter(name.c_str())) - { - if (ImGui::MenuItem(name.c_str())) - { - ChangePlayerModel(name); - } - } - } - } - else - { - ImGui::TextWrapped(TEXT("Player.CustomSkinTutorial")); - ImGui::Spacing(); - if (ImGui::Button(TEXT("Player.DownloadModloader"), ImVec2(Widget::CalcSize(1)))) - ShellExecute(NULL, "open", "https://gtaforums.com/topic/669520-mod-loader/", NULL, NULL, - SW_SHOWNORMAL); - } + CustomSkins.Draw(); ImGui::EndTabItem(); } ImGui::EndTabBar(); @@ -924,7 +850,7 @@ void Player::ShowPage() #else ImGui::TextWrapped(TEXT("Player.WorkSkinOnly")); #endif - Widget::DataList(skinData, ChangePlayerModel); + Widget::DataList(skinData, fArg3Wrapper(playerPage.ChangePlayerModel)); ImGui::EndTabItem(); } #endif diff --git a/src/pages/player.h b/src/pages/player.h index acbd6e6..17bbb75 100644 --- a/src/pages/player.h +++ b/src/pages/player.h @@ -1,47 +1,44 @@ #pragma once #include "pch.h" +#include "interface/ipage.h" -class Player +class PlayerPage : public IPage { private: - static inline bool m_bGodMode; - static inline bool m_bPlayerRegen; - static inline bool m_bModloaderInstalled; - struct KeepPosition + bool m_bGodMode; + bool m_bPlayerRegen; + struct { - static inline bool m_bEnabled = false; - static inline CVector m_fPos; - }; - static inline bool m_bKeepStuff; - static inline bool m_bFreezeWantedLevel; + bool m_bEnabled = false; + CVector m_fPos; + } m_RespawnDieLoc; + bool m_bKeepStuff; + bool m_bFreezeWantedLevel; #ifdef GTAVC - static inline bool m_bNoUndress; + bool m_bNoUndress; // Tommy won't lose clothes after busted/ wasted #endif #ifdef GTASA - static inline bool m_bAimSkinChanger; - static inline bool m_bDrunkEffect; - static inline bool m_bFastSprint; - static inline ResourceStore m_ClothData { "clothes", eResourceType::TYPE_TEXT_IMAGE, ImVec2(70, 100)}; - struct CustomSkins - { - static inline ImGuiTextFilter m_Filter; - static inline std::vector m_List; - }; + bool m_bAimSkinChanger; + bool m_bDrunkEffect; + bool m_bFastSprint; + ResourceStore m_ClothData { "clothes", eResourceType::TYPE_TEXT_IMAGE, ImVec2(70, 100)}; - static void ChangePlayerModel(std::string& model); - static void ChangePlayerCloth(std::string& model); + void SetCloth(str& id); + void SetModel(str& id); #else - static inline ResourceStore skinData { BY_GAME(NULL, "skins", "peds"), eResourceType::TYPE_TEXT }; - static void ChangePlayerModel(std::string& cat, std::string& name, std::string& id); + ResourceStore skinData { BY_GAME(NULL, "skins", "peds"), eResourceType::TYPE_TEXT }; + void ChangePlayerModel(str& cat, str& name, str& id); #endif + friend class IFeature; + PlayerPage(); + PlayerPage(const PlayerPage&); + public: - Player() = delete; - Player(const Player&) = delete; - - static void Init(); - static void ShowPage(); + void Draw(); }; + +extern PlayerPage &playerPage; diff --git a/src/pages/scene.h b/src/pages/scene.h index a812483..1b116bf 100644 --- a/src/pages/scene.h +++ b/src/pages/scene.h @@ -8,7 +8,7 @@ class ScenePage : public IPage { private: - friend IPage; + friend class IFeature; ScenePage() : IPage(ePageID::Scene, "Window.ScenePage", true){} ScenePage(const ScenePage&); diff --git a/src/pages/teleport.h b/src/pages/teleport.h index 8e49d44..0881547 100644 --- a/src/pages/teleport.h +++ b/src/pages/teleport.h @@ -31,7 +31,7 @@ private: public: ResourceStore m_locData{"locations", eResourceType::TYPE_TEXT}; - friend IPage; + friend class IFeature; TeleportPage(); TeleportPage(const TeleportPage&); diff --git a/src/pages/update.h b/src/pages/update.h index 3126dd7..5f442b0 100644 --- a/src/pages/update.h +++ b/src/pages/update.h @@ -5,7 +5,7 @@ class UpdatePage : public IPage { private: - friend IPage; + friend class IFeature; UpdatePage() : IPage(ePageID::Update, "Update", false){} UpdatePage(const UpdatePage&); diff --git a/src/pages/vehicle.cpp b/src/pages/vehicle.cpp index 721160c..0953b11 100644 --- a/src/pages/vehicle.cpp +++ b/src/pages/vehicle.cpp @@ -7,49 +7,45 @@ #include "utils/widget.h" #include "utils/util.h" #include "custom/filehandler.h" +#include "custom/vehpaint.h" +#include "custom/autodrive.h" #ifdef GTASA #include -#include "custom/neon_sa.h" -#include "custom/paint_sa.h" +#include "custom/vehmod_sa.h" #endif -void Vehicle::Init() +VehiclePage& vehiclePage = VehiclePage::Get(); +VehiclePage::VehiclePage() +: IPage(ePageID::Vehicle, "Window.VehiclePage", true) { -#ifdef GTASA - FileHandler::FetchHandlingID(m_VehicleIDE); - Paint::InjectHooks(); -#endif - - FileHandler::FetchColorData(m_CarcolsColorData); - // Get config data - Spawner::m_bSpawnInAir = gConfig.Get("Features.SpawnAircraftInAir", true); - Spawner::m_bSpawnInside = gConfig.Get("Features.SpawnInsideVehicle", true); + m_Spawner.m_bInAir = gConfig.Get("Features.SpawnAircraftInAir", true); + m_Spawner.m_bAsDriver = gConfig.Get("Features.SpawnInsideVehicle", true); - Events::processScriptsEvent += [] + Events::processScriptsEvent += [this] { uint timer = CTimer::m_snTimeInMilliseconds; CPlayerPed* pPlayer = FindPlayerPed(); CVehicle* pVeh = BY_GAME(FindPlayerVehicle(-1, false), FindPlayerVehicle(), FindPlayerVehicle()); - if (pPlayer && Util::IsInVehicle()) + if (pPlayer && Util::IsInCar()) { int hveh = CPools::GetVehicleRef(pVeh); float speed = pVeh->m_vecMoveSpeed.Magnitude() * 50.0f; if (m_bAutoUnflip && pVeh->IsUpsideDown() && speed < 2.0f) { - Util::UnFlipVehicle(pVeh); + Util::UnFlipCar(pVeh); } if (unflipVeh.Pressed()) { - Util::UnFlipVehicle(pVeh); + Util::UnFlipCar(pVeh); } if (fixVeh.Pressed()) { - Util::FixVehicle(pVeh); + Util::FixCar(pVeh); Util::SetMessage("Vehicle fixed"); } @@ -121,72 +117,9 @@ void Vehicle::Init() { Util::SetCarForwardSpeed(pVeh, m_fLockSpeed); } - -#ifdef GTASA - if (UnlimitedNitro::m_bEnabled && pVeh->m_nVehicleSubClass == VEHICLE_AUTOMOBILE) - { - patch::Set(0x969165, 0, true); // All cars have nitro - patch::Set(0x96918B, 0, true); // All taxis have nitro - - if (KeyPressed(VK_LBUTTON)) - { - if (!UnlimitedNitro::m_bCompAdded) - { - AddComponent("1010", false); - UnlimitedNitro::m_bCompAdded = true; - } - } - else - { - if (UnlimitedNitro::m_bCompAdded) - { - RemoveComponent("1010", false); - UnlimitedNitro::m_bCompAdded = false; - } - } - } - - if (NeonData::m_bRainbowEffect && timer - NeonData::m_nRainbowTimer > 50) - { - int red, green, blue; - - Util::RainbowValues(red, green, blue, 0.25); - Neon.Install(pVeh, red, green, blue); - NeonData::m_nRainbowTimer = timer; - } -#endif } #ifdef GTASA - // Traffic neons - if (NeonData::m_bApplyOnTraffic && timer - NeonData::m_bTrafficTimer > 1000) - { - for (CVehicle* veh : CPools::ms_pVehiclePool) - { - int chance = 0; - - if (veh->m_nVehicleClass == CLASS_NORMAL) // Normal - { - chance = Random(1, 20); - } - - if (veh->m_nVehicleClass == CLASS_RICHFAMILY) // Rich family - { - chance = Random(1, 4); - } - - if (veh->m_nVehicleClass == CLASS_EXECUTIVE) // Executive - { - chance = Random(1, 3); - } - - if (chance == 1 && !Neon.IsInstalled(veh) && veh->m_pDriver != pPlayer) - { - Neon.Install(veh, Random(0, 255), Random(0, 255), Random(0, 255)); - } - } - NeonData::m_bTrafficTimer = timer; - } if (m_bBikeFly && pVeh && pVeh->IsDriver(pPlayer)) { @@ -207,54 +140,8 @@ void Vehicle::Init() } #ifdef GTASA -void Vehicle::AddComponent(const std::string& component, const bool display_message) -{ - try - { - CPlayerPed* player = FindPlayerPed(); - int icomp = std::stoi(component); - int hveh = CPools::GetVehicleRef(player->m_pVehicle); - - CStreaming::RequestModel(icomp, eStreamingFlags::PRIORITY_REQUEST); - CStreaming::LoadAllRequestedModels(true); - player->m_pVehicle->AddVehicleUpgrade(icomp); - CStreaming::SetModelIsDeletable(icomp); - - if (display_message) - { - Util::SetMessage("Component added"); - } - } - catch (...) - { - Log::Print("Failed to add component to vehicle {}", component); - } -} - - -void Vehicle::RemoveComponent(const std::string& component, const bool display_message) -{ - try - { - CPlayerPed* player = FindPlayerPed(); - int icomp = std::stoi(component); - int hveh = CPools::GetVehicleRef(player->m_pVehicle); - - player->m_pVehicle->RemoveVehicleUpgrade(icomp); - - if (display_message) - { - Util::SetMessage("Component removed"); - } - } - catch (...) - { - Log::Print("Failed to remove component from vehicle {}", component); - } -} - // hardcoded for now -int Vehicle::GetRandomTrainIdForModel(int model) +int VehiclePage::GetRandomTrainIdForModel(int model) { static int train_ids[] = { @@ -322,7 +209,7 @@ void WarpPlayerIntoVehicle(CVehicle *pVeh, int seatId) } #endif -void Vehicle::AddNewVehicle() +void VehiclePage::AddNew() { static char name[INPUT_BUFFER_SIZE]; static int model = 0; @@ -335,8 +222,8 @@ void Vehicle::AddNewVehicle() if (CModelInfo::IsCarModel(model)) { std::string key = std::format("Custom.{} (Added)", name); - Spawner::m_VehData.m_pData->Set(key.c_str(), std::to_string(model)); - Spawner::m_VehData.m_pData->Save(); + m_Spawner.m_VehData.m_pData->Set(key.c_str(), std::to_string(model)); + m_Spawner.m_VehData.m_pData->Save(); Util::SetMessage(TEXT("Window.AddEntryMSG")); } else @@ -352,7 +239,7 @@ void Vehicle::AddNewVehicle() if (Command(hPlayer)) { model = pPlayer->m_pVehicle->m_nModelIndex; - std::string str = Vehicle::GetNameFromModel(model); + std::string str = Util::GetCarName(model); strcpy(name, str.c_str()); } else @@ -363,9 +250,9 @@ void Vehicle::AddNewVehicle() } #ifdef GTASA -void Vehicle::SpawnVehicle(std::string& smodel) +void VehiclePage::SpawnVehicle(std::string& smodel) #else -void Vehicle::SpawnVehicle(std::string& rootkey, std::string& vehName, std::string& smodel) +void VehiclePage::SpawnVehicle(std::string& rootkey, std::string& vehName, std::string& smodel) #endif { CPlayerPed* player = FindPlayerPed(); @@ -378,7 +265,7 @@ void Vehicle::SpawnVehicle(std::string& rootkey, std::string& vehName, std::stri float speed = 0; bool bInVehicle = Command(hplayer); - if (bInVehicle && Spawner::m_bSpawnInside) + if (bInVehicle && m_Spawner.m_bAsDriver) { CVehicle* pveh = player->m_pVehicle; int hveh = CPools::GetVehicleRef(pveh); @@ -404,7 +291,7 @@ void Vehicle::SpawnVehicle(std::string& rootkey, std::string& vehName, std::stri if (interior == 0) { - if (Spawner::m_bSpawnInAir && (CModelInfo::IsHeliModel(imodel) || CModelInfo::IsPlaneModel(imodel))) + if (m_Spawner.m_bInAir && (CModelInfo::IsHeliModel(imodel) || CModelInfo::IsPlaneModel(imodel))) { pos.z = 400; } @@ -446,7 +333,7 @@ void Vehicle::SpawnVehicle(std::string& rootkey, std::string& vehName, std::stri if (veh->m_pDriver) Command(CPools::GetPedRef(veh->m_pDriver)); - if (Spawner::m_bSpawnInside) + if (m_Spawner.m_bAsDriver) { Command(hplayer, hveh); Util::SetCarForwardSpeed(veh, speed); @@ -466,13 +353,13 @@ void Vehicle::SpawnVehicle(std::string& rootkey, std::string& vehName, std::stri CStreaming::RequestModel(imodel, PRIORITY_REQUEST); CStreaming::LoadAllRequestedModels(false); #ifdef GTASA - if (Spawner::m_nLicenseText[0] != '\0') + if (m_Spawner.m_nLicenseText[0] != '\0') { - Command(imodel, Spawner::m_nLicenseText); + Command(imodel, m_Spawner.m_nLicenseText); } #endif int hveh = 0; - if (Spawner::m_bSpawnInside) + if (m_Spawner.m_bAsDriver) { Command(imodel, pos.x, pos.y, pos.z + 4.0f, &hveh); veh = CPools::GetVehicle(hveh); @@ -526,102 +413,7 @@ void Vehicle::SpawnVehicle(std::string& rootkey, std::string& vehName, std::stri #endif } -std::string Vehicle::GetNameFromModel(int model) -{ -#ifdef GTA3 - return std::to_string(model); -#else - return (const char*)CModelInfo::GetModelInfo(model) + 0x32; -#endif -} - -int Vehicle::GetModelFromName(const char* name) -{ - int model = 0; - CBaseModelInfo* pModelInfo = CModelInfo::GetModelInfo((char*)name, &model); - - if (model > 0 && model < 1000000 && GetNameFromModel(model) != "") - { - return model; - } - else - { - return 0; - } -} - -static void StartAutoDrive(CVehicle *pVeh, const char *buf = nullptr) -{ - int hVeh = CPools::GetVehicleRef(pVeh); - CVector pos; - - if (buf == nullptr) - { -#ifdef GTASA - tRadarTrace targetBlip = CRadar::ms_RadarTrace[LOWORD(FrontEndMenuManager.m_nTargetBlipIndex)]; - pos = targetBlip.m_vecPos; - if (targetBlip.m_nRadarSprite != RADAR_SPRITE_WAYPOINT) - { - Util::SetMessage(TEXT("Teleport.TargetBlipText")); - return; - } -#else - return; -#endif - } - else - { - if (sscanf(buf, "%f,%f,%f", &pos.x, &pos.y, &pos.z) != 3) - { - int dim; - sscanf(buf, "%d,%f,%f,%f", &dim, &pos.x, &pos.y, &pos.z); - } - } - - int model = pVeh->m_nModelIndex; - if (CModelInfo::IsBoatModel(model)) - { - Command(hVeh, pos.x, pos.y, pos.z); - } - else if (CModelInfo::IsPlaneModel(model)) - { - CVector p = pVeh->GetPosition(); - p.z = 300.0f; -#ifdef GTASA - pVeh->SetPosn(p); -#elif GTAVC - pVeh->SetPosition(p); -#else - pVeh->SetPos(p); -#endif - Command(hVeh, pos.x, pos.y, 300.0f, 30, 200); - } - else if (CModelInfo::IsHeliModel(model)) - { - CVector p = pVeh->GetPosition(); - p.z = 300.0f; -#ifdef GTASA - pVeh->SetPosn(p); -#elif GTAVC - pVeh->SetPosition(p); -#else - pVeh->SetPos(p); -#endif - Command(hVeh, pos.x, pos.y, 300.0f, 30, 200); - } -#ifdef GTASA - else if (CModelInfo::IsTrainModel(model)) - { - return; - } -#endif - else - { - Command(hVeh, pos.x, pos.y, pos.z); - } -} - -void Vehicle::ShowPage() +void VehiclePage::Draw() { ImGui::Spacing(); CPlayerPed* pPlayer = FindPlayerPed(); @@ -639,16 +431,16 @@ void Vehicle::ShowPage() ImGui::SameLine(); - if (ImGui::Button(TEXT("Vehicle.FixCar"), ImVec2(Widget::CalcSize(3))) && Util::IsInVehicle()) + if (ImGui::Button(TEXT("Vehicle.FixCar"), ImVec2(Widget::CalcSize(3))) && Util::IsInCar()) { - Util::FixVehicle(pVeh); + Util::FixCar(pVeh); } ImGui::SameLine(); - if (ImGui::Button(TEXT("Vehicle.FlipCar"), ImVec2(Widget::CalcSize(3))) && Util::IsInVehicle()) + if (ImGui::Button(TEXT("Vehicle.FlipCar"), ImVec2(Widget::CalcSize(3))) && Util::IsInCar()) { - Util::UnFlipVehicle(pVeh); + Util::UnFlipCar(pVeh); } ImGui::Spacing(); @@ -790,7 +582,7 @@ void Vehicle::ShowPage() Widget::CheckboxAddr(TEXT("Vehicle.PerfectHandling"), 0x96914C); Widget::CheckboxAddr(TEXT("Vehicle.TankMode"), 0x969164); - Widget::Checkbox(TEXT("Vehicle.InfNitro"), &UnlimitedNitro::m_bEnabled, TEXT("Vehicle.InfNitroTip")); + Widget::Checkbox(TEXT("Vehicle.InfNitro"), &VehMod.m_Nitro.m_bEnabled, TEXT("Vehicle.InfNitroTip")); if (Widget::Checkbox(TEXT("Vehicle.FlipNoBurn"), &m_bVehFlipNoBurn, TEXT("Vehicle.FlipNoBurnTip"))) { // MixSets (Link2012) @@ -948,7 +740,7 @@ void Vehicle::ShowPage() #endif if (ImGui::CollapsingHeader(TEXT(bPlayerInCar ? "Vehicle.SwitchSeats" : "Vehicle.EnterNearVeh"))) { - CVehicle* pTargetVeh = bPlayerInCar ? pVeh : Util::GetClosestVehicle(); + CVehicle* pTargetVeh = bPlayerInCar ? pVeh : Util::GetClosestCar(); if (pTargetVeh) { @@ -957,7 +749,7 @@ void Vehicle::ShowPage() ImGui::Spacing(); ImGui::Columns(2, 0, false); - ImGui::Text(GetNameFromModel(pTargetVeh->m_nModelIndex).c_str()); + ImGui::Text(Util::GetCarName(pTargetVeh->m_nModelIndex).c_str()); ImGui::NextColumn(); ImGui::Text(TEXT("Vehicle.TotalSeats"), (seats + 1)); ImGui::Columns(1); @@ -999,14 +791,15 @@ void Vehicle::ShowPage() } if (ImGui::CollapsingHeader(TEXT("Vehicle.RemoveVehRadius"))) { - ImGui::InputInt(TEXT("Vehicle.Radius"), &m_nVehRemoveRadius); + static int removeRadius; + ImGui::InputInt(TEXT("Vehicle.Radius"), &removeRadius); ImGui::Spacing(); if (ImGui::Button(TEXT("Vehicle.RemoveVeh"), Widget::CalcSize(1))) { CPlayerPed* player = FindPlayerPed(); for (CVehicle* pVeh : CPools::ms_pVehiclePool) { - if (DistanceBetweenPoints(pVeh->GetPosition(), player->GetPosition()) < m_nVehRemoveRadius + if (DistanceBetweenPoints(pVeh->GetPosition(), player->GetPosition()) < removeRadius && player->m_pVehicle != pVeh) { Command(CPools::GetVehicleRef(pVeh)); @@ -1042,6 +835,7 @@ void Vehicle::ShowPage() Widget::EditAddr(TEXT("Vehicle.DirtLvl"), (int)pVeh + 0x4B0, 0, 7.5, 15); if (pVeh->m_nVehicleClass == VEHICLE_AUTOMOBILE && ImGui::CollapsingHeader(TEXT("Vehicle.Doors"))) { + static int m_nDoorMenuButton; ImGui::Columns(2, 0, false); ImGui::RadioButton(TEXT("Vehicle.Damage"), &m_nDoorMenuButton, 0); ImGui::RadioButton(TEXT("Vehicle.Fix"), &m_nDoorMenuButton, 1); @@ -1141,14 +935,14 @@ void Vehicle::ShowPage() { ImGui::Spacing(); ImGui::Columns(2, 0, false); - if (Widget::Checkbox(TEXT("Vehicle.SpawnInside"), &Spawner::m_bSpawnInside)) + if (Widget::Checkbox(TEXT("Vehicle.SpawnInside"), &m_Spawner.m_bAsDriver)) { - gConfig.Set("Features.SpawnInsideVehicle", Spawner::m_bSpawnInside); + gConfig.Set("Features.SpawnInsideVehicle", m_Spawner.m_bAsDriver); } ImGui::NextColumn(); - if( Widget::Checkbox(TEXT("Vehicle.SpawnInAir"), &Spawner::m_bSpawnInAir)) + if( Widget::Checkbox(TEXT("Vehicle.SpawnInAir"), &m_Spawner.m_bInAir)) { - gConfig.Set("Features.SpawnAircraftInAir", Spawner::m_bSpawnInAir); + gConfig.Set("Features.SpawnAircraftInAir", m_Spawner.m_bInAir); } ImGui::Columns(1); @@ -1189,14 +983,14 @@ void Vehicle::ShowPage() #ifdef GTASA ImGui::SameLine(); ImGui::SetNextItemWidth(width); - ImGui::InputTextWithHint("##LicenseText", TEXT("Vehicle.PlateText"), Spawner::m_nLicenseText, 9); + ImGui::InputTextWithHint("##LicenseText", TEXT("Vehicle.PlateText"), m_Spawner.m_nLicenseText, 9); - Widget::ImageList(Spawner::m_VehData, SpawnVehicle, + Widget::ImageList(m_Spawner.m_VehData, fArgWrapper(vehiclePage.SpawnVehicle), [](std::string& str){ - return GetNameFromModel(std::stoi(str)); - }, nullptr, AddNewVehicle); + return Util::GetCarName(std::stoi(str)); + }, nullptr, fArgNoneWrapper(vehiclePage.AddNew)); #else - Widget::DataList(Spawner::m_VehData, SpawnVehicle, AddNewVehicle); + Widget::DataList(m_Spawner.m_VehData, fArg3Wrapper(vehiclePage.SpawnVehicle), fArgNoneWrapper(vehiclePage.AddNew)); #endif ImGui::EndTabItem(); } @@ -1207,401 +1001,13 @@ void Vehicle::ShowPage() if (ImGui::BeginTabItem(TEXT("Vehicle.AutoDrive"))) { ImGui::Spacing(); - if (ImGui::Button(TEXT("Vehicle.AutoDriveStop"), Widget::CalcSize(1))) - { - Command(hplayer, hveh); - } - ImGui::Spacing(); - if (ImGui::BeginTabBar("PassTabaBar")) - { - if (ImGui::BeginTabItem(TEXT("Teleport.Coordinates"))) - { - static char buf[INPUT_BUFFER_SIZE]; - ImGui::Spacing(); - ImGui::TextWrapped(TEXT("Vehicle.AutoDriveInfo")); - ImGui::Spacing(); - ImGui::InputTextWithHint(TEXT("Teleport.Coordinates"), "x, y, z", buf, IM_ARRAYSIZE(buf)); - ImGui::Spacing(); - if (ImGui::Button(TEXT("Vehicle.AutoDriveCoord"), Widget::CalcSize(BY_GAME(2,1,1)))) - { - StartAutoDrive(pVeh, buf); - } -#ifdef GTASA - ImGui::SameLine(); - if (ImGui::Button(TEXT("Vehicle.AutoDriveMarker"), Widget::CalcSize(2))) - { - StartAutoDrive(pVeh); - } -#endif - ImGui::EndTabItem(); - } - if (ImGui::BeginTabItem(TEXT("Teleport.Location"))) - { - ImGui::Spacing(); - Widget::DataList(teleportPage.m_locData, - [](std::string& rootkey, std::string& bLocName, std::string& loc) - { - CVehicle* pVeh = BY_GAME(FindPlayerVehicle(-1, false), FindPlayerVehicle(), FindPlayerVehicle()); - StartAutoDrive(pVeh, loc.c_str()); - }); - ImGui::EndTabItem(); - } - ImGui::EndTabBar(); - } + AutoDrive.Draw(); ImGui::EndTabItem(); } - if (ImGui::BeginTabItem(TEXT("Vehicle.Color"))) - { + + VehPaint.Draw(); #ifdef GTASA - Paint::GenerateNodeList(veh, PaintData::m_vecNames, PaintData::m_Selected); - - ImGui::Spacing(); - if (ImGui::Button(TEXT("Vehicle.ResetColor"), ImVec2(Widget::CalcSize()))) - { - Paint::ResetNodeColor(veh, PaintData::m_Selected); - Util::SetMessage(TEXT("Vehicle.ResetColorMSG")); - } - ImGui::Spacing(); - - Widget::ListBox(TEXT("Vehicle.Component"), PaintData::m_vecNames, PaintData::m_Selected); - - if (ImGui::ColorEdit3(TEXT("Vehicle.ColorPicker"), PaintData::m_fColorPicker)) - { - uchar r = PaintData::m_fColorPicker[0] * 255; - uchar g = PaintData::m_fColorPicker[1] * 255; - uchar b = PaintData::m_fColorPicker[2] * 255; - Paint::SetNodeColor(veh, PaintData::m_Selected, { r, g, b, 255 }, PaintData::m_bMatFilter); - } -#endif - - ImGui::Spacing(); - ImGui::Columns(2, NULL, false); - -#ifdef GTASA - ImGui::Checkbox(TEXT("Vehicle.MatFilter"), &PaintData::m_bMatFilter); - ImGui::RadioButton(TEXT("Vehicle.Primary"), &PaintData::m_nRadioButton, 1); - ImGui::RadioButton(TEXT("Vehicle.Secondary"), &PaintData::m_nRadioButton, 2); - ImGui::NextColumn(); - ImGui::NewLine(); - ImGui::RadioButton(TEXT("Vehicle.Tertiary"), &PaintData::m_nRadioButton, 3); - ImGui::RadioButton(TEXT("Vehicle.Quaternary"), &PaintData::m_nRadioButton, 4); -#else - ImGui::RadioButton(TEXT("Vehicle.Primary"), &PaintData::m_nRadioButton, 1); - ImGui::NextColumn(); - ImGui::RadioButton(TEXT("Vehicle.Secondary"), &PaintData::m_nRadioButton, 2); -#endif - ImGui::Spacing(); - ImGui::Columns(1); - ImGui::Text(TEXT("Vehicle.SelectPreset")); - ImGui::Spacing(); - - int count = (int)m_CarcolsColorData.size(); - - ImVec2 size = Widget::CalcSize(); - int btnsInRow = ImGui::GetWindowContentRegionWidth() / (size.y * 2); - int btnSize = (ImGui::GetWindowContentRegionWidth() - int(ImGuiStyleVar_ItemSpacing) * (btnsInRow - - 0.6 * btnsInRow)) / btnsInRow; - - ImGui::BeginChild("Colorss"); - - for (int colorId = 0; colorId < count; ++colorId) - { - if (Widget::ColorBtn(colorId, m_CarcolsColorData[colorId], ImVec2(btnSize, btnSize))) - { - *(uint8_replacement*)(int(veh) + BY_GAME(0x433, 0x19F, 0x19B) + PaintData::m_nRadioButton) = colorId; - } - - if ((colorId + 1) % btnsInRow != 0) - { - ImGui::SameLine(0.0, 4.0); - } - } - - ImGui::EndChild(); - ImGui::EndTabItem(); - } -#ifdef GTASA - if (gRenderer != Render_DirectX11) - { - if (ImGui::BeginTabItem(TEXT("Vehicle.NeonsTab"))) - { - int model = veh->m_nModelIndex; - ImGui::Spacing(); - if (ImGui::Button(TEXT("Vehicle.RemoveNeon"), ImVec2(Widget::CalcSize()))) - { - Neon.Remove(veh); - Util::SetMessage(TEXT("Vehicle.RemoveNeonMSG")); - } - - ImGui::Spacing(); - ImGui::Columns(2, NULL, false); - - bool pulsing = Neon.IsPulsingEnabled(veh); - if (Widget::Checkbox(TEXT("Vehicle.PulsingNeon"), &pulsing)) - { - Neon.SetPulsing(veh, pulsing); - } - - Widget::Checkbox(TEXT("Vehicle.RainbowNeon"), &NeonData::m_bRainbowEffect, TEXT("Vehicle.RainbowNeonMSG")); - ImGui::NextColumn(); - Widget::Checkbox(TEXT("Vehicle.TrafficNeon"), &NeonData::m_bApplyOnTraffic, TEXT("Vehicle.TrafficNeonMSG")); - ImGui::Columns(1); - - ImGui::Spacing(); - - if (ImGui::ColorEdit3(TEXT("Vehicle.ColorPicker"), NeonData::m_fColorPicker)) - { - int r = static_cast(NeonData::m_fColorPicker[0] * 255); - int g = static_cast(NeonData::m_fColorPicker[1] * 255); - int b = static_cast(NeonData::m_fColorPicker[2] * 255); - - Neon.Install(veh, r, g, b); - } - - - ImGui::Spacing(); - ImGui::Text(TEXT("Vehicle.SelectPreset")); - - int count = (int)m_CarcolsColorData.size(); - ImVec2 size = Widget::CalcSize(); - int btnsInRow = ImGui::GetWindowContentRegionWidth() / (size.y * 2); - int btnSize = (ImGui::GetWindowContentRegionWidth() - int(ImGuiStyleVar_ItemSpacing) * (btnsInRow - - 0.6 * btnsInRow)) / btnsInRow; - - ImGui::BeginChild("Neonss"); - - for (int color_id = 0; color_id < count; ++color_id) - { - auto& color = m_CarcolsColorData[color_id]; - if (Widget::ColorBtn(color_id, color, ImVec2(btnSize, btnSize))) - { - int r = static_cast(color[0] * 255); - int g = static_cast(color[1] * 255); - int b = static_cast(color[2] * 255); - - Neon.Install(veh, r, g, b); - } - - if ((color_id + 1) % btnsInRow != 0) - { - ImGui::SameLine(0.0, 4.0); - } - } - - ImGui::EndChild(); - ImGui::EndTabItem(); - } - if (ImGui::BeginTabItem(TEXT("Vehicle.TextureTab"))) - { - Paint::GenerateNodeList(veh, PaintData::m_vecNames, PaintData::m_Selected); - - ImGui::Spacing(); - if (ImGui::Button(TEXT("Vehicle.ResetTexture"), ImVec2(Widget::CalcSize()))) - { - Paint::ResetNodeTexture(veh, PaintData::m_Selected); - Util::SetMessage(TEXT("Vehicle.ResetTextureMSG")); - } - ImGui::Spacing(); - - Widget::ListBox(TEXT("Vehicle.Component"), PaintData::m_vecNames, PaintData::m_Selected); - ImGui::Spacing(); - - ImGui::Columns(2, NULL, false); - ImGui::Checkbox(TEXT("Vehicle.MatFilter"), &PaintData::m_bMatFilter); - ImGui::NextColumn(); - int maxpjob, curpjob; - Command(hveh, &maxpjob); - - if (maxpjob > 0) - { - Command(hveh, &curpjob); - - if (ImGui::ArrowButton("Left", ImGuiDir_Left)) - { - curpjob -= 1; - if (curpjob < -1) - { - curpjob = maxpjob - 1; - } - Command(hveh, curpjob); - } - ImGui::SameLine(); - ImGui::Text("%s: %d",TEXT("Vehicle.Paintjob"), curpjob+2); - ImGui::SameLine(); - if (ImGui::ArrowButton("Right", ImGuiDir_Right)) - { - curpjob += 1; - if (curpjob > maxpjob) - { - curpjob = -1; - } - Command(hveh, curpjob); - } - - ImGui::Spacing(); - } - ImGui::Columns(1); - ImGui::Spacing(); - Widget::ImageList(Paint::m_TextureData, - [](std::string& str) - { - Paint::SetNodeTexture(FindPlayerPed()->m_pVehicle, PaintData::m_Selected, str, - PaintData::m_bMatFilter); - }, - [](std::string& str) - { - return str; - }, nullptr, [](){}); - - ImGui::EndTabItem(); - } - } - if (ImGui::BeginTabItem(TEXT("Vehicle.TuneTab"))) - { - ImGui::Spacing(); - Widget::ImageList(m_TuneData, - [](std::string& str) - { - AddComponent(str); - }, - // [](std::string& str) - // { - // RemoveComponent(str); - // }, - [](std::string& str) - { - return str; - }, - [](std::string& str) - { - return ((bool(*)(int, CVehicle*))0x49B010)(std::stoi(str), FindPlayerPed()->m_pVehicle); - }); - - ImGui::EndTabItem(); - } - if (ImGui::BeginTabItem(TEXT("Vehicle.HandlingTab"))) - { - ImGui::Spacing(); - - // https://github.com/multitheftauto/mtasa-blue/blob/16769b8d1c94e2b9fe6323dcba46d1305f87a190/Client/game_sa/CModelInfoSA.h#L213 - CBaseModelInfo* pInfo = CModelInfo::GetModelInfo(pPlayer->m_pVehicle->m_nModelIndex); - int handlingID = patch::Get((int)pInfo + 74, false); // CBaseModelInfo + 74 = handlingID - tHandlingData *pHandlingData = reinterpret_cast(0xC2B9DC + (handlingID * 224)); // sizeof(tHandlingData) = 224 - - if (ImGui::Button(TEXT("Vehicle.ResetHandling"), ImVec2(Widget::CalcSize(3)))) - { - gHandlingDataMgr.LoadHandlingData(); - Util::SetMessage(TEXT("Vehicle.ResetHandlingMSG")); - } - - ImGui::SameLine(); - - if (ImGui::Button(TEXT("Vehicle.SaveFile"), ImVec2(Widget::CalcSize(3)))) - { - FileHandler::GenerateHandlingFile(pHandlingData, m_VehicleIDE); - Util::SetMessage(TEXT("Vehicle.SaveFileMSG")); - } - - ImGui::SameLine(); - - if (ImGui::Button(TEXT("Vehicle.ReadMore"), ImVec2(Widget::CalcSize(3)))) - { - ShellExecute(NULL, "open", "https://projectcerbera.com/gta/sa/tutorials/handling", NULL, NULL, - SW_SHOWNORMAL); - } - - ImGui::Spacing(); - - ImGui::BeginChild("HandlingChild"); - - std::vector abs{ {TEXT("Vehicle.On"), 1}, {TEXT("Vehicle.Off"), 0} }; - Widget::EditRadioBtnAddr(TEXT("Vehicle.Abs"), (int)&pHandlingData->m_bABS, abs); - - Widget::EditAddr(TEXT("Vehicle.ADM"), (int)&pHandlingData->m_fSuspensionAntiDiveMultiplier, 0.0f, 0.0f, 1.0f); - Widget::EditAddr(TEXT("Vehicle.AnimGroup"), (int)&pHandlingData->m_nAnimGroup, 0, 0, 20); - Widget::EditAddr(TEXT("Vehicle.BrakeBias"), (int)&pHandlingData->m_fBrakeBias, 0.0f, 0.0f, 1.0f); - - // Brake deceleration calculation - float BrakeDeceleration = pHandlingData->m_fBrakeDeceleration * 2500; - Widget::EditAddr(TEXT("Vehicle.BrakeDecel"), (int)&pHandlingData->m_fBrakeDeceleration, 0.0f, 0.0f, 20.0f, 2500.0f); - pHandlingData->m_fBrakeDeceleration = BrakeDeceleration / 2500; - - Widget::EditAddr(TEXT("Vehicle.CemterMassX"), (int)&pHandlingData->m_vecCentreOfMass.x, -10.0f, -10.0f, 10.0f); - Widget::EditAddr(TEXT("Vehicle.CemterMassY"), (int)&pHandlingData->m_vecCentreOfMass.y, -10.0f, -10.0f, 10.0f); - Widget::EditAddr(TEXT("Vehicle.CemterMassZ"), (int)&pHandlingData->m_vecCentreOfMass.z, -10.0f, -10.0f, 10.0f); - - // CDM calculations - float factor = (1.0 / pHandlingData->m_fMass); - float fCDM = pHandlingData->m_fCollisionDamageMultiplier / (2000.0f * factor); - Widget::EditAddr(TEXT("Vehicle.CDM"), (int)&fCDM, 0.0f, 0.0f, 1.0f, 0.3381f); - pHandlingData->m_fCollisionDamageMultiplier = factor * fCDM * 2000.0f; - - Widget::EditAddr(TEXT("Vehicle.DampingLvl"), (int)&pHandlingData->m_fSuspensionDampingLevel, -10.0f, -10.0f, 10.0f); // test later - Widget::EditAddr(TEXT("Vehicle.DragMult"), (int)&pHandlingData->m_fDragMult, 0.0f, 0.0f, 30.0f); - - std::vector drive_type - { - {TEXT("Vehicle.FrontWheelDrive"), 70}, - {TEXT("Vehicle.RearWheelDrive"), 82}, - {TEXT("Vehicle.FourWheelDrive"), 52} - }; - Widget::EditRadioBtnAddr(TEXT("Vehicle.DriveType"), (int)&pHandlingData->m_transmissionData.m_nDriveType, drive_type); - - // Engine acceleration calculation - float fEngineAcceleration = pHandlingData->m_transmissionData.m_fEngineAcceleration * 12500; - Widget::EditAddr(TEXT("Vehicle.EngineAccel"), (int)&fEngineAcceleration, 0.0f, 0.0f, 49.0f, 12500.0f); - pHandlingData->m_transmissionData.m_fEngineAcceleration = fEngineAcceleration / 12500; - - - Widget::EditAddr(TEXT("Vehicle.EngineInertia"), (int)&pHandlingData->m_transmissionData.m_fEngineInertia, 0.1f, 0.1f, 400.0f); - - std::vector engine_type - { - {TEXT("Vehicle.Petrol"), 80}, {TEXT("Vehicle.Diseal"), 68}, {TEXT("Vehicle.Electric"), 69} - }; - Widget::EditRadioBtnAddr(TEXT("Vehicle.EngineType"), (int)&pHandlingData->m_transmissionData.m_nEngineType, engine_type); - - std::vector lights - { - {TEXT("Vehicle.Long"), 0}, {TEXT("Vehicle.Small"), 1}, - {TEXT("Vehicle.Big"), 2}, {TEXT("Vehicle.Tall"), 3} - }; - Widget::EditRadioBtnAddr(TEXT("Vehicle.FrontLights"), (int)&pHandlingData->m_nFrontLights, lights); - - Widget::EditAddr(TEXT("Vehicle.ForceLevel"), (int)&pHandlingData->m_fSuspensionForceLevel, -10.0f, -10.0f, 10.0f); // test later - - Widget::EditBits(TEXT("Vehicle.HandlingFlags"), (int)&pHandlingData->m_nHandlingFlags, m_HandlingFlagNames); - - Widget::EditAddr(TEXT("Vehicle.HighSpeedDamping"), (int)&pHandlingData->m_fSuspensionDampingLevel, -10.0f, -10.0f, 10.0f); // test later - Widget::EditAddr(TEXT("Vehicle.LowerKimit"), (int)&pHandlingData->m_fSuspensionLowerLimit, -10.0f, -10.0f, 10.0f); // test later - Widget::EditAddr(TEXT("Vehicle.Mass"), (int)&pHandlingData->m_fMass, 1.0f, 1.0f, 50000.0f); - - // Max Velocity calculation - int MaxVelocity = pHandlingData->m_transmissionData.m_fMaxGearVelocity / *(float*)0xC2B9BC; - Widget::EditAddr(TEXT("Vehicle.MaxVelocity"), (int)&MaxVelocity, 1.0f, 1.0f, 1000.0f); - pHandlingData->m_transmissionData.m_fMaxGearVelocity = MaxVelocity * (*(float*)0xC2B9BC); - - Widget::EditBits(TEXT("Vehicle.ModelFlags"), (int)&pHandlingData->m_nModelFlags, m_ModelFlagNames); - - Widget::EditAddr(TEXT("Vehicle.MonValue"), (int)&pHandlingData->m_nMonetaryValue, 1, 1, 100000); - Widget::EditAddr(TEXT("Vehicle.NumGears"), (int)&pHandlingData->m_transmissionData.m_nNumberOfGears, 1, 1, 10); - Widget::EditAddr(TEXT("Vehicle.PercentSubmerged"), (int)&pHandlingData->m_nPercentSubmerged, 10, 10, 120); - - Widget::EditRadioBtnAddr(TEXT("Vehicle.RearLights"), (int)&pHandlingData->m_nRearLights, lights); - - Widget::EditAddr(TEXT("Vehicle.SeatOffset"), (int)&pHandlingData->m_fSeatOffsetDistance, 0.0f, 0.0f, 1.0f); - Widget::EditAddr(TEXT("Vehicle.SteeringLock"), (int)&pHandlingData->m_fSteeringLock, 10.0f, 10.0f, 50.0f); - Widget::EditAddr(TEXT("Vehicle.SuspensionBias"), (int)&pHandlingData->m_fSuspensionBiasBetweenFrontAndRear, 0.0f, 0.0f, 1.0f); - Widget::EditAddr(TEXT("Vehicle.TractionBias"), (int)&pHandlingData->m_fTractionBias, 0.0f, 0.0f, 1.0f); - Widget::EditAddr(TEXT("Vehicle.TractionLoss"), (int)&pHandlingData->m_fTractionLoss, 0.0f, 0.0f, 1.0f); - Widget::EditAddr(TEXT("Vehicle.TractionMul"), (int)&pHandlingData->m_fTractionMultiplier, 0.5f, 0.5f, 2.0f); - Widget::EditAddr(TEXT("Vehicle.TurnMass"), (int)&pHandlingData->m_fTurnMass, 20.0f, 20.0f, 1000.0f); // test later - Widget::EditAddr(TEXT("Vehicle.UpperLimit"), (int)&pHandlingData->m_fSuspensionUpperLimit, -1.0f, -1.0f, 1.0f); - - ImGui::EndChild(); - - ImGui::EndTabItem(); - } + VehMod.Draw(); #endif } ImGui::EndTabBar(); diff --git a/src/pages/vehicle.h b/src/pages/vehicle.h index 9719483..3683fa1 100644 --- a/src/pages/vehicle.h +++ b/src/pages/vehicle.h @@ -1,111 +1,50 @@ #pragma once #include "pch.h" +#include "interface/ipage.h" -class Vehicle +class VehiclePage : public IPage { private: - static inline bool m_bAutoUnflip; - static inline bool m_bBikeFly; - static inline bool m_bDontFallBike; - static inline bool m_bVehHeavy; - static inline bool m_bVehWatertight; - static inline bool m_bNoDamage; - static inline int m_nDoorMenuButton; - static inline std::string m_DoorNames[6] = + bool m_bAutoUnflip; + bool m_bBikeFly; + bool m_bDontFallBike; + bool m_bVehHeavy; + bool m_bVehWatertight; + bool m_bNoDamage; + std::string m_DoorNames[6] = { "Hood", "Boot", "Front left door", "Front right door", "Rear left door", "Rear right door" }; - static inline int m_nVehRemoveRadius; - static inline bool m_bLockSpeed; - static inline float m_fLockSpeed; - static inline std::vector> m_CarcolsColorData; - struct PaintData - { - static inline bool m_bMatFilter = true; - static inline int m_nRadioButton = 1; - static inline float m_fColorPicker[3] { 0, 0, 0 }; - static inline std::vector m_vecNames{"Default"}; - static inline std::string m_Selected = "Default"; - }; + bool m_bLockSpeed; + float m_fLockSpeed; #ifdef GTASA - static inline bool m_bDisableColDetection; - static inline bool m_bVehFlipNoBurn; - static inline bool m_bMoreTrainCams; - static inline bool m_bNoDerail; - static inline std::map m_VehicleIDE; - struct NeonData - { - static inline float m_fColorPicker[3] { 0, 0, 0 }; - static inline bool m_bRainbowEffect; - static inline uint m_nRainbowTimer; - static inline bool m_bApplyOnTraffic; - static inline uint m_bTrafficTimer; - }; - static inline ResourceStore m_TuneData { "components", eResourceType::TYPE_IMAGE_TEXT, ImVec2(100, 80) }; + bool m_bDisableColDetection; + bool m_bVehFlipNoBurn; + bool m_bNoDerail; #endif - struct Spawner + struct { -#ifdef GTASA - static inline ResourceStore m_VehData { "vehicles", eResourceType::TYPE_IMAGE_TEXT, ImVec2(100, 75)}; -#else - static inline ResourceStore m_VehData {"vehicles", eResourceType::TYPE_TEXT}; -#endif - static inline bool m_bSpawnInside = true; - static inline bool m_bSpawnInAir = true; - static inline char m_nLicenseText[9]; - }; - struct UnlimitedNitro - { - static inline bool m_bEnabled; - static inline bool m_bCompAdded; - }; + ResourceStore m_VehData { "vehicles", BY_GAME(eResourceType::TYPE_IMAGE_TEXT, eResourceType::TYPE_TEXT, + eResourceType::TYPE_TEXT), ImVec2(100, 75)}; + bool m_bAsDriver = true; + bool m_bInAir = true; + char m_nLicenseText[9]; + } m_Spawner; -#ifdef GTASA - static inline std::vector m_HandlingFlagNames = // 32 flags - { - "1G_BOOST", "2G_BOOST", "NPC_ANTI_ROLL", "NPC_NEUTRAL_HANDL", "NO_HANDBRAKE", "STEER_REARWHEELS", - "HB_REARWHEEL_STEER", "ALT_STEER_OPT", - "WHEEL_F_NARROW2", "WHEEL_F_NARROW", "WHEEL_F_WIDE", "WHEEL_F_WIDE2", "WHEEL_R_NARROW2", "WHEEL_R_NARROW", - "WHEEL_R_WIDE", "WHEEL_R_WIDE2", - "HYDRAULIC_GEOM", "HYDRAULIC_INST", "HYDRAULIC_NONE", "NOS_INST", "OFFROAD_ABILITY", "OFFROAD_ABILITY2", - "HALOGEN_LIGHTS", "PROC_REARWHEEL_1ST", - "USE_MAXSP_LIMIT", "LOW_RIDER", "STREET_RACER", "SWINGING_CHASSIS", "Unused 1", "Unused 2", "Unused 3", - "Unused 4" - }; - - static inline std::vector m_ModelFlagNames = // 32 flags - { - "IS_VAN", "IS_BUS", "IS_LOW", "IS_BIG", "REVERSE_BONNET", "HANGING_BOOT", "TAILGATE_BOOT", "NOSWING_BOOT", - "NO_DOORS", "TANDEM_SEATS", - "SIT_IN_BOAT", "CONVERTIBLE", "NO_EXHAUST", "DOUBLE_EXHAUST", "NO1FPS_LOOK_BEHIND", "FORCE_DOOR_CHECK", - "AXLE_F_NOTILT", "AXLE_F_SOLID", "AXLE_F_MCPHERSON", - "AXLE_F_REVERSE", "AXLE_R_NOTILT", "AXLE_R_SOLID", "AXLE_R_MCPHERSON", "AXLE_R_REVERSE", "IS_BIKE", "IS_HELI", - "IS_PLANE", "IS_BOAT", "BOUNCE_PANELS", - "DOUBLE_RWHEELS", "FORCE_GROUND_CLEARANCE", "IS_HATCHBAC1K" - }; -#endif - -private: - -#ifdef GTASA - static void AddComponent(const std::string& component, bool display_message = true); - static void RemoveComponent(const std::string& component, bool display_message = true); - static int GetRandomTrainIdForModel(int model); -#endif + friend class IFeature; + VehiclePage(); + VehiclePage(const VehiclePage&); public: - Vehicle() = delete; - Vehicle(const Vehicle&) = delete; + void AddNew(); + void Draw(); - static void AddNewVehicle(); #ifdef GTASA - static void SpawnVehicle(std::string& name); + int GetRandomTrainIdForModel(int model); + void SpawnVehicle(std::string& name); #else - static void SpawnVehicle(std::string& rootkey, std::string& vehName, std::string& model); + void SpawnVehicle(std::string& rootkey, std::string& vehName, std::string& model); #endif - - static void Init(); - static std::string GetNameFromModel(int model); - static int GetModelFromName(const char* name); - static void ShowPage(); }; + +extern VehiclePage& vehiclePage; \ No newline at end of file diff --git a/src/pages/visual.cpp b/src/pages/visual.cpp index 22fca49..d82fbf4 100644 --- a/src/pages/visual.cpp +++ b/src/pages/visual.cpp @@ -133,7 +133,9 @@ static std::vector m_WeatherNames #endif }; -void Visual::Init() +VisualPage& visualPage = VisualPage::Get(); +VisualPage::VisualPage() +: IPage(ePageID::Visual, "Window.VisualPage", true) { #ifdef GTASA if (GetModuleHandle("timecycle24.asi")) @@ -142,7 +144,7 @@ void Visual::Init() } #endif - Events::processScriptsEvent += [] + Events::processScriptsEvent += [this] { // TODO: Needs improvement static short m_nBacWeatherType; @@ -401,7 +403,7 @@ void TimecycSlider(const char* label, T* ptr, int min, int max) } template -bool Visual::TimeCycColorEdit3(const char* label, T* r, T* g, T* b, ImGuiColorEditFlags flags) +bool VisualPage::TimeCycColorEdit3(const char* label, T* r, T* g, T* b, ImGuiColorEditFlags flags) { bool rtn = false; int val = CalcArrayIndex(); @@ -430,7 +432,7 @@ bool Visual::TimeCycColorEdit3(const char* label, T* r, T* g, T* b, ImGuiColorEd } template -void Visual::TimecycSlider(const char* label, T* ptr, int min, int max) +void VisualPage::TimecycSlider(const char* label, T* ptr, int min, int max) { int val = CalcArrayIndex(); #ifdef GTASA @@ -446,7 +448,7 @@ void Visual::TimecycSlider(const char* label, T* ptr, int min, int max) } template -bool Visual::TimeCycColorEdit4(const char* label, T* r, T* g, T* b, T* a, ImGuiColorEditFlags flags) +bool VisualPage::TimeCycColorEdit4(const char* label, T* r, T* g, T* b, T* a, ImGuiColorEditFlags flags) { bool rtn = false; int val = CalcArrayIndex(); @@ -522,7 +524,7 @@ static void ColorPickerAddr(const char* label, int addr, ImVec4&& default_color) } } -void Visual::PatchRadar() +void VisualPage::PatchRadar() { #ifdef GTASA static float clockPosX = *(float*)*(int*)0x58EC16; @@ -598,7 +600,7 @@ void Visual::PatchRadar() #endif } -void Visual::ShowPage() +void VisualPage::Draw() { if (ImGui::BeginTabBar("Visual", ImGuiTabBarFlags_NoTooltip + ImGuiTabBarFlags_FittingPolicyScroll)) { @@ -619,11 +621,11 @@ void Visual::ShowPage() if (m_bDisableHydrant) { // don't call Fx_c::TriggerWaterHydrant - plugin::patch::Nop(0x4A0D70, 5); + patch::Nop(0x4A0D70, 5); } else { - plugin::patch::SetRaw(0x4A0D70, (char*)"\xE9\x94\x3F\xF6\xFF", 5); + patch::SetRaw(0x4A0D70, (char*)"\xE9\x94\x3F\xF6\xFF", 5); } } Widget::CheckboxAddr(TEXT("Visual.FogEffect"), 0xC402C6); @@ -650,18 +652,18 @@ void Visual::ShowPage() else { // restore - plugin::patch::SetRaw(0x575BF6, (char*)"\xE8\x65\x1F\x1B\x00", 5); - plugin::patch::SetRaw(0x575C40, (char*)"\xE8\x1B\x1F\x1B\x00", 5); - plugin::patch::SetRaw(0x575C84, (char*)"\xE8\xD7\x1E\x1B\x00", 5); - plugin::patch::SetRaw(0x575CCE, (char*)"\xE8\x8D\x1E\x1B\x00", 5); - plugin::patch::SetRaw(0x575D1F, (char*)"\xE8\x3C\x1E\x1B\x00", 5); - plugin::patch::SetRaw(0x575D6F, (char*)"\xE8\xEC\x1D\x1B\x00", 5); - plugin::patch::SetRaw(0x575DC2, (char*)"\xE8\x99\x1D\x1B\x00", 5); - plugin::patch::SetRaw(0x575E12, (char*)"\xE8\x49\x1D\x1B\x00", 5); - plugin::patch::SetRaw(0x5754EC, (char*)"\xD8\x0D\x20\x95\x85\x00", 6); - plugin::patch::SetRaw(0x575537, (char*)"\xD8\x0D\x24\x95\x85\x00", 6); - plugin::patch::SetRaw(0x575311, (char*)"\xD8\x0D\x70\x53\x86\x00", 6); - plugin::patch::SetRaw(0x575361, (char*)"\xD8\x0D\x6C\x53\x86\x00", 6); + patch::SetRaw(0x575BF6, (char*)"\xE8\x65\x1F\x1B\x00", 5); + patch::SetRaw(0x575C40, (char*)"\xE8\x1B\x1F\x1B\x00", 5); + patch::SetRaw(0x575C84, (char*)"\xE8\xD7\x1E\x1B\x00", 5); + patch::SetRaw(0x575CCE, (char*)"\xE8\x8D\x1E\x1B\x00", 5); + patch::SetRaw(0x575D1F, (char*)"\xE8\x3C\x1E\x1B\x00", 5); + patch::SetRaw(0x575D6F, (char*)"\xE8\xEC\x1D\x1B\x00", 5); + patch::SetRaw(0x575DC2, (char*)"\xE8\x99\x1D\x1B\x00", 5); + patch::SetRaw(0x575E12, (char*)"\xE8\x49\x1D\x1B\x00", 5); + patch::SetRaw(0x5754EC, (char*)"\xD8\x0D\x20\x95\x85\x00", 6); + patch::SetRaw(0x575537, (char*)"\xD8\x0D\x24\x95\x85\x00", 6); + patch::SetRaw(0x575311, (char*)"\xD8\x0D\x70\x53\x86\x00", 6); + patch::SetRaw(0x575361, (char*)"\xD8\x0D\x6C\x53\x86\x00", 6); } } Widget::CheckboxAddr(TEXT("Visual.GrainEffect"), 0xC402B4); @@ -692,14 +694,14 @@ void Visual::ShowPage() if (m_bInvisibleWater) { // don't call CWaterLevel::RenderWater() - plugin::patch::Nop(0x53E004, 5); - plugin::patch::Nop(0x53E142, 5); + patch::Nop(0x53E004, 5); + patch::Nop(0x53E142, 5); } else { // restore call CWaterLevel::RenderWater() - plugin::patch::SetRaw(0x53E004, (char*)"\xE8\x47\x16\x1B\x00", 5); - plugin::patch::SetRaw(0x53E142, (char*)"\xE8\x09\x15\x1B\x00", 5); + patch::SetRaw(0x53E004, (char*)"\xE8\x47\x16\x1B\x00", 5); + patch::SetRaw(0x53E142, (char*)"\xE8\x09\x15\x1B\x00", 5); } } } @@ -740,7 +742,7 @@ void Visual::ShowPage() patch::Set(0xBA830C, 0.0); patch::Set(0xBA8308, 1.0); - // stop map rotaiton + // stop map rotation patch::Nop(0x5837FB, 6); patch::Nop(0x583805, 6); patch::Nop(0x58380D, 6); @@ -763,20 +765,20 @@ void Visual::ShowPage() if (m_bNoWater) { // don't call CWaterLevel::RenderWater() - plugin::patch::Nop(0x53E004, 5); - plugin::patch::Nop(0x53E142, 5); + patch::Nop(0x53E004, 5); + patch::Nop(0x53E142, 5); // rtn CWaterLevel::GetWaterLevelNoWaves - plugin::patch::SetRaw(0x6E8580, (char*)"\x32\xC0\xC3", 3); + patch::SetRaw(0x6E8580, (char*)"\x32\xC0\xC3", 3); } else { // restore call CWaterLevel::RenderWater() - plugin::patch::SetRaw(0x53E004, (char*)"\xE8\x47\x16\x1B\x00", 5); - plugin::patch::SetRaw(0x53E142, (char*)"\xE8\x09\x15\x1B\x00", 5); + patch::SetRaw(0x53E004, (char*)"\xE8\x47\x16\x1B\x00", 5); + patch::SetRaw(0x53E142, (char*)"\xE8\x09\x15\x1B\x00", 5); // restore CWaterLevel::GetWaterLevelNoWaves - plugin::patch::SetRaw(0x6E8580, (char*)"\x51\xD9\x44", 3); + patch::SetRaw(0x6E8580, (char*)"\x51\xD9\x44", 3); } } bool radar_state = (patch::Get(0xBA676C) != 2); diff --git a/src/pages/visual.h b/src/pages/visual.h index 09b6a00..c7f2811 100644 --- a/src/pages/visual.h +++ b/src/pages/visual.h @@ -1,38 +1,41 @@ #pragma once #include "pch.h" +#include "interface/ipage.h" -class Visual +class VisualPage : public IPage { private: - static inline bool m_bLockWeather; + bool m_bLockWeather; #ifdef GTASA - static inline bool m_bInvisibleWater; - static inline bool m_bNoWater; - static inline bool m_bDisableHydrant; - static inline bool m_bNoMoneyZeros; - static inline bool m_bNoPartciles; - static inline bool m_bNoPostFX; - static inline bool m_bNoTextures; - static inline bool m_bFullScreenMap; - static inline bool m_bSquareRadar; - static inline bool m_bNoRadarRot; + bool m_bInvisibleWater; + bool m_bNoWater; + bool m_bDisableHydrant; + bool m_bNoMoneyZeros; + bool m_bNoPartciles; + bool m_bNoPostFX; + bool m_bNoTextures; + bool m_bFullScreenMap; + bool m_bSquareRadar; + bool m_bNoRadarRot; #endif + friend class IFeature; + VisualPage(); + VisualPage(const VisualPage&); + template - static bool TimeCycColorEdit3(const char* label, T* r, T* g, T* b, ImGuiColorEditFlags flags = 0); + bool TimeCycColorEdit3(const char* label, T* r, T* g, T* b, ImGuiColorEditFlags flags = 0); template - static bool TimeCycColorEdit4(const char* label, T* r, T* g, T* b, T* a, ImGuiColorEditFlags flags = 0); + bool TimeCycColorEdit4(const char* label, T* r, T* g, T* b, T* a, ImGuiColorEditFlags flags = 0); template - static void TimecycSlider(const char* label, T* data, int min, int max); + void TimecycSlider(const char* label, T* data, int min, int max); public: - Visual() = delete; - Visual(const Visual&) = delete; - - static void Init(); - static void ShowPage(); + void Draw(); // Patches the radar for visual changes - static void PatchRadar(); -}; \ No newline at end of file + void PatchRadar(); +}; + +extern VisualPage& visualPage; \ No newline at end of file diff --git a/src/pages/weapon.cpp b/src/pages/weapon.cpp index dc2a018..7f19c49 100644 --- a/src/pages/weapon.cpp +++ b/src/pages/weapon.cpp @@ -4,9 +4,11 @@ #include "utils/util.h" #include -void WeaponPage::Init() +WeaponPage& weaponPage = WeaponPage::Get(); +WeaponPage::WeaponPage() +: IPage(ePageID::Weapon, "Window.WeaponPage", true) { - Events::processScriptsEvent += [] + Events::processScriptsEvent += [this] { CPlayerPed* player = FindPlayerPed(); @@ -94,11 +96,11 @@ void WeaponPage::Init() } #ifdef GTASA -void WeaponPage::SetGangWeapon(std::string& weapon_type) +void WeaponPage::GangStruct::SetWeapon(std::string& weaponType) { - m_nGangWeaponList[m_nSelectedGang][m_nSelectedWeapon] = std::stoi(weapon_type); - CGangs::SetGangWeapons(m_nSelectedGang, m_nGangWeaponList[m_nSelectedGang][0], m_nGangWeaponList[m_nSelectedGang][1], - m_nGangWeaponList[m_nSelectedGang][2]); + m_WeaponList[m_nSelected][m_nSelectedWeapon] = std::stoi(weaponType); + CGangs::SetGangWeapons(m_nSelected, m_WeaponList[m_nSelected][0], m_WeaponList[m_nSelected][1], + m_WeaponList[m_nSelected][2]); } #else // Implementation of SA opcode 0x555 @@ -206,7 +208,7 @@ void WeaponPage::GiveWeaponToPlayer(std::string& weapon_type) } } #else -void Weapon::GiveWeaponToPlayer(std::string& rootkey, std::string& name, std::string& model) +void WeaponPage::GiveWeaponToPlayer(std::string& rootkey, std::string& name, std::string& model) { CPlayerPed* player = FindPlayerPed(); int hplayer = CPools::GetPedRef(player); @@ -376,17 +378,17 @@ void WeaponPage::Draw() m_nAmmoCount = (m_nAmmoCount > 99999) ? 99999 : m_nAmmoCount; } #ifdef GTASA - Widget::ImageList(m_WeaponData, GiveWeaponToPlayer, - [](std::string& str) + Widget::ImageList(m_WeaponData, fArgWrapper(weaponPage.GiveWeaponToPlayer), + [this](std::string& str) { return m_WeaponData.m_pData->Get(str.c_str(), "Unknown"); }, [](std::string& str) { return str != "0"; /*Unarmed*/ - }, AddNew); + }, fArgNoneWrapper(weaponPage.AddNew)); #else - Widget::DataList(m_WeaponData, GiveWeaponToPlayer, AddWeapon); + Widget::DataList(m_WeaponData, fArg3Wrapper(weaponPage.GiveWeaponToPlayer), fArgNoneWrapper(weaponPage.AddNew)); #endif ImGui::EndTabItem(); } @@ -399,15 +401,15 @@ void WeaponPage::Draw() "Ballas\0Grove street families\0Los santos vagos\0San fierro rifa\0Da nang boys\0" "Mafia\0Mountain cloud triad\0Varrio los aztecas\0Gang9\0Gang10\0" }; - ImGui::Combo(TEXT("Weapon.SelectGang"), &m_nSelectedGang, gangList); - ImGui::Combo(TEXT("Ped.SelectWeapon"), &m_nSelectedWeapon, "Weapon 1\0Weapon 2\0Weapon 3\0"); + ImGui::Combo(TEXT("Weapon.SelectGang"), &m_Gang.m_nSelected, gangList); + ImGui::Combo(TEXT("Ped.SelectWeapon"), &m_Gang.m_nSelectedWeapon, "Weapon 1\0Weapon 2\0Weapon 3\0"); ImGui::Spacing(); - std::string key = std::to_string(m_nGangWeaponList[m_nSelectedGang][m_nSelectedWeapon]); + std::string key = std::to_string(m_Gang.m_WeaponList[m_Gang.m_nSelected][m_Gang.m_nSelectedWeapon]); ImGui::Text(TEXT("Weapon.CurrentWeapon"), m_WeaponData.m_pData->Get(key.c_str(), "Unknown").c_str()); ImGui::Spacing(); - Widget::ImageList(m_WeaponData, SetGangWeapon, - [](std::string& str){ + Widget::ImageList(m_WeaponData, fArgWrapper(weaponPage.m_Gang.SetWeapon), + [this](std::string& str){ return m_WeaponData.m_pData->Get(str.c_str(), "Unknown"); }, [](std::string& str){ diff --git a/src/pages/weapon.h b/src/pages/weapon.h index f635834..1832ea1 100644 --- a/src/pages/weapon.h +++ b/src/pages/weapon.h @@ -1,59 +1,65 @@ #pragma once #include "pch.h" +#include "interface/ipage.h" -class WeaponPage +class WeaponPage : public IPage { private: - static inline bool m_bFastReload; - static inline bool m_bHugeDamage; - static inline bool m_bLongRange; - static inline int m_nAmmoCount = 99999; - static inline int m_nSelectedWeapon; + bool m_bFastReload; + bool m_bHugeDamage; + bool m_bLongRange; + int m_nAmmoCount = 99999; #ifdef GTASA - static inline bool m_bAutoAim; - static inline bool m_bRapidFire; - static inline bool m_bDualWeild; - static inline bool m_bMoveAim; - static inline bool m_bMoveFire; - static inline bool m_bNoSpread; - static inline int m_nSelectedGang; - static inline int m_nGangWeaponList[10][3] = + bool m_bAutoAim; + bool m_bRapidFire; + bool m_bDualWeild; + bool m_bMoveAim; + bool m_bMoveFire; + bool m_bNoSpread; + struct GangStruct { - {WEAPON_PISTOL, WEAPON_MICRO_UZI, WEAPON_UNARMED}, // Ballas - {WEAPON_PISTOL, WEAPON_UNARMED, WEAPON_UNARMED}, // Grove - {WEAPON_PISTOL, WEAPON_UNARMED, WEAPON_UNARMED}, // Vagos - {WEAPON_UNARMED, WEAPON_UNARMED, WEAPON_UNARMED}, // SF Rifa - {WEAPON_PISTOL, WEAPON_MICRO_UZI, WEAPON_UNARMED}, // Da Nang Boys - {WEAPON_DESERT_EAGLE, WEAPON_UNARMED, WEAPON_UNARMED}, // Mafia - {WEAPON_PISTOL, WEAPON_AK47, WEAPON_UNARMED}, // Triads - {WEAPON_PISTOL, WEAPON_MICRO_UZI, WEAPON_UNARMED}, // VLA - {WEAPON_UNARMED, WEAPON_UNARMED, WEAPON_UNARMED}, // Gang 9 - {WEAPON_UNARMED, WEAPON_UNARMED, WEAPON_UNARMED}, // Gang 10 - }; + int m_nSelected; + int m_nSelectedWeapon; + int m_WeaponList[10][3] = + { + {WEAPON_PISTOL, WEAPON_MICRO_UZI, WEAPON_UNARMED}, // Ballas + {WEAPON_PISTOL, WEAPON_UNARMED, WEAPON_UNARMED}, // Grove + {WEAPON_PISTOL, WEAPON_UNARMED, WEAPON_UNARMED}, // Vagos + {WEAPON_UNARMED, WEAPON_UNARMED, WEAPON_UNARMED}, // SF Rifa + {WEAPON_PISTOL, WEAPON_MICRO_UZI, WEAPON_UNARMED}, // Da Nang Boys + {WEAPON_DESERT_EAGLE, WEAPON_UNARMED, WEAPON_UNARMED}, // Mafia + {WEAPON_PISTOL, WEAPON_AK47, WEAPON_UNARMED}, // Triads + {WEAPON_PISTOL, WEAPON_MICRO_UZI, WEAPON_UNARMED}, // VLA + {WEAPON_UNARMED, WEAPON_UNARMED, WEAPON_UNARMED}, // Gang 9 + {WEAPON_UNARMED, WEAPON_UNARMED, WEAPON_UNARMED}, // Gang 10 + }; + + void SetWeapon(std::string& weaponType); + } m_Gang; #else - static inline bool m_bInfiniteAmmo; + bool m_bInfiniteAmmo; #endif + friend class IFeature; + WeaponPage(); + WeaponPage(const WeaponPage&); + public: - WeaponPage() = delete; - WeaponPage(const WeaponPage&) = delete; + ResourceStore m_WeaponData { "weapons", BY_GAME(eResourceType::TYPE_IMAGE_TEXT, eResourceType::TYPE_TEXT, + eResourceType::TYPE_TEXT), ImVec2(65, 65) }; - static void Init(); - - static void Draw(); + // Add new weapon entry + void AddNew(); + void Draw(); - static void AddNew(); #ifdef GTASA - static inline ResourceStore m_WeaponData { "weapons", eResourceType::TYPE_IMAGE_TEXT, ImVec2(65, 65) }; - - static void GiveWeaponToPlayer(std::string& weapon_type); - static void SetGangWeapon(std::string& weapon_type); + void GiveWeaponToPlayer(std::string& weaponType); #else - static inline ResourceStore m_WeaponData { "weapons", eResourceType::TYPE_TEXT }; - - static void GiveWeaponToPlayer(std::string& rootkey, std::string& model, std::string& name); + void GiveWeaponToPlayer(std::string& rootkey, std::string& model, std::string& name); #endif }; +extern WeaponPage& weaponPage; + diff --git a/src/pages/welcome.h b/src/pages/welcome.h index c7d61c0..d9f8fba 100644 --- a/src/pages/welcome.h +++ b/src/pages/welcome.h @@ -5,7 +5,7 @@ class WelcomePage : public IPage { private: - friend IPage; + friend class IFeature; WelcomePage() : IPage(ePageID::Welcome, "Welcome", false) { PageHandler::SetCurrentPage(this); diff --git a/src/pch.cpp b/src/pch.cpp index 09211f0..148a2d9 100644 --- a/src/pch.cpp +++ b/src/pch.cpp @@ -1,5 +1,5 @@ #include "pch.h" -eRenderer gRenderer = Render_Unknown; +eRenderer gRenderer = eRenderer::Unknown; DataStore gConfig = DataStore(FILE_NAME, true); ResourceStore gTextureList { "misc", eResourceType::TYPE_IMAGE, ImVec2(100, 80) }; diff --git a/src/pch.h b/src/pch.h index 06f3384..77bd642 100644 --- a/src/pch.h +++ b/src/pch.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -67,25 +68,26 @@ using namespace plugin; -enum eRenderer +enum class eRenderer { - Render_DirectX9, - Render_DirectX11, - Render_Unknown + DirectX9, + DirectX11, + Unknown }; extern eRenderer gRenderer; extern DataStore gConfig; -typedef std::string str; -typedef void(*fArg3_t)(str&, str&, str&); -typedef void(*fArg1_t)(str&); -typedef void(*fArgNone_t)(); -typedef std::string(*fRtnArg1_t)(str&); -typedef bool(*fRtnBoolArg1_t)(str&); +using str = std::string; +using fArgNone_t = std::function; +using fArg1_t = std::function; +using fArg3_t = std::function; +using fRtnArg1_t = std::function; +using fRtnBoolArg1_t = std::function; #define fArg3Wrapper(x) [](str& a, str& b, str& c){x(a, b, c);} #define fArgWrapper(x) [](str& a){x(a);} +#define fRtnArgWrapper(x) [](str& a){return x(a);} #define fArgNoneWrapper(x) [](){x();} #ifdef GTASA diff --git a/src/utils/d3dhook.cpp b/src/utils/d3dhook.cpp index ab142b2..d0f9669 100644 --- a/src/utils/d3dhook.cpp +++ b/src/utils/d3dhook.cpp @@ -62,7 +62,7 @@ void D3dHook::ProcessFrame(void* ptr) { FontMgr::ReloadAll(); - if (gRenderer == Render_DirectX9) + if (gRenderer == eRenderer::DirectX9) { ImGui_ImplDX9_InvalidateDeviceObjects(); } @@ -85,7 +85,7 @@ void D3dHook::ProcessFrame(void* ptr) } ImGui_ImplWin32_NewFrame(); - if (gRenderer == Render_DirectX9) + if (gRenderer == eRenderer::DirectX9) { ImGui_ImplDX9_NewFrame(); } @@ -104,7 +104,7 @@ void D3dHook::ProcessFrame(void* ptr) ImGui::EndFrame(); ImGui::Render(); - if (gRenderer == Render_DirectX9) + if (gRenderer == eRenderer::DirectX9) { ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData()); } @@ -116,7 +116,7 @@ void D3dHook::ProcessFrame(void* ptr) if (FontMgr::IsFontReloadRequired()) { FontMgr::ReloadAll(); - if (gRenderer == Render_DirectX9) + if (gRenderer == eRenderer::DirectX9) { ImGui_ImplDX9_InvalidateDeviceObjects(); } @@ -135,7 +135,7 @@ void D3dHook::ProcessFrame(void* ptr) patch::Nop(0x00531155, 5); // shift trigger fix #endif - if (gRenderer == Render_DirectX9) + if (gRenderer == eRenderer::DirectX9) { ImGui_ImplDX9_Init(reinterpret_cast(ptr)); } @@ -270,7 +270,7 @@ bool D3dHook::Init(void *pCallback) */ if (init(kiero::RenderType::D3D9) == kiero::Status::Success) { - gRenderer = Render_DirectX9; + gRenderer = eRenderer::DirectX9; kiero::bind(16, (void**)&oReset, hkReset); kiero::bind(42, (void**)&oEndScene, hkEndScene); pCallbackFunc = pCallback; @@ -281,7 +281,7 @@ bool D3dHook::Init(void *pCallback) if (init(kiero::RenderType::D3D11) == kiero::Status::Success) { - gRenderer = Render_DirectX11; + gRenderer = eRenderer::DirectX11; kiero::bind(8, (void**)&oPresent, hkPresent); pCallbackFunc = pCallback; hookInjected = true; diff --git a/src/utils/overlay.cpp b/src/utils/overlay.cpp index 5633e03..dbc8866 100644 --- a/src/utils/overlay.cpp +++ b/src/utils/overlay.cpp @@ -102,7 +102,7 @@ void Overlay::ProcessModelInfo() #ifdef GTASA if (pEnt->m_nType == ENTITY_TYPE_VEHICLE) { - text = std::format("{}\n{}", model, Vehicle::GetNameFromModel(model)); + text = std::format("{}\n{}", model, Util::GetCarName(model)); } else if (pEnt->m_nType == ENTITY_TYPE_PED) { @@ -326,7 +326,7 @@ void Overlay::ProcessCommands(std::string&& str) if (wep_name == "jetpack") { std::string weapon = "-1"; - WeaponPage::GiveWeaponToPlayer(weapon); + weaponPage.GiveWeaponToPlayer(weapon); Util::SetMessage(TEXT("Menu.WeaponSpawned")); } else @@ -337,7 +337,7 @@ void Overlay::ProcessCommands(std::string&& str) if (wep_name != "" && pweaponinfo->m_nModelId1 != -1) { - WeaponPage::GiveWeaponToPlayer(weapon_name); + weaponPage.GiveWeaponToPlayer(weapon_name); Util::SetMessage(TEXT("Menu.WeaponSpawned")); } else @@ -351,11 +351,11 @@ void Overlay::ProcessCommands(std::string&& str) std::string veh_name; ss >> veh_name; - int model = Vehicle::GetModelFromName(veh_name.c_str()); + int model = Util::GetCarModel(veh_name.c_str()); if (model != 0) { std::string smodel = std::to_string(model); - Vehicle::SpawnVehicle(smodel); + vehiclePage.SpawnVehicle(smodel); Util::SetMessage(TEXT("Menu.VehicleSpawned")); } else diff --git a/src/utils/rpc.cpp b/src/utils/rpc.cpp index 12e2bf7..ab05a50 100644 --- a/src/utils/rpc.cpp +++ b/src/utils/rpc.cpp @@ -121,7 +121,7 @@ void RPC::DrawPages() if (BY_GAME(pPed->m_nPedFlags.bInVehicle, pPed->m_bInVehicle, pPed->m_bInVehicle)) { - std::string name = Vehicle::GetNameFromModel(pPed->m_pVehicle->m_nModelIndex); + std::string name = Util::GetCarName(pPed->m_pVehicle->m_nModelIndex); std::transform(name.begin(), name.end(), name.begin(), asciitolower); smallImgText = std::format("{} {} {} {}", TEXT("RPC.Driving"), name, TEXT("RPC.In"), Util::GetLocationName(&pPed->GetPosition())); smallImg = "drive"; diff --git a/src/utils/util.cpp b/src/utils/util.cpp index bf869fe..47ff1a4 100644 --- a/src/utils/util.cpp +++ b/src/utils/util.cpp @@ -37,6 +37,30 @@ ImVec2 Util::ConvertMapToScreen(ImVec2 pos, ImVec2 mapSz, ImVec2 screenSz) return pos; } +std::string Util::GetCarName(int model) +{ +#ifdef GTA3 + return std::to_string(model); +#else + return (const char*)CModelInfo::GetModelInfo(model) + 0x32; +#endif +} + +int Util::GetCarModel(const char* name) +{ + int model = 0; + CBaseModelInfo* pModelInfo = CModelInfo::GetModelInfo((char*)name, &model); + + if (model > 0 && model < 1000000 && GetCarName(model) != "") + { + return model; + } + else + { + return 0; + } +} + void Util::SetMessage(const char *message, bool b1, bool b2, bool b3) { #if GTASA @@ -57,7 +81,7 @@ float Util::RoundFloat(float val) return roundf(val * 100) / 100; } -bool Util::IsInVehicle(CPed *pPed) +bool Util::IsInCar(CPed *pPed) { if (!pPed) { @@ -67,7 +91,7 @@ bool Util::IsInVehicle(CPed *pPed) return BY_GAME(pPed->m_nPedFlags.bInVehicle, pPed->m_bInVehicle, pPed->m_bInVehicle); } -void Util::FixVehicle(CVehicle *pVeh) +void Util::FixCar(CVehicle *pVeh) { #ifdef GTASA pVeh->Fix(); @@ -91,7 +115,7 @@ void Util::FixVehicle(CVehicle *pVeh) pVeh->m_fHealth = 1000.0f; } -void Util::UnFlipVehicle(CVehicle *pVeh) +void Util::UnFlipCar(CVehicle *pVeh) { #ifdef GTASA int hveh = CPools::GetVehicleRef(pVeh); @@ -170,14 +194,14 @@ std::string Util::GetLocationName(CVector* pos) } #ifdef GTASA -void Util::ClearCharTasksVehCheck(CPed* pPed) +void Util::ClearCharTasksCarCheck(CPed* pPed) { uint hped = CPools::GetPedRef(pPed); uint hveh = NULL; bool veh_engine = true; float speed; - if (IsInVehicle(pPed)) + if (IsInCar(pPed)) { hveh = CPools::GetVehicleRef(pPed->m_pVehicle); veh_engine = pPed->m_pVehicle->m_nVehicleFlags.bEngineOn; @@ -223,7 +247,7 @@ int Util::GetLargestGangInZone() // implemention of opcode 0AB5 (STORE_CLOSEST_ENTITIES) // https://github.com/cleolibrary/CLEO4/blob/916d400f4a731ba1dd0ff16e52bdb056f42b7038/source/CCustomOpcodeSystem.cpp#L1671 -CVehicle* Util::GetClosestVehicle() +CVehicle* Util::GetClosestCar() { CPlayerPed* player = FindPlayerPed(); diff --git a/src/utils/util.h b/src/utils/util.h index 41ed185..9bc3c3a 100644 --- a/src/utils/util.h +++ b/src/utils/util.h @@ -19,24 +19,29 @@ public: Util(Util&) = delete; #ifdef GTASA + static void ClearCharTasksCarCheck(CPed* ped); static int GetLargestGangInZone(); - static void ClearCharTasksVehCheck(CPed* ped); static bool IsOnMission(); #endif - + static ImVec2 ConvertScreenToMap(ImVec2 pos, ImVec2 mapSz, ImVec2 screenSz); static ImVec2 ConvertMapToScreen(ImVec2 pos, ImVec2 mapSz, ImVec2 screenSz); - static void UnFlipVehicle(CVehicle *pVeh); - static void FixVehicle(CVehicle *pVeh); - static CPed* GetClosestPed(); - static CVehicle* GetClosestVehicle(); + + static void FixCar(CVehicle *pVeh); + static void SetCarForwardSpeed(CVehicle *pVeh, float speed); + static CVehicle* GetClosestCar(); + static int GetCarModel(const char* name); + static std::string GetCarName(int model); + static bool IsInCar(CPed *pPed = FindPlayerPed()); + static void UnFlipCar(CVehicle *pVeh); + static void GetCPUUsageInit(); static double GetCurrentCPUUsage(); + static float RoundFloat(float val); + + static CPed* GetClosestPed(); static std::string GetLocationName(CVector* pos); static bool IsOnCutscene(); - static bool IsInVehicle(CPed *pPed = FindPlayerPed()); static void RainbowValues(int& r, int& g, int& b, float speed); - static void SetCarForwardSpeed(CVehicle *pVeh, float speed); static void SetMessage(const char *message, bool b1 = false, bool b2 = false, bool b3 = false); - static float RoundFloat(float val); }; diff --git a/src/utils/widget.cpp b/src/utils/widget.cpp index c21825c..675c1b7 100644 --- a/src/utils/widget.cpp +++ b/src/utils/widget.cpp @@ -324,7 +324,7 @@ void Widget::ImageList(ResourceStore &store, fArg1_t clickFunc, fRtnArg1_t getNa m_ImageSize.x /= imagesInRow; bool showImages = !menuPage.m_bTextOnlyMode; - if (gRenderer == Render_DirectX11) + if (gRenderer == eRenderer::DirectX11) { showImages = false; }