Refactor code more & fix issue with clothes
This commit is contained in:
parent
5e4b7a9420
commit
6495b36952
@ -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 += []()
|
||||
|
@ -11,7 +11,7 @@ class AnimationMgr : public ICheat<AnimationMgr>
|
||||
private:
|
||||
CPed *m_pTarget = nullptr; // target ped pointer
|
||||
|
||||
friend class ICheat;
|
||||
friend class IFeature;
|
||||
AnimationMgr();
|
||||
AnimationMgr(const AnimationMgr&);
|
||||
|
||||
|
126
src/custom/autodrive.cpp
Normal file
126
src/custom/autodrive.cpp
Normal file
@ -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<Commands::BOAT_GOTO_COORDS>(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<Commands::PLANE_GOTO_COORDS>(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<Commands::HELI_GOTO_COORDS>(hVeh, pos.x, pos.y, 300.0f, 30, 200);
|
||||
}
|
||||
#ifdef GTASA
|
||||
else if (CModelInfo::IsTrainModel(model))
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
Command<Commands::CAR_GOTO_COORDINATES>(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<Commands::WARP_CHAR_INTO_CAR>(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();
|
||||
}
|
||||
}
|
26
src/custom/autodrive.h
Normal file
26
src/custom/autodrive.h
Normal file
@ -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<AutoDriveMgr>
|
||||
{
|
||||
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;
|
76
src/custom/customskins_sa.cpp
Normal file
76
src/custom/customskins_sa.cpp
Normal file
@ -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<eLogLevel::Error>("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/");
|
||||
}
|
||||
}
|
||||
}
|
34
src/custom/customskins_sa.h
Normal file
34
src/custom/customskins_sa.h
Normal file
@ -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<CustomSkinsMgr>
|
||||
{
|
||||
private:
|
||||
ImGuiTextFilter m_Filter;
|
||||
std::vector<std::string> 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;
|
@ -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&);
|
||||
|
||||
|
@ -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&);
|
||||
|
||||
|
@ -31,7 +31,7 @@ private:
|
||||
RwTexture* m_pNeonTexture = nullptr; // pointer to the neon mask texture
|
||||
VehicleExtendedData<NeonData> m_VehNeon;
|
||||
|
||||
friend ICheat;
|
||||
friend class IFeature;
|
||||
NeonMgr();
|
||||
NeonMgr(NeonMgr&);
|
||||
~NeonMgr();
|
||||
|
@ -11,7 +11,7 @@ class ParticleMgr : public ICheat<ParticleMgr>
|
||||
private:
|
||||
std::vector<int> m_nList;
|
||||
|
||||
friend class ICheat;
|
||||
friend class IFeature;
|
||||
ParticleMgr(){};
|
||||
ParticleMgr(const ParticleMgr&);
|
||||
|
||||
|
@ -12,7 +12,7 @@ private:
|
||||
std::string m_EnabledCheats[92][2];
|
||||
DataStore m_pData {"cheats"};
|
||||
|
||||
friend ICheat;
|
||||
friend class IFeature;
|
||||
RandomCheatsMgr();
|
||||
RandomCheatsMgr(const RandomCheatsMgr&);
|
||||
|
||||
|
@ -9,7 +9,7 @@ class TopDownCamera : public ICheat<TopDownCamera>
|
||||
{
|
||||
private:
|
||||
|
||||
friend ICheat;
|
||||
friend class IFeature;
|
||||
TopDownCamera();
|
||||
TopDownCamera(const TopDownCamera&);
|
||||
|
||||
|
255
src/custom/vehmod_sa.cpp
Normal file
255
src/custom/vehmod_sa.cpp
Normal file
@ -0,0 +1,255 @@
|
||||
#include "pch.h"
|
||||
#include "vehmod_sa.h"
|
||||
#include "utils/widget.h"
|
||||
#include "filehandler.h"
|
||||
|
||||
static std::vector<std::string> 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<std::string> 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<BYTE>(0x969165, 0, true); // All cars have nitro
|
||||
patch::Set<BYTE>(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<eLogLevel::Warn>("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<eLogLevel::Warn>("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<WORD>((int)pInfo + 74, false); // CBaseModelInfo + 74 = handlingID
|
||||
tHandlingData *pHandlingData = reinterpret_cast<tHandlingData*>(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<Widget::BindInfo> 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<BYTE>(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<Widget::BindInfo> 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<Widget::BindInfo> 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<Widget::BindInfo> 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<int>(TEXT("Vehicle.MonValue"), (int)&pHandlingData->m_nMonetaryValue, 1, 1, 100000);
|
||||
Widget::EditAddr<BYTE>(TEXT("Vehicle.NumGears"), (int)&pHandlingData->m_transmissionData.m_nNumberOfGears, 1, 1, 10);
|
||||
Widget::EditAddr<BYTE>(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();
|
||||
}
|
||||
}
|
34
src/custom/vehmod_sa.h
Normal file
34
src/custom/vehmod_sa.h
Normal file
@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include "pch.h"
|
||||
#include "interface/ifeature.hpp"
|
||||
|
||||
/*
|
||||
VehModMgr Class
|
||||
Handles tunes & handling
|
||||
*/
|
||||
class VehModMgr : public IFeature<VehModMgr>
|
||||
{
|
||||
private:
|
||||
ResourceStore m_TuneData { "components", eResourceType::TYPE_IMAGE_TEXT, ImVec2(100, 80) };
|
||||
std::map<int, std::string> 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;
|
287
src/custom/vehpaint.cpp
Normal file
287
src/custom/vehpaint.cpp
Normal file
@ -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<int>(m_Neon.m_fColorPicker[0] * 255);
|
||||
int g = static_cast<int>(m_Neon.m_fColorPicker[1] * 255);
|
||||
int b = static_cast<int>(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<int>(color[0] * 255);
|
||||
int g = static_cast<int>(color[1] * 255);
|
||||
int b = static_cast<int>(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<Commands::GET_NUM_AVAILABLE_PAINTJOBS>(hVeh, &maxpjob);
|
||||
|
||||
if (maxpjob > 0)
|
||||
{
|
||||
Command<Commands::GET_CURRENT_VEHICLE_PAINTJOB>(hVeh, &curpjob);
|
||||
|
||||
if (ImGui::ArrowButton("Left", ImGuiDir_Left))
|
||||
{
|
||||
curpjob -= 1;
|
||||
if (curpjob < -1)
|
||||
{
|
||||
curpjob = maxpjob - 1;
|
||||
}
|
||||
Command<Commands::GIVE_VEHICLE_PAINTJOB>(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<Commands::GIVE_VEHICLE_PAINTJOB>(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
|
||||
}
|
42
src/custom/vehpaint.h
Normal file
42
src/custom/vehpaint.h
Normal file
@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
#include "interface/ifeature.hpp"
|
||||
|
||||
/*
|
||||
VehPaintMgr Class
|
||||
Handles neon, textures for vehicle
|
||||
*/
|
||||
class VehPaintMgr : public IFeature<VehPaintMgr>
|
||||
{
|
||||
private:
|
||||
std::vector<std::vector<float>> 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<std::string> 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;
|
@ -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
|
||||
|
@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
#include "ifeature.hpp"
|
||||
|
||||
template<typename T>
|
||||
class ICheat
|
||||
class ICheat : public IFeature<T>
|
||||
{
|
||||
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
|
||||
{
|
||||
|
12
src/interface/ifeature.hpp
Normal file
12
src/interface/ifeature.hpp
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
template<typename T>
|
||||
class IFeature
|
||||
{
|
||||
public:
|
||||
static T &Get()
|
||||
{
|
||||
static T _instance;
|
||||
return _instance;
|
||||
}
|
||||
};
|
@ -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<size_t>(ePageID::None);
|
||||
if (index <= size)
|
||||
{
|
||||
if (m_PageList.size() < size)
|
||||
{
|
||||
m_PageList.resize(size);
|
||||
}
|
||||
m_PageList[index] = page;
|
||||
}
|
||||
}
|
||||
|
||||
void PageHandler::SetCurrentPage(PagePtr page)
|
||||
|
@ -1,21 +1,24 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#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<typename T>
|
||||
class IPage
|
||||
class IPage : public IFeature<T>
|
||||
{
|
||||
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<PagePtr>(this));
|
||||
PageHandler::AddPage(reinterpret_cast<PagePtr>(this), static_cast<size_t>(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
|
||||
{
|
||||
|
@ -5,7 +5,7 @@
|
||||
class AnniversaryPage : public IPage<AnniversaryPage>
|
||||
{
|
||||
private:
|
||||
friend IPage;
|
||||
friend class IFeature;
|
||||
AnniversaryPage() : IPage<AnniversaryPage>(ePageID::Anniversary, "Anniversary", false){}
|
||||
AnniversaryPage(const AnniversaryPage&);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -28,7 +28,7 @@ private:
|
||||
ResourceStore m_StatData{ "stats", eResourceType::TYPE_TEXT };
|
||||
#endif
|
||||
|
||||
friend IPage;
|
||||
friend class IFeature;
|
||||
GamePage();
|
||||
GamePage(const GamePage&);
|
||||
|
||||
|
@ -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"));
|
||||
|
@ -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&);
|
||||
|
||||
|
@ -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<PedPage>(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<Commands::CREATE_CHAR>(Spawner::m_nSelectedPedType + 4, 290 + currentSlot, pos.x, pos.y, pos.z + 1, &hplayer);
|
||||
Command<Commands::CREATE_CHAR>(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<Commands::LOAD_SPECIAL_CHARACTER>(currentSlot, model.c_str());
|
||||
Command<Commands::LOAD_ALL_MODELS_NOW>();
|
||||
|
||||
Command<Commands::CREATE_CHAR>(Spawner::m_nSelectedPedType + 4, 108+currentSlot, pos.x, pos.y, pos.z + 1, &hplayer);
|
||||
Command<Commands::CREATE_CHAR>(m_Spawner.m_nSelectedPedType + 4, 108+currentSlot, pos.x, pos.y, pos.z + 1, &hplayer);
|
||||
Command<Commands::UNLOAD_SPECIAL_CHARACTER>(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<Commands::CREATE_CHAR>(Spawner::m_nSelectedPedType + 4, iModel, pos.x, pos.y, pos.z + 1, &hplayer);
|
||||
Command<Commands::CREATE_CHAR>(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<Commands::MARK_CHAR_AS_NO_LONGER_NEEDED>(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<Commands::GET_WEAPONTYPE_MODEL>(Spawner::m_nWeaponId, &model);
|
||||
Command<Commands::GET_WEAPONTYPE_MODEL>(m_Spawner.m_nWeaponId, &model);
|
||||
CStreaming::RequestModel(model, PRIORITY_REQUEST);
|
||||
CStreaming::LoadAllRequestedModels(false);
|
||||
Command<Commands::GIVE_WEAPON_TO_CHAR>(hplayer, Spawner::m_nWeaponId, 999);
|
||||
Command<Commands::GIVE_WEAPON_TO_CHAR>(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/");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,41 +1,47 @@
|
||||
#pragma once
|
||||
#include "pch.h"
|
||||
#include "interface/ipage.h"
|
||||
|
||||
class Ped
|
||||
class PedPage : public IPage<PedPage>
|
||||
{
|
||||
private:
|
||||
static inline bool m_bBigHead;
|
||||
static inline bool m_bThinBody;
|
||||
|
||||
struct Spawner
|
||||
bool m_bBigHead;
|
||||
bool m_bThinBody;
|
||||
struct
|
||||
{
|
||||
static inline std::vector<CPed*> 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<CPed*> 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;
|
||||
|
@ -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<PlayerPage>(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<eLogLevel::Error>("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<Commands::IS_CHAR_DEAD>(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<std::string>("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
|
||||
|
@ -1,47 +1,44 @@
|
||||
#pragma once
|
||||
#include "pch.h"
|
||||
#include "interface/ipage.h"
|
||||
|
||||
class Player
|
||||
class PlayerPage : public IPage<PlayerPage>
|
||||
{
|
||||
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<std::string> 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;
|
||||
|
@ -8,7 +8,7 @@
|
||||
class ScenePage : public IPage<ScenePage>
|
||||
{
|
||||
private:
|
||||
friend IPage;
|
||||
friend class IFeature;
|
||||
ScenePage() : IPage<ScenePage>(ePageID::Scene, "Window.ScenePage", true){}
|
||||
ScenePage(const ScenePage&);
|
||||
|
||||
|
@ -31,7 +31,7 @@ private:
|
||||
public:
|
||||
ResourceStore m_locData{"locations", eResourceType::TYPE_TEXT};
|
||||
|
||||
friend IPage;
|
||||
friend class IFeature;
|
||||
TeleportPage();
|
||||
TeleportPage(const TeleportPage&);
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
class UpdatePage : public IPage<UpdatePage>
|
||||
{
|
||||
private:
|
||||
friend IPage;
|
||||
friend class IFeature;
|
||||
UpdatePage() : IPage<UpdatePage>(ePageID::Update, "Update", false){}
|
||||
UpdatePage(const UpdatePage&);
|
||||
|
||||
|
@ -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 <tHandlingData.h>
|
||||
#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<VehiclePage>(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<BYTE>(0x969165, 0, true); // All cars have nitro
|
||||
patch::Set<BYTE>(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<eLogLevel::Warn>("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<eLogLevel::Warn>("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<Commands::IS_CHAR_IN_ANY_CAR>(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<Commands::IS_CHAR_IN_ANY_CAR>(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<Commands::DELETE_CHAR>(CPools::GetPedRef(veh->m_pDriver));
|
||||
|
||||
if (Spawner::m_bSpawnInside)
|
||||
if (m_Spawner.m_bAsDriver)
|
||||
{
|
||||
Command<Commands::WARP_CHAR_INTO_CAR>(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<Commands::CUSTOM_PLATE_FOR_NEXT_CAR>(imodel, Spawner::m_nLicenseText);
|
||||
Command<Commands::CUSTOM_PLATE_FOR_NEXT_CAR>(imodel, m_Spawner.m_nLicenseText);
|
||||
}
|
||||
#endif
|
||||
int hveh = 0;
|
||||
if (Spawner::m_bSpawnInside)
|
||||
if (m_Spawner.m_bAsDriver)
|
||||
{
|
||||
Command<Commands::CREATE_CAR>(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<Commands::BOAT_GOTO_COORDS>(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<Commands::PLANE_GOTO_COORDS>(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<Commands::HELI_GOTO_COORDS>(hVeh, pos.x, pos.y, 300.0f, 30, 200);
|
||||
}
|
||||
#ifdef GTASA
|
||||
else if (CModelInfo::IsTrainModel(model))
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
Command<Commands::CAR_GOTO_COORDINATES>(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<Commands::DELETE_CAR>(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<Commands::WARP_CHAR_INTO_CAR>(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<int>(NeonData::m_fColorPicker[0] * 255);
|
||||
int g = static_cast<int>(NeonData::m_fColorPicker[1] * 255);
|
||||
int b = static_cast<int>(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<int>(color[0] * 255);
|
||||
int g = static_cast<int>(color[1] * 255);
|
||||
int b = static_cast<int>(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<Commands::GET_NUM_AVAILABLE_PAINTJOBS>(hveh, &maxpjob);
|
||||
|
||||
if (maxpjob > 0)
|
||||
{
|
||||
Command<Commands::GET_CURRENT_VEHICLE_PAINTJOB>(hveh, &curpjob);
|
||||
|
||||
if (ImGui::ArrowButton("Left", ImGuiDir_Left))
|
||||
{
|
||||
curpjob -= 1;
|
||||
if (curpjob < -1)
|
||||
{
|
||||
curpjob = maxpjob - 1;
|
||||
}
|
||||
Command<Commands::GIVE_VEHICLE_PAINTJOB>(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<Commands::GIVE_VEHICLE_PAINTJOB>(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<WORD>((int)pInfo + 74, false); // CBaseModelInfo + 74 = handlingID
|
||||
tHandlingData *pHandlingData = reinterpret_cast<tHandlingData*>(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<Widget::BindInfo> 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<BYTE>(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<Widget::BindInfo> 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<Widget::BindInfo> 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<Widget::BindInfo> 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<int>(TEXT("Vehicle.MonValue"), (int)&pHandlingData->m_nMonetaryValue, 1, 1, 100000);
|
||||
Widget::EditAddr<BYTE>(TEXT("Vehicle.NumGears"), (int)&pHandlingData->m_transmissionData.m_nNumberOfGears, 1, 1, 10);
|
||||
Widget::EditAddr<BYTE>(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();
|
||||
|
@ -1,111 +1,50 @@
|
||||
#pragma once
|
||||
#include "pch.h"
|
||||
#include "interface/ipage.h"
|
||||
|
||||
class Vehicle
|
||||
class VehiclePage : public IPage<VehiclePage>
|
||||
{
|
||||
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<std::vector<float>> 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<std::string> 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<int, std::string> 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<std::string> 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<std::string> 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;
|
@ -133,7 +133,9 @@ static std::vector<std::string> m_WeatherNames
|
||||
#endif
|
||||
};
|
||||
|
||||
void Visual::Init()
|
||||
VisualPage& visualPage = VisualPage::Get();
|
||||
VisualPage::VisualPage()
|
||||
: IPage<VisualPage>(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<typename T>
|
||||
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 <typename T>
|
||||
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 <typename T>
|
||||
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<float>(0xBA830C, 0.0);
|
||||
patch::Set<float>(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<BYTE>(0xBA676C) != 2);
|
||||
|
@ -1,38 +1,41 @@
|
||||
#pragma once
|
||||
#include "pch.h"
|
||||
#include "interface/ipage.h"
|
||||
|
||||
class Visual
|
||||
class VisualPage : public IPage<VisualPage>
|
||||
{
|
||||
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<typename T>
|
||||
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 <typename T>
|
||||
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 <typename T>
|
||||
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();
|
||||
};
|
||||
void PatchRadar();
|
||||
};
|
||||
|
||||
extern VisualPage& visualPage;
|
@ -4,9 +4,11 @@
|
||||
#include "utils/util.h"
|
||||
#include <CWeaponInfo.h>
|
||||
|
||||
void WeaponPage::Init()
|
||||
WeaponPage& weaponPage = WeaponPage::Get();
|
||||
WeaponPage::WeaponPage()
|
||||
: IPage<WeaponPage>(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){
|
||||
|
@ -1,59 +1,65 @@
|
||||
#pragma once
|
||||
#include "pch.h"
|
||||
#include "interface/ipage.h"
|
||||
|
||||
class WeaponPage
|
||||
class WeaponPage : public IPage<WeaponPage>
|
||||
{
|
||||
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;
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
class WelcomePage : public IPage<WelcomePage>
|
||||
{
|
||||
private:
|
||||
friend IPage;
|
||||
friend class IFeature;
|
||||
WelcomePage() : IPage<WelcomePage>(ePageID::Welcome, "Welcome", false)
|
||||
{
|
||||
PageHandler::SetCurrentPage(this);
|
||||
|
@ -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) };
|
||||
|
22
src/pch.h
22
src/pch.h
@ -6,6 +6,7 @@
|
||||
#include <d3d11Shader.h>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
@ -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<void()>;
|
||||
using fArg1_t = std::function<void(str&)>;
|
||||
using fArg3_t = std::function<void(str&, str&, str&)>;
|
||||
using fRtnArg1_t = std::function<std::string(str&)>;
|
||||
using fRtnBoolArg1_t = std::function<bool(str&)>;
|
||||
|
||||
#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
|
||||
|
@ -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<IDirect3DDevice9*>(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;
|
||||
|
@ -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
|
||||
|
@ -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";
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user