Replace Ui -> Widget class

This commit is contained in:
Grinch_ 2022-07-01 14:06:34 +06:00
parent 495a0d1207
commit c249437dcc
16 changed files with 982 additions and 1082 deletions

View File

@ -1,6 +1,5 @@
#include "pch.h"
#include "animation.h"
#include "ui.h"
#include "widget.h"
#include "util.h"
@ -310,11 +309,11 @@ void Animation::ShowPage()
ImGui::Spacing();
ImGui::Columns(2, nullptr, false);
Ui::CheckboxWithHint(TEXT("Animation.LoopCheckbox"), &m_Loop, TEXT("Animation.LoopCheckboxText"));
Ui::CheckboxWithHint(TEXT("Animation.SecondaryCheckbox"), &m_bSecondary, TEXT("Animation.SecondaryCheckboxText"));
Widget::Checkbox(TEXT("Animation.LoopCheckbox"), &m_Loop, TEXT("Animation.LoopCheckboxText"));
Widget::Checkbox(TEXT("Animation.SecondaryCheckbox"), &m_bSecondary, TEXT("Animation.SecondaryCheckboxText"));
ImGui::NextColumn();
#ifdef GTASA
Ui::CheckboxWithHint(TEXT("Animation.PedAnim"), &m_PedAnim, TEXT("Animation.PedAnimText"));
Widget::Checkbox(TEXT("Animation.PedAnim"), &m_PedAnim, TEXT("Animation.PedAnimText"));
#endif
ImGui::Columns(1);
ImGui::Spacing();
@ -397,7 +396,7 @@ void Animation::ShowPage()
Particle::m_nParticleList.pop_back();
}
ImGui::Spacing();
if (Ui::CheckboxBitFlag(TEXT("Animation.InvisiblePlayer"), pPlayer->m_nPedFlags.bDontRender))
if (Widget::CheckboxBits(TEXT("Animation.InvisiblePlayer"), pPlayer->m_nPedFlags.bDontRender))
{
pPlayer->m_nPedFlags.bDontRender = (pPlayer->m_nPedFlags.bDontRender == 1) ? 0 : 1;
}
@ -442,7 +441,7 @@ void Animation::ShowPage()
Command<Commands::GIVE_MELEE_ATTACK_TO_CHAR>(hPlayer, fightStyle + 4, 6);
SetHelpMessage(TEXT("Animation.FightingStyleSet"));
}
if (Ui::ListBoxStr(TEXT("Animation.WalkingStyle"), walkStyles, walkStyle))
if (Widget::ListBox(TEXT("Animation.WalkingStyle"), walkStyles, walkStyle))
{
if (walkStyle == "default")
{

View File

@ -1,5 +1,4 @@
#include "pch.h"
#include "ui.h"
#include "widget.h"
#include "updater.h"
#include "d3dhook.h"
@ -17,6 +16,49 @@
#include "visual.h"
#include "weapon.h"
static bool DrawTitleBar()
{
bool hovered, held;
ImGuiWindow *window = ImGui::GetCurrentWindow();
ImGuiStyle& Style = ImGui::GetStyle();
ImGuiID id = window->GetID("#CLOSE");
ImGui::PushFont(FontMgr::Get("title"));
Widget::TextCentered(MENU_TITLE);
// Return now, skip drawing close btn
if (!ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows
| ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem))
{
ImGui::PopFont();
return false;
}
// init draw stuff
ImVec2 rectMin = ImGui::GetItemRectMin();
float fontSize = ImGui::GetFontSize();
ImRect titleRect = window->TitleBarRect();
float framePadding = Style.FramePadding.x;
ImVec2 pos = ImVec2(titleRect.Max.x - framePadding*2 - fontSize, titleRect.Min.y);
const ImRect bb(pos, pos + ImVec2(fontSize, fontSize) + Style.FramePadding * 2.0f);
ImRect bbInteract = bb;
const float areaVisibleRatio = window->OuterRectClipped.GetArea() / bb.GetArea();
if (areaVisibleRatio < 1.5f)
{
bbInteract.Expand(ImFloor(bbInteract.GetSize() * -0.25f));
}
bool pressed = ImGui::ButtonBehavior(bbInteract, id, &hovered, &held);
// drawing close button here
float cross_extent = (fontSize * 0.3f) - 1.0f;
ImVec2 closePos = ImVec2(bb.GetCenter().x - cross_extent, rectMin.y);
ImU32 closeCol = ImGui::GetColorU32(held || hovered ? ImVec4(0.80f, 0.0f, 0.0f, 1.0f) : ImVec4(0.80f, 0.80f, 0.80f, 1.00f));
window->DrawList->AddText(closePos, closeCol, "X");
ImGui::PopFont();
return pressed;
}
void CheatMenu::DrawWindow()
{
ImGuiIO& io = ImGui::GetIO();
@ -42,7 +84,7 @@ void CheatMenu::DrawWindow()
if (ImGui::Begin(MENU_TITLE, NULL, ImGuiWindowFlags_NoCollapse || ImGuiWindowFlags_NoTitleBar))
{
m_bShowMenu = !Ui::DrawTitleBar();
m_bShowMenu = !DrawTitleBar();
ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(250, 350));
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,
ImVec2(ImGui::GetWindowWidth() / 85, ImGui::GetWindowHeight() / 200));

View File

@ -1,7 +1,6 @@
#include "pch.h"
#include "menu.h"
#include "game.h"
#include "ui.h"
#include "widget.h"
#include "util.h"
#ifdef GTASA
@ -468,20 +467,20 @@ void Game::ShowPage()
}
}
Ui::CheckboxAddress(TEXT("Game.FasterClock"), BY_GAME(0x96913B, 0xA10B87, 0x95CDBB));
Widget::CheckboxAddr(TEXT("Game.FasterClock"), BY_GAME(0x96913B, 0xA10B87, 0x95CDBB));
#ifdef GTASA
if (Ui::CheckboxWithHint(TEXT("Game.ForbiddenWantedLevel"), &m_bForbiddenArea, TEXT("Game.ForbiddenWantedLevelText")))
if (Widget::Checkbox(TEXT("Game.ForbiddenWantedLevel"), &m_bForbiddenArea, TEXT("Game.ForbiddenWantedLevelText")))
{
patch::Set<BYTE>(0x441770, m_bForbiddenArea ? 0x83 : 0xC3, false);
}
Ui::CheckboxAddress(TEXT("Game.FreePNS"), 0x96C009);
Widget::CheckboxAddr(TEXT("Game.FreePNS"), 0x96C009);
#endif
#ifdef GTAVC
ImGui::NextColumn();
#endif
#ifdef GTASA
Ui::CheckboxAddress(TEXT("Game.FreezeGame"), 0xA10B48);
Widget::CheckboxAddr(TEXT("Game.FreezeGame"), 0xA10B48);
#endif
if (ImGui::Checkbox(TEXT("Game.FreezeGameTime"), &m_bFreezeTime))
{
@ -502,7 +501,7 @@ void Game::ShowPage()
{
Command<Commands::FREEZE_ONSCREEN_TIMER>(m_bMissionTimer);
}
if (Ui::CheckboxWithHint(TEXT("Game.HardMode"), &HardMode::m_bEnabled, TEXT("Game.HardModeText")))
if (Widget::Checkbox(TEXT("Game.HardMode"), &HardMode::m_bEnabled, TEXT("Game.HardModeText")))
{
CPlayerPed* player = FindPlayerPed();
@ -531,7 +530,7 @@ void Game::ShowPage()
}
}
#ifdef GTASA
if (Ui::CheckboxWithHint(TEXT("Game.NoWaterPhysics"), &m_bNoWaterPhysics))
if (Widget::Checkbox(TEXT("Game.NoWaterPhysics"), &m_bNoWaterPhysics))
{
if (m_bNoWaterPhysics)
{
@ -542,15 +541,15 @@ void Game::ShowPage()
patch::Set<uint8_t>(0x6C2759, 0, true);
}
}
if (Ui::CheckboxWithHint(TEXT("Game.KeepStuff"), &m_bKeepStuff, TEXT("Game.KeepStuffText")))
if (Widget::Checkbox(TEXT("Game.KeepStuff"), &m_bKeepStuff, TEXT("Game.KeepStuffText")))
{
Command<Commands::SWITCH_ARREST_PENALTIES>(m_bKeepStuff);
Command<Commands::SWITCH_DEATH_PENALTIES>(m_bKeepStuff);
}
Ui::CheckboxWithHint(TEXT("Game.Screenshot"), &m_bScreenShot,
Widget::Checkbox(TEXT("Game.Screenshot"), &m_bScreenShot,
std::format("{} {}", TEXT("Game.ScreenshotTip"),
quickSceenShot.GetNameString()).c_str());
Ui::CheckboxWithHint(TEXT("Game.SolidWater"), &m_bSolidWater, TEXT("Game.SolidWaterText"));
Widget::Checkbox(TEXT("Game.SolidWater"), &m_bSolidWater, TEXT("Game.SolidWaterText"));
#endif
if (ImGui::Checkbox(TEXT("Game.SyncSystemTime"), &m_bSyncTime))
{
@ -580,14 +579,14 @@ void Game::ShowPage()
ImGui::Spacing();
ImGui::Separator();
}
}//0xC17040
#endif
Ui::EditAddress<int>(TEXT("Game.DaysPassed"), BY_GAME(0xB79038, 0x97F1F4, 0x8F2BB8), 0, 9999);
Ui::EditReference(TEXT("Game.FPSLimit"), RsGlobal.maxFPS, 1, 30, 60);
Widget::EditAddr<int>(TEXT("Game.DaysPassed"), BY_GAME(0xB79038, 0x97F1F4, 0x8F2BB8), 0, 9999);
Widget::EditAddr<int>(TEXT("Game.FPSLimit"), (uint)&(RsGlobal.maxFPS), 1, 30, 999);
#ifdef GTASA
if (ImGui::CollapsingHeader(TEXT("Game.Freecam")))
{
if (Ui::CheckboxWithHint(TEXT("Game.Enable"), &Freecam::m_bEnabled, TEXT("Game.EnableText")))
if (Widget::Checkbox(TEXT("Game.Enable"), &Freecam::m_bEnabled, TEXT("Game.EnableText")))
{
if (!Freecam::m_bEnabled)
{
@ -604,14 +603,15 @@ void Game::ShowPage()
ImGui::Separator();
}
#endif
Ui::EditReference(TEXT("Game.GameSpeed"), CTimer::ms_fTimeScale, 1, 1, 10);
Ui::EditFloat(TEXT("Game.Gravity"), BY_GAME(0x863984, 0x68F5F0, 0x5F68D4), -1.0f, 0.008f, 1.0f, 1.0f, 0.01f);
Widget::EditAddr<float>(TEXT("Game.GameSpeed"), reinterpret_cast<uint>(&CTimer::ms_fTimeScale), 1, 1, 10);
Widget::EditAddr(TEXT("Game.Gravity"), BY_GAME(0x863984, 0x68F5F0, 0x5F68D4), -1.0f, 0.008f, 1.0f, 1.0f, 0.01f);
if (ImGui::CollapsingHeader(TEXT("Game.SetTime")))
{
int hour = CClock::ms_nGameClockHours;
int minute = CClock::ms_nGameClockMinutes;
ImGui::PushItemWidth(ImGui::GetWindowContentRegionWidth()/2);
if (ImGui::InputInt(TEXT("Game.Hour"), &hour))
{
if (hour < 0) hour = 23;
@ -625,30 +625,25 @@ void Game::ShowPage()
if (minute > 59) minute = 0;
CClock::ms_nGameClockMinutes = minute;
}
ImGui::Spacing();
ImGui::Separator();
}
#ifdef GTASA
static std::vector<Ui::NamedMemory> themes
{
{TEXT("Game.Beach"), 0x969159}, {TEXT("Game.Country"), 0x96917D}, {TEXT("Game.FunHouse"), 0x969176}, {TEXT("Game.Ninja"), 0x96915C}
};
Ui::EditRadioButtonAddress(TEXT("Game.Themes"), themes);
if (ImGui::CollapsingHeader(TEXT("Game.TotalMinutesDay")))
{
static int min = 24;
if (ImGui::InputInt(TEXT("Game.Minute"), &min))
if (ImGui::InputInt(TEXT("Game.TotalMinutesDay"), &min))
{
int val = min * 41.666666667f;
patch::Set<uint32_t>(0x5BA35F, val, true);
patch::Set<uint32_t>(0x53BDEC, val, true);
}
#endif
ImGui::PopItemWidth();
ImGui::Spacing();
ImGui::Separator();
}
#ifdef GTASA
static std::vector<Widget::BindInfo> themes
{
{TEXT("Game.Beach"), 0x969159}, {TEXT("Game.Country"), 0x96917D}, {TEXT("Game.FunHouse"), 0x969176}, {TEXT("Game.Ninja"), 0x96915C}
};
Widget::EditRadioBtnAddr(TEXT("Game.Themes"), themes);
#endif
if (ImGui::CollapsingHeader(TEXT("Game.Weather")))
{
@ -805,9 +800,9 @@ void Game::ShowPage()
ImGui::Spacing();
ImGui::PushItemWidth((ImGui::GetWindowContentRegionWidth() - ImGui::GetStyle().ItemSpacing.x)/2);
Ui::ListBoxStr("##Categories", m_StatData.m_Categories, m_StatData.m_Selected);
Widget::ListBox("##Categories", m_StatData.m_Categories, m_StatData.m_Selected);
ImGui::SameLine();
Widget::FilterWithHint("##Filter", m_StatData.m_Filter, TEXT("Window.Search"));
Widget::Filter("##Filter", m_StatData.m_Filter, TEXT("Window.Search"));
ImGui::PopItemWidth();
ImGui::Spacing();
@ -821,7 +816,7 @@ void Game::ShowPage()
std::string name = v2.value_or<std::string>("Unknown");
if (m_StatData.m_Filter.PassFilter(name.c_str()))
{
Ui::EditStat(name.c_str(), std::stoi(std::string(k2.str())));
Widget::EditStat(name.c_str(), std::stoi(std::string(k2.str())));
}
}
}

View File

@ -1,6 +1,5 @@
#include "pch.h"
#include "menu.h"
#include "ui.h"
#include "widget.h"
#include "util.h"
#include "updater.h"
@ -337,7 +336,7 @@ void Menu::ShowPage()
if (vec.size() > 0)
{
if (Ui::ListBox(TEXT("Menu.Language"), vec, selected))
if (Widget::ListBox(TEXT("Menu.Language"), vec, selected))
{
if (Locale::SetLocale(selected) == Locale::eReturnCodes::SUCCESS)
{
@ -368,7 +367,7 @@ void Menu::ShowPage()
ImGui::NextColumn();
if (gRenderer == Render_DirectX9
&& Ui::CheckboxWithHint(TEXT("Menu.TextOnlyMode"), &m_bTextOnlyMode, TEXT("Menu.TextOnlyModeHint")))
&& Widget::Checkbox(TEXT("Menu.TextOnlyMode"), &m_bTextOnlyMode, TEXT("Menu.TextOnlyModeHint")))
{
gConfig.Set("Menu.TextOnlyMode", m_bTextOnlyMode);
}
@ -381,7 +380,7 @@ void Menu::ShowPage()
ImGui::Spacing();
ImGui::Spacing();
ImGui::SameLine();
if (Ui::ListBox(TEXT("Menu.Position"), Overlay::posNames, (int&)Overlay::mSelectedPos))
if (Widget::ListBox(TEXT("Menu.Position"), Overlay::posNames, (int&)Overlay::mSelectedPos))
{
gConfig.Set<int>("Overlay.SelectedPosition", static_cast<int>(Overlay::mSelectedPos));
}

View File

@ -1,6 +1,5 @@
#include "pch.h"
#include "ped.h"
#include "ui.h"
#include "widget.h"
#include "util.h"
#include "weapon.h"
@ -202,42 +201,42 @@ void Ped::ShowPage()
ImGui::BeginChild("CheckboxesChild");
ImGui::Columns(2, 0, false);
#ifndef GTAVC
Ui::CheckboxWithHint(TEXT("Ped.BigHead"), &m_bBigHead);
Widget::Checkbox(TEXT("Ped.BigHead"), &m_bBigHead);
#endif
#ifdef GTASA
Ui::CheckboxAddress(TEXT("Ped.ElvisEverywhere"), 0x969157);
Ui::CheckboxAddress(TEXT("Ped.EveryoneArmed"), 0x969140);
Ui::CheckboxAddress(TEXT("Ped.GangsControl"), 0x96915B);
Ui::CheckboxAddress(TEXT("Ped.GangsEverywhere"), 0x96915A);
Ui::CheckboxWithHint(TEXT("Ped.GangWars"), &CGangWars::bGangWarsActive);
Widget::CheckboxAddr(TEXT("Ped.ElvisEverywhere"), 0x969157);
Widget::CheckboxAddr(TEXT("Ped.EveryoneArmed"), 0x969140);
Widget::CheckboxAddr(TEXT("Ped.GangsControl"), 0x96915B);
Widget::CheckboxAddr(TEXT("Ped.GangsEverywhere"), 0x96915A);
Widget::Checkbox(TEXT("Ped.GangWars"), &CGangWars::bGangWarsActive);
ImGui::NextColumn();
Ui::CheckboxAddress(TEXT("Ped.PedsMayhem"), 0x96913E);
Ui::CheckboxAddress(TEXT("Ped.PedsAtkRocket"), 0x969158);
Ui::CheckboxAddress(TEXT("Ped.PedsRiot"), 0x969175);
Ui::CheckboxAddress(TEXT("Ped.SlutMagnet"), 0x96915D);
Ui::CheckboxWithHint(TEXT("Ped.ThinBody"), &m_bThinBody);
Widget::CheckboxAddr(TEXT("Ped.PedsMayhem"), 0x96913E);
Widget::CheckboxAddr(TEXT("Ped.PedsAtkRocket"), 0x969158);
Widget::CheckboxAddr(TEXT("Ped.PedsRiot"), 0x969175);
Widget::CheckboxAddr(TEXT("Ped.SlutMagnet"), 0x96915D);
Widget::Checkbox(TEXT("Ped.ThinBody"), &m_bThinBody);
#elif GTAVC
Ui::CheckboxAddress(TEXT("Ped.NoProstitutes"), 0xA10B99);
Ui::CheckboxAddress(TEXT("Ped.SlutMagnet"), 0xA10B5F);
Widget::CheckboxAddr(TEXT("Ped.NoProstitutes"), 0xA10B99);
Widget::CheckboxAddr(TEXT("Ped.SlutMagnet"), 0xA10B5F);
ImGui::NextColumn();
Ui::CheckboxAddress(TEXT("Ped.WeaponAll"), 0xA10AB3);
Widget::CheckboxAddr(TEXT("Ped.WeaponAll"), 0xA10AB3);
#else
// Bad idea lol
static bool pedsMayhem;
if (Ui::CheckboxWithHint(TEXT("Ped.PedsMayhem"), &pedsMayhem))
if (Widget::Checkbox(TEXT("Ped.PedsMayhem"), &pedsMayhem))
{
Call<0x4911C0>();
}
static bool everyoneAttacksPlayer;
if (Ui::CheckboxWithHint(TEXT("Ped.EveryoneAtk"), &everyoneAttacksPlayer))
if (Widget::Checkbox(TEXT("Ped.EveryoneAtk"), &everyoneAttacksPlayer))
{
Call<0x491270>();
}
ImGui::NextColumn();
Ui::CheckboxAddress(TEXT("Ped.NastyLimbs"), 0x95CD44);
Ui::CheckboxAddress(TEXT("Ped.WeaponAll"), 0x95CCF6);
Widget::CheckboxAddr(TEXT("Ped.NastyLimbs"), 0x95CD44);
Widget::CheckboxAddr(TEXT("Ped.WeaponAll"), 0x95CCF6);
#endif
ImGui::Columns(1);
ImGui::EndChild();
@ -248,15 +247,15 @@ void Ped::ShowPage()
{
ImGui::Spacing();
ImGui::BeginChild("MenusChild");
Ui::EditReference<float>(TEXT("Ped.PedDensityMul"), CPopulation::PedDensityMultiplier, 0, 1, 10);
Widget::EditAddr<float>(TEXT("Ped.PedDensityMul"), reinterpret_cast<uint>(&CPopulation::PedDensityMultiplier), 0, 1, 10);
#ifdef GTASA
if (ImGui::CollapsingHeader(TEXT("Ped.RecruitAnyone")))
{
static std::vector<Ui::NamedMemory> selectWeapon
static std::vector<Widget::BindInfo> selectWeapon
{
{"9mm", 0x96917C}, {"AK47", 0x96917D}, {"Rockets", 0x96917E}
};
Ui::RadioButtonAddress(TEXT("Ped.SelectWeapon"), selectWeapon);
Widget::EditRadioBtnAddr(TEXT("Ped.SelectWeapon"), selectWeapon);
ImGui::Spacing();
ImGui::Separator();
}
@ -321,9 +320,9 @@ void Ped::ShowPage()
ImGui::Spacing();
ImGui::BeginChild("PedCOnfig");
ImGui::Columns(2, 0, false);
Ui::CheckboxWithHint(TEXT("Ped.NoMove"), &Spawner::m_bPedMove);
Widget::Checkbox(TEXT("Ped.NoMove"), &Spawner::m_bPedMove);
ImGui::NextColumn();
Ui::CheckboxWithHint(TEXT("Ped.PedBleed"), &Spawner::m_bPedBleed);
Widget::Checkbox(TEXT("Ped.PedBleed"), &Spawner::m_bPedBleed);
ImGui::Columns(1);
ImGui::Spacing();

View File

@ -1,7 +1,6 @@
#include "pch.h"
#include "player.h"
#include "menu.h"
#include "ui.h"
#include "widget.h"
#include "util.h"
@ -411,25 +410,25 @@ void Player::ShowPage()
ImGui::Columns(2, 0, false);
#ifdef GTASA
Ui::CheckboxAddress(TEXT("Player.BountyYourself"), 0x96913F);
Widget::CheckboxAddr(TEXT("Player.BountyYourself"), 0x96913F);
ImGui::BeginDisabled(TopDownCamera::m_bEnabled);
if (Ui::CheckboxWithHint(TEXT("Player.DrunkEffect"), &m_bDrunkEffect))
if (Widget::Checkbox(TEXT("Player.DrunkEffect"), &m_bDrunkEffect))
{
if (!m_bDrunkEffect)
{
Command<eScriptCommands::COMMAND_SET_PLAYER_DRUNKENNESS> (0, 0);
}
}
if (Ui::CheckboxWithHint(TEXT("Player.FastSprint"), &m_bFastSprint, TEXT("Player.FastSprintTip")))
if (Widget::Checkbox(TEXT("Player.FastSprint"), &m_bFastSprint, TEXT("Player.FastSprintTip")))
{
patch::Set<float>(0x8D2458, m_bFastSprint ? 0.1f : 5.0f);
}
ImGui::EndDisabled();
#endif
Ui::CheckboxAddress(TEXT("Player.FreeHealthcare"), (int)&pInfo->m_bGetOutOfHospitalFree);
Widget::CheckboxAddr(TEXT("Player.FreeHealthcare"), (int)&pInfo->m_bGetOutOfHospitalFree);
if (Ui::CheckboxWithHint(TEXT("Player.FreezeWL"), &m_bFreezeWantedLevel))
if (Widget::Checkbox(TEXT("Player.FreezeWL"), &m_bFreezeWantedLevel))
{
static unsigned int chaosLvl;
if (m_bFreezeWantedLevel)
@ -452,7 +451,7 @@ void Player::ShowPage()
}
}
if (Ui::CheckboxWithHint(TEXT("Player.GodMode"), &m_bGodMode))
if (Widget::Checkbox(TEXT("Player.GodMode"), &m_bGodMode))
{
#ifdef GTASA
patch::Set<bool>(0x96916D, m_bGodMode, false);
@ -475,39 +474,39 @@ void Player::ShowPage()
pPlayer->m_nFlags.bMeleeProof = m_bGodMode;
#endif
}
Ui::CheckboxWithHint(TEXT("Player.HealthRegen"), &m_bHealthRegen, TEXT("Player.HealthRegenTip"));
Widget::Checkbox(TEXT("Player.HealthRegen"), &m_bHealthRegen, TEXT("Player.HealthRegenTip"));
#ifdef GTASA
Ui::CheckboxAddress(TEXT("Player.CycleJump"), 0x969161);
Ui::CheckboxAddress(TEXT("Player.InfO2"), 0x96916E);
if (Ui::CheckboxBitFlag(TEXT("Player.InvisPlayer"), pPlayer->m_nPedFlags.bDontRender))
Widget::CheckboxAddr(TEXT("Player.CycleJump"), 0x969161);
Widget::CheckboxAddr(TEXT("Player.InfO2"), 0x96916E);
if (Widget::CheckboxBits(TEXT("Player.InvisPlayer"), pPlayer->m_nPedFlags.bDontRender))
{
pPlayer->m_nPedFlags.bDontRender = !pPlayer->m_nPedFlags.bDontRender;
}
Ui::CheckboxAddress(TEXT("Player.InfSprint"), 0xB7CEE4);
Widget::CheckboxAddr(TEXT("Player.InfSprint"), 0xB7CEE4);
#else
Ui::CheckboxAddress(TEXT("Player.InfSprint"), (int)&pInfo->m_bInfiniteSprint);
Widget::CheckboxAddr(TEXT("Player.InfSprint"),Ui::CheckboxBits (int)&pInfo->m_bInfiniteSprint);
#endif
ImGui::NextColumn();
#ifdef GTASA
if (Ui::CheckboxBitFlag(TEXT("Player.LockControl"), pad->bPlayerSafe))
if (Widget::CheckboxBits(TEXT("Player.LockControl"), pad->bPlayerSafe))
{
pad->bPlayerSafe = !pad->bPlayerSafe;
}
Ui::CheckboxAddressEx(TEXT("Player.MaxAppeal"), 0x969180, 1, 0);
Ui::CheckboxAddress(TEXT("Player.MegaJump"), 0x96916C);
Ui::CheckboxAddress(TEXT("Player.MegaPunch"), 0x969173);
Ui::CheckboxAddress(TEXT("Player.NeverGetHungry"), 0x969174);
Widget::CheckboxAddrRaw(TEXT("Player.MaxAppeal"), 0x969180, 1, "\x01", "\x00");
Widget::CheckboxAddr(TEXT("Player.MegaJump"), 0x96916C);
Widget::CheckboxAddr(TEXT("Player.MegaPunch"), 0x969173);
Widget::CheckboxAddr(TEXT("Player.NeverGetHungry"), 0x969174);
bool never_wanted = patch::Get<bool>(0x969171, false);
if (Ui::CheckboxWithHint(TEXT("Player.NeverWanted"), &never_wanted))
if (Widget::Checkbox(TEXT("Player.NeverWanted"), &never_wanted))
{
CCheat::NotWantedCheat();
}
#else
static bool neverWanted = false;
if (Ui::CheckboxWithHint(TEXT("Player.NeverWanted"), &neverWanted))
if (Widget::Checkbox(TEXT("Player.NeverWanted"), &neverWanted))
{
if (neverWanted)
{
@ -535,12 +534,12 @@ void Player::ShowPage()
}
}
#endif
Ui::CheckboxAddress(TEXT("Player.NoFee"), (int)&pInfo->m_bGetOutOfJailFree);
Ui::CheckboxWithHint(TEXT("Player.RespawnDieLoc"), &KeepPosition::m_bEnabled, TEXT("Player.RespawnDieLocTip"));
Widget::CheckboxAddr(TEXT("Player.NoFee"), (int)&pInfo->m_bGetOutOfJailFree);
Widget::Checkbox(TEXT("Player.RespawnDieLoc"), &KeepPosition::m_bEnabled, TEXT("Player.RespawnDieLocTip"));
#ifdef GTASA
static bool sprintInt = false;
if (Ui::CheckboxWithHint(TEXT("Player.SprintEverywhere"), &sprintInt, TEXT("Player.SprintEverywhereTip")))
if (Widget::Checkbox(TEXT("Player.SprintEverywhere"), &sprintInt, TEXT("Player.SprintEverywhereTip")))
{
if (sprintInt)
{
@ -561,7 +560,7 @@ void Player::ShowPage()
bool state = BY_GAME(pPlayer->m_nPhysicalFlags.bBulletProof, pPlayer->m_nFlags.bBulletProof,
pPlayer->m_nFlags.bBulletProof);
if (Ui::CheckboxWithHint(TEXT("Player.BulletProof"), &state, nullptr, m_bGodMode))
if (Widget::Checkbox(TEXT("Player.BulletProof"), &state, nullptr, m_bGodMode))
{
BY_GAME(pPlayer->m_nPhysicalFlags.bBulletProof, pPlayer->m_nFlags.bBulletProof,
pPlayer->m_nFlags.bBulletProof) = state;
@ -569,7 +568,7 @@ void Player::ShowPage()
state = BY_GAME(pPlayer->m_nPhysicalFlags.bCollisionProof, pPlayer->m_nFlags.bCollisionProof,
pPlayer->m_nFlags.bCollisionProof);
if (Ui::CheckboxWithHint(TEXT("Player.CollisionProof"), &state, nullptr, m_bGodMode))
if (Widget::Checkbox(TEXT("Player.CollisionProof"), &state, nullptr, m_bGodMode))
{
BY_GAME(pPlayer->m_nPhysicalFlags.bCollisionProof, pPlayer->m_nFlags.bCollisionProof,
pPlayer->m_nFlags.bCollisionProof) = state;
@ -577,7 +576,7 @@ void Player::ShowPage()
state = BY_GAME(pPlayer->m_nPhysicalFlags.bExplosionProof, pPlayer->m_nFlags.bExplosionProof,
pPlayer->m_nFlags.bExplosionProof);
if (Ui::CheckboxWithHint(TEXT("Player.ExplosionProof"), &state, nullptr, m_bGodMode))
if (Widget::Checkbox(TEXT("Player.ExplosionProof"), &state, nullptr, m_bGodMode))
{
BY_GAME(pPlayer->m_nPhysicalFlags.bExplosionProof, pPlayer->m_nFlags.bExplosionProof,
pPlayer->m_nFlags.bExplosionProof) = state;
@ -587,7 +586,7 @@ void Player::ShowPage()
state = BY_GAME(pPlayer->m_nPhysicalFlags.bFireProof, pPlayer->m_nFlags.bFireProof,
pPlayer->m_nFlags.bFireProof);
if (Ui::CheckboxWithHint(TEXT("Player.FireProof"), &state, nullptr, m_bGodMode))
if (Widget::Checkbox(TEXT("Player.FireProof"), &state, nullptr, m_bGodMode))
{
BY_GAME(pPlayer->m_nPhysicalFlags.bFireProof, pPlayer->m_nFlags.bFireProof,
pPlayer->m_nFlags.bFireProof) = state;
@ -595,7 +594,7 @@ void Player::ShowPage()
state = BY_GAME(pPlayer->m_nPhysicalFlags.bMeleeProof, pPlayer->m_nFlags.bMeleeProof,
pPlayer->m_nFlags.bMeleeProof);
if (Ui::CheckboxWithHint(TEXT("Player.MeeleProof"), &state, nullptr, m_bGodMode))
if (Widget::Checkbox(TEXT("Player.MeeleProof"), &state, nullptr, m_bGodMode))
{
BY_GAME(pPlayer->m_nPhysicalFlags.bMeleeProof, pPlayer->m_nFlags.bMeleeProof,
pPlayer->m_nFlags.bMeleeProof) = state;
@ -609,7 +608,7 @@ void Player::ShowPage()
{
ImGui::BeginChild("PlayerMenus");
Ui::EditReference(TEXT("Player.Armour"), pPlayer->m_fArmour, 0, 100, BY_GAME(pInfo->m_nMaxArmour, pInfo->m_nMaxArmour, 100));
Widget::EditAddr<float>(TEXT("Player.Armour"), reinterpret_cast<uint>(&pPlayer->m_fArmour), 0, 100, BY_GAME(pInfo->m_nMaxArmour, pInfo->m_nMaxArmour, 100));
#ifdef GTASA
if (ImGui::CollapsingHeader(TEXT("Player.Body")))
{
@ -653,28 +652,28 @@ void Player::ShowPage()
ImGui::Separator();
}
Ui::EditStat(TEXT("Player.Energy"), STAT_ENERGY);
Ui::EditStat(TEXT("Player.Fat"), STAT_FAT);
Widget::EditStat(TEXT("Player.Energy"), STAT_ENERGY);
Widget::EditStat(TEXT("Player.Fat"), STAT_FAT);
#endif
Ui::EditReference(TEXT("Player.Health"), pPlayer->m_fHealth, 0, 100, BY_GAME(static_cast<int>(pPlayer->m_fMaxHealth), 100, 100));
Widget::EditAddr<float>(TEXT("Player.Health"), reinterpret_cast<uint>(&pPlayer->m_fHealth), 0, 100, BY_GAME(static_cast<int>(pPlayer->m_fMaxHealth), 100, 100));
#ifdef GTASA
Ui::EditStat(TEXT("Player.LungCapacity"), STAT_LUNG_CAPACITY);
Widget::EditStat(TEXT("Player.LungCapacity"), STAT_LUNG_CAPACITY);
Ui::EditReference(TEXT("Player.MaxArmour"), pInfo->m_nMaxArmour, 0, 100, 255);
Ui::EditStat(TEXT("Player.MaxHealth"), STAT_MAX_HEALTH, 0, 569, 1450);
Ui::EditAddress<int>(TEXT("Player.Money"), 0xB7CE50, -99999999, 0, 99999999);
Widget::EditAddr<uchar>(TEXT("Player.MaxArmour"), reinterpret_cast<uint>(&pInfo->m_nMaxArmour), 0, 100, 255);
Widget::EditStat(TEXT("Player.MaxHealth"), STAT_MAX_HEALTH, 0, 569, 1450);
Widget::EditAddr<int>(TEXT("Player.Money"), 0xB7CE50, -99999999, 0, 99999999);
#else
int money = pInfo->m_nMoney;
Ui::EditAddress<int>(TEXT("Player.Money"), (int)&money, -9999999, 0, 99999999);
Widget::EditAddr<int>(TEXT("Player.Money"), (int)&money, -9999999, 0, 99999999);
pInfo->m_nMoney = money;
pInfo->m_nDisplayMoney = money;
#endif
#ifdef GTASA
Ui::EditStat(TEXT("Player.Muscle"), STAT_MUSCLE);
Ui::EditStat(TEXT("Player.Respect"), STAT_RESPECT);
Ui::EditStat(TEXT("Player.Stamina"), STAT_STAMINA);
Widget::EditStat(TEXT("Player.Muscle"), STAT_MUSCLE);
Widget::EditStat(TEXT("Player.Respect"), STAT_RESPECT);
Widget::EditStat(TEXT("Player.Stamina"), STAT_STAMINA);
if (ImGui::CollapsingHeader(TEXT("Player.TopDownCamera")))
{
if (ImGui::Checkbox(TEXT("Window.Enabled"), &TopDownCamera::m_bEnabled))
@ -769,7 +768,7 @@ void Player::ShowPage()
{
ImGui::Spacing();
if (Ui::CheckboxWithHint(TEXT("Player.AimSkinChanger"), &m_bAimSkinChanger, TEXT("Player.AimSkinChangerTip") + aimSkinChanger.Pressed()))
if (Widget::Checkbox(TEXT("Player.AimSkinChanger"), &m_bAimSkinChanger, TEXT("Player.AimSkinChangerTip") + aimSkinChanger.Pressed()))
{
gConfig.Set("Features.AimSkinChanger", m_bAimSkinChanger);
}
@ -855,7 +854,7 @@ void Player::ShowPage()
if (m_bModloaderInstalled)
{
Widget::FilterWithHint(TEXT("Window.Search"), m_ClothData.m_Filter,
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"));

View File

@ -1,7 +1,6 @@
#include "pch.h"
#include "teleport.h"
#include "menu.h"
#include "ui.h"
#include "widget.h"
#include "util.h"
@ -217,7 +216,7 @@ void Teleport::ShowPage()
ImGui::Checkbox(TEXT("Teleport.InsertCoord"), &m_bInsertCoord);
ImGui::NextColumn();
#ifdef GTASA
if (Ui::CheckboxWithHint(TEXT("Teleport.QuickTeleport"), &m_bQuickTeleport,
if (Widget::Checkbox(TEXT("Teleport.QuickTeleport"), &m_bQuickTeleport,
std::string(TEXT_S("Teleport.QuickTeleportHint")
+ quickTeleport.GetNameString()).c_str()))
{

View File

@ -1,546 +0,0 @@
#include "pch.h"
#include "util.h"
#include "ui.h"
#include "widget.h"
#include "../depend/imgui/imgui_internal.h"
#include "menu.h"
ImVec2 Ui::GetSize(short count, bool spacing)
{
if (count == 1)
{
spacing = false;
}
// manually tested values
float factor = ImGui::GetStyle().ItemSpacing.x / 2.0f;
float x;
if (count == 3)
{
factor = ImGui::GetStyle().ItemSpacing.x / 1.403f;
}
if (spacing)
{
x = ImGui::GetWindowContentRegionWidth() / count - factor;
}
else
{
x = ImGui::GetWindowContentRegionWidth() / count;
}
return ImVec2(x, ImGui::GetFrameHeight() * 1.3f);
}
// Really messy code, cleanup someday
bool Ui::DrawTitleBar()
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
ImGuiID id = window->GetID("#CLOSE");
ImGui::PushFont(FontMgr::Get("title"));
Widget::TextCentered(MENU_TITLE);
if (!ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows
| ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem))
{
ImGui::PopFont();
return false;
}
ImVec2 rectMin = ImGui::GetItemRectMin(); // get pos of title text
ImGuiStyle& Style = ImGui::GetStyle();
float framePadding = Style.FramePadding.x;
float fontSize = ImGui::GetFontSize();
ImRect title_bar_rect = window->TitleBarRect();
ImVec2 pos = ImVec2(title_bar_rect.Max.x - framePadding*2 - fontSize, title_bar_rect.Min.y);
// drawing the close button
const ImRect bb(pos, pos + ImVec2(g.FontSize, g.FontSize) + g.Style.FramePadding * 2.0f);
ImRect bb_interact = bb;
const float area_to_visible_ratio = window->OuterRectClipped.GetArea() / bb.GetArea();
if (area_to_visible_ratio < 1.5f)
{
bb_interact.Expand(ImFloor(bb_interact.GetSize() * -0.25f));
}
bool hovered, held;
bool pressed = ImGui::ButtonBehavior(bb_interact, id, &hovered, &held);
float cross_extent = (fontSize * 0.3f) - 1.0f;
ImVec2 closePos = ImVec2(bb.GetCenter().x - cross_extent, rectMin.y);
ImU32 closeCol = ImGui::GetColorU32(held || hovered ? ImVec4(0.80f, 0.0f, 0.0f, 1.0f) : ImVec4(0.80f, 0.80f, 0.80f, 1.00f));
window->DrawList->AddText(closePos, closeCol, "X");
ImGui::PopFont();
return pressed;
}
bool Ui::ListBox(const char* label, const std::vector<std::string>& all_items, int& selected)
{
bool rtn = false;
if (ImGui::BeginCombo(label, all_items[selected].c_str()))
{
for (size_t index = 0; index < all_items.size(); index++)
{
if (selected != index)
{
if (ImGui::MenuItem(all_items[index].c_str()))
{
selected = index;
rtn = true;
}
}
}
ImGui::EndCombo();
}
return rtn;
}
bool Ui::ListBoxStr(const char* label, const std::vector<std::string>& all_items, std::string& selected)
{
bool rtn = false;
if (ImGui::BeginCombo(label, selected.c_str()))
{
for (std::string current_item : all_items)
{
if (ImGui::MenuItem(current_item.c_str()))
{
selected = current_item;
rtn = true;
}
}
ImGui::EndCombo();
}
return rtn;
}
bool Ui::CheckboxWithHint(const char* label, bool* v, const char* hint, bool is_disabled)
{
// set things up
bool pressed = false;
const ImGuiStyle& style = ImGui::GetStyle();
const ImVec2 textSize = ImGui::CalcTextSize(label, nullptr, true);
float square_sz = ImGui::GetFrameHeight();
ImDrawList* drawlist = ImGui::GetWindowDrawList();
ImU32 color = ImGui::GetColorU32(ImGuiCol_FrameBg);
std::string slabel = "##InvCheckboxBtn" + std::string(label);
ImGui::BeginDisabled(is_disabled);
// process the button states
if (ImGui::InvisibleButton(slabel.c_str(), ImVec2(square_sz, square_sz)) && !is_disabled)
{
pressed = true;
*v = !*v;
}
if (ImGui::IsItemHovered() && !is_disabled)
{
color = ImGui::GetColorU32(ImGuiCol_FrameBgHovered);
}
// draw the button
ImVec2 min = ImGui::GetItemRectMin();
ImVec2 max = ImGui::GetItemRectMax();
drawlist->AddRectFilled(min, max, color, ImGui::GetStyle().FrameRounding);
int pad = static_cast<int>(square_sz / 6.0);
pad = (pad < 1) ? 1 : pad;
if (*v)
{
// draw the checkmark
float sz = (square_sz - pad * 2.0);
float thickness = sz / 5.0;
thickness = (thickness < 1.0) ? 1.0 : thickness;
sz = sz - thickness * 0.5;
auto pos = ImVec2(min.x + pad, min.y + pad);
pos.x = pos.x + thickness * 0.25;
pos.y = pos.y + thickness * 0.25;
float third = sz / 3.0;
float bx = pos.x + third;
float by = pos.y + sz - third * 0.5;
drawlist->PathLineTo(ImVec2(bx - third, by - third));
drawlist->PathLineTo(ImVec2(bx, by));
drawlist->PathLineTo(ImVec2(bx + third * 2.0, by - third * 2.0));
drawlist->PathStroke(ImGui::GetColorU32(ImGuiCol_CheckMark), false, thickness);
}
// draw label
ImGui::SameLine(0, style.ItemInnerSpacing.x);
if (ImGui::InvisibleButton(label, ImVec2(ImGui::CalcTextSize(label, nullptr, true).x, square_sz)) && !is_disabled)
{
pressed = true;
*v = !*v;
}
min = ImGui::GetItemRectMin();
drawlist->AddText(ImVec2(min.x, min.y + style.ItemInnerSpacing.y / 2), ImGui::GetColorU32(ImGuiCol_Text), label);
// draw hint
if (hint != nullptr)
{
ImGui::SameLine(0, style.ItemInnerSpacing.x);
ImGui::InvisibleButton("?", ImGui::CalcTextSize("?", nullptr, true));
min = ImGui::GetItemRectMin();
drawlist->AddText(ImVec2(min.x, min.y + style.ItemInnerSpacing.y / 2), ImGui::GetColorU32(ImGuiCol_TextDisabled),
"?");
if (ImGui::IsItemHovered() && !is_disabled)
{
ImGui::BeginTooltip();
ImGui::Text(hint);
ImGui::Spacing();
ImGui::EndTooltip();
}
}
ImGui::EndDisabled();
return pressed;
}
bool Ui::CheckboxAddress(const char* label, const int addr, const char* hint)
{
bool rtn = false;
bool state = patch::Get<bool>(addr, false);
if (CheckboxWithHint(label, &state, hint) && addr != NULL)
{
patch::Set<bool>(addr, state, false);
rtn = true;
}
return rtn;
}
bool Ui::CheckboxAddressEx(const char* label, const int addr, int enabled_val, int disabled_val, const char* hint)
{
bool rtn = false;
bool state = false;
int val = 0;
patch::GetRaw(addr, &val, 1, false);
state = (val == enabled_val);
if (CheckboxWithHint(label, &state, hint) && addr != NULL)
{
if (state)
{
patch::SetRaw(addr, &enabled_val, 1, false);
}
else
{
patch::SetRaw(addr, &disabled_val, 1, false);
}
rtn = true;
}
return rtn;
}
bool Ui::CheckboxBitFlag(const char* label, uint flag, const char* hint)
{
bool rtn = false;
bool state = (flag == 1) ? true : false;
if (CheckboxWithHint(label, &state, hint))
{
flag = state ? 1 : 0;
rtn = true;
}
return rtn;
}
#ifdef GTASA
void Ui::EditStat(const char* label, const int stat_id, const int min, const int def, const int max)
{
if (ImGui::CollapsingHeader(label))
{
int val = static_cast<int>(CStats::GetStatValue(stat_id));
ImGui::Columns(3, nullptr, false);
ImGui::Text("Min: %d", min);
ImGui::NextColumn();
ImGui::Text("Def: %d", def);
ImGui::NextColumn();
ImGui::Text("Max: %d", max);
ImGui::Columns(1);
ImGui::Spacing();
if (ImGui::InputInt(("Set value##" + std::string(label)).c_str(), &val))
CStats::SetStatValue(stat_id, static_cast<float>(val));
ImGui::Spacing();
if (ImGui::Button(("Minimum##" + std::string(label)).c_str(), GetSize(3)))
CStats::SetStatValue(stat_id, static_cast<float>(min));
ImGui::SameLine();
if (ImGui::Button(("Default##" + std::string(label)).c_str(), GetSize(3)))
CStats::SetStatValue(stat_id, static_cast<float>(def));
ImGui::SameLine();
if (ImGui::Button(("Maximum##" + std::string(label)).c_str(), GetSize(3)))
CStats::SetStatValue(stat_id, static_cast<float>(max));
ImGui::Spacing();
ImGui::Separator();
}
}
#endif
void Ui::RadioButtonAddress(const char* label, std::vector<NamedMemory>& named_mem)
{
size_t btn_in_column = named_mem.size() / 2 - 1;
ImGui::Text(label);
ImGui::Columns(2, nullptr, false);
bool state = true;
for (size_t i = 0; i < named_mem.size(); i++)
{
if (patch::Get<bool>(named_mem[i].addr, false))
state = false;
}
if (ImGui::RadioButton((std::string("None##") + label).c_str(), state))
{
for (size_t i = 0; i < named_mem.size(); i++)
patch::Set<bool>(named_mem[i].addr, false);
}
for (size_t i = 0; i < named_mem.size(); i++)
{
state = patch::Get<bool>(named_mem[i].addr, false);
if (ImGui::RadioButton(named_mem[i].name.c_str(), state))
{
for (size_t i = 0; i < named_mem.size(); i++)
patch::Set<bool>(named_mem[i].addr, false);
patch::Set<bool>(named_mem[i].addr, true);
}
if (i == btn_in_column)
ImGui::NextColumn();
}
ImGui::Columns(1);
}
void Ui::RadioButtonAddressEx(const char* label, int addr, std::vector<NamedValue>& named_val)
{
size_t btn_in_column = named_val.size() / 2;
ImGui::Text(label);
ImGui::Columns(2, nullptr, false);
int mem_val = 0;
patch::GetRaw(addr, &mem_val, 1, false);
for (size_t i = 0; i < named_val.size(); i++)
{
if (ImGui::RadioButton(named_val[i].name.c_str(), &mem_val, named_val[i].value))
patch::SetRaw(addr, &named_val[i].value, 1, false);
if (i == btn_in_column)
ImGui::NextColumn();
}
ImGui::Columns(1);
}
void Ui::EditRadioButtonAddress(const char* label, std::vector<NamedMemory>& named_mem)
{
if (ImGui::CollapsingHeader(label))
{
RadioButtonAddress(label, named_mem);
ImGui::Spacing();
ImGui::Separator();
}
}
void Ui::EditRadioButtonAddressEx(const char* label, int addr, std::vector<NamedValue>& named_val)
{
if (ImGui::CollapsingHeader(label))
{
RadioButtonAddressEx(label, addr, named_val);
ImGui::Spacing();
ImGui::Separator();
}
}
void Ui::ColorPickerAddress(const char* label, int base_addr, ImVec4&& default_color)
{
if (ImGui::CollapsingHeader(label))
{
float cur_color[4];
cur_color[0] = patch::Get<BYTE>(base_addr, false);
cur_color[1] = patch::Get<BYTE>(base_addr + 1, false);
cur_color[2] = patch::Get<BYTE>(base_addr + 2, false);
cur_color[3] = patch::Get<BYTE>(base_addr + 3, false);
// 0-255 -> 0-1
cur_color[0] /= 255;
cur_color[1] /= 255;
cur_color[2] /= 255;
cur_color[3] /= 255;
if (ImGui::ColorPicker4(std::string("Pick color##" + std::string(label)).c_str(), cur_color))
{
// 0-1 -> 0-255
cur_color[0] *= 255;
cur_color[1] *= 255;
cur_color[2] *= 255;
cur_color[3] *= 255;
patch::Set<BYTE>(base_addr, cur_color[0], false);
patch::Set<BYTE>(base_addr + 1, cur_color[1], false);
patch::Set<BYTE>(base_addr + 2, cur_color[2], false);
patch::Set<BYTE>(base_addr + 3, cur_color[3], false);
}
ImGui::Spacing();
if (ImGui::Button("Reset to default", GetSize()))
{
patch::Set<BYTE>(base_addr, default_color.x, false);
patch::Set<BYTE>(base_addr + 1, default_color.y, false);
patch::Set<BYTE>(base_addr + 2, default_color.z, false);
patch::Set<BYTE>(base_addr + 3, default_color.w, false);
}
ImGui::Spacing();
ImGui::Separator();
}
}
void Ui::EditBits(const char* label, const int address, const std::vector<std::string>& names)
{
auto mem_val = (int*)address;
if (ImGui::CollapsingHeader(label))
{
ImGui::Columns(2, nullptr, false);
for (int i = 0; i < 32; ++i)
{
int mask = 1 << i;
bool state = *mem_val & mask;
if (ImGui::Checkbox(names[i].c_str(), &state))
{
*mem_val ^= mask;
}
if (i + 1 == 32 / 2)
{
ImGui::NextColumn();
}
}
ImGui::Columns(1);
ImGui::Spacing();
ImGui::Separator();
}
}
void Ui::EditFloat(const char* label, const int address, const float min, const float def, const float max,
const float mul, const float change)
{
if (ImGui::CollapsingHeader(label))
{
float val = patch::Get<float>(address, false) * mul;
int items = 3;
if (min == def)
items = 2;
ImGui::Columns(items, nullptr, false);
ImGui::Text("Min: %f", min);
if (items == 3)
{
ImGui::NextColumn();
ImGui::Text("Def: %f", def);
}
ImGui::NextColumn();
ImGui::Text("Max: %f", max);
ImGui::Columns(1);
ImGui::Spacing();
int size = ImGui::GetFrameHeight();
if (ImGui::InputFloat(("##" + std::string(label)).c_str(), &val))
patch::SetFloat(address, val / mul, false);
ImGui::SameLine(0.0, 4.0);
if (ImGui::Button("-", ImVec2(size, size)) && (val - change) > min)
{
val -= change;
patch::SetFloat(address, val / mul, false);
}
ImGui::SameLine(0.0, 4.0);
if (ImGui::Button("+", ImVec2(size, size)) && (val + change) < max)
{
val += change;
patch::SetFloat(address, val / mul, false);
}
ImGui::SameLine(0.0, 4.0);
ImGui::Text("Set");
ImGui::Spacing();
if (ImGui::Button(("Minimum##" + std::string(label)).c_str(), GetSize(items)))
patch::Set<float>(address, min / mul, false);
if (items == 3)
{
ImGui::SameLine();
if (ImGui::Button(("Default##" + std::string(label)).c_str(), GetSize(items)))
patch::Set<float>(address, def / mul, false);
}
ImGui::SameLine();
if (ImGui::Button(("Maximum##" + std::string(label)).c_str(), GetSize(items)))
patch::Set<float>(address, max / mul, false);
ImGui::Spacing();
ImGui::Separator();
}
}
bool Ui::ColorButton(int color_id, std::vector<float>& color, ImVec2 size)
{
bool rtn = false;
std::string label = "Color " + std::to_string(color_id);
if (ImGui::ColorButton(label.c_str(), ImVec4(color[0], color[1], color[2], 1), 0, size))
{
rtn = true;
}
if (ImGui::IsItemHovered())
{
ImDrawList* drawlist = ImGui::GetWindowDrawList();
drawlist->AddRectFilled(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(),
ImGui::GetColorU32(ImGuiCol_ModalWindowDimBg));
}
return rtn;
}

174
src/ui.h
View File

@ -1,174 +0,0 @@
#pragma once
#include "pch.h"
// TODO: Fix this messy code
class Ui
{
public:
struct NamedMemory
{
std::string name;
int addr;
};
struct NamedValue
{
std::string name;
int value;
};
Ui() = delete;
Ui(Ui&) = delete;
static bool ColorButton(int color_id, std::vector<float>& color, ImVec2 size);
static bool CheckboxAddress(const char* label, int addr = NULL, const char* hint = nullptr);
static bool CheckboxAddressEx(const char* label, int addr = NULL, int enabled_val = 1, int disabled_val = 0,
const char* hint = nullptr);
static bool CheckboxBitFlag(const char* label, uint flag, const char* hint = nullptr);
static bool CheckboxWithHint(const char* label, bool* state, const char* hint = nullptr, bool is_disabled = false);
static bool DrawTitleBar();
template <typename T>
static void EditAddress(const char* label, int address, int min = 0, int def = 0, int max = 100);
static void EditBits(const char* label, int address, const std::vector<std::string>& names);
static void EditFloat(const char* label, int address, float min, float def, float max, float mul = 1, float change = 1.0f);
template <typename T>
static void EditReference(const char* label, T& address, int min = 0, int def = 0, int max = 100);
static void EditRadioButtonAddress(const char* label, std::vector<NamedMemory>& named_mem);
static void EditRadioButtonAddressEx(const char* label, int addr, std::vector<NamedValue>& named_val);
#ifdef GTASA
static void EditStat(const char* label, int stat_id, int min = 0, int def = 0, int max = 1000);
#endif
static ImVec2 GetSize(short count = 1, bool spacing = true);
static bool ListBox(const char* label, const std::vector<std::string>& all_items, int& selected);
static bool ListBoxStr(const char* label, const std::vector<std::string>& all_items, std::string& selected);
static void RadioButtonAddress(const char* label, std::vector<NamedMemory>& named_mem);
static void RadioButtonAddressEx(const char* label, int addr, std::vector<NamedValue>& named_val);
static void ColorPickerAddress(const char* label, int base_addr, ImVec4&& default_color);
};
template <typename T>
void Ui::EditAddress(const char* label, const int address, const int min, const int def, const int max)
{
if (ImGui::CollapsingHeader(label))
{
int val = patch::Get<T>(address, false);
int items = 3;
if (min == def)
{
items = 2;
}
ImGui::Columns(items, nullptr, false);
ImGui::Text(("Min: " + std::to_string(min)).c_str());
if (items == 3)
{
ImGui::NextColumn();
ImGui::Text(("Def: " + std::to_string(def)).c_str());
}
ImGui::NextColumn();
ImGui::Text(("Max: " + std::to_string(max)).c_str());
ImGui::Columns(1);
ImGui::Spacing();
if (ImGui::InputInt(("Set value##" + std::string(label)).c_str(), &val))
{
patch::Set<T>(address, val, false);
}
ImGui::Spacing();
if (val < min)
{
val = min;
}
if (val > max)
{
val = max;
}
if (ImGui::Button(("Minimum##" + std::string(label)).c_str(), GetSize(items)))
{
patch::Set<T>(address, min, false);
}
if (items == 3)
{
ImGui::SameLine();
if (ImGui::Button(("Default##" + std::string(label)).c_str(), GetSize(3)))
{
patch::Set<T>(address, def, false);
}
}
ImGui::SameLine();
if (ImGui::Button(("Maximum##" + std::string(label)).c_str(), GetSize(items)))
{
patch::Set<T>(address, max, false);
}
ImGui::Spacing();
ImGui::Separator();
}
}
template <typename T>
void Ui::EditReference(const char* label, T& address, const int min, const int def, const int max)
{
if (ImGui::CollapsingHeader(label))
{
int val = static_cast<int>(address);
ImGui::Columns(3, nullptr, false);
ImGui::Text(("Min: " + std::to_string(min)).c_str());
ImGui::NextColumn();
ImGui::Text(("Def: " + std::to_string(def)).c_str());
ImGui::NextColumn();
ImGui::Text(("Max: " + std::to_string(max)).c_str());
ImGui::Columns(1);
ImGui::Spacing();
if (ImGui::InputInt(("Set value##" + std::string(label)).c_str(), &val))
{
address = static_cast<float>(val);
}
ImGui::Spacing();
if (ImGui::Button(("Minimum##" + std::string(label)).c_str(), GetSize(3)))
{
address = static_cast<float>(min);
}
ImGui::SameLine();
if (ImGui::Button(("Default##" + std::string(label)).c_str(), GetSize(3)))
{
address = static_cast<float>(def);
}
ImGui::SameLine();
if (ImGui::Button(("Maximum##" + std::string(label)).c_str(), GetSize(3)))
{
address = static_cast<float>(max);
}
ImGui::Spacing();
ImGui::Separator();
}
}

View File

@ -1,7 +1,6 @@
#include "pch.h"
#include "vehicle.h"
#include "menu.h"
#include "ui.h"
#include "widget.h"
#include "util.h"
#include "filehandler.h"
@ -544,19 +543,19 @@ void Vehicle::ShowPage()
ImGui::BeginChild("CheckboxesChild");
ImGui::Columns(2, 0, false);
#ifdef GTASA
Ui::CheckboxAddress(TEXT("Vehicle.AimDrive"), 0x969179);
Ui::CheckboxAddress(TEXT("Vehicle.AllNitro"), 0x969165);
Widget::CheckboxAddr(TEXT("Vehicle.AimDrive"), 0x969179);
Widget::CheckboxAddr(TEXT("Vehicle.AllNitro"), 0x969165);
#endif
#ifndef GTA3
Ui::CheckboxAddress(TEXT("Vehicle.AggroDriver"), BY_GAME(0x96914F,0xA10B47, NULL));
Ui::CheckboxAddress(TEXT("Vehicle.AllTaxiNitro"), BY_GAME(0x96918B,0xA10B3A, NULL));
Ui::CheckboxWithHint(TEXT("Vehicle.BikeFly"), &m_bBikeFly);
Ui::CheckboxAddress(TEXT("Vehicle.BoatFly"), BY_GAME(0x969153, 0xA10B11, NULL));
Widget::CheckboxAddr(TEXT("Vehicle.AggroDriver"), BY_GAME(0x96914F,0xA10B47, NULL));
Widget::CheckboxAddr(TEXT("Vehicle.AllTaxiNitro"), BY_GAME(0x96918B,0xA10B3A, NULL));
Widget::Checkbox(TEXT("Vehicle.BikeFly"), &m_bBikeFly);
Widget::CheckboxAddr(TEXT("Vehicle.BoatFly"), BY_GAME(0x969153, 0xA10B11, NULL));
#endif
Ui::CheckboxAddress(TEXT("Vehicle.CarFly"), BY_GAME(0x969160, 0xA10B28, 0x95CD75));
Ui::CheckboxWithHint(TEXT("Vehicle.CarHeavy"), &m_bVehHeavy);
if (Ui::CheckboxWithHint(TEXT("Vehicle.DmgProof"), &m_bNoDamage, TEXT("Vehicle.DmgProofTip")))
Widget::CheckboxAddr(TEXT("Vehicle.CarFly"), BY_GAME(0x969160, 0xA10B28, 0x95CD75));
Widget::Checkbox(TEXT("Vehicle.CarHeavy"), &m_bVehHeavy);
if (Widget::Checkbox(TEXT("Vehicle.DmgProof"), &m_bNoDamage, TEXT("Vehicle.DmgProofTip")))
{
if (pVeh && !m_bNoDamage)
{
@ -584,9 +583,9 @@ void Vehicle::ShowPage()
}
}
#ifdef GTASA
Ui::CheckboxAddressEx(TEXT("Vehicle.LockTrainCam"), 0x52A52F, 171, 6);
Ui::CheckboxAddress(TEXT("Vehicle.LessTraffic"), 0x96917A);
if (Ui::CheckboxWithHint(TEXT("Vehicle.NoDerail"), &m_bNoDerail))
Widget::CheckboxAddrRaw(TEXT("Vehicle.LockTrainCam"), 0x52A52F, 1, "\xAB", "\x06");
Widget::CheckboxAddr(TEXT("Vehicle.LessTraffic"), 0x96917A);
if (Widget::Checkbox(TEXT("Vehicle.NoDerail"), &m_bNoDerail))
{
if (m_bNoDerail)
{
@ -599,7 +598,7 @@ void Vehicle::ShowPage()
patch::SetRaw(0x6F8C2A, (void*)"\x8A\x46\x36\xA8\xF8\xD8\x8E", 7);
}
}
// if (Ui::CheckboxWithHint(TEXT("Vehicle.NoColl"), &m_bDisableColDetection))
// if (Widget::Checkbox(TEXT("Vehicle.NoColl"), &m_bDisableColDetection))
// {
// if (m_bDisableColDetection)
// {
@ -625,7 +624,7 @@ void Vehicle::ShowPage()
#endif
ImGui::NextColumn();
#ifndef GTA3
if (Ui::CheckboxWithHint(TEXT("Vehicle.StayOnBike"), &m_bDontFallBike))
if (Widget::Checkbox(TEXT("Vehicle.StayOnBike"), &m_bDontFallBike))
{
if (m_bDontFallBike)
{
@ -648,20 +647,20 @@ void Vehicle::ShowPage()
#endif
}
}
Ui::CheckboxAddress(TEXT("Vehicle.DriveWater"), BY_GAME(0x969152, 0xA10B81, NULL));
Widget::CheckboxAddr(TEXT("Vehicle.DriveWater"), BY_GAME(0x969152, 0xA10B81, NULL));
#endif
#ifdef GTASA
Ui::CheckboxAddress(TEXT("Vehicle.FloatOnHit"), 0x969166);
Widget::CheckboxAddr(TEXT("Vehicle.FloatOnHit"), 0x969166);
#endif
#ifndef GTA3
Ui::CheckboxAddress(TEXT("Vehicle.GreenLights"), BY_GAME(0x96914E, 0xA10ADC, NULL));
Widget::CheckboxAddr(TEXT("Vehicle.GreenLights"), BY_GAME(0x96914E, 0xA10ADC, NULL));
#endif
#ifdef GTASA
Ui::CheckboxAddress(TEXT("Vehicle.PerfectHandling"), 0x96914C);
Ui::CheckboxAddress(TEXT("Vehicle.TankMode"), 0x969164);
Widget::CheckboxAddr(TEXT("Vehicle.PerfectHandling"), 0x96914C);
Widget::CheckboxAddr(TEXT("Vehicle.TankMode"), 0x969164);
Ui::CheckboxWithHint(TEXT("Vehicle.InfNitro"), &UnlimitedNitro::m_bEnabled, TEXT("Vehicle.InfNitroTip"));
if (Ui::CheckboxWithHint(TEXT("Vehicle.FlipNoBurn"), &m_bVehFlipNoBurn, TEXT("Vehicle.FlipNoBurnTip")))
Widget::Checkbox(TEXT("Vehicle.InfNitro"), &UnlimitedNitro::m_bEnabled, TEXT("Vehicle.InfNitroTip"));
if (Widget::Checkbox(TEXT("Vehicle.FlipNoBurn"), &m_bVehFlipNoBurn, TEXT("Vehicle.FlipNoBurnTip")))
{
// MixSets (Link2012)
if (m_bVehFlipNoBurn)
@ -681,10 +680,10 @@ void Vehicle::ShowPage()
}
#elif GTA3
Ui::CheckboxAddress(TEXT("Vehicle.PerfectHandling"), 0x95CD66);
Widget::CheckboxAddr(TEXT("Vehicle.PerfectHandling"), 0x95CD66);
#endif
Ui::CheckboxWithHint(TEXT("Vehicle.Watertight"), &m_bVehWatertight, TEXT("Vehicle.WatertightTip"));
Ui::CheckboxAddress(TEXT("Vehicle.OnlyWheels"), BY_GAME(0x96914B, 0xA10B70, 0x95CD78));
Widget::Checkbox(TEXT("Vehicle.Watertight"), &m_bVehWatertight, TEXT("Vehicle.WatertightTip"));
Widget::CheckboxAddr(TEXT("Vehicle.OnlyWheels"), BY_GAME(0x96914B, 0xA10B70, 0x95CD78));
ImGui::Columns(1);
if (is_driver)
@ -697,38 +696,38 @@ void Vehicle::ShowPage()
bool state = false;
#ifdef GTASA
state = pVeh->m_nVehicleFlags.bAlwaysSkidMarks;
if (Ui::CheckboxWithHint(TEXT("Vehicle.SkidMarks"), &state, nullptr))
if (Widget::Checkbox(TEXT("Vehicle.SkidMarks"), &state, nullptr))
pVeh->m_nVehicleFlags.bAlwaysSkidMarks = state;
#endif
state = BY_GAME(pVeh->m_nPhysicalFlags.bBulletProof, pVeh->m_nFlags.bBulletProof, pVeh->m_nFlags.bBulletProof);
if (Ui::CheckboxWithHint(TEXT("Vehicle.BulletProof"), &state, nullptr, m_bNoDamage))
if (Widget::Checkbox(TEXT("Vehicle.BulletProof"), &state, nullptr, m_bNoDamage))
{
BY_GAME(pVeh->m_nPhysicalFlags.bBulletProof, pVeh->m_nFlags.bBulletProof, pVeh->m_nFlags.bBulletProof) = state;
}
state = BY_GAME(pVeh->m_nPhysicalFlags.bCollisionProof, pVeh->m_nFlags.bCollisionProof, pVeh->m_nFlags.bCollisionProof);
if (Ui::CheckboxWithHint(TEXT("Vehicle.ColProof"), &state, nullptr, m_bNoDamage))
if (Widget::Checkbox(TEXT("Vehicle.ColProof"), &state, nullptr, m_bNoDamage))
{
BY_GAME(pVeh->m_nPhysicalFlags.bCollisionProof, pVeh->m_nFlags.bCollisionProof, pVeh->m_nFlags.bCollisionProof) = state;
}
#ifdef GTASA
state = pVeh->m_nVehicleFlags.bDisableParticles;
if (Ui::CheckboxWithHint(TEXT("Vehicle.NoParticles"), &state, nullptr))
if (Widget::Checkbox(TEXT("Vehicle.NoParticles"), &state, nullptr))
{
pVeh->m_nVehicleFlags.bDisableParticles = state;
}
state = pVeh->m_nVehicleFlags.bVehicleCanBeTargetted;
if (Ui::CheckboxWithHint(TEXT("Vehicle.DriverTarget"), &state))
if (Widget::Checkbox(TEXT("Vehicle.DriverTarget"), &state))
{
pVeh->m_nVehicleFlags.bVehicleCanBeTargetted = state;
}
#endif
state = BY_GAME(!pVeh->m_nVehicleFlags.bEngineBroken, true, true) || pVeh->m_nVehicleFlags.bEngineOn;
if (Ui::CheckboxWithHint(TEXT("Vehicle.EngineOn"), &state, nullptr, !is_driver))
if (Widget::Checkbox(TEXT("Vehicle.EngineOn"), &state, nullptr, !is_driver))
{
#ifdef GTASA
pVeh->m_nVehicleFlags.bEngineBroken = !state;
@ -737,13 +736,13 @@ void Vehicle::ShowPage()
}
state = BY_GAME(pVeh->m_nPhysicalFlags.bExplosionProof, pVeh->m_nFlags.bExplosionProof, pVeh->m_nFlags.bExplosionProof);
if (Ui::CheckboxWithHint(TEXT("Vehicle.ExplosionProof"), &state, nullptr, m_bNoDamage))
if (Widget::Checkbox(TEXT("Vehicle.ExplosionProof"), &state, nullptr, m_bNoDamage))
{
BY_GAME(pVeh->m_nPhysicalFlags.bExplosionProof, pVeh->m_nFlags.bExplosionProof, pVeh->m_nFlags.bExplosionProof) = state;
}
state = BY_GAME(pVeh->m_nPhysicalFlags.bFireProof, pVeh->m_nFlags.bFireProof, pVeh->m_nFlags.bFireProof);
if (Ui::CheckboxWithHint(TEXT("Vehicle.FireProof"), &state, nullptr, m_bNoDamage))
if (Widget::Checkbox(TEXT("Vehicle.FireProof"), &state, nullptr, m_bNoDamage))
{
BY_GAME(pVeh->m_nPhysicalFlags.bFireProof, pVeh->m_nFlags.bFireProof, pVeh->m_nFlags.bFireProof) = state;
}
@ -752,51 +751,51 @@ void Vehicle::ShowPage()
#ifdef GTASA
state = pVeh->m_nVehicleFlags.bVehicleCanBeTargettedByHS;
if (Ui::CheckboxWithHint(TEXT("Vehicle.HSTarget"), &state, TEXT("Vehicle.HSTargetTip")))
if (Widget::Checkbox(TEXT("Vehicle.HSTarget"), &state, TEXT("Vehicle.HSTargetTip")))
{
pVeh->m_nVehicleFlags.bVehicleCanBeTargettedByHS = state;
}
#endif
state = !BY_GAME(pVeh->m_bIsVisible, pVeh->m_nFlags.bIsVisible, pVeh->m_nFlags.bIsVisible);
if (Ui::CheckboxWithHint(TEXT("Vehicle.InvisCar"), &state, nullptr, !is_driver))
if (Widget::Checkbox(TEXT("Vehicle.InvisCar"), &state, nullptr, !is_driver))
{
BY_GAME(pVeh->m_bIsVisible, pVeh->m_nFlags.bIsVisible, pVeh->m_nFlags.bIsVisible) = !state;
}
state = BY_GAME(!pVeh->ms_forceVehicleLightsOff, pVeh->m_nVehicleFlags.bLightsOn, pVeh->m_nVehicleFlags.bLightsOn);
if (Ui::CheckboxWithHint(TEXT("Vehicle.LightsOn"), &state, nullptr, !is_driver))
if (Widget::Checkbox(TEXT("Vehicle.LightsOn"), &state, nullptr, !is_driver))
{
BY_GAME(pVeh->ms_forceVehicleLightsOff, pVeh->m_nVehicleFlags.bLightsOn, pVeh->m_nVehicleFlags.bLightsOn) = state;
}
state = pVeh->m_eDoorLock == DOORLOCK_LOCKED_PLAYER_INSIDE;
if (Ui::CheckboxWithHint(TEXT("Vehicle.LockDoor"), &state, nullptr, !is_driver))
if (Widget::Checkbox(TEXT("Vehicle.LockDoor"), &state, nullptr, !is_driver))
{
pVeh->m_eDoorLock = state ? DOORLOCK_LOCKED_PLAYER_INSIDE : DOORLOCK_UNLOCKED;
}
state = BY_GAME(pVeh->m_nPhysicalFlags.bMeleeProof, pVeh->m_nFlags.bMeleeProof, pVeh->m_nFlags.bMeleeProof);
if (Ui::CheckboxWithHint(TEXT("Vehicle.MeleeProof"), &state, nullptr, m_bNoDamage))
if (Widget::Checkbox(TEXT("Vehicle.MeleeProof"), &state, nullptr, m_bNoDamage))
{
BY_GAME(pVeh->m_nPhysicalFlags.bMeleeProof, pVeh->m_nFlags.bMeleeProof, pVeh->m_nFlags.bMeleeProof) = state;
}
#ifdef GTASA
state = pVeh->m_nVehicleFlags.bPetrolTankIsWeakPoint;
if (Ui::CheckboxWithHint(TEXT("Vehicle.PentrolTank"), &state, TEXT("Vehicle.PetrolTankTip")))
if (Widget::Checkbox(TEXT("Vehicle.PentrolTank"), &state, TEXT("Vehicle.PetrolTankTip")))
{
pVeh->m_nVehicleFlags.bPetrolTankIsWeakPoint = state;
}
state = pVeh->m_nVehicleFlags.bSirenOrAlarm;
if (Ui::CheckboxWithHint(TEXT("Vehicle.Siren"), &state))
if (Widget::Checkbox(TEXT("Vehicle.Siren"), &state))
{
pVeh->m_nVehicleFlags.bSirenOrAlarm = state;
}
state = pVeh->m_nVehicleFlags.bTakeLessDamage;
if (Ui::CheckboxWithHint(TEXT("Vehicle.LessDmg"), &state, nullptr))
if (Widget::Checkbox(TEXT("Vehicle.LessDmg"), &state, nullptr))
{
pVeh->m_nVehicleFlags.bTakeLessDamage = state;
}
@ -814,7 +813,7 @@ void Vehicle::ShowPage()
ImGui::BeginChild("MenusChild");
#ifdef GTASA
Ui::EditAddress<float>(TEXT("Vehicle.DensityMul"), 0x8A5B20, 0, 1, 10);
Widget::EditAddr<float>(TEXT("Vehicle.DensityMul"), 0x8A5B20, 0, 1, 10);
#endif
if (ImGui::CollapsingHeader(TEXT("Vehicle.EnterNearVeh")))
{
@ -891,20 +890,20 @@ void Vehicle::ShowPage()
if (ImGui::CollapsingHeader(TEXT("Vehicle.TrafficOpt")))
{
std::vector<Ui::NamedMemory> color
std::vector<Widget::BindInfo> color
{
{TEXT("Vehicle.Black"), BY_GAME(0x969151, 0xA10B82, NULL)},
{TEXT("Vehicle.Pink"), BY_GAME(0x969150, 0xA10B26, NULL)}
};
Ui::RadioButtonAddress(TEXT("Vehicle.Color"), color);
Widget::EditRadioBtnAddr(TEXT("Vehicle.Color"), color);
ImGui::Spacing();
#ifdef GTASA
std::vector<Ui::NamedMemory> type
std::vector<Widget::BindInfo> type
{
{TEXT("Vehicle.Cheap"), 0x96915E}, {TEXT("Vehicle.Country"), 0x96917B},
{TEXT("Vehicle.Fast"), 0x96915F}
};
Ui::RadioButtonAddress(TEXT("Vehicle.Type"), type);
Widget::EditRadioBtnAddr(TEXT("Vehicle.Type"), type);
#endif
ImGui::Spacing();
ImGui::Separator();
@ -916,7 +915,7 @@ void Vehicle::ShowPage()
int hVeh = CPools::GetVehicleRef(pVeh);
#ifdef GTASA
Ui::EditFloat(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")))
{
ImGui::Columns(2, 0, false);
@ -991,7 +990,7 @@ void Vehicle::ShowPage()
#endif
if (ImGui::CollapsingHeader(TEXT("Vehicle.SetSpeed")))
{
Ui::CheckboxWithHint(TEXT("Vehicle.LockSpeed"), &m_bLockSpeed);
Widget::Checkbox(TEXT("Vehicle.LockSpeed"), &m_bLockSpeed);
ImGui::Spacing();
ImGui::InputFloat(TEXT("Vehicle.Set"), &m_fLockSpeed);
ImGui::Spacing();
@ -1019,12 +1018,12 @@ void Vehicle::ShowPage()
{
ImGui::Spacing();
ImGui::Columns(2, 0, false);
if (Ui::CheckboxWithHint(TEXT("Vehicle.SpawnInside"), &Spawner::m_bSpawnInside))
if (Widget::Checkbox(TEXT("Vehicle.SpawnInside"), &Spawner::m_bSpawnInside))
{
gConfig.Set("Features.SpawnInsideVehicle", Spawner::m_bSpawnInside);
}
ImGui::NextColumn();
if( Ui::CheckboxWithHint(TEXT("Vehicle.SpawnInAir"), &Spawner::m_bSpawnInAir))
if( Widget::Checkbox(TEXT("Vehicle.SpawnInAir"), &Spawner::m_bSpawnInAir))
{
gConfig.Set("Features.SpawnAircraftInAir", Spawner::m_bSpawnInAir);
}
@ -1096,7 +1095,7 @@ void Vehicle::ShowPage()
}
ImGui::Spacing();
Ui::ListBoxStr(TEXT("Vehicle.Component"), PaintData::m_vecNames, PaintData::m_Selected);
Widget::ListBox(TEXT("Vehicle.Component"), PaintData::m_vecNames, PaintData::m_Selected);
if (ImGui::ColorEdit3(TEXT("Vehicle.ColorPicker"), PaintData::m_fColorPicker))
{
@ -1139,7 +1138,7 @@ void Vehicle::ShowPage()
for (int colorId = 0; colorId < count; ++colorId)
{
if (Ui::ColorButton(colorId, m_CarcolsColorData[colorId], ImVec2(btnSize, btnSize)))
if (Widget::ColorBtn(colorId, m_CarcolsColorData[colorId], ImVec2(btnSize, btnSize)))
{
*(uint8_replacement*)(int(veh) + BY_GAME(0x433, 0x19F, 0x19B) + PaintData::m_nRadioButton) = colorId;
}
@ -1170,14 +1169,14 @@ void Vehicle::ShowPage()
ImGui::Columns(2, NULL, false);
bool pulsing = Neon::IsPulsingEnabled(veh);
if (Ui::CheckboxWithHint(TEXT("Vehicle.PulsingNeon"), &pulsing))
if (Widget::Checkbox(TEXT("Vehicle.PulsingNeon"), &pulsing))
{
Neon::SetPulsing(veh, pulsing);
}
Ui::CheckboxWithHint(TEXT("Vehicle.RainbowNeon"), &NeonData::m_bRainbowEffect, TEXT("Vehicle.RainbowNeonMSG"));
Widget::Checkbox(TEXT("Vehicle.RainbowNeon"), &NeonData::m_bRainbowEffect, TEXT("Vehicle.RainbowNeonMSG"));
ImGui::NextColumn();
Ui::CheckboxWithHint(TEXT("Vehicle.TrafficNeon"), &NeonData::m_bApplyOnTraffic, TEXT("Vehicle.TrafficNeonMSG"));
Widget::Checkbox(TEXT("Vehicle.TrafficNeon"), &NeonData::m_bApplyOnTraffic, TEXT("Vehicle.TrafficNeonMSG"));
ImGui::Columns(1);
ImGui::Spacing();
@ -1206,7 +1205,7 @@ void Vehicle::ShowPage()
for (int color_id = 0; color_id < count; ++color_id)
{
auto& color = m_CarcolsColorData[color_id];
if (Ui::ColorButton(color_id, color, ImVec2(btnSize, btnSize)))
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);
@ -1236,7 +1235,7 @@ void Vehicle::ShowPage()
}
ImGui::Spacing();
Ui::ListBoxStr(TEXT("Vehicle.Component"), PaintData::m_vecNames, PaintData::m_Selected);
Widget::ListBox(TEXT("Vehicle.Component"), PaintData::m_vecNames, PaintData::m_Selected);
ImGui::Spacing();
ImGui::Columns(2, NULL, false);
@ -1348,89 +1347,89 @@ void Vehicle::ShowPage()
ImGui::BeginChild("HandlingChild");
std::vector<Ui::NamedValue> abs{ {TEXT("Vehicle.On"), 1}, {TEXT("Vehicle.Off"), 0} };
Ui::EditRadioButtonAddressEx(TEXT("Vehicle.Abs"), (int)&pHandlingData->m_bABS, abs);
std::vector<Widget::BindInfo> abs{ {TEXT("Vehicle.On"), 1}, {TEXT("Vehicle.Off"), 0} };
Widget::EditRadioBtnAddr(TEXT("Vehicle.Abs"), (int)&pHandlingData->m_bABS, abs);
Ui::EditFloat(TEXT("Vehicle.ADM"), (int)&pHandlingData->m_fSuspensionAntiDiveMultiplier, 0.0f, 0.0f, 1.0f);
Ui::EditAddress<BYTE>(TEXT("Vehicle.AnimGroup"), (int)&pHandlingData->m_nAnimGroup, 0, 0, 20);
Ui::EditFloat(TEXT("Vehicle.BrakeBias"), (int)&pHandlingData->m_fBrakeBias, 0.0f, 0.0f, 1.0f);
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;
Ui::EditFloat(TEXT("Vehicle.BrakeDecel"), (int)&pHandlingData->m_fBrakeDeceleration, 0.0f, 0.0f, 20.0f, 2500.0f);
Widget::EditAddr(TEXT("Vehicle.BrakeDecel"), (int)&pHandlingData->m_fBrakeDeceleration, 0.0f, 0.0f, 20.0f, 2500.0f);
pHandlingData->m_fBrakeDeceleration = BrakeDeceleration / 2500;
Ui::EditFloat(TEXT("Vehicle.CemterMassX"), (int)&pHandlingData->m_vecCentreOfMass.x, -10.0f, -10.0f, 10.0f);
Ui::EditFloat(TEXT("Vehicle.CemterMassY"), (int)&pHandlingData->m_vecCentreOfMass.y, -10.0f, -10.0f, 10.0f);
Ui::EditFloat(TEXT("Vehicle.CemterMassZ"), (int)&pHandlingData->m_vecCentreOfMass.z, -10.0f, -10.0f, 10.0f);
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);
Ui::EditFloat(TEXT("Vehicle.CDM"), (int)&fCDM, 0.0f, 0.0f, 1.0f, 0.3381f);
Widget::EditAddr(TEXT("Vehicle.CDM"), (int)&fCDM, 0.0f, 0.0f, 1.0f, 0.3381f);
pHandlingData->m_fCollisionDamageMultiplier = factor * fCDM * 2000.0f;
Ui::EditFloat(TEXT("Vehicle.DampingLvl"), (int)&pHandlingData->m_fSuspensionDampingLevel, -10.0f, -10.0f, 10.0f); // test later
Ui::EditFloat(TEXT("Vehicle.DragMult"), (int)&pHandlingData->m_fDragMult, 0.0f, 0.0f, 30.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<Ui::NamedValue> drive_type
std::vector<Widget::BindInfo> drive_type
{
{TEXT("Vehicle.FrontWheelDrive"), 70},
{TEXT("Vehicle.RearWheelDrive"), 82},
{TEXT("Vehicle.FourWheelDrive"), 52}
};
Ui::EditRadioButtonAddressEx(TEXT("Vehicle.DriveType"), (int)&pHandlingData->m_transmissionData.m_nDriveType, drive_type);
Widget::EditRadioBtnAddr(TEXT("Vehicle.DriveType"), (int)&pHandlingData->m_transmissionData.m_nDriveType, drive_type);
// Engine acceleration calculation
float fEngineAcceleration = pHandlingData->m_transmissionData.m_fEngineAcceleration * 12500;
Ui::EditFloat(TEXT("Vehicle.EngineAccel"), (int)&fEngineAcceleration, 0.0f, 0.0f, 49.0f, 12500.0f);
Widget::EditAddr(TEXT("Vehicle.EngineAccel"), (int)&fEngineAcceleration, 0.0f, 0.0f, 49.0f, 12500.0f);
pHandlingData->m_transmissionData.m_fEngineAcceleration = fEngineAcceleration / 12500;
Ui::EditFloat(TEXT("Vehicle.EngineInertia"), (int)&pHandlingData->m_transmissionData.m_fEngineInertia, 0.1f, 0.1f, 400.0f);
Widget::EditAddr(TEXT("Vehicle.EngineInertia"), (int)&pHandlingData->m_transmissionData.m_fEngineInertia, 0.1f, 0.1f, 400.0f);
std::vector<Ui::NamedValue> engine_type
std::vector<Widget::BindInfo> engine_type
{
{TEXT("Vehicle.Petrol"), 80}, {TEXT("Vehicle.Diseal"), 68}, {TEXT("Vehicle.Electric"), 69}
};
Ui::EditRadioButtonAddressEx(TEXT("Vehicle.EngineType"), (int)&pHandlingData->m_transmissionData.m_nEngineType, engine_type);
Widget::EditRadioBtnAddr(TEXT("Vehicle.EngineType"), (int)&pHandlingData->m_transmissionData.m_nEngineType, engine_type);
std::vector<Ui::NamedValue> lights
std::vector<Widget::BindInfo> lights
{
{TEXT("Vehicle.Long"), 0}, {TEXT("Vehicle.Small"), 1},
{TEXT("Vehicle.Big"), 2}, {TEXT("Vehicle.Tall"), 3}
};
Ui::EditRadioButtonAddressEx(TEXT("Vehicle.FrontLights"), (int)&pHandlingData->m_nFrontLights, lights);
Widget::EditRadioBtnAddr(TEXT("Vehicle.FrontLights"), (int)&pHandlingData->m_nFrontLights, lights);
Ui::EditFloat(TEXT("Vehicle.ForceLevel"), (int)&pHandlingData->m_fSuspensionForceLevel, -10.0f, -10.0f, 10.0f); // test later
Widget::EditAddr(TEXT("Vehicle.ForceLevel"), (int)&pHandlingData->m_fSuspensionForceLevel, -10.0f, -10.0f, 10.0f); // test later
Ui::EditBits(TEXT("Vehicle.HandlingFlags"), (int)&pHandlingData->m_nHandlingFlags, m_HandlingFlagNames);
Widget::EditBits(TEXT("Vehicle.HandlingFlags"), (int)&pHandlingData->m_nHandlingFlags, m_HandlingFlagNames);
Ui::EditFloat(TEXT("Vehicle.HighSpeedDamping"), (int)&pHandlingData->m_fSuspensionDampingLevel, -10.0f, -10.0f, 10.0f); // test later
Ui::EditFloat(TEXT("Vehicle.LowerKimit"), (int)&pHandlingData->m_fSuspensionLowerLimit, -10.0f, -10.0f, 10.0f); // test later
Ui::EditFloat(TEXT("Vehicle.Mass"), (int)&pHandlingData->m_fMass, 1.0f, 1.0f, 50000.0f);
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;
Ui::EditFloat(TEXT("Vehicle.MaxVelocity"), (int)&MaxVelocity, 1.0f, 1.0f, 1000.0f);
Widget::EditAddr(TEXT("Vehicle.MaxVelocity"), (int)&MaxVelocity, 1.0f, 1.0f, 1000.0f);
pHandlingData->m_transmissionData.m_fMaxGearVelocity = MaxVelocity * (*(float*)0xC2B9BC);
Ui::EditBits(TEXT("Vehicle.ModelFlags"), (int)&pHandlingData->m_nModelFlags, m_ModelFlagNames);
Widget::EditBits(TEXT("Vehicle.ModelFlags"), (int)&pHandlingData->m_nModelFlags, m_ModelFlagNames);
Ui::EditAddress<int>(TEXT("Vehicle.MonValue"), (int)&pHandlingData->m_nMonetaryValue, 1, 1, 100000);
Ui::EditAddress<BYTE>(TEXT("Vehicle.NumGears"), (int)&pHandlingData->m_transmissionData.m_nNumberOfGears, 1, 1, 10);
Ui::EditAddress<BYTE>(TEXT("Vehicle.PercentSubmerged"), (int)&pHandlingData->m_nPercentSubmerged, 10, 10, 120);
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);
Ui::EditRadioButtonAddressEx(TEXT("Vehicle.RearLights"), (int)&pHandlingData->m_nRearLights, lights);
Widget::EditRadioBtnAddr(TEXT("Vehicle.RearLights"), (int)&pHandlingData->m_nRearLights, lights);
Ui::EditFloat(TEXT("Vehicle.SeatOffset"), (int)&pHandlingData->m_fSeatOffsetDistance, 0.0f, 0.0f, 1.0f);
Ui::EditFloat(TEXT("Vehicle.SteeringLock"), (int)&pHandlingData->m_fSteeringLock, 10.0f, 10.0f, 50.0f);
Ui::EditFloat(TEXT("Vehicle.SuspensionBias"), (int)&pHandlingData->m_fSuspensionBiasBetweenFrontAndRear, 0.0f, 0.0f, 1.0f);
Ui::EditFloat(TEXT("Vehicle.TractionBias"), (int)&pHandlingData->m_fTractionBias, 0.0f, 0.0f, 1.0f);
Ui::EditFloat(TEXT("Vehicle.TractionLoss"), (int)&pHandlingData->m_fTractionLoss, 0.0f, 0.0f, 1.0f);
Ui::EditFloat(TEXT("Vehicle.TractionMul"), (int)&pHandlingData->m_fTractionMultiplier, 0.5f, 0.5f, 2.0f);
Ui::EditFloat(TEXT("Vehicle.TurnMass"), (int)&pHandlingData->m_fTurnMass, 20.0f, 20.0f, 1000.0f); // test later
Ui::EditFloat(TEXT("Vehicle.UpperLimit"), (int)&pHandlingData->m_fSuspensionUpperLimit, -1.0f, -1.0f, 1.0f);
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();

View File

@ -1,6 +1,5 @@
#include "pch.h"
#include "visual.h"
#include "ui.h"
#include "widget.h"
#include "util.h"
#include "game.h"
@ -18,6 +17,24 @@
#define TOTAL_WEATHERS 4
#endif
// Timecyc stuff
static int m_nTimecycHour = 8;
static std::vector<std::string> m_WeatherNames
{
#ifdef GTASA
"EXTRASUNNY LA", "SUNNY LA", "EXTRASUNNY SMOG LA", "SUNNY SMOG LA", "CLOUDY LA", "SUNNY SF", "EXTRASUNNY SF",
"CLOUDY SF", "RAINY SF", "FOGGY SF",
"SUNNY VEGAS", "EXTRASUNNY VEGAS", "CLOUDY VEGAS", "EXTRASUNNY COUNTRYSIDE", "SUNNY COUNTRYSIDE",
"CLOUDY COUNTRYSIDE", "RAINY COUNTRYSIDE",
"EXTRASUNNY DESERT", "SUNNY DESERT", "SANDSTORM DESERT", "UNDERWATER", "EXTRACOLOURS 1", "EXTRACOLOURS 2"
#else
"SUNNY", "CLOUDY", "RAINY", "FOGGY"
#ifdef GTAVC
,"EXTRA_SUNNY", "HURRICANE", "EXTRACOLORS"
#endif
#endif
};
void Visual::Init()
{
#ifdef GTASA
@ -54,7 +71,7 @@ int GetTCVal(T* addr, int index)
return static_cast<int>(arr[index]);
}
void Visual::GenerateTimecycFile()
static void GenerateTimecycFile()
{
#ifdef GTASA
std::ofstream file;
@ -237,7 +254,7 @@ void Visual::GenerateTimecycFile()
#endif
}
int Visual::CalcArrayIndex()
int CalcArrayIndex()
{
int hour = CClock::ms_nGameClockHours;
@ -270,25 +287,24 @@ int Visual::CalcArrayIndex()
}
template<typename T>
bool Visual::TimeCycColorEdit3(const char* label, T* r, T* g, T* b, ImGuiColorEditFlags flags)
bool TimeCycColorEdit3(const char* label, uchar* r, uchar* g, uchar* b)
{
bool rtn = false;
int val = CalcArrayIndex();
#ifdef GTASA
auto red = static_cast<T*>(patch::GetPointer(int(r)));
auto green = static_cast<T*>(patch::GetPointer(int(g)));
auto blue = static_cast<T*>(patch::GetPointer(int(b)));
auto red = static_cast<uchar*>(patch::GetPointer(int(r)));
auto green = static_cast<uchar*>(patch::GetPointer(int(g)));
auto blue = static_cast<uchar*>(patch::GetPointer(int(b)));
#else
auto red = static_cast<T*>(r);
auto green = static_cast<T*>(g);
auto blue = static_cast<T*>(b);
auto red = static_cast<uchar*>(r);
auto green = static_cast<uchar*>(g);
auto blue = static_cast<uchar*>(b);
#endif
float col[3] { red[val] / 255.0f, green[val] / 255.0f, blue[val] / 255.0f };
if (ImGui::ColorEdit3(label, col, flags))
if (ImGui::ColorEdit3(label, col))
{
red[val] = col[0] * 255;
green[val] = col[1] * 255;
@ -300,7 +316,7 @@ bool Visual::TimeCycColorEdit3(const char* label, T* r, T* g, T* b, ImGuiColorEd
}
template <typename T>
void Visual::TimecycSlider(const char* label, T* ptr, int min, int max)
void TimecycSlider(const char* label, T* ptr, int min, int max)
{
int val = CalcArrayIndex();
#ifdef GTASA
@ -315,27 +331,26 @@ void Visual::TimecycSlider(const char* label, T* ptr, int min, int max)
arr[val] = static_cast<T>(a);
}
template <typename T>
bool Visual::TimeCycColorEdit4(const char* label, T* r, T* g, T* b, T* a, ImGuiColorEditFlags flags)
bool TimeCycColorEdit4(const char* label, uchar* r, uchar* g, uchar* b, uchar* a)
{
bool rtn = false;
int val = CalcArrayIndex();
#ifdef GTASA
auto red = static_cast<T*>(patch::GetPointer(int(r)));
auto green = static_cast<T*>(patch::GetPointer(int(g)));
auto blue = static_cast<T*>(patch::GetPointer(int(b)));
auto alpha = static_cast<T*>(patch::GetPointer(int(a)));
auto red = static_cast<uchar*>(patch::GetPointer(int(r)));
auto green = static_cast<uchar*>(patch::GetPointer(int(g)));
auto blue = static_cast<uchar*>(patch::GetPointer(int(b)));
auto alpha = static_cast<uchar*>(patch::GetPointer(int(a)));
#else
auto red = static_cast<T*>(r);
auto green = static_cast<T*>(g);
auto blue = static_cast<T*>(b);
auto alpha = static_cast<T*>(a);
auto red = static_cast<uchar*>(r);
auto green = static_cast<uchar*>(g);
auto blue = static_cast<uchar*>(b);
auto alpha = static_cast<uchar*>(a);
#endif
float col[4] { red[val] / 255.0f, green[val] / 255.0f, blue[val] / 255.0f, alpha[val] / 255.0f };
if (ImGui::ColorEdit4(label, col, flags))
if (ImGui::ColorEdit4(label, col))
{
red[val] = col[0] * 255;
green[val] = col[1] * 255;
@ -347,6 +362,50 @@ bool Visual::TimeCycColorEdit4(const char* label, T* r, T* g, T* b, T* a, ImGuiC
return rtn;
}
static void ColorPickerAddr(const char* label, int addr, ImVec4&& default_color)
{
if (ImGui::CollapsingHeader(label))
{
float cur_color[4];
cur_color[0] = patch::Get<BYTE>(addr, false);
cur_color[1] = patch::Get<BYTE>(addr + 1, false);
cur_color[2] = patch::Get<BYTE>(addr + 2, false);
cur_color[3] = patch::Get<BYTE>(addr + 3, false);
// 0-255 -> 0-1
cur_color[0] /= 255;
cur_color[1] /= 255;
cur_color[2] /= 255;
cur_color[3] /= 255;
if (ImGui::ColorPicker4(std::string("Pick color##" + std::string(label)).c_str(), cur_color))
{
// 0-1 -> 0-255
cur_color[0] *= 255;
cur_color[1] *= 255;
cur_color[2] *= 255;
cur_color[3] *= 255;
patch::Set<BYTE>(addr, cur_color[0], false);
patch::Set<BYTE>(addr + 1, cur_color[1], false);
patch::Set<BYTE>(addr + 2, cur_color[2], false);
patch::Set<BYTE>(addr + 3, cur_color[3], false);
}
ImGui::Spacing();
if (ImGui::Button("Reset to default", Widget::CalcSize()))
{
patch::Set<BYTE>(addr, default_color.x, false);
patch::Set<BYTE>(addr + 1, default_color.y, false);
patch::Set<BYTE>(addr + 2, default_color.z, false);
patch::Set<BYTE>(addr + 3, default_color.w, false);
}
ImGui::Spacing();
ImGui::Separator();
}
}
void Visual::ShowPage()
{
if (ImGui::BeginTabBar("Visual", ImGuiTabBarFlags_NoTooltip + ImGuiTabBarFlags_FittingPolicyScroll))
@ -357,13 +416,13 @@ void Visual::ShowPage()
ImGui::Columns(2, nullptr, false);
#ifdef GTASA
Ui::CheckboxAddress(TEXT("Visual.ArmourBorder"), 0x589123);
Ui::CheckboxAddress(TEXT("Visual.ArmourPercentage"), 0x589125);
Ui::CheckboxAddress(TEXT("Visual.BreathBorder"), 0x589207);
Ui::CheckboxAddress(TEXT("Visual.BreathPercentage"), 0x589209);
Ui::CheckboxAddress(TEXT("Visual.CCTVEffect"), 0xC402C5);
Ui::CheckboxAddress(TEXT("Visual.DarknessFilter"), 0xC402C4);
if (Ui::CheckboxWithHint(TEXT("Visual.DisableHydrant"), &m_bDisableHydrant))
Widget::CheckboxAddr(TEXT("Visual.ArmourBorder"), 0x589123);
Widget::CheckboxAddr(TEXT("Visual.ArmourPercentage"), 0x589125);
Widget::CheckboxAddr(TEXT("Visual.BreathBorder"), 0x589207);
Widget::CheckboxAddr(TEXT("Visual.BreathPercentage"), 0x589209);
Widget::CheckboxAddr(TEXT("Visual.CCTVEffect"), 0xC402C5);
Widget::CheckboxAddr(TEXT("Visual.DarknessFilter"), 0xC402C4);
if (Widget::Checkbox(TEXT("Visual.DisableHydrant"), &m_bDisableHydrant))
{
if (m_bDisableHydrant)
{
@ -375,29 +434,29 @@ void Visual::ShowPage()
plugin::patch::SetRaw(0x4A0D70, (char*)"\xE9\x94\x3F\xF6\xFF", 5);
}
}
Ui::CheckboxAddress(TEXT("Visual.FogEffect"), 0xC402C6);
Ui::CheckboxAddress(TEXT("Visual.GrainEffect"), 0xC402B4);
Ui::CheckboxAddress(TEXT("Visual.GrayRadar"), 0xA444A4);
Ui::CheckboxAddress(TEXT("Visual.HealthBorder"), 0x589353);
Ui::CheckboxAddress(TEXT("Visual.HealthPercentage"), 0x589355);
Widget::CheckboxAddr(TEXT("Visual.FogEffect"), 0xC402C6);
Widget::CheckboxAddr(TEXT("Visual.GrainEffect"), 0xC402B4);
Widget::CheckboxAddr(TEXT("Visual.GrayRadar"), 0xA444A4);
Widget::CheckboxAddr(TEXT("Visual.HealthBorder"), 0x589353);
Widget::CheckboxAddr(TEXT("Visual.HealthPercentage"), 0x589355);
Ui::CheckboxAddress(TEXT("Visual.HeatHazeEffect"), 0xC402BA);
Widget::CheckboxAddr(TEXT("Visual.HeatHazeEffect"), 0xC402BA);
if (Ui::CheckboxWithHint(TEXT("Visual.HideAreaNames"), &CHud::bScriptDontDisplayAreaName))
if (Widget::Checkbox(TEXT("Visual.HideAreaNames"), &CHud::bScriptDontDisplayAreaName))
{
Command<Commands::DISPLAY_ZONE_NAMES>(!CHud::bScriptDontDisplayAreaName);
}
ImGui::NextColumn();
if (Ui::CheckboxWithHint(TEXT("Visual.HideVehNames"), &CHud::bScriptDontDisplayVehicleName))
if (Widget::Checkbox(TEXT("Visual.HideVehNames"), &CHud::bScriptDontDisplayVehicleName))
{
Command<Commands::DISPLAY_CAR_NAMES>(!CHud::bScriptDontDisplayVehicleName);
}
Ui::CheckboxAddressEx(TEXT("Visual.HideWantedLevel"), 0x58DD1B, 0x90, 1);
Ui::CheckboxAddress(TEXT("Visual.InfraredVision"), 0xC402B9);
if (Ui::CheckboxWithHint(TEXT("Visual.InvisibleWater"), &m_bInvisibleWater))
Widget::CheckboxAddrRaw(TEXT("Visual.HideWantedLevel"), 0x58DD1B, 1, "\x90", "\x01");
Widget::CheckboxAddr(TEXT("Visual.InfraredVision"), 0xC402B9);
if (Widget::Checkbox(TEXT("Visual.InvisibleWater"), &m_bInvisibleWater))
{
if (!m_bNoWater)
{
@ -415,9 +474,9 @@ void Visual::ShowPage()
}
}
}
Ui::CheckboxWithHint(TEXT("Visual.LockWeather"), &m_bLockWeather);
Ui::CheckboxAddress(TEXT("Visual.NightVision"), 0xC402B8);
if (Ui::CheckboxWithHint(TEXT("Visual.NoMoneyZeros"), &m_bNoMoneyZeros))
Widget::Checkbox(TEXT("Visual.LockWeather"), &m_bLockWeather);
Widget::CheckboxAddr(TEXT("Visual.NightVision"), 0xC402B8);
if (Widget::Checkbox(TEXT("Visual.NoMoneyZeros"), &m_bNoMoneyZeros))
{
static const char *pos = "$%d", *neg = "-$%d";
if(m_bNoMoneyZeros)
@ -431,7 +490,7 @@ void Visual::ShowPage()
patch::SetRaw(0x58F50A, (void*)"\x8C\x6C\x86\x00", 4);
}
}
if (Ui::CheckboxWithHint(TEXT("Visual.NoParticles"), &m_bNoPartciles))
if (Widget::Checkbox(TEXT("Visual.NoParticles"), &m_bNoPartciles))
{
if(m_bNoPartciles)
{
@ -442,9 +501,9 @@ void Visual::ShowPage()
patch::Set<uint32_t>(0x4AA440, 0x5608EC83, true);
}
}
Ui::CheckboxAddress(TEXT("Visual.NoPostFX"), 0xC402CF);
Widget::CheckboxAddr(TEXT("Visual.NoPostFX"), 0xC402CF);
if (Ui::CheckboxWithHint(TEXT("Visual.NoWater"), &m_bNoWater))
if (Widget::Checkbox(TEXT("Visual.NoWater"), &m_bNoWater))
{
if (m_bNoWater)
{
@ -467,26 +526,26 @@ void Visual::ShowPage()
}
bool radar_state = (patch::Get<BYTE>(0xBA676C) != 2);
if (Ui::CheckboxWithHint(TEXT("Visual.ShowRadar"), &radar_state))
if (Widget::Checkbox(TEXT("Visual.ShowRadar"), &radar_state))
{
patch::Set<BYTE>(0xBA676C, radar_state == true ? 0 : 2);
}
Ui::CheckboxAddress(TEXT("Visual.ShowHud"), 0xBA6769);
Ui::CheckboxAddress(TEXT("Visual.UnderwaterEffect"), 0xC402D3);
Ui::CheckboxAddressEx(TEXT("Visual.UnfogMap"), 0xBA372C, 0x50, 0x0, TEXT("Visual.UnfogMapText"));
Widget::CheckboxAddr(TEXT("Visual.ShowHud"), 0xBA6769);
Widget::CheckboxAddr(TEXT("Visual.UnderwaterEffect"), 0xC402D3);
Widget::CheckboxAddrRaw(TEXT("Visual.UnfogMap"), 0xBA372C, 1, "\x50", "\x00", TEXT("Visual.UnfogMapText"));
#elif GTAVC
Ui::CheckboxAddress(TEXT("Visual.HideRadar"), 0xA10AB6);
Ui::CheckboxWithHint(TEXT("Visual.Lockweather"), &m_bLockWeather);
Ui::CheckboxAddress(TEXT("Visual.ShowHud"), 0x86963A);
Widget::CheckboxAddr(TEXT("Visual.HideRadar"), 0xA10AB6);
Widget::Checkbox(TEXT("Visual.Lockweather"), &m_bLockWeather);
Widget::CheckboxAddr(TEXT("Visual.ShowHud"), 0x86963A);
ImGui::NextColumn();
Ui::CheckboxAddress(TEXT("Visual.GreenScanlines"), 0xA10B69);
Ui::CheckboxAddress(TEXT("Visual.WhiteScanlines"), 0xA10B68);
Widget::CheckboxAddr(TEXT("Visual.GreenScanlines"), 0xA10B69);
Widget::CheckboxAddr(TEXT("Visual.WhiteScanlines"), 0xA10B68);
#else
static bool hideHud, hideRadar;
if (Ui::CheckboxWithHint(TEXT("Visual.HideHud"), &hideHud))
if (Widget::Checkbox(TEXT("Visual.HideHud"), &hideHud))
{
if (hideHud)
{
@ -497,7 +556,7 @@ void Visual::ShowPage()
patch::SetRaw(0x48E420, (char*)"\xE8\x7B\x6E\x07\x00", 5);
}
}
if (Ui::CheckboxWithHint(TEXT("Visual.HideRadar"), &hideRadar))
if (Widget::Checkbox(TEXT("Visual.HideRadar"), &hideRadar))
{
if (hideHud)
{
@ -508,7 +567,7 @@ void Visual::ShowPage()
patch::SetRaw(0x50838D, (char*)"\xE8\x6E\xBE\xF9\xFF", 5);
}
}
Ui::CheckboxWithHint(TEXT("Visual.LockWeather"), &m_bLockWeather);
Widget::Checkbox(TEXT("Visual.LockWeather"), &m_bLockWeather);
#endif
ImGui::Columns(1);
ImGui::EndTabItem();
@ -591,53 +650,53 @@ void Visual::ShowPage()
ImGui::TextWrapped(TEXT("Visual.IncompatibleMods"));
Widget::Tooltip(TEXT("Visual.IncompatibleModsText"));
ImGui::Spacing();
Ui::ColorPickerAddress(TEXT("Visual.ArmourbarColor"), *(int*)0x5890FC, ImVec4(225, 225, 225, 255));
Ui::EditAddress<float>(TEXT("Visual.ArmourbarPosX"), 0x866B78, -999, 94, 999);
Ui::EditAddress<float>(TEXT("Visual.ArmourbarPosY"), 0x862D38, -999, 48, 999);
Ui::ColorPickerAddress(TEXT("Visual.BreathbarColor"), *(int*)0x5891EB, ImVec4(172, 203, 241, 255));
Ui::EditAddress<float>(TEXT("Visual.BreathbarPosX"), *(int*)0x58F11F, -999, 94, 999);
Ui::EditAddress<float>(TEXT("Visual.BreathbarPosY"), *(int*)0x58F100, -999, 62, 999);
Ui::ColorPickerAddress(TEXT("Visual.ClockColor"), *(int*)0x58EBD1, ImVec4(255, 255, 255, 255));
Ui::EditAddress<float>(TEXT("Visual.ClockPosX"), *(int*)0x58EC16, -999, 32, 999);
Ui::EditAddress<float>(TEXT("Visual.ClockPosY"), *(int*)0x58EC04, -999, 22, 999);
Ui::ColorPickerAddress(TEXT("Visual.HealthbarColor"), *(int*)0x589331, ImVec4(180, 25, 29, 255));
Ui::EditAddress<float>(TEXT("Visual.HealthbarPosX"), 0x86535C, -999, 141, 999);
Ui::EditAddress<float>(TEXT("Visual.HealthbarPosY"), 0x866CA8, -999, 77, 999);
Ui::ColorPickerAddress(TEXT("Visual.DrawMenuTitle"), 0xBAB240, ImVec4(0, 0, 0, 255));
Ui::ColorPickerAddress(TEXT("Visual.MoneyColor"), 0xBAB230, ImVec4(54, 104, 44, 255));
Ui::EditAddress<float>(TEXT("Visual.MoneyPosX"), *(int*)0x58F5FC, -999, 32, 999);
Ui::EditAddress<float>(TEXT("Visual.MoneyPosY"), 0x866C88, -999, 89, 999);
static std::vector<Ui::NamedValue> font_outline
ColorPickerAddr(TEXT("Visual.ArmourbarColor"), *(int*)0x5890FC, ImVec4(225, 225, 225, 255));
Widget::EditAddr<float>(TEXT("Visual.ArmourbarPosX"), 0x866B78, -999, 94, 999);
Widget::EditAddr<float>(TEXT("Visual.ArmourbarPosY"), 0x862D38, -999, 48, 999);
ColorPickerAddr(TEXT("Visual.BreathbarColor"), *(int*)0x5891EB, ImVec4(172, 203, 241, 255));
Widget::EditAddr<float>(TEXT("Visual.BreathbarPosX"), *(int*)0x58F11F, -999, 94, 999);
Widget::EditAddr<float>(TEXT("Visual.BreathbarPosY"), *(int*)0x58F100, -999, 62, 999);
ColorPickerAddr(TEXT("Visual.ClockColor"), *(int*)0x58EBD1, ImVec4(255, 255, 255, 255));
Widget::EditAddr<float>(TEXT("Visual.ClockPosX"), *(int*)0x58EC16, -999, 32, 999);
Widget::EditAddr<float>(TEXT("Visual.ClockPosY"), *(int*)0x58EC04, -999, 22, 999);
ColorPickerAddr(TEXT("Visual.HealthbarColor"), *(int*)0x589331, ImVec4(180, 25, 29, 255));
Widget::EditAddr<float>(TEXT("Visual.HealthbarPosX"), 0x86535C, -999, 141, 999);
Widget::EditAddr<float>(TEXT("Visual.HealthbarPosY"), 0x866CA8, -999, 77, 999);
ColorPickerAddr(TEXT("Visual.DrawMenuTitle"), 0xBAB240, ImVec4(0, 0, 0, 255));
ColorPickerAddr(TEXT("Visual.MoneyColor"), 0xBAB230, ImVec4(54, 104, 44, 255));
Widget::EditAddr<float>(TEXT("Visual.MoneyPosX"), *(int*)0x58F5FC, -999, 32, 999);
Widget::EditAddr<float>(TEXT("Visual.MoneyPosY"), 0x866C88, -999, 89, 999);
static std::vector<Widget::BindInfo> font_outline
{
{TEXT("Visual.NoOutline"), 0}, {TEXT("Visual.ThinOutline"), 1}, {TEXT("Visual.DefaultOutline"), 2}
};
Ui::EditRadioButtonAddressEx(TEXT("Visual.MoneyFontOutline"), 0x58F58D, font_outline);
static std::vector<Ui::NamedValue> style
Widget::EditRadioBtnAddr(TEXT("Visual.MoneyFontOutline"), 0x58F58D, font_outline);
static std::vector<Widget::BindInfo> style
{
{TEXT("Visual.Style1"), 1}, {TEXT("Visual.Style2"), 2}, {TEXT("Visual.DefaultStyle"), 3}
};
Ui::EditRadioButtonAddressEx(TEXT("Visual.MoneyFontStyle"), 0x58F57F, style);
Ui::EditAddress<float>(TEXT("Visual.RadarHeight"), *(int*)0x5834F6, 0, 76, 999);
Ui::EditAddress<float>(TEXT("Visual.RadarWidth"), *(int*)0x5834C2, 0, 94, 999);
Ui::EditAddress<float>(TEXT("Visual.RadarPosX"), *(int*)0x5834D4, -999, 40, 999);
Ui::EditAddress<float>(TEXT("Visual.RadarPosY"), *(int*)0x583500, -999, 104, 999);
Ui::EditAddress<int>(TEXT("Visual.RadarZoom"), 0xA444A3, 0, 0, 170);
Ui::ColorPickerAddress(TEXT("Visual.RadioStationColor"), 0xBAB24C, ImVec4(150, 150, 150, 255));
static std::vector<Ui::NamedValue> star_border
Widget::EditRadioBtnAddr(TEXT("Visual.MoneyFontStyle"), 0x58F57F, style);
Widget::EditAddr<float>(TEXT("Visual.RadarHeight"), *(int*)0x5834F6, 0, 76, 999);
Widget::EditAddr<float>(TEXT("Visual.RadarWidth"), *(int*)0x5834C2, 0, 94, 999);
Widget::EditAddr<float>(TEXT("Visual.RadarPosX"), *(int*)0x5834D4, -999, 40, 999);
Widget::EditAddr<float>(TEXT("Visual.RadarPosY"), *(int*)0x583500, -999, 104, 999);
Widget::EditAddr<int>(TEXT("Visual.RadarZoom"), 0xA444A3, 0, 0, 170);
ColorPickerAddr(TEXT("Visual.RadioStationColor"), 0xBAB24C, ImVec4(150, 150, 150, 255));
static std::vector<Widget::BindInfo> star_border
{
{TEXT("Visual.NoBorder"), 0}, {TEXT("Visual.DefaultBorder"), 1}, {TEXT("Visual.BoldBorder"), 2}
};
Ui::EditRadioButtonAddressEx(TEXT("Visual.WantedStarBorder"), 0x58DD41, star_border);
Ui::EditAddress<float>(TEXT("Visual.WantedPosX"), *(int*)0x58DD0F, -999, 29, 999);
Ui::EditAddress<float>(TEXT("Visual.WantedPosY"), *(int*)0x58DDFC, -999, 114, 999);
Ui::EditAddress<float>(TEXT("Visual.WeaponAmmoPosX"), *(int*)0x58FA02, -999, 32, 999);
Ui::EditAddress<float>(TEXT("Visual.WeaponAmmoPosY"), *(int*)0x58F9E6, -999, 43, 999);
Ui::EditAddress<float>(TEXT("Visual.WeaponIconPosX"), *(int*)0x58F927, -999, 32, 999);
Ui::EditAddress<float>(TEXT("Visual.WeaponIconPosY"), *(int*)0x58F913, -999, 20, 999);
Widget::EditRadioBtnAddr(TEXT("Visual.WantedStarBorder"), 0x58DD41, star_border);
Widget::EditAddr<float>(TEXT("Visual.WantedPosX"), *(int*)0x58DD0F, -999, 29, 999);
Widget::EditAddr<float>(TEXT("Visual.WantedPosY"), *(int*)0x58DDFC, -999, 114, 999);
Widget::EditAddr<float>(TEXT("Visual.WeaponAmmoPosX"), *(int*)0x58FA02, -999, 32, 999);
Widget::EditAddr<float>(TEXT("Visual.WeaponAmmoPosY"), *(int*)0x58F9E6, -999, 43, 999);
Widget::EditAddr<float>(TEXT("Visual.WeaponIconPosX"), *(int*)0x58F927, -999, 32, 999);
Widget::EditAddr<float>(TEXT("Visual.WeaponIconPosY"), *(int*)0x58F913, -999, 20, 999);
#elif GTAVC
Ui::EditAddress<float>(TEXT("Visual.RadarPosX"), 0x68FD2C, -999, 40, 999);
Ui::EditAddress<float>(TEXT("Visual.RadarPosY"), 0x68FD34, -999, 104, 999);
Ui::EditAddress<BYTE>(TEXT("Visual.RadarWidth"), 0x68FD28, -999, 20, 999);
Widget::EditAddr<float>(TEXT("Visual.RadarPosX"), 0x68FD2C, -999, 40, 999);
Widget::EditAddr<float>(TEXT("Visual.RadarPosY"), 0x68FD34, -999, 104, 999);
Widget::EditAddr<BYTE>(TEXT("Visual.RadarWidth"), 0x68FD28, -999, 20, 999);
#endif
ImGui::EndChild();
@ -667,13 +726,13 @@ void Visual::ShowPage()
ImGui::Spacing();
int weather = CWeather::OldWeatherType;
if (Ui::ListBox(TEXT("Visual.CurrentWeather"), m_WeatherNames, weather))
if (Widget::ListBox(TEXT("Visual.CurrentWeather"), m_WeatherNames, weather))
{
CWeather::OldWeatherType = weather;
}
weather = CWeather::NewWeatherType;
if (Ui::ListBox(TEXT("Visual.NextWeather"), m_WeatherNames, weather))
if (Widget::ListBox(TEXT("Visual.NextWeather"), m_WeatherNames, weather))
{
CWeather::NewWeatherType = weather;
}

View File

@ -16,33 +16,6 @@ private:
static inline bool m_bNoTextures;
#endif
// Timecyc stuff
static inline int m_nTimecycHour = 8;
static inline std::vector<std::string> m_WeatherNames
{
#ifdef GTASA
"EXTRASUNNY LA", "SUNNY LA", "EXTRASUNNY SMOG LA", "SUNNY SMOG LA", "CLOUDY LA", "SUNNY SF", "EXTRASUNNY SF",
"CLOUDY SF", "RAINY SF", "FOGGY SF",
"SUNNY VEGAS", "EXTRASUNNY VEGAS", "CLOUDY VEGAS", "EXTRASUNNY COUNTRYSIDE", "SUNNY COUNTRYSIDE",
"CLOUDY COUNTRYSIDE", "RAINY COUNTRYSIDE",
"EXTRASUNNY DESERT", "SUNNY DESERT", "SANDSTORM DESERT", "UNDERWATER", "EXTRACOLOURS 1", "EXTRACOLOURS 2"
#else
"SUNNY", "CLOUDY", "RAINY", "FOGGY"
#ifdef GTAVC
,"EXTRA_SUNNY", "HURRICANE", "EXTRACOLORS"
#endif
#endif
};
static void GenerateTimecycFile();
static int CalcArrayIndex();
template<typename T>
static bool TimeCycColorEdit3(const char* label, T* r, T* g, T* b, ImGuiColorEditFlags flags = 0);
template <typename T>
static bool TimeCycColorEdit4(const char* label, T* r, T* g, T* b, T* a, ImGuiColorEditFlags flags = 0);
template <typename T>
static void TimecycSlider(const char* label, T* data, int min, int max);
public:
Visual() = delete;
Visual(const Visual&) = delete;

View File

@ -1,6 +1,5 @@
#include "pch.h"
#include "weapon.h"
#include "ui.h"
#include "widget.h"
#include "util.h"
#include "CWeaponInfo.h"
@ -277,8 +276,8 @@ void Weapon::ShowPage()
Widget::Tooltip(TEXT("Weapon.WeaponTweaksText"));
ImGui::Columns(2, 0, false);
#ifdef GTASA
Ui::CheckboxWithHint(TEXT("Weapon.FastAim"), &m_bAutoAim, TEXT("Weapon.FastAimText"));
if (Ui::CheckboxWithHint(TEXT("Weapon.DualWeild"), &m_bDualWeild,TEXT("Weapon.DualWeildText")))
Widget::Checkbox(TEXT("Weapon.FastAim"), &m_bAutoAim, TEXT("Weapon.FastAimText"));
if (Widget::Checkbox(TEXT("Weapon.DualWeild"), &m_bDualWeild,TEXT("Weapon.DualWeildText")))
{
if (!m_bDualWeild)
{
@ -286,26 +285,26 @@ void Weapon::ShowPage()
}
}
#endif
if (Ui::CheckboxWithHint(TEXT("Weapon.HugeDamage"), &m_bHugeDamage, TEXT("Weapon.HugeDamageText")))
if (Widget::Checkbox(TEXT("Weapon.HugeDamage"), &m_bHugeDamage, TEXT("Weapon.HugeDamageText")))
{
if (!m_bHugeDamage)
{
CWeaponInfo::LoadWeaponData();
}
}
if (Ui::CheckboxWithHint(TEXT("Weapon.FastReload"), &m_bFastReload))
if (Widget::Checkbox(TEXT("Weapon.FastReload"), &m_bFastReload))
{
Command<Commands::SET_PLAYER_FAST_RELOAD>(hplayer, m_bFastReload);
}
#ifdef GTASA
Ui::CheckboxAddress(TEXT("Weapon.InfiniteAmmo"), 0x969178);
Widget::CheckboxAddr(TEXT("Weapon.InfiniteAmmo"), 0x969178);
ImGui::NextColumn();
#else
ImGui::NextColumn();
Ui::CheckboxWithHint(TEXT("Weapon.InfiniteAmmo"), &m_bInfiniteAmmo);
Widget::Checkbox(TEXT("Weapon.InfiniteAmmo"), &m_bInfiniteAmmo);
#endif
if (Ui::CheckboxWithHint(TEXT("Weapon.LongRange"), &m_bLongRange))
if (Widget::Checkbox(TEXT("Weapon.LongRange"), &m_bLongRange))
{
if (!m_bLongRange)
{
@ -313,21 +312,21 @@ void Weapon::ShowPage()
}
}
#ifdef GTASA
if (Ui::CheckboxWithHint(TEXT("Weapon.MoveWhenAiming"), &m_bMoveAim))
if (Widget::Checkbox(TEXT("Weapon.MoveWhenAiming"), &m_bMoveAim))
{
if (!m_bMoveAim)
{
CWeaponInfo::LoadWeaponData();
}
}
if (Ui::CheckboxWithHint(TEXT("Weapon.MoveWhenFiring"), &m_bMoveFire))
if (Widget::Checkbox(TEXT("Weapon.MoveWhenFiring"), &m_bMoveFire))
{
if (!m_bMoveFire)
{
CWeaponInfo::LoadWeaponData();
}
}
if (Ui::CheckboxWithHint(TEXT("Weapon.RapidFire"), &m_bRapidFire))
if (Widget::Checkbox(TEXT("Weapon.RapidFire"), &m_bRapidFire))
{
if (!m_bRapidFire)
{

View File

@ -1,6 +1,5 @@
#include "pch.h"
#include "widget.h"
#include "ui.h"
#include "menu.h"
static struct
@ -59,7 +58,7 @@ void Widget::Tooltip(const char* text)
}
}
void Widget::FilterWithHint(const char* label, ImGuiTextFilter& filter, const char* hint)
void Widget::Filter(const char* label, ImGuiTextFilter& filter, const char* hint)
{
filter.Draw(label);
@ -90,9 +89,9 @@ void Widget::DataList(ResourceStore& data, ArgCallback3 clickFunc, ArgCallback3
ImGui::Spacing();
// Category box
ImGui::PushItemWidth((ImGui::GetWindowContentRegionWidth() - ImGui::GetStyle().ItemSpacing.x)/2);
Ui::ListBoxStr("##Categories", data.m_Categories, data.m_Selected);
Widget::ListBox("##Categories", data.m_Categories, data.m_Selected);
ImGui::SameLine();
FilterWithHint("##Filter", data.m_Filter, TEXT("Window.Search"));
Filter("##Filter", data.m_Filter, TEXT("Window.Search"));
ImGui::PopItemWidth();
ImGui::Spacing();
@ -152,7 +151,7 @@ void Widget::DataList(ResourceStore& data, ArgCallback3 clickFunc, ArgCallback3
{
ImGui::Spacing();
ImGui::PushItemWidth(ImGui::GetWindowContentRegionWidth());
FilterWithHint("##Filter", data.m_Filter, TEXT("Window.Search"));
Filter("##Filter", data.m_Filter, TEXT("Window.Search"));
ImGui::PopItemWidth();
ImGui::Spacing();
ImGui::BeginChild(1);
@ -282,9 +281,9 @@ void Widget::ImageList(ResourceStore &store, ArgCallback leftClickFunc, ArgCallb
}
ImGui::PushItemWidth((ImGui::GetWindowContentRegionWidth() - style.ItemSpacing.x)/2);
Ui::ListBoxStr("##Categories", store.m_Categories, store.m_Selected);
Widget::ListBox("##Categories", store.m_Categories, store.m_Selected);
ImGui::SameLine();
FilterWithHint("##Filter", store.m_Filter, "Search");
Filter("##Filter", store.m_Filter, "Search");
ImGui::Spacing();
@ -372,4 +371,443 @@ void Widget::ImageList(ResourceStore &store, ArgCallback leftClickFunc, ArgCallb
}
}
ImGui::EndChild();
}
bool Widget::ColorBtn(int colorId, std::vector<float>& color, ImVec2 size)
{
bool rtn = false;
std::string label = "Color " + std::to_string(colorId);
if (ImGui::ColorButton(label.c_str(), ImVec4(color[0], color[1], color[2], 1), 0, size))
{
rtn = true;
}
if (ImGui::IsItemHovered())
{
ImDrawList* drawlist = ImGui::GetWindowDrawList();
drawlist->AddRectFilled(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(),
ImGui::GetColorU32(ImGuiCol_ModalWindowDimBg));
}
return rtn;
}
bool Widget::Checkbox(const char* label, bool* v, const char* hint, bool is_disabled)
{
// set things up
bool pressed = false;
const ImGuiStyle& style = ImGui::GetStyle();
const ImVec2 textSize = ImGui::CalcTextSize(label, nullptr, true);
float square_sz = ImGui::GetFrameHeight();
ImDrawList* drawlist = ImGui::GetWindowDrawList();
ImU32 color = ImGui::GetColorU32(ImGuiCol_FrameBg);
std::string slabel = "##InvCheckboxBtn" + std::string(label);
ImGui::BeginDisabled(is_disabled);
// process the button states
if (ImGui::InvisibleButton(slabel.c_str(), ImVec2(square_sz, square_sz)) && !is_disabled)
{
pressed = true;
*v = !*v;
}
if (ImGui::IsItemHovered() && !is_disabled)
{
color = ImGui::GetColorU32(ImGuiCol_FrameBgHovered);
}
// draw the button
ImVec2 min = ImGui::GetItemRectMin();
ImVec2 max = ImGui::GetItemRectMax();
drawlist->AddRectFilled(min, max, color, ImGui::GetStyle().FrameRounding);
int pad = static_cast<int>(square_sz / 6.0);
pad = (pad < 1) ? 1 : pad;
if (*v)
{
// draw the checkmark
float sz = (square_sz - pad * 2.0);
float thickness = sz / 5.0;
thickness = (thickness < 1.0) ? 1.0 : thickness;
sz = sz - thickness * 0.5;
auto pos = ImVec2(min.x + pad, min.y + pad);
pos.x = pos.x + thickness * 0.25;
pos.y = pos.y + thickness * 0.25;
float third = sz / 3.0;
float bx = pos.x + third;
float by = pos.y + sz - third * 0.5;
drawlist->PathLineTo(ImVec2(bx - third, by - third));
drawlist->PathLineTo(ImVec2(bx, by));
drawlist->PathLineTo(ImVec2(bx + third * 2.0, by - third * 2.0));
drawlist->PathStroke(ImGui::GetColorU32(ImGuiCol_CheckMark), false, thickness);
}
// draw label
ImGui::SameLine(0, style.ItemInnerSpacing.x);
if (ImGui::InvisibleButton(label, ImVec2(ImGui::CalcTextSize(label, nullptr, true).x, square_sz)) && !is_disabled)
{
pressed = true;
*v = !*v;
}
min = ImGui::GetItemRectMin();
drawlist->AddText(ImVec2(min.x, min.y + style.ItemInnerSpacing.y / 2), ImGui::GetColorU32(ImGuiCol_Text), label);
// draw hint
if (hint != nullptr)
{
ImGui::SameLine(0, style.ItemInnerSpacing.x);
ImGui::InvisibleButton("?", ImGui::CalcTextSize("?", nullptr, true));
min = ImGui::GetItemRectMin();
drawlist->AddText(ImVec2(min.x, min.y + style.ItemInnerSpacing.y / 2), ImGui::GetColorU32(ImGuiCol_TextDisabled),
"?");
if (ImGui::IsItemHovered() && !is_disabled)
{
ImGui::BeginTooltip();
ImGui::Text(hint);
ImGui::Spacing();
ImGui::EndTooltip();
}
}
ImGui::EndDisabled();
return pressed;
}
bool Widget::CheckboxAddr(const char* label, uint addr, const char* hint)
{
bool rtn = false;
bool state = patch::Get<bool>(addr, false);
if (Checkbox(label, &state, hint) && addr != NULL)
{
patch::Set<bool>(addr, state, false);
rtn = true;
}
return rtn;
}
bool Widget::CheckboxAddrRaw(const char* label, uint addr, size_t size, const char* enabled, const char* disabled, const char* hint)
{
bool rtn = false;
char* buf = new char[size+1];
patch::GetRaw(addr, buf, size);
buf[size] = '\0';
bool state = !strcmp(buf, enabled);
if (Checkbox(label, &state, hint))
{
if (state)
{
patch::SetRaw(addr, const_cast<char*>(enabled), size);
}
else
{
patch::SetRaw(addr, const_cast<char*>(disabled), size);
}
rtn = true;
}
delete buf;
return rtn;
}
bool Widget::CheckboxBits(const char* label, uint flag, const char* hint)
{
bool rtn = false;
bool state = (flag == 1) ? true : false;
if (Checkbox(label, &state, hint))
{
flag = state ? 1 : 0;
rtn = true;
}
return rtn;
}
void Widget::EditAddr(const char* label, uint address, float min, float def, float max, float mul, float change)
{
if (ImGui::CollapsingHeader(label))
{
float val = patch::Get<float>(address, false) * mul;
int items = 3;
if (min == def)
{
items = 2;
}
ImGui::Columns(items, nullptr, false);
ImGui::Text("Min: %f", min);
if (items == 3)
{
ImGui::NextColumn();
ImGui::Text("Def: %f", def);
}
ImGui::NextColumn();
ImGui::Text("Max: %f", max);
ImGui::Columns(1);
ImGui::Spacing();
int size = ImGui::GetFrameHeight();
if (ImGui::InputFloat(("##" + std::string(label)).c_str(), &val))
{
patch::SetFloat(address, val / mul, false);
}
ImGui::SameLine(0.0, 4.0);
if (ImGui::Button("-", ImVec2(size, size)) && (val - change) > min)
{
val -= change;
patch::SetFloat(address, val / mul, false);
}
ImGui::SameLine(0.0, 4.0);
if (ImGui::Button("+", ImVec2(size, size)) && (val + change) < max)
{
val += change;
patch::SetFloat(address, val / mul, false);
}
ImGui::SameLine(0.0, 4.0);
ImGui::Text("Set");
ImGui::Spacing();
if (ImGui::Button(("Minimum##" + std::string(label)).c_str(), CalcSize(items)))
{
patch::Set<float>(address, min / mul, false);
}
if (items == 3)
{
ImGui::SameLine();
if (ImGui::Button(("Default##" + std::string(label)).c_str(), CalcSize(items)))
{
patch::Set<float>(address, def / mul, false);
}
}
ImGui::SameLine();
if (ImGui::Button(("Maximum##" + std::string(label)).c_str(), CalcSize(items)))
{
patch::Set<float>(address, max / mul, false);
}
ImGui::Spacing();
ImGui::Separator();
}
}
void Widget::EditBits(const char* label, const int address, VecStr& names)
{
auto mem_val = (int*)address;
if (ImGui::CollapsingHeader(label))
{
ImGui::Columns(2, nullptr, false);
for (int i = 0; i < 32; ++i)
{
int mask = 1 << i;
bool state = *mem_val & mask;
if (ImGui::Checkbox(names[i].c_str(), &state))
{
*mem_val ^= mask;
}
if (i + 1 == 32 / 2)
{
ImGui::NextColumn();
}
}
ImGui::Columns(1);
ImGui::Spacing();
ImGui::Separator();
}
}
#ifdef GTASA
void Widget::EditStat(const char* label, const int stat_id, const int min, const int def, const int max)
{
if (ImGui::CollapsingHeader(label))
{
int val = static_cast<int>(CStats::GetStatValue(stat_id));
ImGui::Columns(3, nullptr, false);
ImGui::Text("Min: %d", min);
ImGui::NextColumn();
ImGui::Text("Def: %d", def);
ImGui::NextColumn();
ImGui::Text("Max: %d", max);
ImGui::Columns(1);
ImGui::Spacing();
if (ImGui::InputInt(("Set value##" + std::string(label)).c_str(), &val))
{
CStats::SetStatValue(stat_id, static_cast<float>(val));
}
ImGui::Spacing();
if (ImGui::Button(("Minimum##" + std::string(label)).c_str(), CalcSize(3)))
{
CStats::SetStatValue(stat_id, static_cast<float>(min));
}
ImGui::SameLine();
if (ImGui::Button(("Default##" + std::string(label)).c_str(), CalcSize(3)))
{
CStats::SetStatValue(stat_id, static_cast<float>(def));
}
ImGui::SameLine();
if (ImGui::Button(("Maximum##" + std::string(label)).c_str(), CalcSize(3)))
{
CStats::SetStatValue(stat_id, static_cast<float>(max));
}
ImGui::Spacing();
ImGui::Separator();
}
}
#endif
bool Widget::ListBox(const char* label, VecStr& allItems, std::string& selected)
{
bool rtn = false;
if (ImGui::BeginCombo(label, selected.c_str()))
{
for (std::string curItem : allItems)
{
if (ImGui::MenuItem(curItem.c_str()))
{
selected = curItem;
rtn = true;
}
}
ImGui::EndCombo();
}
return rtn;
}
bool Widget::ListBox(const char* label, VecStr& allItems, int& selected)
{
bool rtn = false;
if (ImGui::BeginCombo(label, std::to_string(selected).c_str()))
{
for (size_t index = 0; index < allItems.size(); ++index)
{
if (ImGui::MenuItem(allItems[index].c_str()))
{
selected = index;
rtn = true;
}
}
ImGui::EndCombo();
}
return rtn;
}
void Widget::EditRadioBtnAddr(const char* label, std::vector<BindInfo>& addrInfo)
{
if (ImGui::CollapsingHeader(label))
{
size_t btnsInColumn = addrInfo.size() / 2 - 1;
ImGui::Columns(2, nullptr, false);
bool state = true;
for (size_t i = 0; i < addrInfo.size(); i++)
{
if (patch::Get<bool>(addrInfo[i].val, false))
{
state = false;
}
}
if (ImGui::RadioButton((std::string("None##") + label).c_str(), state))
{
for (size_t i = 0; i < addrInfo.size(); i++)
{
patch::Set<bool>(addrInfo[i].val, false);
}
}
for (size_t i = 0; i < addrInfo.size(); i++)
{
state = patch::Get<bool>(addrInfo[i].val, false);
if (ImGui::RadioButton(addrInfo[i].name.c_str(), state))
{
for (size_t i = 0; i < addrInfo.size(); i++)
{
patch::Set<bool>(addrInfo[i].val, false);
}
patch::Set<bool>(addrInfo[i].val, true);
}
if (i == btnsInColumn)
{
ImGui::NextColumn();
}
}
ImGui::Columns(1);
ImGui::Spacing();
ImGui::Separator();
}
}
void Widget::EditRadioBtnAddr(const char* label, uint addr, std::vector<BindInfo>& valInfo)
{
if (ImGui::CollapsingHeader(label))
{
size_t btnsInColumn = valInfo.size() / 2;
ImGui::Columns(2, nullptr, false);
int mem_val = 0;
patch::GetRaw(addr, &mem_val, 1, false);
for (size_t i = 0; i < valInfo.size(); i++)
{
if (ImGui::RadioButton(valInfo[i].name.c_str(), &mem_val, valInfo[i].val))
{
patch::SetRaw(addr, &valInfo[i].val, 1, false);
}
if (i == btnsInColumn)
{
ImGui::NextColumn();
}
}
ImGui::Columns(1);
ImGui::Spacing();
ImGui::Separator();
}
}

View File

@ -4,32 +4,152 @@
/*
Widgets Class
Contains useful ui utilities
TODO:
Replace the horrible Ui class
*/
class Widget
{
private:
using VecStr = const std::vector<std::string>;
public:
struct BindInfo
{
std::string name;
uint val;
};
Widget() = delete;
Widget(Widget&) = delete;
// Calculates button size based on window width & spacing flags
static ImVec2 CalcSize(short count = 1, bool spacing = true);
// Regular checkbox with hint support
static bool Checkbox(const char* label, bool* state, const char* hint = nullptr,
bool is_disabled = false);
// Checkbox for bool memory address
static bool CheckboxAddr(const char* label, uint addr, const char* hint = nullptr);
// Checkbox with raw memory input
static bool CheckboxAddrRaw(const char* label, uint addr, uint size, const char* enabled,
const char* disabled, const char* hint = nullptr);
// Checkbox for bit fields
static bool CheckboxBits(const char* label, uint flag, const char* hint = nullptr);
// Displays a button with specified color id
static bool ColorBtn(int colorId, std::vector<float>& color, ImVec2 size);
// Draws DataStore data in the interface
static void DataList(ResourceStore& data, ArgCallback3 clickFunc, ArgCallback3 removeFunc);
// Draws a dropdown editor for memory address
template <typename T>
static void EditAddr(const char* label, uint address, int min = 0, int def = 0, int max = 100);
// Draws a dropdown editor for memory address float
static void EditAddr(const char* label, uint address, float min = 0.0f, float def = 0.0f,
float max = 100.0f, float mul = 1, float change = 1.0f);
// Draws a dropdown editor for memory bits
static void EditBits(const char* label, int address, VecStr& names);
// Draws radio button list from address
static void EditRadioBtnAddr(const char* label, std::vector<BindInfo>& addrInfo);
static void EditRadioBtnAddr(const char* label, uint addr, std::vector<BindInfo>& valInfo);
#ifdef GTASA
// Draws a dropdown editor for editing stats, only sa
static void EditStat(const char* label, int stat_id, int min = 0, int def = 0, int max = 1000);
#endif
// ImGui::TextFilter with hint support
static void FilterWithHint(const char* label, ImGuiTextFilter& filter, const char* hint);
static void Filter(const char* label, ImGuiTextFilter& filter, const char* hint);
// Draws ResourceStore images in the interface
static void ImageList(ResourceStore &store, ArgCallback leftClickFunc, ArgCallback rightClickFunc,
ArgCallbackRtn getNameFunc, ArgCallbackRtnBool verifyFunc = nullptr);
// Draws a dropdown listbox
static bool ListBox(const char* label, VecStr& allItems, int& selected);
static bool ListBox(const char* label, VecStr& allItems, std::string& selected);
// Text aligned to the center of the window
static void TextCentered(const std::string& text);
// Displays a popup with helpful text
static void Tooltip(const char* text);
};
};
template <typename T>
void Widget::EditAddr(const char* label, uint address, int min, int def, int max)
{
if (ImGui::CollapsingHeader(label))
{
int val = patch::Get<T>(address, false);
int items = 3;
if (min == def)
{
items = 2;
}
ImGui::Columns(items, nullptr, false);
ImGui::Text(("Min: " + std::to_string(min)).c_str());
if (items == 3)
{
ImGui::NextColumn();
ImGui::Text(("Def: " + std::to_string(def)).c_str());
}
ImGui::NextColumn();
ImGui::Text(("Max: " + std::to_string(max)).c_str());
ImGui::Columns(1);
ImGui::Spacing();
if (ImGui::InputInt(("Set value##" + std::string(label)).c_str(), &val))
{
patch::Set<T>(address, val, false);
}
ImGui::Spacing();
if (val < min)
{
val = min;
}
if (val > max)
{
val = max;
}
if (ImGui::Button(("Minimum##" + std::string(label)).c_str(), CalcSize(items)))
{
patch::Set<T>(address, min, false);
}
if (items == 3)
{
ImGui::SameLine();
if (ImGui::Button(("Default##" + std::string(label)).c_str(), CalcSize(3)))
{
patch::Set<T>(address, def, false);
}
}
ImGui::SameLine();
if (ImGui::Button(("Maximum##" + std::string(label)).c_str(), CalcSize(items)))
{
patch::Set<T>(address, max, false);
}
ImGui::Spacing();
ImGui::Separator();
}
}

View File

@ -74,8 +74,8 @@ project "CheatMenuIII"
"../src/updater.cpp",
"../src/datastore.h",
"../src/datastore.cpp",
"../src/ui.h",
"../src/ui.cpp",
"../src/widget.h",
"../src/widget.cpp",
"../src/log.h",
"../src/log.cpp",
"../src/util.h",
@ -174,8 +174,8 @@ project "CheatMenuVC"
"../src/player.cpp",
"../src/ped.h",
"../src/ped.cpp",
"../src/ui.h",
"../src/ui.cpp",
"../src/widget.h",
"../src/widget.cpp",
"../src/log.h",
"../src/log.cpp",
"../src/vehicle.h",