Refactor code more & fix issue with clothes
This commit is contained in:
parent
5e4b7a9420
commit
6495b36952
@ -127,14 +127,6 @@ void CheatMenu::Init()
|
|||||||
|
|
||||||
ApplyStyle();
|
ApplyStyle();
|
||||||
Locale::Init(FILE_NAME "/locale/", "English", "English");
|
Locale::Init(FILE_NAME "/locale/", "English", "English");
|
||||||
// GenHeaderList();
|
|
||||||
|
|
||||||
// Init menu parts
|
|
||||||
Player::Init();
|
|
||||||
Ped::Init();
|
|
||||||
Vehicle::Init();
|
|
||||||
Visual::Init();
|
|
||||||
WeaponPage::Init();
|
|
||||||
Overlay::Init();
|
Overlay::Init();
|
||||||
|
|
||||||
Events::processScriptsEvent += []()
|
Events::processScriptsEvent += []()
|
||||||
|
@ -11,7 +11,7 @@ class AnimationMgr : public ICheat<AnimationMgr>
|
|||||||
private:
|
private:
|
||||||
CPed *m_pTarget = nullptr; // target ped pointer
|
CPed *m_pTarget = nullptr; // target ped pointer
|
||||||
|
|
||||||
friend class ICheat;
|
friend class IFeature;
|
||||||
AnimationMgr();
|
AnimationMgr();
|
||||||
AnimationMgr(const 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
|
CVehicle *m_pLastVeh; // vehicle player was in
|
||||||
int m_nVehSeat; // seat id of player vehicle
|
int m_nVehSeat; // seat id of player vehicle
|
||||||
|
|
||||||
friend class ICheat;
|
friend class IFeature;
|
||||||
CutsceneMgr();
|
CutsceneMgr();
|
||||||
CutsceneMgr(const CutsceneMgr&);
|
CutsceneMgr(const CutsceneMgr&);
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ private:
|
|||||||
bool m_bHudState; // backup of the prev game hud state
|
bool m_bHudState; // backup of the prev game hud state
|
||||||
bool m_bRadarState; // backup of the prev game radar state
|
bool m_bRadarState; // backup of the prev game radar state
|
||||||
|
|
||||||
friend ICheat;
|
friend class IFeature;
|
||||||
FreecamMgr();
|
FreecamMgr();
|
||||||
FreecamMgr(const FreecamMgr&);
|
FreecamMgr(const FreecamMgr&);
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ private:
|
|||||||
RwTexture* m_pNeonTexture = nullptr; // pointer to the neon mask texture
|
RwTexture* m_pNeonTexture = nullptr; // pointer to the neon mask texture
|
||||||
VehicleExtendedData<NeonData> m_VehNeon;
|
VehicleExtendedData<NeonData> m_VehNeon;
|
||||||
|
|
||||||
friend ICheat;
|
friend class IFeature;
|
||||||
NeonMgr();
|
NeonMgr();
|
||||||
NeonMgr(NeonMgr&);
|
NeonMgr(NeonMgr&);
|
||||||
~NeonMgr();
|
~NeonMgr();
|
||||||
|
@ -11,7 +11,7 @@ class ParticleMgr : public ICheat<ParticleMgr>
|
|||||||
private:
|
private:
|
||||||
std::vector<int> m_nList;
|
std::vector<int> m_nList;
|
||||||
|
|
||||||
friend class ICheat;
|
friend class IFeature;
|
||||||
ParticleMgr(){};
|
ParticleMgr(){};
|
||||||
ParticleMgr(const ParticleMgr&);
|
ParticleMgr(const ParticleMgr&);
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ private:
|
|||||||
std::string m_EnabledCheats[92][2];
|
std::string m_EnabledCheats[92][2];
|
||||||
DataStore m_pData {"cheats"};
|
DataStore m_pData {"cheats"};
|
||||||
|
|
||||||
friend ICheat;
|
friend class IFeature;
|
||||||
RandomCheatsMgr();
|
RandomCheatsMgr();
|
||||||
RandomCheatsMgr(const RandomCheatsMgr&);
|
RandomCheatsMgr(const RandomCheatsMgr&);
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ class TopDownCamera : public ICheat<TopDownCamera>
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
friend ICheat;
|
friend class IFeature;
|
||||||
TopDownCamera();
|
TopDownCamera();
|
||||||
TopDownCamera(const 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_NAME "Cheat Menu"
|
||||||
#define MENU_VERSION_NUMBER "3.3"
|
#define MENU_VERSION_NUMBER "3.3"
|
||||||
#define MENU_VERSION MENU_VERSION_NUMBER"-beta"
|
#define MENU_VERSION MENU_VERSION_NUMBER"-beta"
|
||||||
#define BUILD_NUMBER "20220810"
|
#define BUILD_NUMBER "20220820"
|
||||||
#define MENU_TITLE MENU_NAME " v" MENU_VERSION
|
#define MENU_TITLE MENU_NAME " v" MENU_VERSION
|
||||||
|
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "ifeature.hpp"
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class ICheat
|
class ICheat : public IFeature<T>
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
bool m_bEnabled = false;
|
bool m_bEnabled = false;
|
||||||
@ -20,12 +21,6 @@ public:
|
|||||||
m_bEnabled = true;
|
m_bEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static T &Get()
|
|
||||||
{
|
|
||||||
static T _instance;
|
|
||||||
return _instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the current stae of the cheat
|
// Returns the current stae of the cheat
|
||||||
virtual const bool GetState() final
|
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 "imgui/imgui_internal.h"
|
||||||
#include "pages/welcome.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)
|
void PageHandler::SetCurrentPage(PagePtr page)
|
||||||
|
@ -1,21 +1,24 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "ifeature.hpp"
|
||||||
|
|
||||||
enum class ePageID
|
enum class ePageID
|
||||||
{
|
{
|
||||||
Anniversary,
|
Teleport,
|
||||||
Game,
|
|
||||||
Menu,
|
|
||||||
None,
|
|
||||||
Ped,
|
|
||||||
Player,
|
Player,
|
||||||
|
Ped,
|
||||||
Scene,
|
Scene,
|
||||||
Teleport,
|
|
||||||
Update,
|
|
||||||
Vehicle,
|
Vehicle,
|
||||||
Visual,
|
|
||||||
Weapon,
|
Weapon,
|
||||||
Welcome
|
Game,
|
||||||
|
Visual,
|
||||||
|
Menu,
|
||||||
|
|
||||||
|
// Pages without headers
|
||||||
|
None,
|
||||||
|
Anniversary,
|
||||||
|
Update,
|
||||||
|
Welcome,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -38,7 +41,7 @@ public:
|
|||||||
static void DrawPages();
|
static void DrawPages();
|
||||||
|
|
||||||
// Add a new page
|
// Add a new page
|
||||||
static void AddPage(PagePtr page);
|
static void AddPage(PagePtr page, size_t index);
|
||||||
static void SetCurrentPage(PagePtr page);
|
static void SetCurrentPage(PagePtr page);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -47,7 +50,7 @@ public:
|
|||||||
Every page must inherit this
|
Every page must inherit this
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class IPage
|
class IPage : public IFeature<T>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
ePageID m_eID; // Menu page ID
|
ePageID m_eID; // Menu page ID
|
||||||
@ -58,18 +61,12 @@ public:
|
|||||||
IPage(ePageID page, const std::string& key, bool header)
|
IPage(ePageID page, const std::string& key, bool header)
|
||||||
: m_eID(page), m_NameKey(key), m_bHasHeader(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
|
// Page drawing code goes here
|
||||||
virtual void Draw() = 0;
|
virtual void Draw() = 0;
|
||||||
|
|
||||||
static T &Get()
|
|
||||||
{
|
|
||||||
static T _instance;
|
|
||||||
return _instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the ID of the page
|
// Returns the ID of the page
|
||||||
virtual ePageID GetPageID() final
|
virtual ePageID GetPageID() final
|
||||||
{
|
{
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
class AnniversaryPage : public IPage<AnniversaryPage>
|
class AnniversaryPage : public IPage<AnniversaryPage>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
friend IPage;
|
friend class IFeature;
|
||||||
AnniversaryPage() : IPage<AnniversaryPage>(ePageID::Anniversary, "Anniversary", false){}
|
AnniversaryPage() : IPage<AnniversaryPage>(ePageID::Anniversary, "Anniversary", false){}
|
||||||
AnniversaryPage(const AnniversaryPage&);
|
AnniversaryPage(const AnniversaryPage&);
|
||||||
|
|
||||||
|
@ -175,7 +175,6 @@ void SetPlayerMission(std::string& rootkey, std::string& name, std::string& id)
|
|||||||
|
|
||||||
void GamePage::Draw()
|
void GamePage::Draw()
|
||||||
{
|
{
|
||||||
ImGui::Spacing();
|
|
||||||
CPlayerPed* pPlayer = FindPlayerPed();
|
CPlayerPed* pPlayer = FindPlayerPed();
|
||||||
int hplayer = CPools::GetPedRef(pPlayer);
|
int hplayer = CPools::GetPedRef(pPlayer);
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ private:
|
|||||||
ResourceStore m_StatData{ "stats", eResourceType::TYPE_TEXT };
|
ResourceStore m_StatData{ "stats", eResourceType::TYPE_TEXT };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
friend IPage;
|
friend class IFeature;
|
||||||
GamePage();
|
GamePage();
|
||||||
GamePage(const GamePage&);
|
GamePage(const GamePage&);
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ void MenuPage::Draw()
|
|||||||
}
|
}
|
||||||
ImGui::NextColumn();
|
ImGui::NextColumn();
|
||||||
|
|
||||||
if (gRenderer == Render_DirectX9
|
if (gRenderer == eRenderer::DirectX9
|
||||||
&& Widget::Checkbox(TEXT("Menu.TextOnlyMode"), &m_bTextOnlyMode, TEXT("Menu.TextOnlyModeHint")))
|
&& Widget::Checkbox(TEXT("Menu.TextOnlyMode"), &m_bTextOnlyMode, TEXT("Menu.TextOnlyModeHint")))
|
||||||
{
|
{
|
||||||
gConfig.Set("Menu.TextOnlyMode", m_bTextOnlyMode);
|
gConfig.Set("Menu.TextOnlyMode", m_bTextOnlyMode);
|
||||||
@ -380,6 +380,12 @@ void MenuPage::Draw()
|
|||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::Text("MinHook");
|
ImGui::Text("MinHook");
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("_AG & jeremii");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("Radar code");
|
||||||
|
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::Text(TEXT("Main.TranslatorName"));
|
ImGui::Text(TEXT("Main.TranslatorName"));
|
||||||
|
@ -8,7 +8,7 @@ public:
|
|||||||
bool m_bDiscordRPC; // Is the discord rich presence enabled
|
bool m_bDiscordRPC; // Is the discord rich presence enabled
|
||||||
bool m_bTextOnlyMode; // Hide all menu images mode
|
bool m_bTextOnlyMode; // Hide all menu images mode
|
||||||
|
|
||||||
friend IPage;
|
friend class IFeature;
|
||||||
MenuPage();
|
MenuPage();
|
||||||
MenuPage(const MenuPage&);
|
MenuPage(const MenuPage&);
|
||||||
|
|
||||||
|
@ -23,14 +23,17 @@ static const char* pedTypeList = "Civ Male\0Civ Female\0Cop\0Leones\0Triads\0Dia
|
|||||||
|
|
||||||
#endif
|
#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
|
Taken from gta chaos mod by Lordmau5 & _AG
|
||||||
TODO: Implement in VC too
|
TODO: Implement in VC too
|
||||||
*/
|
*/
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
Events::pedRenderEvent += [](CPed *ped)
|
Events::pedRenderEvent += [this](CPed *ped)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (m_bBigHead)// || m_bThinBody)
|
if (m_bBigHead)// || m_bThinBody)
|
||||||
@ -86,7 +89,7 @@ void Ped::Init()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ped::AddNewPed()
|
void PedPage::AddNewPed()
|
||||||
{
|
{
|
||||||
static char name[8];
|
static char name[8];
|
||||||
static int model = 0;
|
static int model = 0;
|
||||||
@ -118,12 +121,12 @@ void Ped::AddNewPed()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
void Ped::SpawnPed(std::string& model)
|
void PedPage::SpawnPed(std::string& model)
|
||||||
#else
|
#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
|
#endif
|
||||||
{
|
{
|
||||||
if (Spawner::m_List.size() == SPAWN_PED_LIMIT)
|
if (m_Spawner.m_List.size() == SPAWN_PED_LIMIT)
|
||||||
{
|
{
|
||||||
Util::SetMessage(TEXT("Ped.MaxLimit"));
|
Util::SetMessage(TEXT("Ped.MaxLimit"));
|
||||||
return;
|
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::RequestSpecialChar(currentSlot, name.c_str(), PRIORITY_REQUEST);
|
||||||
CStreaming::LoadAllRequestedModels(true);
|
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);
|
CStreaming::SetSpecialCharIsDeletable(290 + currentSlot);
|
||||||
|
|
||||||
// SA has 10 slots
|
// 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_SPECIAL_CHARACTER>(currentSlot, model.c_str());
|
||||||
Command<Commands::LOAD_ALL_MODELS_NOW>();
|
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);
|
Command<Commands::UNLOAD_SPECIAL_CHARACTER>(currentSlot);
|
||||||
|
|
||||||
++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::RequestModel(iModel, eStreamingFlags::PRIORITY_REQUEST);
|
||||||
CStreaming::LoadAllRequestedModels(false);
|
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);
|
CStreaming::SetModelIsDeletable(iModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
ped = CPools::GetPed(hplayer);
|
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
|
else
|
||||||
{
|
{
|
||||||
Command<Commands::MARK_CHAR_AS_NO_LONGER_NEEDED>(hplayer);
|
Command<Commands::MARK_CHAR_AS_NO_LONGER_NEEDED>(hplayer);
|
||||||
}
|
}
|
||||||
ped->m_nPedFlags.bPedIsBleeding = Spawner::m_bPedBleed;
|
ped->m_nPedFlags.bPedIsBleeding = m_Spawner.m_bPedBleed;
|
||||||
ped->m_nWeaponAccuracy = Spawner::m_nAccuracy;
|
ped->m_nWeaponAccuracy = m_Spawner.m_nAccuracy;
|
||||||
ped->m_fHealth = Spawner::m_nPedHealth;
|
ped->m_fHealth = m_Spawner.m_nPedHealth;
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
if (Spawner::m_nWeaponId != 0)
|
if (m_Spawner.m_nWeaponId != 0)
|
||||||
{
|
{
|
||||||
int model = 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::RequestModel(model, PRIORITY_REQUEST);
|
||||||
CStreaming::LoadAllRequestedModels(false);
|
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
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ped::ShowPage()
|
void PedPage::Draw()
|
||||||
{
|
{
|
||||||
if (ImGui::BeginTabBar("Ped", ImGuiTabBarFlags_NoTooltip + ImGuiTabBarFlags_FittingPolicyScroll))
|
if (ImGui::BeginTabBar("Ped", ImGuiTabBarFlags_NoTooltip + ImGuiTabBarFlags_FittingPolicyScroll))
|
||||||
{
|
{
|
||||||
@ -320,12 +323,12 @@ void Ped::ShowPage()
|
|||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
if (ImGui::Button(TEXT("Ped.RemoveFrozen"), Widget::CalcSize(1)))
|
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);
|
CWorld::Remove(ped);
|
||||||
ped->Remove();
|
ped->Remove();
|
||||||
}
|
}
|
||||||
Spawner::m_List.clear();
|
m_Spawner.m_List.clear();
|
||||||
}
|
}
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
if (ImGui::BeginTabBar("SpawnPedBar"))
|
if (ImGui::BeginTabBar("SpawnPedBar"))
|
||||||
@ -336,12 +339,14 @@ void Ped::ShowPage()
|
|||||||
{
|
{
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
Widget::ImageList(m_PedData, SpawnPed,
|
Widget::ImageList(m_PedData, fArgWrapper(pedPage.SpawnPed),
|
||||||
[](std::string& str){
|
[this](str &text)
|
||||||
return m_PedData.m_pData->Get(str.c_str(), "Unknown");
|
{
|
||||||
}, nullptr, AddNewPed);
|
return m_PedData.m_pData->Get(text.c_str(), "Unknown");
|
||||||
|
},
|
||||||
|
nullptr, fArgNoneWrapper(pedPage.AddNewPed));
|
||||||
#else
|
#else
|
||||||
Widget::DataList(m_PedData, SpawnPed, AddNewPed);
|
Widget::DataList(m_PedData, fArg3Wrapper(pedPage.SpawnPed), fArgNoneWrapper(pedPage.AddNewPed));
|
||||||
#endif
|
#endif
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
@ -350,26 +355,26 @@ void Ped::ShowPage()
|
|||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ImGui::BeginChild("PedCOnfig");
|
ImGui::BeginChild("PedCOnfig");
|
||||||
ImGui::Columns(2, 0, false);
|
ImGui::Columns(2, 0, false);
|
||||||
Widget::Checkbox(TEXT("Ped.NoMove"), &Spawner::m_bPedMove);
|
Widget::Checkbox(TEXT("Ped.NoMove"), &m_Spawner.m_bPedMove);
|
||||||
ImGui::NextColumn();
|
ImGui::NextColumn();
|
||||||
Widget::Checkbox(TEXT("Ped.PedBleed"), &Spawner::m_bPedBleed);
|
Widget::Checkbox(TEXT("Ped.PedBleed"), &m_Spawner.m_bPedBleed);
|
||||||
ImGui::Columns(1);
|
ImGui::Columns(1);
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ImGui::SliderInt(TEXT("Ped.Accuracy"), &Spawner::m_nAccuracy, 0.0, 100.0);
|
ImGui::SliderInt(TEXT("Ped.Accuracy"), &m_Spawner.m_nAccuracy, 0.0, 100.0);
|
||||||
if (ImGui::InputInt(TEXT("Ped.Health"), &Spawner::m_nPedHealth))
|
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::EndChild();
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
@ -380,25 +385,25 @@ void Ped::ShowPage()
|
|||||||
ImGui::Text(TEXT("Ped.SelectedWeapon"), weaponName.c_str());
|
ImGui::Text(TEXT("Ped.SelectedWeapon"), weaponName.c_str());
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
Widget::ImageList(WeaponPage::m_WeaponData,
|
Widget::ImageList(weaponPage.m_WeaponData,
|
||||||
[](std::string& str)
|
[this](std::string& str)
|
||||||
{
|
{
|
||||||
Spawner::m_nWeaponId = std::stoi(str);
|
m_Spawner.m_nWeaponId = std::stoi(str);
|
||||||
weaponName = WeaponPage::m_WeaponData.m_pData->Get(str.c_str(), "Unknown");
|
weaponName = weaponPage.m_WeaponData.m_pData->Get(str.c_str(), "Unknown");
|
||||||
},
|
},
|
||||||
[](std::string& str)
|
[](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)
|
[](std::string& str)
|
||||||
{
|
{
|
||||||
return str != "-1"; /*Jetpack*/
|
return str != "-1"; /*Jetpack*/
|
||||||
});
|
});
|
||||||
#else
|
#else
|
||||||
Widget::DataList(Weapon::m_WeaponData,
|
Widget::DataList(weaponPage.m_WeaponData,
|
||||||
[](std::string& root, std::string& key, std::string& id)
|
[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;
|
weaponName = key;
|
||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
@ -462,8 +467,7 @@ void Ped::ShowPage()
|
|||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
if (ImGui::Button(TEXT("Ped.DownloadExGangWars"), Widget::CalcSize(1)))
|
if (ImGui::Button(TEXT("Ped.DownloadExGangWars"), Widget::CalcSize(1)))
|
||||||
{
|
{
|
||||||
ShellExecute(NULL, "open", "https://gtaforums.com/topic/682194-extended-gang-wars/", NULL, NULL,
|
OPEN_LINK("https://gtaforums.com/topic/682194-extended-gang-wars/");
|
||||||
SW_SHOWNORMAL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,41 +1,47 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
|
#include "interface/ipage.h"
|
||||||
|
|
||||||
class Ped
|
class PedPage : public IPage<PedPage>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static inline bool m_bBigHead;
|
bool m_bBigHead;
|
||||||
static inline bool m_bThinBody;
|
bool m_bThinBody;
|
||||||
|
struct
|
||||||
struct Spawner
|
|
||||||
{
|
{
|
||||||
static inline std::vector<CPed*> m_List;
|
std::vector<CPed*> m_List;
|
||||||
static inline int m_nAccuracy = 50;
|
int m_nAccuracy = 50;
|
||||||
static inline int m_nPedHealth = 100;
|
int m_nPedHealth = 100;
|
||||||
static inline bool m_bPedMove;
|
bool m_bPedMove;
|
||||||
static inline bool m_bPedBleed;
|
bool m_bPedBleed;
|
||||||
static inline int m_nSelectedPedType;
|
int m_nSelectedPedType;
|
||||||
static inline int m_nWeaponId;
|
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
|
#ifdef GTASA
|
||||||
static void SpawnPed(std::string& model);
|
void SpawnPed(str& model);
|
||||||
#else
|
#else
|
||||||
static void SpawnPed(std::string& cat, std::string& name, std::string& model);
|
void SpawnPed(str& cat, str& name, str& model);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
static inline DataStore m_SpecialPedData {"special_peds"};
|
DataStore m_SpecialPedData {"special_peds"};
|
||||||
static inline ResourceStore m_PedData{"peds", eResourceType::TYPE_IMAGE_TEXT, ImVec2(65, 110)};
|
ResourceStore m_PedData{"peds", eResourceType::TYPE_IMAGE_TEXT, ImVec2(65, 110)};
|
||||||
#else
|
#else
|
||||||
static inline ResourceStore m_PedData {"peds", eResourceType::TYPE_TEXT};
|
ResourceStore m_PedData {"peds", eResourceType::TYPE_TEXT};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Ped() = delete;
|
void Draw();
|
||||||
Ped(const Ped&) = delete;
|
|
||||||
|
|
||||||
static void Init();
|
|
||||||
static void ShowPage();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern PedPage &pedPage;
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
#include "ped.h"
|
#include "ped.h"
|
||||||
#include "custom/topdowncam_sa.h"
|
#include "custom/topdowncam_sa.h"
|
||||||
|
#include "custom/customskins_sa.h"
|
||||||
|
|
||||||
static inline const char* clothNameList[18] =
|
static inline const char* clothNameList[18] =
|
||||||
{
|
{
|
||||||
@ -28,7 +29,9 @@ static inline void PlayerModelBrokenFix()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void Player::Init()
|
PlayerPage &playerPage = PlayerPage::Get();
|
||||||
|
PlayerPage::PlayerPage()
|
||||||
|
: IPage<PlayerPage>(ePageID::Player, "Window.PlayerPage", true)
|
||||||
{
|
{
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
// Fix player model being broken after rebuild
|
// Fix player model being broken after rebuild
|
||||||
@ -36,42 +39,7 @@ void Player::Init()
|
|||||||
m_bAimSkinChanger = gConfig.Get("Features.AimSkinChanger", false);
|
m_bAimSkinChanger = gConfig.Get("Features.AimSkinChanger", false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Events::processScriptsEvent += [this]
|
||||||
// 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 += []
|
|
||||||
{
|
{
|
||||||
uint timer = CTimer::m_snTimeInMilliseconds;
|
uint timer = CTimer::m_snTimeInMilliseconds;
|
||||||
CPlayerPed* player = FindPlayerPed();
|
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))
|
if (Command<Commands::IS_CHAR_DEAD>(hplayer))
|
||||||
{
|
{
|
||||||
KeepPosition::m_fPos = player->GetPosition();
|
m_RespawnDieLoc.m_fPos = player->GetPosition();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CVector cur_pos = player->GetPosition();
|
CVector cur_pos = player->GetPosition();
|
||||||
|
|
||||||
if (KeepPosition::m_fPos.x != 0 && KeepPosition::m_fPos.x != cur_pos.x
|
if (m_RespawnDieLoc.m_fPos.x != 0 && m_RespawnDieLoc.m_fPos.x != cur_pos.x
|
||||||
&& KeepPosition::m_fPos.y != 0 && KeepPosition::m_fPos.y != cur_pos.y)
|
&& m_RespawnDieLoc.m_fPos.y != 0 && m_RespawnDieLoc.m_fPos.y != cur_pos.y)
|
||||||
{
|
{
|
||||||
BY_GAME(player->Teleport(KeepPosition::m_fPos, false)
|
BY_GAME(player->Teleport(m_RespawnDieLoc.m_fPos, false)
|
||||||
, player->Teleport(KeepPosition::m_fPos), player->Teleport(KeepPosition::m_fPos));
|
, player->Teleport(m_RespawnDieLoc.m_fPos), player->Teleport(m_RespawnDieLoc.m_fPos));
|
||||||
KeepPosition::m_fPos = CVector(0, 0, 0);
|
m_RespawnDieLoc.m_fPos = CVector(0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -179,7 +147,7 @@ void Player::Init()
|
|||||||
if (targetPed)
|
if (targetPed)
|
||||||
{
|
{
|
||||||
player->SetModelIndex(targetPed->m_nModelIndex);
|
player->SetModelIndex(targetPed->m_nModelIndex);
|
||||||
Util::ClearCharTasksVehCheck(player);
|
Util::ClearCharTasksCarCheck(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -221,7 +189,7 @@ void Player::Init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
void Player::ChangePlayerCloth(std::string& name)
|
void PlayerPage::SetCloth(std::string& name)
|
||||||
{
|
{
|
||||||
int bodyPart;
|
int bodyPart;
|
||||||
char model[16], tex[16];
|
char model[16], tex[16];
|
||||||
@ -259,47 +227,32 @@ void Player::ChangePlayerCloth(std::string& name)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef GTASA
|
#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) !=
|
if (pedPage.m_PedData.m_pData->Contains(model.c_str()))
|
||||||
CustomSkins::m_List.end();
|
|
||||||
|
|
||||||
if (Ped::m_PedData.m_pData->Contains(model.c_str()) || custom_skin)
|
|
||||||
{
|
{
|
||||||
CPlayerPed* player = FindPlayerPed();
|
CPlayerPed* player = FindPlayerPed();
|
||||||
if (Ped::m_SpecialPedData.Contains(model.c_str()) || custom_skin)
|
if (pedPage.m_SpecialPedData.Contains(model.c_str()))
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name = pedPage.m_SpecialPedData.Get(model.c_str(), "Unknown");
|
||||||
if (Ped::m_SpecialPedData.Contains(model.c_str()))
|
|
||||||
{
|
|
||||||
name = Ped::m_SpecialPedData.Get(model.c_str(), "Unknown");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
name = model;
|
|
||||||
}
|
|
||||||
|
|
||||||
CStreaming::RequestSpecialChar(1, name.c_str(), PRIORITY_REQUEST);
|
CStreaming::RequestSpecialChar(1, name.c_str(), PRIORITY_REQUEST);
|
||||||
CStreaming::LoadAllRequestedModels(true);
|
CStreaming::LoadAllRequestedModels(true);
|
||||||
|
|
||||||
player->SetModelIndex(291);
|
player->SetModelIndex(291);
|
||||||
|
|
||||||
CStreaming::SetSpecialCharIsDeletable(291);
|
CStreaming::SetSpecialCharIsDeletable(291);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int imodel = std::stoi(model);
|
int imodel = std::stoi(model);
|
||||||
|
|
||||||
CStreaming::RequestModel(imodel, eStreamingFlags::PRIORITY_REQUEST);
|
CStreaming::RequestModel(imodel, eStreamingFlags::PRIORITY_REQUEST);
|
||||||
CStreaming::LoadAllRequestedModels(false);
|
CStreaming::LoadAllRequestedModels(false);
|
||||||
player->SetModelIndex(imodel);
|
player->SetModelIndex(imodel);
|
||||||
CStreaming::SetModelIsDeletable(imodel);
|
CStreaming::SetModelIsDeletable(imodel);
|
||||||
}
|
}
|
||||||
Util::ClearCharTasksVehCheck(player);
|
Util::ClearCharTasksCarCheck(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#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();
|
CPlayerPed* player = FindPlayerPed();
|
||||||
|
|
||||||
@ -329,7 +282,7 @@ void Player::ChangePlayerModel(std::string& cat, std::string& key, std::string&
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void Player::ShowPage()
|
void PlayerPage::Draw()
|
||||||
{
|
{
|
||||||
CPlayerPed* pPlayer = FindPlayerPed();
|
CPlayerPed* pPlayer = FindPlayerPed();
|
||||||
int hplayer = CPools::GetPedRef(pPlayer);
|
int hplayer = CPools::GetPedRef(pPlayer);
|
||||||
@ -574,7 +527,7 @@ void Player::ShowPage()
|
|||||||
#endif
|
#endif
|
||||||
Widget::CheckboxAddr(TEXT("Player.NoFee"), (int)&pInfo->m_bGetOutOfJailFree);
|
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"));
|
Widget::Checkbox(TEXT("Player.PlayerRegen"), &m_bPlayerRegen, TEXT("Player.PlayerRegenTip"));
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
static bool sprintInt = false;
|
static bool sprintInt = false;
|
||||||
@ -684,7 +637,7 @@ void Player::ShowPage()
|
|||||||
if (ImGui::Button(TEXT("Player.ChangeToCJ"), ImVec2(Widget::CalcSize(1))))
|
if (ImGui::Button(TEXT("Player.ChangeToCJ"), ImVec2(Widget::CalcSize(1))))
|
||||||
{
|
{
|
||||||
pPlayer->SetModelIndex(0);
|
pPlayer->SetModelIndex(0);
|
||||||
Util::ClearCharTasksVehCheck(pPlayer);
|
Util::ClearCharTasksCarCheck(pPlayer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
@ -806,7 +759,8 @@ void Player::ShowPage()
|
|||||||
{
|
{
|
||||||
if (pPlayer->m_nModelIndex == 0)
|
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::stringstream ss(str);
|
||||||
std::string temp;
|
std::string temp;
|
||||||
@ -825,7 +779,7 @@ void Player::ShowPage()
|
|||||||
if (ImGui::Button(TEXT("Player.ChangeToCJ"), ImVec2(Widget::CalcSize(1))))
|
if (ImGui::Button(TEXT("Player.ChangeToCJ"), ImVec2(Widget::CalcSize(1))))
|
||||||
{
|
{
|
||||||
pPlayer->SetModelIndex(0);
|
pPlayer->SetModelIndex(0);
|
||||||
Util::ClearCharTasksVehCheck(pPlayer);
|
Util::ClearCharTasksCarCheck(pPlayer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
@ -837,7 +791,6 @@ void Player::ShowPage()
|
|||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
|
|
||||||
ImGui::BeginChild("ClothesRemove");
|
ImGui::BeginChild("ClothesRemove");
|
||||||
size_t count = 0;
|
|
||||||
if (ImGui::Button(TEXT("Player.RemoveAll"), ImVec2(Widget::CalcSize(2))))
|
if (ImGui::Button(TEXT("Player.RemoveAll"), ImVec2(Widget::CalcSize(2))))
|
||||||
{
|
{
|
||||||
CPlayerPed* player = FindPlayerPed();
|
CPlayerPed* player = FindPlayerPed();
|
||||||
@ -848,12 +801,13 @@ void Player::ShowPage()
|
|||||||
CClothes::RebuildPlayer(player, false);
|
CClothes::RebuildPlayer(player, false);
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
size_t count = 0;
|
||||||
for (auto [k, v] : m_ClothData.m_pData->Items())
|
for (auto [k, v] : m_ClothData.m_pData->Items())
|
||||||
{
|
{
|
||||||
if (ImGui::Button(std::string(k.str()).c_str(), ImVec2(Widget::CalcSize(2))))
|
if (ImGui::Button(std::string(k.str()).c_str(), ImVec2(Widget::CalcSize(2))))
|
||||||
{
|
{
|
||||||
CPlayerPed* player = FindPlayerPed();
|
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);
|
CClothes::RebuildPlayer(player, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -869,45 +823,17 @@ void Player::ShowPage()
|
|||||||
}
|
}
|
||||||
if (ImGui::BeginTabItem(TEXT("Player.PedSkinsTab")))
|
if (ImGui::BeginTabItem(TEXT("Player.PedSkinsTab")))
|
||||||
{
|
{
|
||||||
Widget::ImageList(Ped::m_PedData, ChangePlayerModel,
|
Widget::ImageList(pedPage.m_PedData, fArgWrapper(playerPage.SetModel),
|
||||||
[](std::string& str)
|
[](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();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
if (ImGui::BeginTabItem(TEXT("Player.CustomSkinsTab")))
|
if (ImGui::BeginTabItem(TEXT("Player.CustomSkinsTab")))
|
||||||
{
|
{
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
|
CustomSkins.Draw();
|
||||||
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);
|
|
||||||
}
|
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
ImGui::EndTabBar();
|
ImGui::EndTabBar();
|
||||||
@ -924,7 +850,7 @@ void Player::ShowPage()
|
|||||||
#else
|
#else
|
||||||
ImGui::TextWrapped(TEXT("Player.WorkSkinOnly"));
|
ImGui::TextWrapped(TEXT("Player.WorkSkinOnly"));
|
||||||
#endif
|
#endif
|
||||||
Widget::DataList(skinData, ChangePlayerModel);
|
Widget::DataList(skinData, fArg3Wrapper(playerPage.ChangePlayerModel));
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,47 +1,44 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
|
#include "interface/ipage.h"
|
||||||
|
|
||||||
class Player
|
class PlayerPage : public IPage<PlayerPage>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static inline bool m_bGodMode;
|
bool m_bGodMode;
|
||||||
static inline bool m_bPlayerRegen;
|
bool m_bPlayerRegen;
|
||||||
static inline bool m_bModloaderInstalled;
|
struct
|
||||||
struct KeepPosition
|
|
||||||
{
|
{
|
||||||
static inline bool m_bEnabled = false;
|
bool m_bEnabled = false;
|
||||||
static inline CVector m_fPos;
|
CVector m_fPos;
|
||||||
};
|
} m_RespawnDieLoc;
|
||||||
static inline bool m_bKeepStuff;
|
bool m_bKeepStuff;
|
||||||
static inline bool m_bFreezeWantedLevel;
|
bool m_bFreezeWantedLevel;
|
||||||
|
|
||||||
#ifdef GTAVC
|
#ifdef GTAVC
|
||||||
static inline bool m_bNoUndress;
|
bool m_bNoUndress; // Tommy won't lose clothes after busted/ wasted
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
static inline bool m_bAimSkinChanger;
|
bool m_bAimSkinChanger;
|
||||||
static inline bool m_bDrunkEffect;
|
bool m_bDrunkEffect;
|
||||||
static inline bool m_bFastSprint;
|
bool m_bFastSprint;
|
||||||
static inline ResourceStore m_ClothData { "clothes", eResourceType::TYPE_TEXT_IMAGE, ImVec2(70, 100)};
|
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void ChangePlayerModel(std::string& model);
|
void SetCloth(str& id);
|
||||||
static void ChangePlayerCloth(std::string& model);
|
void SetModel(str& id);
|
||||||
#else
|
#else
|
||||||
static inline ResourceStore skinData { BY_GAME(NULL, "skins", "peds"), eResourceType::TYPE_TEXT };
|
ResourceStore skinData { BY_GAME(NULL, "skins", "peds"), eResourceType::TYPE_TEXT };
|
||||||
static void ChangePlayerModel(std::string& cat, std::string& name, std::string& id);
|
void ChangePlayerModel(str& cat, str& name, str& id);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
friend class IFeature;
|
||||||
|
PlayerPage();
|
||||||
|
PlayerPage(const PlayerPage&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Player() = delete;
|
void Draw();
|
||||||
Player(const Player&) = delete;
|
|
||||||
|
|
||||||
static void Init();
|
|
||||||
static void ShowPage();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern PlayerPage &playerPage;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
class ScenePage : public IPage<ScenePage>
|
class ScenePage : public IPage<ScenePage>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
friend IPage;
|
friend class IFeature;
|
||||||
ScenePage() : IPage<ScenePage>(ePageID::Scene, "Window.ScenePage", true){}
|
ScenePage() : IPage<ScenePage>(ePageID::Scene, "Window.ScenePage", true){}
|
||||||
ScenePage(const ScenePage&);
|
ScenePage(const ScenePage&);
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
ResourceStore m_locData{"locations", eResourceType::TYPE_TEXT};
|
ResourceStore m_locData{"locations", eResourceType::TYPE_TEXT};
|
||||||
|
|
||||||
friend IPage;
|
friend class IFeature;
|
||||||
TeleportPage();
|
TeleportPage();
|
||||||
TeleportPage(const TeleportPage&);
|
TeleportPage(const TeleportPage&);
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
class UpdatePage : public IPage<UpdatePage>
|
class UpdatePage : public IPage<UpdatePage>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
friend IPage;
|
friend class IFeature;
|
||||||
UpdatePage() : IPage<UpdatePage>(ePageID::Update, "Update", false){}
|
UpdatePage() : IPage<UpdatePage>(ePageID::Update, "Update", false){}
|
||||||
UpdatePage(const UpdatePage&);
|
UpdatePage(const UpdatePage&);
|
||||||
|
|
||||||
|
@ -7,49 +7,45 @@
|
|||||||
#include "utils/widget.h"
|
#include "utils/widget.h"
|
||||||
#include "utils/util.h"
|
#include "utils/util.h"
|
||||||
#include "custom/filehandler.h"
|
#include "custom/filehandler.h"
|
||||||
|
#include "custom/vehpaint.h"
|
||||||
|
#include "custom/autodrive.h"
|
||||||
|
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
#include <tHandlingData.h>
|
#include <tHandlingData.h>
|
||||||
#include "custom/neon_sa.h"
|
#include "custom/vehmod_sa.h"
|
||||||
#include "custom/paint_sa.h"
|
|
||||||
#endif
|
#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
|
// Get config data
|
||||||
Spawner::m_bSpawnInAir = gConfig.Get("Features.SpawnAircraftInAir", true);
|
m_Spawner.m_bInAir = gConfig.Get("Features.SpawnAircraftInAir", true);
|
||||||
Spawner::m_bSpawnInside = gConfig.Get("Features.SpawnInsideVehicle", true);
|
m_Spawner.m_bAsDriver = gConfig.Get("Features.SpawnInsideVehicle", true);
|
||||||
|
|
||||||
Events::processScriptsEvent += []
|
Events::processScriptsEvent += [this]
|
||||||
{
|
{
|
||||||
uint timer = CTimer::m_snTimeInMilliseconds;
|
uint timer = CTimer::m_snTimeInMilliseconds;
|
||||||
CPlayerPed* pPlayer = FindPlayerPed();
|
CPlayerPed* pPlayer = FindPlayerPed();
|
||||||
CVehicle* pVeh = BY_GAME(FindPlayerVehicle(-1, false), FindPlayerVehicle(), FindPlayerVehicle());
|
CVehicle* pVeh = BY_GAME(FindPlayerVehicle(-1, false), FindPlayerVehicle(), FindPlayerVehicle());
|
||||||
|
|
||||||
if (pPlayer && Util::IsInVehicle())
|
if (pPlayer && Util::IsInCar())
|
||||||
{
|
{
|
||||||
int hveh = CPools::GetVehicleRef(pVeh);
|
int hveh = CPools::GetVehicleRef(pVeh);
|
||||||
float speed = pVeh->m_vecMoveSpeed.Magnitude() * 50.0f;
|
float speed = pVeh->m_vecMoveSpeed.Magnitude() * 50.0f;
|
||||||
if (m_bAutoUnflip && pVeh->IsUpsideDown() && speed < 2.0f)
|
if (m_bAutoUnflip && pVeh->IsUpsideDown() && speed < 2.0f)
|
||||||
{
|
{
|
||||||
Util::UnFlipVehicle(pVeh);
|
Util::UnFlipCar(pVeh);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unflipVeh.Pressed())
|
if (unflipVeh.Pressed())
|
||||||
{
|
{
|
||||||
Util::UnFlipVehicle(pVeh);
|
Util::UnFlipCar(pVeh);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fixVeh.Pressed())
|
if (fixVeh.Pressed())
|
||||||
{
|
{
|
||||||
Util::FixVehicle(pVeh);
|
Util::FixCar(pVeh);
|
||||||
Util::SetMessage("Vehicle fixed");
|
Util::SetMessage("Vehicle fixed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,72 +117,9 @@ void Vehicle::Init()
|
|||||||
{
|
{
|
||||||
Util::SetCarForwardSpeed(pVeh, m_fLockSpeed);
|
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
|
#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))
|
if (m_bBikeFly && pVeh && pVeh->IsDriver(pPlayer))
|
||||||
{
|
{
|
||||||
@ -207,54 +140,8 @@ void Vehicle::Init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GTASA
|
#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
|
// hardcoded for now
|
||||||
int Vehicle::GetRandomTrainIdForModel(int model)
|
int VehiclePage::GetRandomTrainIdForModel(int model)
|
||||||
{
|
{
|
||||||
static int train_ids[] =
|
static int train_ids[] =
|
||||||
{
|
{
|
||||||
@ -322,7 +209,7 @@ void WarpPlayerIntoVehicle(CVehicle *pVeh, int seatId)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void Vehicle::AddNewVehicle()
|
void VehiclePage::AddNew()
|
||||||
{
|
{
|
||||||
static char name[INPUT_BUFFER_SIZE];
|
static char name[INPUT_BUFFER_SIZE];
|
||||||
static int model = 0;
|
static int model = 0;
|
||||||
@ -335,8 +222,8 @@ void Vehicle::AddNewVehicle()
|
|||||||
if (CModelInfo::IsCarModel(model))
|
if (CModelInfo::IsCarModel(model))
|
||||||
{
|
{
|
||||||
std::string key = std::format("Custom.{} (Added)", name);
|
std::string key = std::format("Custom.{} (Added)", name);
|
||||||
Spawner::m_VehData.m_pData->Set(key.c_str(), std::to_string(model));
|
m_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->Save();
|
||||||
Util::SetMessage(TEXT("Window.AddEntryMSG"));
|
Util::SetMessage(TEXT("Window.AddEntryMSG"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -352,7 +239,7 @@ void Vehicle::AddNewVehicle()
|
|||||||
if (Command<Commands::IS_CHAR_IN_ANY_CAR>(hPlayer))
|
if (Command<Commands::IS_CHAR_IN_ANY_CAR>(hPlayer))
|
||||||
{
|
{
|
||||||
model = pPlayer->m_pVehicle->m_nModelIndex;
|
model = pPlayer->m_pVehicle->m_nModelIndex;
|
||||||
std::string str = Vehicle::GetNameFromModel(model);
|
std::string str = Util::GetCarName(model);
|
||||||
strcpy(name, str.c_str());
|
strcpy(name, str.c_str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -363,9 +250,9 @@ void Vehicle::AddNewVehicle()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
void Vehicle::SpawnVehicle(std::string& smodel)
|
void VehiclePage::SpawnVehicle(std::string& smodel)
|
||||||
#else
|
#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
|
#endif
|
||||||
{
|
{
|
||||||
CPlayerPed* player = FindPlayerPed();
|
CPlayerPed* player = FindPlayerPed();
|
||||||
@ -378,7 +265,7 @@ void Vehicle::SpawnVehicle(std::string& rootkey, std::string& vehName, std::stri
|
|||||||
float speed = 0;
|
float speed = 0;
|
||||||
|
|
||||||
bool bInVehicle = Command<Commands::IS_CHAR_IN_ANY_CAR>(hplayer);
|
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;
|
CVehicle* pveh = player->m_pVehicle;
|
||||||
int hveh = CPools::GetVehicleRef(pveh);
|
int hveh = CPools::GetVehicleRef(pveh);
|
||||||
@ -404,7 +291,7 @@ void Vehicle::SpawnVehicle(std::string& rootkey, std::string& vehName, std::stri
|
|||||||
|
|
||||||
if (interior == 0)
|
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;
|
pos.z = 400;
|
||||||
}
|
}
|
||||||
@ -446,7 +333,7 @@ void Vehicle::SpawnVehicle(std::string& rootkey, std::string& vehName, std::stri
|
|||||||
if (veh->m_pDriver)
|
if (veh->m_pDriver)
|
||||||
Command<Commands::DELETE_CHAR>(CPools::GetPedRef(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);
|
Command<Commands::WARP_CHAR_INTO_CAR>(hplayer, hveh);
|
||||||
Util::SetCarForwardSpeed(veh, speed);
|
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::RequestModel(imodel, PRIORITY_REQUEST);
|
||||||
CStreaming::LoadAllRequestedModels(false);
|
CStreaming::LoadAllRequestedModels(false);
|
||||||
#ifdef GTASA
|
#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
|
#endif
|
||||||
int hveh = 0;
|
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);
|
Command<Commands::CREATE_CAR>(imodel, pos.x, pos.y, pos.z + 4.0f, &hveh);
|
||||||
veh = CPools::GetVehicle(hveh);
|
veh = CPools::GetVehicle(hveh);
|
||||||
@ -526,102 +413,7 @@ void Vehicle::SpawnVehicle(std::string& rootkey, std::string& vehName, std::stri
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Vehicle::GetNameFromModel(int model)
|
void VehiclePage::Draw()
|
||||||
{
|
|
||||||
#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()
|
|
||||||
{
|
{
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
CPlayerPed* pPlayer = FindPlayerPed();
|
CPlayerPed* pPlayer = FindPlayerPed();
|
||||||
@ -639,16 +431,16 @@ void Vehicle::ShowPage()
|
|||||||
|
|
||||||
ImGui::SameLine();
|
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();
|
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();
|
ImGui::Spacing();
|
||||||
@ -790,7 +582,7 @@ void Vehicle::ShowPage()
|
|||||||
Widget::CheckboxAddr(TEXT("Vehicle.PerfectHandling"), 0x96914C);
|
Widget::CheckboxAddr(TEXT("Vehicle.PerfectHandling"), 0x96914C);
|
||||||
Widget::CheckboxAddr(TEXT("Vehicle.TankMode"), 0x969164);
|
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")))
|
if (Widget::Checkbox(TEXT("Vehicle.FlipNoBurn"), &m_bVehFlipNoBurn, TEXT("Vehicle.FlipNoBurnTip")))
|
||||||
{
|
{
|
||||||
// MixSets (Link2012)
|
// MixSets (Link2012)
|
||||||
@ -948,7 +740,7 @@ void Vehicle::ShowPage()
|
|||||||
#endif
|
#endif
|
||||||
if (ImGui::CollapsingHeader(TEXT(bPlayerInCar ? "Vehicle.SwitchSeats" : "Vehicle.EnterNearVeh")))
|
if (ImGui::CollapsingHeader(TEXT(bPlayerInCar ? "Vehicle.SwitchSeats" : "Vehicle.EnterNearVeh")))
|
||||||
{
|
{
|
||||||
CVehicle* pTargetVeh = bPlayerInCar ? pVeh : Util::GetClosestVehicle();
|
CVehicle* pTargetVeh = bPlayerInCar ? pVeh : Util::GetClosestCar();
|
||||||
|
|
||||||
if (pTargetVeh)
|
if (pTargetVeh)
|
||||||
{
|
{
|
||||||
@ -957,7 +749,7 @@ void Vehicle::ShowPage()
|
|||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ImGui::Columns(2, 0, false);
|
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::NextColumn();
|
||||||
ImGui::Text(TEXT("Vehicle.TotalSeats"), (seats + 1));
|
ImGui::Text(TEXT("Vehicle.TotalSeats"), (seats + 1));
|
||||||
ImGui::Columns(1);
|
ImGui::Columns(1);
|
||||||
@ -999,14 +791,15 @@ void Vehicle::ShowPage()
|
|||||||
}
|
}
|
||||||
if (ImGui::CollapsingHeader(TEXT("Vehicle.RemoveVehRadius")))
|
if (ImGui::CollapsingHeader(TEXT("Vehicle.RemoveVehRadius")))
|
||||||
{
|
{
|
||||||
ImGui::InputInt(TEXT("Vehicle.Radius"), &m_nVehRemoveRadius);
|
static int removeRadius;
|
||||||
|
ImGui::InputInt(TEXT("Vehicle.Radius"), &removeRadius);
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
if (ImGui::Button(TEXT("Vehicle.RemoveVeh"), Widget::CalcSize(1)))
|
if (ImGui::Button(TEXT("Vehicle.RemoveVeh"), Widget::CalcSize(1)))
|
||||||
{
|
{
|
||||||
CPlayerPed* player = FindPlayerPed();
|
CPlayerPed* player = FindPlayerPed();
|
||||||
for (CVehicle* pVeh : CPools::ms_pVehiclePool)
|
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)
|
&& player->m_pVehicle != pVeh)
|
||||||
{
|
{
|
||||||
Command<Commands::DELETE_CAR>(CPools::GetVehicleRef(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);
|
Widget::EditAddr(TEXT("Vehicle.DirtLvl"), (int)pVeh + 0x4B0, 0, 7.5, 15);
|
||||||
if (pVeh->m_nVehicleClass == VEHICLE_AUTOMOBILE && ImGui::CollapsingHeader(TEXT("Vehicle.Doors")))
|
if (pVeh->m_nVehicleClass == VEHICLE_AUTOMOBILE && ImGui::CollapsingHeader(TEXT("Vehicle.Doors")))
|
||||||
{
|
{
|
||||||
|
static int m_nDoorMenuButton;
|
||||||
ImGui::Columns(2, 0, false);
|
ImGui::Columns(2, 0, false);
|
||||||
ImGui::RadioButton(TEXT("Vehicle.Damage"), &m_nDoorMenuButton, 0);
|
ImGui::RadioButton(TEXT("Vehicle.Damage"), &m_nDoorMenuButton, 0);
|
||||||
ImGui::RadioButton(TEXT("Vehicle.Fix"), &m_nDoorMenuButton, 1);
|
ImGui::RadioButton(TEXT("Vehicle.Fix"), &m_nDoorMenuButton, 1);
|
||||||
@ -1141,14 +935,14 @@ void Vehicle::ShowPage()
|
|||||||
{
|
{
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ImGui::Columns(2, 0, false);
|
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();
|
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);
|
ImGui::Columns(1);
|
||||||
|
|
||||||
@ -1189,14 +983,14 @@ void Vehicle::ShowPage()
|
|||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::SetNextItemWidth(width);
|
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){
|
[](std::string& str){
|
||||||
return GetNameFromModel(std::stoi(str));
|
return Util::GetCarName(std::stoi(str));
|
||||||
}, nullptr, AddNewVehicle);
|
}, nullptr, fArgNoneWrapper(vehiclePage.AddNew));
|
||||||
#else
|
#else
|
||||||
Widget::DataList(Spawner::m_VehData, SpawnVehicle, AddNewVehicle);
|
Widget::DataList(m_Spawner.m_VehData, fArg3Wrapper(vehiclePage.SpawnVehicle), fArgNoneWrapper(vehiclePage.AddNew));
|
||||||
#endif
|
#endif
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
@ -1207,401 +1001,13 @@ void Vehicle::ShowPage()
|
|||||||
if (ImGui::BeginTabItem(TEXT("Vehicle.AutoDrive")))
|
if (ImGui::BeginTabItem(TEXT("Vehicle.AutoDrive")))
|
||||||
{
|
{
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
if (ImGui::Button(TEXT("Vehicle.AutoDriveStop"), Widget::CalcSize(1)))
|
AutoDrive.Draw();
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
if (ImGui::BeginTabItem(TEXT("Vehicle.Color")))
|
|
||||||
{
|
VehPaint.Draw();
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
Paint::GenerateNodeList(veh, PaintData::m_vecNames, PaintData::m_Selected);
|
VehMod.Draw();
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
ImGui::EndTabBar();
|
ImGui::EndTabBar();
|
||||||
|
@ -1,111 +1,50 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
|
#include "interface/ipage.h"
|
||||||
|
|
||||||
class Vehicle
|
class VehiclePage : public IPage<VehiclePage>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static inline bool m_bAutoUnflip;
|
bool m_bAutoUnflip;
|
||||||
static inline bool m_bBikeFly;
|
bool m_bBikeFly;
|
||||||
static inline bool m_bDontFallBike;
|
bool m_bDontFallBike;
|
||||||
static inline bool m_bVehHeavy;
|
bool m_bVehHeavy;
|
||||||
static inline bool m_bVehWatertight;
|
bool m_bVehWatertight;
|
||||||
static inline bool m_bNoDamage;
|
bool m_bNoDamage;
|
||||||
static inline int m_nDoorMenuButton;
|
std::string m_DoorNames[6] =
|
||||||
static inline std::string m_DoorNames[6] =
|
|
||||||
{ "Hood", "Boot", "Front left door", "Front right door", "Rear left door", "Rear right door" };
|
{ "Hood", "Boot", "Front left door", "Front right door", "Rear left door", "Rear right door" };
|
||||||
static inline int m_nVehRemoveRadius;
|
bool m_bLockSpeed;
|
||||||
static inline bool m_bLockSpeed;
|
float m_fLockSpeed;
|
||||||
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";
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
static inline bool m_bDisableColDetection;
|
bool m_bDisableColDetection;
|
||||||
static inline bool m_bVehFlipNoBurn;
|
bool m_bVehFlipNoBurn;
|
||||||
static inline bool m_bMoreTrainCams;
|
bool m_bNoDerail;
|
||||||
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) };
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct Spawner
|
struct
|
||||||
{
|
{
|
||||||
#ifdef GTASA
|
ResourceStore m_VehData { "vehicles", BY_GAME(eResourceType::TYPE_IMAGE_TEXT, eResourceType::TYPE_TEXT,
|
||||||
static inline ResourceStore m_VehData { "vehicles", eResourceType::TYPE_IMAGE_TEXT, ImVec2(100, 75)};
|
eResourceType::TYPE_TEXT), ImVec2(100, 75)};
|
||||||
#else
|
bool m_bAsDriver = true;
|
||||||
static inline ResourceStore m_VehData {"vehicles", eResourceType::TYPE_TEXT};
|
bool m_bInAir = true;
|
||||||
#endif
|
char m_nLicenseText[9];
|
||||||
static inline bool m_bSpawnInside = true;
|
} m_Spawner;
|
||||||
static inline bool m_bSpawnInAir = true;
|
|
||||||
static inline char m_nLicenseText[9];
|
|
||||||
};
|
|
||||||
struct UnlimitedNitro
|
|
||||||
{
|
|
||||||
static inline bool m_bEnabled;
|
|
||||||
static inline bool m_bCompAdded;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef GTASA
|
friend class IFeature;
|
||||||
static inline std::vector<std::string> m_HandlingFlagNames = // 32 flags
|
VehiclePage();
|
||||||
{
|
VehiclePage(const VehiclePage&);
|
||||||
"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
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Vehicle() = delete;
|
void AddNew();
|
||||||
Vehicle(const Vehicle&) = delete;
|
void Draw();
|
||||||
|
|
||||||
static void AddNewVehicle();
|
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
static void SpawnVehicle(std::string& name);
|
int GetRandomTrainIdForModel(int model);
|
||||||
|
void SpawnVehicle(std::string& name);
|
||||||
#else
|
#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
|
#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
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
void Visual::Init()
|
VisualPage& visualPage = VisualPage::Get();
|
||||||
|
VisualPage::VisualPage()
|
||||||
|
: IPage<VisualPage>(ePageID::Visual, "Window.VisualPage", true)
|
||||||
{
|
{
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
if (GetModuleHandle("timecycle24.asi"))
|
if (GetModuleHandle("timecycle24.asi"))
|
||||||
@ -142,7 +144,7 @@ void Visual::Init()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Events::processScriptsEvent += []
|
Events::processScriptsEvent += [this]
|
||||||
{
|
{
|
||||||
// TODO: Needs improvement
|
// TODO: Needs improvement
|
||||||
static short m_nBacWeatherType;
|
static short m_nBacWeatherType;
|
||||||
@ -401,7 +403,7 @@ void TimecycSlider(const char* label, T* ptr, int min, int max)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
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;
|
bool rtn = false;
|
||||||
int val = CalcArrayIndex();
|
int val = CalcArrayIndex();
|
||||||
@ -430,7 +432,7 @@ bool Visual::TimeCycColorEdit3(const char* label, T* r, T* g, T* b, ImGuiColorEd
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
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();
|
int val = CalcArrayIndex();
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
@ -446,7 +448,7 @@ void Visual::TimecycSlider(const char* label, T* ptr, int min, int max)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
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;
|
bool rtn = false;
|
||||||
int val = CalcArrayIndex();
|
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
|
#ifdef GTASA
|
||||||
static float clockPosX = *(float*)*(int*)0x58EC16;
|
static float clockPosX = *(float*)*(int*)0x58EC16;
|
||||||
@ -598,7 +600,7 @@ void Visual::PatchRadar()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Visual::ShowPage()
|
void VisualPage::Draw()
|
||||||
{
|
{
|
||||||
if (ImGui::BeginTabBar("Visual", ImGuiTabBarFlags_NoTooltip + ImGuiTabBarFlags_FittingPolicyScroll))
|
if (ImGui::BeginTabBar("Visual", ImGuiTabBarFlags_NoTooltip + ImGuiTabBarFlags_FittingPolicyScroll))
|
||||||
{
|
{
|
||||||
@ -619,11 +621,11 @@ void Visual::ShowPage()
|
|||||||
if (m_bDisableHydrant)
|
if (m_bDisableHydrant)
|
||||||
{
|
{
|
||||||
// don't call Fx_c::TriggerWaterHydrant
|
// don't call Fx_c::TriggerWaterHydrant
|
||||||
plugin::patch::Nop(0x4A0D70, 5);
|
patch::Nop(0x4A0D70, 5);
|
||||||
}
|
}
|
||||||
else
|
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);
|
Widget::CheckboxAddr(TEXT("Visual.FogEffect"), 0xC402C6);
|
||||||
@ -650,18 +652,18 @@ void Visual::ShowPage()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// restore
|
// restore
|
||||||
plugin::patch::SetRaw(0x575BF6, (char*)"\xE8\x65\x1F\x1B\x00", 5);
|
patch::SetRaw(0x575BF6, (char*)"\xE8\x65\x1F\x1B\x00", 5);
|
||||||
plugin::patch::SetRaw(0x575C40, (char*)"\xE8\x1B\x1F\x1B\x00", 5);
|
patch::SetRaw(0x575C40, (char*)"\xE8\x1B\x1F\x1B\x00", 5);
|
||||||
plugin::patch::SetRaw(0x575C84, (char*)"\xE8\xD7\x1E\x1B\x00", 5);
|
patch::SetRaw(0x575C84, (char*)"\xE8\xD7\x1E\x1B\x00", 5);
|
||||||
plugin::patch::SetRaw(0x575CCE, (char*)"\xE8\x8D\x1E\x1B\x00", 5);
|
patch::SetRaw(0x575CCE, (char*)"\xE8\x8D\x1E\x1B\x00", 5);
|
||||||
plugin::patch::SetRaw(0x575D1F, (char*)"\xE8\x3C\x1E\x1B\x00", 5);
|
patch::SetRaw(0x575D1F, (char*)"\xE8\x3C\x1E\x1B\x00", 5);
|
||||||
plugin::patch::SetRaw(0x575D6F, (char*)"\xE8\xEC\x1D\x1B\x00", 5);
|
patch::SetRaw(0x575D6F, (char*)"\xE8\xEC\x1D\x1B\x00", 5);
|
||||||
plugin::patch::SetRaw(0x575DC2, (char*)"\xE8\x99\x1D\x1B\x00", 5);
|
patch::SetRaw(0x575DC2, (char*)"\xE8\x99\x1D\x1B\x00", 5);
|
||||||
plugin::patch::SetRaw(0x575E12, (char*)"\xE8\x49\x1D\x1B\x00", 5);
|
patch::SetRaw(0x575E12, (char*)"\xE8\x49\x1D\x1B\x00", 5);
|
||||||
plugin::patch::SetRaw(0x5754EC, (char*)"\xD8\x0D\x20\x95\x85\x00", 6);
|
patch::SetRaw(0x5754EC, (char*)"\xD8\x0D\x20\x95\x85\x00", 6);
|
||||||
plugin::patch::SetRaw(0x575537, (char*)"\xD8\x0D\x24\x95\x85\x00", 6);
|
patch::SetRaw(0x575537, (char*)"\xD8\x0D\x24\x95\x85\x00", 6);
|
||||||
plugin::patch::SetRaw(0x575311, (char*)"\xD8\x0D\x70\x53\x86\x00", 6);
|
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(0x575361, (char*)"\xD8\x0D\x6C\x53\x86\x00", 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Widget::CheckboxAddr(TEXT("Visual.GrainEffect"), 0xC402B4);
|
Widget::CheckboxAddr(TEXT("Visual.GrainEffect"), 0xC402B4);
|
||||||
@ -692,14 +694,14 @@ void Visual::ShowPage()
|
|||||||
if (m_bInvisibleWater)
|
if (m_bInvisibleWater)
|
||||||
{
|
{
|
||||||
// don't call CWaterLevel::RenderWater()
|
// don't call CWaterLevel::RenderWater()
|
||||||
plugin::patch::Nop(0x53E004, 5);
|
patch::Nop(0x53E004, 5);
|
||||||
plugin::patch::Nop(0x53E142, 5);
|
patch::Nop(0x53E142, 5);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// restore call CWaterLevel::RenderWater()
|
// restore call CWaterLevel::RenderWater()
|
||||||
plugin::patch::SetRaw(0x53E004, (char*)"\xE8\x47\x16\x1B\x00", 5);
|
patch::SetRaw(0x53E004, (char*)"\xE8\x47\x16\x1B\x00", 5);
|
||||||
plugin::patch::SetRaw(0x53E142, (char*)"\xE8\x09\x15\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>(0xBA830C, 0.0);
|
||||||
patch::Set<float>(0xBA8308, 1.0);
|
patch::Set<float>(0xBA8308, 1.0);
|
||||||
|
|
||||||
// stop map rotaiton
|
// stop map rotation
|
||||||
patch::Nop(0x5837FB, 6);
|
patch::Nop(0x5837FB, 6);
|
||||||
patch::Nop(0x583805, 6);
|
patch::Nop(0x583805, 6);
|
||||||
patch::Nop(0x58380D, 6);
|
patch::Nop(0x58380D, 6);
|
||||||
@ -763,20 +765,20 @@ void Visual::ShowPage()
|
|||||||
if (m_bNoWater)
|
if (m_bNoWater)
|
||||||
{
|
{
|
||||||
// don't call CWaterLevel::RenderWater()
|
// don't call CWaterLevel::RenderWater()
|
||||||
plugin::patch::Nop(0x53E004, 5);
|
patch::Nop(0x53E004, 5);
|
||||||
plugin::patch::Nop(0x53E142, 5);
|
patch::Nop(0x53E142, 5);
|
||||||
|
|
||||||
// rtn CWaterLevel::GetWaterLevelNoWaves
|
// rtn CWaterLevel::GetWaterLevelNoWaves
|
||||||
plugin::patch::SetRaw(0x6E8580, (char*)"\x32\xC0\xC3", 3);
|
patch::SetRaw(0x6E8580, (char*)"\x32\xC0\xC3", 3);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// restore call CWaterLevel::RenderWater()
|
// restore call CWaterLevel::RenderWater()
|
||||||
plugin::patch::SetRaw(0x53E004, (char*)"\xE8\x47\x16\x1B\x00", 5);
|
patch::SetRaw(0x53E004, (char*)"\xE8\x47\x16\x1B\x00", 5);
|
||||||
plugin::patch::SetRaw(0x53E142, (char*)"\xE8\x09\x15\x1B\x00", 5);
|
patch::SetRaw(0x53E142, (char*)"\xE8\x09\x15\x1B\x00", 5);
|
||||||
|
|
||||||
// restore CWaterLevel::GetWaterLevelNoWaves
|
// 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);
|
bool radar_state = (patch::Get<BYTE>(0xBA676C) != 2);
|
||||||
|
@ -1,38 +1,41 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
|
#include "interface/ipage.h"
|
||||||
|
|
||||||
class Visual
|
class VisualPage : public IPage<VisualPage>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static inline bool m_bLockWeather;
|
bool m_bLockWeather;
|
||||||
|
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
static inline bool m_bInvisibleWater;
|
bool m_bInvisibleWater;
|
||||||
static inline bool m_bNoWater;
|
bool m_bNoWater;
|
||||||
static inline bool m_bDisableHydrant;
|
bool m_bDisableHydrant;
|
||||||
static inline bool m_bNoMoneyZeros;
|
bool m_bNoMoneyZeros;
|
||||||
static inline bool m_bNoPartciles;
|
bool m_bNoPartciles;
|
||||||
static inline bool m_bNoPostFX;
|
bool m_bNoPostFX;
|
||||||
static inline bool m_bNoTextures;
|
bool m_bNoTextures;
|
||||||
static inline bool m_bFullScreenMap;
|
bool m_bFullScreenMap;
|
||||||
static inline bool m_bSquareRadar;
|
bool m_bSquareRadar;
|
||||||
static inline bool m_bNoRadarRot;
|
bool m_bNoRadarRot;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
friend class IFeature;
|
||||||
|
VisualPage();
|
||||||
|
VisualPage(const VisualPage&);
|
||||||
|
|
||||||
template<typename T>
|
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>
|
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>
|
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:
|
public:
|
||||||
Visual() = delete;
|
void Draw();
|
||||||
Visual(const Visual&) = delete;
|
|
||||||
|
|
||||||
static void Init();
|
|
||||||
static void ShowPage();
|
|
||||||
|
|
||||||
// Patches the radar for visual changes
|
// Patches the radar for visual changes
|
||||||
static void PatchRadar();
|
void PatchRadar();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern VisualPage& visualPage;
|
@ -4,9 +4,11 @@
|
|||||||
#include "utils/util.h"
|
#include "utils/util.h"
|
||||||
#include <CWeaponInfo.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();
|
CPlayerPed* player = FindPlayerPed();
|
||||||
|
|
||||||
@ -94,11 +96,11 @@ void WeaponPage::Init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GTASA
|
#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);
|
m_WeaponList[m_nSelected][m_nSelectedWeapon] = std::stoi(weaponType);
|
||||||
CGangs::SetGangWeapons(m_nSelectedGang, m_nGangWeaponList[m_nSelectedGang][0], m_nGangWeaponList[m_nSelectedGang][1],
|
CGangs::SetGangWeapons(m_nSelected, m_WeaponList[m_nSelected][0], m_WeaponList[m_nSelected][1],
|
||||||
m_nGangWeaponList[m_nSelectedGang][2]);
|
m_WeaponList[m_nSelected][2]);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// Implementation of SA opcode 0x555
|
// Implementation of SA opcode 0x555
|
||||||
@ -206,7 +208,7 @@ void WeaponPage::GiveWeaponToPlayer(std::string& weapon_type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#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();
|
CPlayerPed* player = FindPlayerPed();
|
||||||
int hplayer = CPools::GetPedRef(player);
|
int hplayer = CPools::GetPedRef(player);
|
||||||
@ -376,17 +378,17 @@ void WeaponPage::Draw()
|
|||||||
m_nAmmoCount = (m_nAmmoCount > 99999) ? 99999 : m_nAmmoCount;
|
m_nAmmoCount = (m_nAmmoCount > 99999) ? 99999 : m_nAmmoCount;
|
||||||
}
|
}
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
Widget::ImageList(m_WeaponData, GiveWeaponToPlayer,
|
Widget::ImageList(m_WeaponData, fArgWrapper(weaponPage.GiveWeaponToPlayer),
|
||||||
[](std::string& str)
|
[this](std::string& str)
|
||||||
{
|
{
|
||||||
return m_WeaponData.m_pData->Get(str.c_str(), "Unknown");
|
return m_WeaponData.m_pData->Get(str.c_str(), "Unknown");
|
||||||
},
|
},
|
||||||
[](std::string& str)
|
[](std::string& str)
|
||||||
{
|
{
|
||||||
return str != "0"; /*Unarmed*/
|
return str != "0"; /*Unarmed*/
|
||||||
}, AddNew);
|
}, fArgNoneWrapper(weaponPage.AddNew));
|
||||||
#else
|
#else
|
||||||
Widget::DataList(m_WeaponData, GiveWeaponToPlayer, AddWeapon);
|
Widget::DataList(m_WeaponData, fArg3Wrapper(weaponPage.GiveWeaponToPlayer), fArgNoneWrapper(weaponPage.AddNew));
|
||||||
#endif
|
#endif
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
@ -399,15 +401,15 @@ void WeaponPage::Draw()
|
|||||||
"Ballas\0Grove street families\0Los santos vagos\0San fierro rifa\0Da nang boys\0"
|
"Ballas\0Grove street families\0Los santos vagos\0San fierro rifa\0Da nang boys\0"
|
||||||
"Mafia\0Mountain cloud triad\0Varrio los aztecas\0Gang9\0Gang10\0"
|
"Mafia\0Mountain cloud triad\0Varrio los aztecas\0Gang9\0Gang10\0"
|
||||||
};
|
};
|
||||||
ImGui::Combo(TEXT("Weapon.SelectGang"), &m_nSelectedGang, gangList);
|
ImGui::Combo(TEXT("Weapon.SelectGang"), &m_Gang.m_nSelected, gangList);
|
||||||
ImGui::Combo(TEXT("Ped.SelectWeapon"), &m_nSelectedWeapon, "Weapon 1\0Weapon 2\0Weapon 3\0");
|
ImGui::Combo(TEXT("Ped.SelectWeapon"), &m_Gang.m_nSelectedWeapon, "Weapon 1\0Weapon 2\0Weapon 3\0");
|
||||||
ImGui::Spacing();
|
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::Text(TEXT("Weapon.CurrentWeapon"), m_WeaponData.m_pData->Get(key.c_str(), "Unknown").c_str());
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
Widget::ImageList(m_WeaponData, SetGangWeapon,
|
Widget::ImageList(m_WeaponData, fArgWrapper(weaponPage.m_Gang.SetWeapon),
|
||||||
[](std::string& str){
|
[this](std::string& str){
|
||||||
return m_WeaponData.m_pData->Get(str.c_str(), "Unknown");
|
return m_WeaponData.m_pData->Get(str.c_str(), "Unknown");
|
||||||
},
|
},
|
||||||
[](std::string& str){
|
[](std::string& str){
|
||||||
|
@ -1,59 +1,65 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
|
#include "interface/ipage.h"
|
||||||
|
|
||||||
class WeaponPage
|
class WeaponPage : public IPage<WeaponPage>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static inline bool m_bFastReload;
|
bool m_bFastReload;
|
||||||
static inline bool m_bHugeDamage;
|
bool m_bHugeDamage;
|
||||||
static inline bool m_bLongRange;
|
bool m_bLongRange;
|
||||||
static inline int m_nAmmoCount = 99999;
|
int m_nAmmoCount = 99999;
|
||||||
static inline int m_nSelectedWeapon;
|
|
||||||
|
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
static inline bool m_bAutoAim;
|
bool m_bAutoAim;
|
||||||
static inline bool m_bRapidFire;
|
bool m_bRapidFire;
|
||||||
static inline bool m_bDualWeild;
|
bool m_bDualWeild;
|
||||||
static inline bool m_bMoveAim;
|
bool m_bMoveAim;
|
||||||
static inline bool m_bMoveFire;
|
bool m_bMoveFire;
|
||||||
static inline bool m_bNoSpread;
|
bool m_bNoSpread;
|
||||||
static inline int m_nSelectedGang;
|
struct GangStruct
|
||||||
static inline int m_nGangWeaponList[10][3] =
|
|
||||||
{
|
{
|
||||||
{WEAPON_PISTOL, WEAPON_MICRO_UZI, WEAPON_UNARMED}, // Ballas
|
int m_nSelected;
|
||||||
{WEAPON_PISTOL, WEAPON_UNARMED, WEAPON_UNARMED}, // Grove
|
int m_nSelectedWeapon;
|
||||||
{WEAPON_PISTOL, WEAPON_UNARMED, WEAPON_UNARMED}, // Vagos
|
int m_WeaponList[10][3] =
|
||||||
{WEAPON_UNARMED, WEAPON_UNARMED, WEAPON_UNARMED}, // SF Rifa
|
{
|
||||||
{WEAPON_PISTOL, WEAPON_MICRO_UZI, WEAPON_UNARMED}, // Da Nang Boys
|
{WEAPON_PISTOL, WEAPON_MICRO_UZI, WEAPON_UNARMED}, // Ballas
|
||||||
{WEAPON_DESERT_EAGLE, WEAPON_UNARMED, WEAPON_UNARMED}, // Mafia
|
{WEAPON_PISTOL, WEAPON_UNARMED, WEAPON_UNARMED}, // Grove
|
||||||
{WEAPON_PISTOL, WEAPON_AK47, WEAPON_UNARMED}, // Triads
|
{WEAPON_PISTOL, WEAPON_UNARMED, WEAPON_UNARMED}, // Vagos
|
||||||
{WEAPON_PISTOL, WEAPON_MICRO_UZI, WEAPON_UNARMED}, // VLA
|
{WEAPON_UNARMED, WEAPON_UNARMED, WEAPON_UNARMED}, // SF Rifa
|
||||||
{WEAPON_UNARMED, WEAPON_UNARMED, WEAPON_UNARMED}, // Gang 9
|
{WEAPON_PISTOL, WEAPON_MICRO_UZI, WEAPON_UNARMED}, // Da Nang Boys
|
||||||
{WEAPON_UNARMED, WEAPON_UNARMED, WEAPON_UNARMED}, // Gang 10
|
{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
|
#else
|
||||||
static inline bool m_bInfiniteAmmo;
|
bool m_bInfiniteAmmo;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
friend class IFeature;
|
||||||
|
WeaponPage();
|
||||||
|
WeaponPage(const WeaponPage&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WeaponPage() = delete;
|
ResourceStore m_WeaponData { "weapons", BY_GAME(eResourceType::TYPE_IMAGE_TEXT, eResourceType::TYPE_TEXT,
|
||||||
WeaponPage(const WeaponPage&) = delete;
|
eResourceType::TYPE_TEXT), ImVec2(65, 65) };
|
||||||
|
|
||||||
static void Init();
|
// Add new weapon entry
|
||||||
|
void AddNew();
|
||||||
static void Draw();
|
void Draw();
|
||||||
|
|
||||||
static void AddNew();
|
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
static inline ResourceStore m_WeaponData { "weapons", eResourceType::TYPE_IMAGE_TEXT, ImVec2(65, 65) };
|
void GiveWeaponToPlayer(std::string& weaponType);
|
||||||
|
|
||||||
static void GiveWeaponToPlayer(std::string& weapon_type);
|
|
||||||
static void SetGangWeapon(std::string& weapon_type);
|
|
||||||
#else
|
#else
|
||||||
static inline ResourceStore m_WeaponData { "weapons", eResourceType::TYPE_TEXT };
|
void GiveWeaponToPlayer(std::string& rootkey, std::string& model, std::string& name);
|
||||||
|
|
||||||
static void GiveWeaponToPlayer(std::string& rootkey, std::string& model, std::string& name);
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern WeaponPage& weaponPage;
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
class WelcomePage : public IPage<WelcomePage>
|
class WelcomePage : public IPage<WelcomePage>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
friend IPage;
|
friend class IFeature;
|
||||||
WelcomePage() : IPage<WelcomePage>(ePageID::Welcome, "Welcome", false)
|
WelcomePage() : IPage<WelcomePage>(ePageID::Welcome, "Welcome", false)
|
||||||
{
|
{
|
||||||
PageHandler::SetCurrentPage(this);
|
PageHandler::SetCurrentPage(this);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
eRenderer gRenderer = Render_Unknown;
|
eRenderer gRenderer = eRenderer::Unknown;
|
||||||
DataStore gConfig = DataStore(FILE_NAME, true);
|
DataStore gConfig = DataStore(FILE_NAME, true);
|
||||||
|
|
||||||
ResourceStore gTextureList { "misc", eResourceType::TYPE_IMAGE, ImVec2(100, 80) };
|
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 <d3d11Shader.h>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@ -67,25 +68,26 @@
|
|||||||
|
|
||||||
using namespace plugin;
|
using namespace plugin;
|
||||||
|
|
||||||
enum eRenderer
|
enum class eRenderer
|
||||||
{
|
{
|
||||||
Render_DirectX9,
|
DirectX9,
|
||||||
Render_DirectX11,
|
DirectX11,
|
||||||
Render_Unknown
|
Unknown
|
||||||
};
|
};
|
||||||
|
|
||||||
extern eRenderer gRenderer;
|
extern eRenderer gRenderer;
|
||||||
extern DataStore gConfig;
|
extern DataStore gConfig;
|
||||||
|
|
||||||
typedef std::string str;
|
using str = std::string;
|
||||||
typedef void(*fArg3_t)(str&, str&, str&);
|
using fArgNone_t = std::function<void()>;
|
||||||
typedef void(*fArg1_t)(str&);
|
using fArg1_t = std::function<void(str&)>;
|
||||||
typedef void(*fArgNone_t)();
|
using fArg3_t = std::function<void(str&, str&, str&)>;
|
||||||
typedef std::string(*fRtnArg1_t)(str&);
|
using fRtnArg1_t = std::function<std::string(str&)>;
|
||||||
typedef bool(*fRtnBoolArg1_t)(str&);
|
using fRtnBoolArg1_t = std::function<bool(str&)>;
|
||||||
|
|
||||||
#define fArg3Wrapper(x) [](str& a, str& b, str& c){x(a, b, c);}
|
#define fArg3Wrapper(x) [](str& a, str& b, str& c){x(a, b, c);}
|
||||||
#define fArgWrapper(x) [](str& a){x(a);}
|
#define fArgWrapper(x) [](str& a){x(a);}
|
||||||
|
#define fRtnArgWrapper(x) [](str& a){return x(a);}
|
||||||
#define fArgNoneWrapper(x) [](){x();}
|
#define fArgNoneWrapper(x) [](){x();}
|
||||||
|
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
|
@ -62,7 +62,7 @@ void D3dHook::ProcessFrame(void* ptr)
|
|||||||
{
|
{
|
||||||
FontMgr::ReloadAll();
|
FontMgr::ReloadAll();
|
||||||
|
|
||||||
if (gRenderer == Render_DirectX9)
|
if (gRenderer == eRenderer::DirectX9)
|
||||||
{
|
{
|
||||||
ImGui_ImplDX9_InvalidateDeviceObjects();
|
ImGui_ImplDX9_InvalidateDeviceObjects();
|
||||||
}
|
}
|
||||||
@ -85,7 +85,7 @@ void D3dHook::ProcessFrame(void* ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ImGui_ImplWin32_NewFrame();
|
ImGui_ImplWin32_NewFrame();
|
||||||
if (gRenderer == Render_DirectX9)
|
if (gRenderer == eRenderer::DirectX9)
|
||||||
{
|
{
|
||||||
ImGui_ImplDX9_NewFrame();
|
ImGui_ImplDX9_NewFrame();
|
||||||
}
|
}
|
||||||
@ -104,7 +104,7 @@ void D3dHook::ProcessFrame(void* ptr)
|
|||||||
ImGui::EndFrame();
|
ImGui::EndFrame();
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
|
|
||||||
if (gRenderer == Render_DirectX9)
|
if (gRenderer == eRenderer::DirectX9)
|
||||||
{
|
{
|
||||||
ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
|
ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
|
||||||
}
|
}
|
||||||
@ -116,7 +116,7 @@ void D3dHook::ProcessFrame(void* ptr)
|
|||||||
if (FontMgr::IsFontReloadRequired())
|
if (FontMgr::IsFontReloadRequired())
|
||||||
{
|
{
|
||||||
FontMgr::ReloadAll();
|
FontMgr::ReloadAll();
|
||||||
if (gRenderer == Render_DirectX9)
|
if (gRenderer == eRenderer::DirectX9)
|
||||||
{
|
{
|
||||||
ImGui_ImplDX9_InvalidateDeviceObjects();
|
ImGui_ImplDX9_InvalidateDeviceObjects();
|
||||||
}
|
}
|
||||||
@ -135,7 +135,7 @@ void D3dHook::ProcessFrame(void* ptr)
|
|||||||
patch::Nop(0x00531155, 5); // shift trigger fix
|
patch::Nop(0x00531155, 5); // shift trigger fix
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (gRenderer == Render_DirectX9)
|
if (gRenderer == eRenderer::DirectX9)
|
||||||
{
|
{
|
||||||
ImGui_ImplDX9_Init(reinterpret_cast<IDirect3DDevice9*>(ptr));
|
ImGui_ImplDX9_Init(reinterpret_cast<IDirect3DDevice9*>(ptr));
|
||||||
}
|
}
|
||||||
@ -270,7 +270,7 @@ bool D3dHook::Init(void *pCallback)
|
|||||||
*/
|
*/
|
||||||
if (init(kiero::RenderType::D3D9) == kiero::Status::Success)
|
if (init(kiero::RenderType::D3D9) == kiero::Status::Success)
|
||||||
{
|
{
|
||||||
gRenderer = Render_DirectX9;
|
gRenderer = eRenderer::DirectX9;
|
||||||
kiero::bind(16, (void**)&oReset, hkReset);
|
kiero::bind(16, (void**)&oReset, hkReset);
|
||||||
kiero::bind(42, (void**)&oEndScene, hkEndScene);
|
kiero::bind(42, (void**)&oEndScene, hkEndScene);
|
||||||
pCallbackFunc = pCallback;
|
pCallbackFunc = pCallback;
|
||||||
@ -281,7 +281,7 @@ bool D3dHook::Init(void *pCallback)
|
|||||||
|
|
||||||
if (init(kiero::RenderType::D3D11) == kiero::Status::Success)
|
if (init(kiero::RenderType::D3D11) == kiero::Status::Success)
|
||||||
{
|
{
|
||||||
gRenderer = Render_DirectX11;
|
gRenderer = eRenderer::DirectX11;
|
||||||
kiero::bind(8, (void**)&oPresent, hkPresent);
|
kiero::bind(8, (void**)&oPresent, hkPresent);
|
||||||
pCallbackFunc = pCallback;
|
pCallbackFunc = pCallback;
|
||||||
hookInjected = true;
|
hookInjected = true;
|
||||||
|
@ -102,7 +102,7 @@ void Overlay::ProcessModelInfo()
|
|||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
if (pEnt->m_nType == ENTITY_TYPE_VEHICLE)
|
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)
|
else if (pEnt->m_nType == ENTITY_TYPE_PED)
|
||||||
{
|
{
|
||||||
@ -326,7 +326,7 @@ void Overlay::ProcessCommands(std::string&& str)
|
|||||||
if (wep_name == "jetpack")
|
if (wep_name == "jetpack")
|
||||||
{
|
{
|
||||||
std::string weapon = "-1";
|
std::string weapon = "-1";
|
||||||
WeaponPage::GiveWeaponToPlayer(weapon);
|
weaponPage.GiveWeaponToPlayer(weapon);
|
||||||
Util::SetMessage(TEXT("Menu.WeaponSpawned"));
|
Util::SetMessage(TEXT("Menu.WeaponSpawned"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -337,7 +337,7 @@ void Overlay::ProcessCommands(std::string&& str)
|
|||||||
|
|
||||||
if (wep_name != "" && pweaponinfo->m_nModelId1 != -1)
|
if (wep_name != "" && pweaponinfo->m_nModelId1 != -1)
|
||||||
{
|
{
|
||||||
WeaponPage::GiveWeaponToPlayer(weapon_name);
|
weaponPage.GiveWeaponToPlayer(weapon_name);
|
||||||
Util::SetMessage(TEXT("Menu.WeaponSpawned"));
|
Util::SetMessage(TEXT("Menu.WeaponSpawned"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -351,11 +351,11 @@ void Overlay::ProcessCommands(std::string&& str)
|
|||||||
std::string veh_name;
|
std::string veh_name;
|
||||||
ss >> veh_name;
|
ss >> veh_name;
|
||||||
|
|
||||||
int model = Vehicle::GetModelFromName(veh_name.c_str());
|
int model = Util::GetCarModel(veh_name.c_str());
|
||||||
if (model != 0)
|
if (model != 0)
|
||||||
{
|
{
|
||||||
std::string smodel = std::to_string(model);
|
std::string smodel = std::to_string(model);
|
||||||
Vehicle::SpawnVehicle(smodel);
|
vehiclePage.SpawnVehicle(smodel);
|
||||||
Util::SetMessage(TEXT("Menu.VehicleSpawned"));
|
Util::SetMessage(TEXT("Menu.VehicleSpawned"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -121,7 +121,7 @@ void RPC::DrawPages()
|
|||||||
|
|
||||||
if (BY_GAME(pPed->m_nPedFlags.bInVehicle, pPed->m_bInVehicle, pPed->m_bInVehicle))
|
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);
|
std::transform(name.begin(), name.end(), name.begin(), asciitolower);
|
||||||
smallImgText = std::format("{} {} {} {}", TEXT("RPC.Driving"), name, TEXT("RPC.In"), Util::GetLocationName(&pPed->GetPosition()));
|
smallImgText = std::format("{} {} {} {}", TEXT("RPC.Driving"), name, TEXT("RPC.In"), Util::GetLocationName(&pPed->GetPosition()));
|
||||||
smallImg = "drive";
|
smallImg = "drive";
|
||||||
|
@ -37,6 +37,30 @@ ImVec2 Util::ConvertMapToScreen(ImVec2 pos, ImVec2 mapSz, ImVec2 screenSz)
|
|||||||
return pos;
|
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)
|
void Util::SetMessage(const char *message, bool b1, bool b2, bool b3)
|
||||||
{
|
{
|
||||||
#if GTASA
|
#if GTASA
|
||||||
@ -57,7 +81,7 @@ float Util::RoundFloat(float val)
|
|||||||
return roundf(val * 100) / 100;
|
return roundf(val * 100) / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Util::IsInVehicle(CPed *pPed)
|
bool Util::IsInCar(CPed *pPed)
|
||||||
{
|
{
|
||||||
if (!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);
|
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
|
#ifdef GTASA
|
||||||
pVeh->Fix();
|
pVeh->Fix();
|
||||||
@ -91,7 +115,7 @@ void Util::FixVehicle(CVehicle *pVeh)
|
|||||||
pVeh->m_fHealth = 1000.0f;
|
pVeh->m_fHealth = 1000.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Util::UnFlipVehicle(CVehicle *pVeh)
|
void Util::UnFlipCar(CVehicle *pVeh)
|
||||||
{
|
{
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
int hveh = CPools::GetVehicleRef(pVeh);
|
int hveh = CPools::GetVehicleRef(pVeh);
|
||||||
@ -170,14 +194,14 @@ std::string Util::GetLocationName(CVector* pos)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
void Util::ClearCharTasksVehCheck(CPed* pPed)
|
void Util::ClearCharTasksCarCheck(CPed* pPed)
|
||||||
{
|
{
|
||||||
uint hped = CPools::GetPedRef(pPed);
|
uint hped = CPools::GetPedRef(pPed);
|
||||||
uint hveh = NULL;
|
uint hveh = NULL;
|
||||||
bool veh_engine = true;
|
bool veh_engine = true;
|
||||||
float speed;
|
float speed;
|
||||||
|
|
||||||
if (IsInVehicle(pPed))
|
if (IsInCar(pPed))
|
||||||
{
|
{
|
||||||
hveh = CPools::GetVehicleRef(pPed->m_pVehicle);
|
hveh = CPools::GetVehicleRef(pPed->m_pVehicle);
|
||||||
veh_engine = pPed->m_pVehicle->m_nVehicleFlags.bEngineOn;
|
veh_engine = pPed->m_pVehicle->m_nVehicleFlags.bEngineOn;
|
||||||
@ -223,7 +247,7 @@ int Util::GetLargestGangInZone()
|
|||||||
|
|
||||||
// implemention of opcode 0AB5 (STORE_CLOSEST_ENTITIES)
|
// implemention of opcode 0AB5 (STORE_CLOSEST_ENTITIES)
|
||||||
// https://github.com/cleolibrary/CLEO4/blob/916d400f4a731ba1dd0ff16e52bdb056f42b7038/source/CCustomOpcodeSystem.cpp#L1671
|
// https://github.com/cleolibrary/CLEO4/blob/916d400f4a731ba1dd0ff16e52bdb056f42b7038/source/CCustomOpcodeSystem.cpp#L1671
|
||||||
CVehicle* Util::GetClosestVehicle()
|
CVehicle* Util::GetClosestCar()
|
||||||
{
|
{
|
||||||
CPlayerPed* player = FindPlayerPed();
|
CPlayerPed* player = FindPlayerPed();
|
||||||
|
|
||||||
|
@ -19,24 +19,29 @@ public:
|
|||||||
Util(Util&) = delete;
|
Util(Util&) = delete;
|
||||||
|
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
|
static void ClearCharTasksCarCheck(CPed* ped);
|
||||||
static int GetLargestGangInZone();
|
static int GetLargestGangInZone();
|
||||||
static void ClearCharTasksVehCheck(CPed* ped);
|
|
||||||
static bool IsOnMission();
|
static bool IsOnMission();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static ImVec2 ConvertScreenToMap(ImVec2 pos, ImVec2 mapSz, ImVec2 screenSz);
|
static ImVec2 ConvertScreenToMap(ImVec2 pos, ImVec2 mapSz, ImVec2 screenSz);
|
||||||
static ImVec2 ConvertMapToScreen(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 void FixCar(CVehicle *pVeh);
|
||||||
static CPed* GetClosestPed();
|
static void SetCarForwardSpeed(CVehicle *pVeh, float speed);
|
||||||
static CVehicle* GetClosestVehicle();
|
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 void GetCPUUsageInit();
|
||||||
static double GetCurrentCPUUsage();
|
static double GetCurrentCPUUsage();
|
||||||
|
static float RoundFloat(float val);
|
||||||
|
|
||||||
|
static CPed* GetClosestPed();
|
||||||
static std::string GetLocationName(CVector* pos);
|
static std::string GetLocationName(CVector* pos);
|
||||||
static bool IsOnCutscene();
|
static bool IsOnCutscene();
|
||||||
static bool IsInVehicle(CPed *pPed = FindPlayerPed());
|
|
||||||
static void RainbowValues(int& r, int& g, int& b, float speed);
|
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 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;
|
m_ImageSize.x /= imagesInRow;
|
||||||
|
|
||||||
bool showImages = !menuPage.m_bTextOnlyMode;
|
bool showImages = !menuPage.m_bTextOnlyMode;
|
||||||
if (gRenderer == Render_DirectX11)
|
if (gRenderer == eRenderer::DirectX11)
|
||||||
{
|
{
|
||||||
showImages = false;
|
showImages = false;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user