Bug fixes & tweaks

1. Fixed FPS issue with windowed mode
2. Probably fixed issues with json saving/loading?
3. Added first time welcome page
4. Some refactored code
This commit is contained in:
Grinch_ 2020-12-22 02:24:07 +06:00
parent b14d43caac
commit 47d1dab0c2
17 changed files with 366 additions and 285 deletions

View File

@ -6,8 +6,6 @@ set(no_group_source_files
"Animation.h"
"CheatMenu.cpp"
"CheatMenu.h"
"CustomWidgets.cpp"
"CustomWidgets.h"
"Events.cpp"
"Events.h"
"external/imgui/imgui_impl_dx11.cpp"

View File

@ -18,6 +18,9 @@ void CheatMenu::ProcessMenu()
Ui::DrawHeaders(header);
Globals::menu_size = ImGui::GetWindowSize();
config.SetValue("window.sizeX", Globals::menu_size.x);
config.SetValue("window.sizeY", Globals::menu_size.y);
ImGui::PopStyleVar(2);
ImGui::End();
}
@ -48,8 +51,9 @@ CheatMenu::CheatMenu()
flog << "Log Started." << std::endl;
// Load menu settings
Globals::menu_size.x = config.GetValue<float>("window.sizeX", screen::GetScreenWidth() / 4.0f);
Globals::menu_size.y = config.GetValue<float>("window.sizeY", screen::GetScreenHeight() / 1.2f);
Globals::header_id = config.GetValueStr("window.id","");
Globals::menu_size.x = config.GetValue("window.sizeX", screen::GetScreenWidth() / 4.0f);
Globals::menu_size.y = config.GetValue("window.sizeY", screen::GetScreenHeight() / 1.2f);
srand(CTimer::m_snTimeInMilliseconds);
};
@ -70,7 +74,14 @@ CheatMenu::CheatMenu()
Globals::last_key_timer = CTimer::m_snTimeInMilliseconds;
}
Hook::show_mouse = Globals::show_menu || Menu::commands::show_menu;
bool windows_visible = Globals::show_menu || Menu::commands::show_menu;
if (Hook::show_mouse != windows_visible)
{
if (Hook::show_mouse) // Only write when the menu closes
config.WriteToDisk();
Hook::show_mouse = windows_visible;
}
}
};
@ -81,11 +92,6 @@ CheatMenu::CheatMenu()
Events::shutdownRwEvent += []
{
// Save config data
config.SetValue("window.sizeX", Globals::menu_size.x);
config.SetValue("window.sizeY", Globals::menu_size.y);
config.WriteToDisk();
flog << "Log Finished." << std::endl;
};
}

View File

@ -1,90 +0,0 @@
#include "pch.h"
#include "CustomWidgets.h"
// Checkbox with support for hints, disable
bool CustomWidgets::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 text_size = ImGui::CalcTextSize(label, NULL, true);
float square_sz = ImGui::GetFrameHeight();
ImDrawList *drawlist = ImGui::GetWindowDrawList();
ImU32 color = ImGui::GetColorU32(ImGuiCol_FrameBg);
std::string slabel = "##InvCheckboxBtn" + std::string(label);
if (is_disabled)
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
// 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);
int pad = 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;
ImVec2 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, NULL, true).x, square_sz)) && !is_disabled)
{
pressed = true;
*v = !*v;
}
min = ImGui::GetItemRectMin();
drawlist->AddText(ImVec2(min.x, min.y + style.ItemInnerSpacing.y), ImGui::GetColorU32(ImGuiCol_Text), label);
// draw hint
if (hint != nullptr)
{
ImGui::SameLine(0, style.ItemInnerSpacing.x);
ImGui::InvisibleButton("?", ImGui::CalcTextSize("?", NULL, true));
min = ImGui::GetItemRectMin();
drawlist->AddText(ImVec2(min.x, min.y + style.ItemInnerSpacing.y), ImGui::GetColorU32(ImGuiCol_TextDisabled), "?");
if (ImGui::IsItemHovered() && !is_disabled)
{
ImGui::BeginTooltip();
ImGui::Text(hint);
ImGui::Spacing();
ImGui::EndTooltip();
}
}
if (is_disabled)
ImGui::PopStyleVar();
return pressed;
}

View File

@ -1,7 +0,0 @@
#pragma once
class CustomWidgets
{
public:
static bool Checkbox(const char* label, bool* v, const char* hint = nullptr, bool is_disabled = false);
};

View File

@ -58,6 +58,14 @@ HRESULT Hook::PresentDx9(IDirect3DDevice9 *pDevice, RECT* pSourceRect, RECT* pDe
Globals::font_screen_size = ImVec2(screen::GetScreenWidth(), screen::GetScreenHeight());
}
static RwBool fullscreen = RsGlobal.ps->fullScreen;
if (fullscreen != RsGlobal.ps->fullScreen)
{
flog << "LETS GO" << std::endl;
fullscreen = RsGlobal.ps->fullScreen;
ImGui_ImplDX9_InvalidateDeviceObjects();
}
ImGui_ImplDX9_NewFrame();
ImGui_ImplWin32_NewFrame();
ImGui::NewFrame();
@ -158,15 +166,15 @@ void Hook::ShowMouse(bool state)
{
if (state)
{
patch::PutRetn(0x6194A0);
patch::SetUChar(0x6194A0, 0xC3);
patch::Nop(0x53F417, 5); // don't call CPad__getMouseState
patch::SetRaw(0x53F41F, "\x33\xC0\x0F\x84", 4);
patch::SetRaw(0x53F41F, "\x33\xC0\x0F\x84", 4); // disable camera mouse movement
}
else
{
patch::SetRaw(0x541DF5, "\xE8\x46\xF3\xFE\xFF", 5); // call CControllerConfigManager::AffectPadFromKeyBoard
patch::SetRaw(0x53F417, "\xE8\xB4\x7A\x20\x00", 5); // call CPad__getMouseState
patch::SetRaw(0x53F41F, "\x85\xC0\x0F\x8C", 4); // xor eax, eax -> test eax, eax
patch::SetRaw(0x53F41F, "\x85\xC0\x0F\x8C", 4); // xor eax, eax -> test eax, eax , enable camera mouse movement
// jz loc_53F526 -> jl loc_53F526
patch::SetUChar(0x6194A0, 0xE9); // jmp setup
}

View File

@ -1,25 +1,28 @@
#include "pch.h"
#include "Json.h"
CJson::CJson(const char* name,bool create_new)
CJson::CJson(const char* name)
{
file_path = "./CheatMenu/json/"+ std::string(name) +".json";
if (std::experimental::filesystem::exists(file_path))
{
std::ifstream file(file_path);
file >> data;
file.close();
try
{
std::ifstream file(file_path);
file >> data;
file.close();
}
catch (...)
{
flog << "Error occured trying to read " << file_path << std::endl;
data = "{}"_json;
}
}
else
{
if (create_new)
{
std::fstream new_file(file_path,std::fstream::out);
data = "{}"_json;
new_file.close();
}
else flog << "File doesn't exist " << file_path << std::endl;
data = "{}"_json;
flog << "File doesn't exist " << file_path << std::endl;
}
}
@ -36,6 +39,37 @@ void CJson::LoadData(std::vector<std::string>& vec, std::string& selected) // Te
vec.push_back(element.key());
}
std::string CJson::GetValueStr(std::string&& key, std::string&& default_val)
{
try {
std::stringstream ss(key);
std::string line;
nlohmann::json *json = &data;
while (getline(ss, line, '.'))
json = &((*json)[line]);
return json->get<std::string>();
}
catch (...) {
return default_val;
}
}
void CJson::SetValueStr(std::string&& key, std::string& val)
{
std::stringstream ss(key);
std::string line;
nlohmann::json *json = &data;
while (getline(ss, line, '.'))
json = &((*json)[line]);
*json = val;
}
CJson::~CJson()
{
// Saving here won't work on crash

View File

@ -13,6 +13,9 @@ public:
Returns a value from json structure hierarchy using '.'
Example: "Menu.Window.X"
*/
// overload since typeid(std::string) doesn't work
std::string GetValueStr(std::string&& key, std::string&& default_val);
template <typename T>
T GetValue(std::string&& key, T&& default_val)
{
@ -42,6 +45,7 @@ public:
Allows to save values in json hierarchy using '.'
Example: "Menu.Window.X"
*/
template <typename T>
void SetValue(std::string&& key, T&& val)
{
@ -60,6 +64,7 @@ public:
*json = val;
}
void SetValueStr(std::string&& key, std::string& val);
/*
Loads the section names into a category vector.
Used to create drop down category menus
@ -70,7 +75,7 @@ public:
Saves json data to disk
*/
void WriteToDisk();
CJson(const char* text, bool create_new = false);
CJson(const char* text);
~CJson();
};

View File

@ -55,36 +55,6 @@ Menu::Menu()
hotkey::command_window[0] = config.GetValue("hotkey.command_window.key1", VK_LMENU);
hotkey::command_window[1] = config.GetValue("hotkey.command_window.key2", VK_KEY_C);
};
Events::shutdownRwEvent += []
{
// save config data
config.SetValue("overlay.coord", overlay::coord);
config.SetValue("overlay.fps", overlay::fps);
config.SetValue("overlay.loc_name", overlay::loc_name);
config.SetValue("overlay.transparent", overlay::transparent);
config.SetValue("overlay.veh_health", overlay::veh_health);
config.SetValue("overlay.veh_speed", overlay::veh_speed);
config.SetValue("overlay.selected_pos", overlay::selected_pos);
config.SetValue("overlay.posX", overlay::posX);
config.SetValue("overlay.posY", overlay::posY);
// Hotkeys
config.SetValue("hotkey.aim_skin_changer.key1", hotkey::aim_skin_changer[0]);
config.SetValue("hotkey.aim_skin_changer.key2", hotkey::aim_skin_changer[1]);
config.SetValue("hotkey.quick_screenshot.key1", hotkey::quick_ss[0]);
config.SetValue("hotkey.quick_screenshot.key2", hotkey::quick_ss[1]);
config.SetValue("hotkey.quick_tp.key1", hotkey::quick_tp[0]);
config.SetValue("hotkey.quick_tp.key2", hotkey::quick_tp[1]);
config.SetValue("hotkey.menu_open.key1", hotkey::menu_open[0]);
config.SetValue("hotkey.menu_open.key2", hotkey::menu_open[1]);
config.SetValue("hotkey.command_window.key1", hotkey::command_window[0]);
config.SetValue("hotkey.command_window.key2", hotkey::command_window[1]);
};
}
Menu::~Menu()
@ -112,7 +82,11 @@ void Menu::ProcessOverlay()
else
{
if (overlay::posX != NULL && overlay::posY != NULL)
{
config.SetValue("overlay.posX", overlay::posX);
config.SetValue("overlay.posY", overlay::posY);
ImGui::SetNextWindowPos(ImVec2(overlay::posX, overlay::posY), ImGuiCond_Once);
}
}
ImGui::SetNextWindowBgAlpha(overlay::transparent ? 0.0f : 0.5f);
@ -278,34 +252,69 @@ void Menu::Main()
ImGui::Spacing();
ImGui::Spacing();
ImGui::SameLine();
Ui::ListBox("Overlay", overlay::pos_names, overlay::selected_pos);
if (Ui::ListBox("Overlay", overlay::pos_names, overlay::selected_pos))
config.SetValue("overlay.selected_pos", overlay::selected_pos);
ImGui::Spacing();
ImGui::Columns(2, NULL, false);
ImGui::Checkbox("No background", &overlay::transparent);
ImGui::Checkbox("Show coordinates", &overlay::coord);
ImGui::Checkbox("Show FPS", &overlay::fps);
if (ImGui::Checkbox("No background", &overlay::transparent))
config.SetValue("overlay.transparent", overlay::transparent);
if (ImGui::Checkbox("Show coordinates", &overlay::coord))
config.SetValue("overlay.coord", overlay::coord);
if (ImGui::Checkbox("Show FPS", &overlay::fps))
config.SetValue("overlay.fps", overlay::fps);
ImGui::NextColumn();
ImGui::Checkbox("Show location", &overlay::loc_name);
ImGui::Checkbox("Show veh health", &overlay::veh_health);
ImGui::Checkbox("Show veh speed", &overlay::veh_speed);
if (ImGui::Checkbox("Show location", &overlay::loc_name))
config.SetValue("overlay.loc_name", overlay::loc_name);
if (ImGui::Checkbox("Show veh health", &overlay::veh_health))
config.SetValue("overlay.veh_health", overlay::veh_health);
if (ImGui::Checkbox("Show veh speed", &overlay::veh_speed))
config.SetValue("overlay.veh_speed", overlay::veh_speed);
ImGui::Columns(1);
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Hotkeys"))
{
ImGui::Spacing();
ImGui::BeginChild("Hotkeys");
Ui::HotKey("Open/ close cheat menu", hotkey::menu_open);
Ui::HotKey("Open/ close command window", hotkey::command_window);
if (Ui::HotKey("Open/ close cheat menu", hotkey::menu_open))
{
config.SetValue("hotkey.menu_open.key1", hotkey::menu_open[0]);
config.SetValue("hotkey.menu_open.key2", hotkey::menu_open[1]);
}
if (Ui::HotKey("Open/ close command window", hotkey::command_window))
{
config.SetValue("hotkey.command_window.key1", hotkey::command_window[0]);
config.SetValue("hotkey.command_window.key2", hotkey::command_window[1]);
}
ImGui::Dummy(ImVec2(0,10));
Ui::HotKey("Activate aim skin changer", hotkey::aim_skin_changer);
Ui::HotKey("Take quick screenshot", hotkey::quick_ss);
Ui::HotKey("Toggle quick teleport", hotkey::quick_tp);
if (Ui::HotKey("Activate aim skin changer", hotkey::aim_skin_changer))
{
config.SetValue("hotkey.aim_skin_changer.key1", hotkey::aim_skin_changer[0]);
config.SetValue("hotkey.aim_skin_changer.key2", hotkey::aim_skin_changer[1]);
}
if (Ui::HotKey("Take quick screenshot", hotkey::quick_ss))
{
config.SetValue("hotkey.quick_screenshot.key1", hotkey::quick_ss[0]);
config.SetValue("hotkey.quick_screenshot.key2", hotkey::quick_ss[1]);
}
if (Ui::HotKey("Toggle quick teleport", hotkey::quick_tp))
{
config.SetValue("hotkey.quick_tp.key1", hotkey::quick_tp[0]);
config.SetValue("hotkey.quick_tp.key2", hotkey::quick_tp[1]);
}
ImGui::Dummy(ImVec2(0, 10));
@ -357,12 +366,12 @@ void Menu::Main()
ImGui::Spacing();
if (ImGui::Button("Discord server", ImVec2(Ui::GetSize(2))))
ShellExecute(NULL, "open", "https://discord.gg/ZzW7kmf", NULL, NULL, SW_SHOWNORMAL);
ShellExecute(NULL, "open", DISCORD_INVITE, NULL, NULL, SW_SHOWNORMAL);
ImGui::SameLine();
if (ImGui::Button("GitHub repo", ImVec2(Ui::GetSize(2))))
ShellExecute(NULL, "open", "https://github.com/user-grinch/Cheat-Menu", NULL, NULL, SW_SHOWNORMAL);
ShellExecute(NULL, "open", GITHUB_LINK, NULL, NULL, SW_SHOWNORMAL);
ImGui::Spacing();
@ -391,7 +400,7 @@ void Menu::Main()
ImGui::Columns(1);
ImGui::Dummy(ImVec2(0, 10));
ImGui::TextWrapped("Copyright GPLv3 2019-2020 Grinch_");
ImGui::TextWrapped("Copyright GPLv3 2019-2021 Grinch_");
ImGui::EndChild();
}

View File

@ -53,11 +53,6 @@ Player::Player()
}
};
Events::shutdownRwEvent += []
{
config.SetValue("aim_skin_changer", aim_skin_changer);
};
Events::processScriptsEvent += []
{
uint timer = CTimer::m_snTimeInMilliseconds;
@ -338,8 +333,8 @@ void Player::Main()
if (ImGui::BeginTabItem("Appearance"))
{
ImGui::Spacing();
Ui::CheckboxWithHint("Aim skin changer", &aim_skin_changer,
(("Activate using Aim ped + ") + Ui::GetHotKeyNameString(Menu::hotkey::aim_skin_changer)).c_str());
if (Ui::CheckboxWithHint("Aim skin changer", &aim_skin_changer,(("Activate using Aim ped + ") + Ui::GetHotKeyNameString(Menu::hotkey::aim_skin_changer)).c_str()))
config.SetValue("aim_skin_changer", aim_skin_changer);
if (ImGui::BeginTabBar("AppearanceTabBar"))
{

View File

@ -87,16 +87,6 @@ Teleport::Teleport()
}
}
};
Events::shutdownRwEvent += []
{
// Clear the Radar coordinates
json.data.erase("Radar");
json.data["Radar"] = {};
config.SetValue("quick_teleport", quick_teleport);
};
}
void Teleport::TeleportPlayer(bool get_marker, CVector* pos, short interior_id)
@ -190,8 +180,11 @@ void Teleport::Main()
ImGui::Columns(2, 0, false);
ImGui::Checkbox("Insert coordinates", &insert_coord);
ImGui::NextColumn();
Ui::CheckboxWithHint("Quick teleport", &quick_teleport,
(std::string("Teleport to marker using ") + Ui::GetHotKeyNameString(Menu::hotkey::quick_tp)).c_str());
if (Ui::CheckboxWithHint("Quick teleport", &quick_teleport,
(std::string("Teleport to marker using ") + Ui::GetHotKeyNameString(Menu::hotkey::quick_tp)).c_str()))
{
config.SetValue("quick_teleport", quick_teleport);
}
ImGui::Columns(1);
ImGui::Spacing();
@ -255,6 +248,11 @@ void Teleport::Main()
if (ImGui::Button("Add location", Ui::GetSize()))
{
json.data["Custom"][location_buffer] = ("0, " + std::string(input_buffer));
// Clear the Radar coordinates
json.data.erase("Radar");
json.data["Radar"] = {};
json.WriteToDisk();
}
ImGui::EndTabItem();

View File

@ -1,6 +1,5 @@
#include "pch.h"
#include "Ui.h"
#include "CustomWidgets.h"
std::string Ui::current_hotkey = "";
@ -69,6 +68,14 @@ ImVec2 Ui::GetSize(short count,bool spacing)
return ImVec2(x, ImGui::GetFrameHeight()*1.3f);
}
void Ui::CenterdText(const std::string& text)
{
float font_size = ImGui::GetFontSize() * text.size() / 2;
ImGui::NewLine();
ImGui::SameLine(ImGui::GetWindowSize().x / 2 -font_size + (font_size / 1.8));
ImGui::Text(text.c_str());
}
void Ui::DrawHeaders(unsortedMap& data)
{
@ -83,12 +90,16 @@ void Ui::DrawHeaders(unsortedMap& data)
const char* btn_text = it->first.c_str();
if (btn_text == Globals::header_id)
{
colors[ImGuiCol_Button] = colors[ImGuiCol_ButtonActive];
func = it->second;
}
if (ImGui::Button(btn_text, GetSize(3, false)))
{
Globals::header_id = btn_text;
config.SetValueStr("window.id", Globals::header_id);
func = it->second;
}
@ -101,9 +112,34 @@ void Ui::DrawHeaders(unsortedMap& data)
ImGui::PopStyleVar();
ImGui::Dummy(ImVec2(0, 10));
if (Globals::header_id != "" && func != nullptr)
if (Globals::header_id == "")
{
if (ImGui::BeginChild("TABSBAR"))
// Show Welcome page
ImGui::NewLine();
std::string title = "Welcome to " + Globals::menu_title + " (" + BUILD_NUMBER + ")";
Ui::CenterdText(title.c_str());
Ui::CenterdText("Author: Grinch_");
ImGui::NewLine();
ImGui::TextWrapped("Please ensure you have the latest version from GitHub.");
ImGui::NewLine();
if (ImGui::Button("Discord server", ImVec2(Ui::GetSize(2))))
ShellExecute(NULL, "open", DISCORD_INVITE, NULL, NULL, SW_SHOWNORMAL);
ImGui::SameLine();
if (ImGui::Button("GitHub repo", ImVec2(Ui::GetSize(2))))
ShellExecute(NULL, "open", GITHUB_LINK, NULL, NULL, SW_SHOWNORMAL);
ImGui::NewLine();
ImGui::TextWrapped("If you find bugs or have suggestions, you can let me know at discord :)");
ImGui::NewLine();
Ui::CenterdText("Copyright GPLv3 2019-2021");
}
else
{
if ( func != nullptr && ImGui::BeginChild("TABSBAR"))
{
((void(*)(void))func)();
ImGui::EndChild();
@ -124,14 +160,90 @@ void Ui::ShowTooltip(const char* text)
}
}
bool Ui::CheckboxWithHint(const char* label, bool* state, const char* hint, const bool is_disabled)
bool Ui::CheckboxWithHint(const char* label, bool *v, const char * hint, bool is_disabled)
{
bool rtn = false;
// set things up
bool pressed = false;
const ImGuiStyle& style = ImGui::GetStyle();
const ImVec2 text_size = ImGui::CalcTextSize(label, NULL, true);
float square_sz = ImGui::GetFrameHeight();
ImDrawList *drawlist = ImGui::GetWindowDrawList();
ImU32 color = ImGui::GetColorU32(ImGuiCol_FrameBg);
std::string slabel = "##InvCheckboxBtn" + std::string(label);
if (CustomWidgets::Checkbox(label,state,hint,is_disabled))
rtn = true;
if (is_disabled)
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
return rtn;
// 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);
int pad = 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;
ImVec2 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, NULL, true).x, square_sz)) && !is_disabled)
{
pressed = true;
*v = !*v;
}
min = ImGui::GetItemRectMin();
drawlist->AddText(ImVec2(min.x, min.y + style.ItemInnerSpacing.y), ImGui::GetColorU32(ImGuiCol_Text), label);
// draw hint
if (hint != nullptr)
{
ImGui::SameLine(0, style.ItemInnerSpacing.x);
ImGui::InvisibleButton("?", ImGui::CalcTextSize("?", NULL, true));
min = ImGui::GetItemRectMin();
drawlist->AddText(ImVec2(min.x, min.y + style.ItemInnerSpacing.y), ImGui::GetColorU32(ImGuiCol_TextDisabled), "?");
if (ImGui::IsItemHovered() && !is_disabled)
{
ImGui::BeginTooltip();
ImGui::Text(hint);
ImGui::Spacing();
ImGui::EndTooltip();
}
}
if (is_disabled)
ImGui::PopStyleVar();
return pressed;
}
bool Ui::CheckboxAddress(const char* label, const int addr, const char* hint)
@ -674,9 +786,10 @@ void Ui::EditFloat(const char *label, const int address, const float min, const
}
}
void Ui::HotKey(const char* label, int* key_array)
bool Ui::HotKey(const char* label, int* key_array)
{
bool active = current_hotkey == label;
bool state = false;
if (active)
{
@ -709,7 +822,10 @@ void Ui::HotKey(const char* label, int* key_array)
if (ImGui::Button((text + std::string("##") + std::string(label)).c_str(), ImVec2(ImGui::GetWindowContentRegionWidth() / 3, ImGui::GetFrameHeight())))
{
if (active)
{
current_hotkey = "";
state = true;
}
else
current_hotkey = label;;
}
@ -721,6 +837,8 @@ void Ui::HotKey(const char* label, int* key_array)
if (!(ImGui::IsWindowFocused() || ImGui::IsItemVisible()))
current_hotkey = "";
return state;
}
bool Ui::HotKeyPressed(int *hotkey)

View File

@ -30,7 +30,7 @@ public:
std::function<void(std::string&)> function;
std::string value;
};
static void CenterdText(const std::string& text);
static bool ColorButton(int color_id, std::vector<float> &color, ImVec2 size);
static bool CheckboxAddress(const char* label, const int addr = NULL, const char* hint = nullptr);
static bool CheckboxAddressEx(const char* label, const int addr = NULL, int enabled_val = 1, int disabled_val = 0, const char* hint = nullptr);
@ -61,7 +61,7 @@ public:
static ImVec2 GetSize(short count = 1, bool spacing = true);
static void HotKey(const char* label, int* key_array);
static bool HotKey(const char* label, int* key_array);
static bool HotKeyPressed(int *hotkey);
static std::string GetHotKeyNameString(int *hotkey);

View File

@ -33,7 +33,6 @@ void Util::LoadTexturesInDirRecursive(const char *path, const char *file_ext,std
{
store_vec.push_back(std::make_unique<TextureStructure>());
HRESULT hr = -1;
flog << p.path().string() << std::endl;
if (Globals::renderer == Render_DirectX9)
hr = D3DXCreateTextureFromFileA(GetD3DDevice(), p.path().string().c_str(), &store_vec.back().get()->texture9);

View File

@ -5,6 +5,7 @@ bool Vehicle::bike_fly = false;
bool Vehicle::dont_fall_bike = false;
bool Vehicle::veh_heavy = false;
bool Vehicle::veh_watertight = false;
bool Vehicle::veh_nodmg = false;
bool Vehicle::lock_speed = false;
float Vehicle::lock_speed_val = 0;
@ -92,6 +93,16 @@ Vehicle::Vehicle()
{
int hveh = CPools::GetVehicleRef(veh);
if (veh_nodmg)
{
veh->m_nPhysicalFlags.bBulletProof = true;
veh->m_nPhysicalFlags.bExplosionProof = true;
veh->m_nPhysicalFlags.bFireProof = true;
veh->m_nPhysicalFlags.bCollisionProof = true;
veh->m_nPhysicalFlags.bMeeleProof = true;
veh->m_nVehicleFlags.bCanBeDamaged = true;
}
player->m_nPedFlags.CantBeKnockedOffBike = dont_fall_bike ? 1 : 2;
Command<Commands::SET_CAR_HEAVY>(hveh, veh_heavy);
Command<Commands::SET_CAR_WATERTIGHT>(hveh, veh_watertight);
@ -579,8 +590,12 @@ void Vehicle::Main()
if (ImGui::Button("Fix vehicle", ImVec2(Ui::GetSize(3))))
{
if (Command<Commands::IS_CHAR_IN_ANY_CAR>(hplayer))
if (player && player->m_pVehicle)
{
player->m_pVehicle->Fix();
player->m_pVehicle->m_fHealth = 1000.0f;
}
}
ImGui::SameLine();
@ -603,7 +618,9 @@ void Vehicle::Main()
if (ImGui::BeginTabBar("Vehicle", ImGuiTabBarFlags_NoTooltip + ImGuiTabBarFlags_FittingPolicyScroll))
{
bool is_driver = player->m_pVehicle && player->m_pVehicle->IsDriver(player);
CVehicle *pVeh = player->m_pVehicle;
bool is_driver = pVeh && player->m_pVehicle->IsDriver(player);
ImGui::Spacing();
if (ImGui::BeginTabItem("Checkboxes"))
@ -620,56 +637,90 @@ void Vehicle::Main()
Ui::CheckboxAddress("Boats fly", 0x969153);
Ui::CheckboxAddress("Cars fly", 0x969160);
Ui::CheckboxWithHint("Cars heavy", &veh_heavy);
Ui::CheckboxAddress("Decreased traffic", 0x96917A);
Ui::CheckboxWithHint("Don't fall off bike", &dont_fall_bike);
Ui::CheckboxAddress("Drive on water", 0x969152);
bool engine = is_driver
&& (!player->m_pVehicle->m_nVehicleFlags.bEngineBroken || player->m_pVehicle->m_nVehicleFlags.bEngineOn);
if (Ui::CheckboxWithHint("Engine on", &engine, "Applies to this vehicle only", !is_driver))
if (Ui::CheckboxWithHint("Damage proof", &veh_nodmg, "Every vehicle entered will be damage proof\nBullet, Collision, Explosion, Fire, Meele etc"))
{
player->m_pVehicle->m_nVehicleFlags.bEngineBroken = !engine;
player->m_pVehicle->m_nVehicleFlags.bEngineOn = engine;
if (pVeh && !veh_nodmg)
{
pVeh->m_nVehicleFlags.bCanBeDamaged = true;
pVeh->m_nPhysicalFlags.bBulletProof = false;
pVeh->m_nPhysicalFlags.bExplosionProof = false;
pVeh->m_nPhysicalFlags.bFireProof = false;
pVeh->m_nPhysicalFlags.bCollisionProof = false;
pVeh->m_nPhysicalFlags.bMeeleProof = false;
}
}
Ui::CheckboxAddress("Decreased traffic", 0x96917A);
ImGui::NextColumn();
Ui::CheckboxWithHint("Don't fall off bike", &dont_fall_bike);
Ui::CheckboxAddress("Drive on water", 0x969152);
Ui::CheckboxAddressEx("Lock train camera", 0x52A52F, 171, 6);
Ui::CheckboxAddress("Float away when hit", 0x969166);
Ui::CheckboxAddress("Green traffic lights", 0x96914E);
bool visible = is_driver && !player->m_pVehicle->m_bIsVisible;
if (Ui::CheckboxWithHint("Invisible car", &visible, "Applies to this vehicle only", !is_driver))
player->m_pVehicle->m_bIsVisible = !visible;
bool lights = is_driver && !player->m_pVehicle->ms_forceVehicleLightsOff;
if (Ui::CheckboxWithHint("Lights on", &lights, "Applies to this vehicle only", !is_driver))
player->m_pVehicle->ms_forceVehicleLightsOff = !lights;
bool lock_status = is_driver && (player->m_pVehicle->m_nDoorLock == CARLOCK_LOCKED_PLAYER_INSIDE);
if (Ui::CheckboxWithHint("Lock doors", &lock_status, "Applies to this vehicle only", !is_driver))
{
if (lock_status)
player->m_pVehicle->m_nDoorLock = CARLOCK_LOCKED_PLAYER_INSIDE;
else
player->m_pVehicle->m_nDoorLock = CARLOCK_UNLOCKED;
}
bool no_dmg = is_driver && (!player->m_pVehicle->m_nVehicleFlags.bCanBeDamaged);
if (Ui::CheckboxWithHint("No damage", &no_dmg, "Applies to this vehicle only", !is_driver))
player->m_pVehicle->m_nVehicleFlags.bCanBeDamaged = !no_dmg;
Ui::CheckboxAddress("Perfect handling", 0x96914C);
Ui::CheckboxAddress("Tank mode", 0x969164);
Ui::CheckboxWithHint("Unlimited nitro", &unlimited_nitro::enabled, "Nitro will activate when left clicked\n\
\nEnabling this would disable\nAll cars have nitro\nAll taxis have nitro");
Ui::CheckboxWithHint("Watertight car", &veh_watertight);
Ui::CheckboxAddress("Wheels only", 0x96914B);
ImGui::Columns(1);
if (is_driver)
{
ImGui::NewLine();
ImGui::TextWrapped("For current vehicle,");
ImGui::Columns(2, 0, false);
bool state = pVeh->m_nPhysicalFlags.bBulletProof;
if (Ui::CheckboxWithHint("Bullet proof", &state, nullptr, veh_nodmg))
pVeh->m_nPhysicalFlags.bBulletProof = state;
state = pVeh->m_nPhysicalFlags.bCollisionProof;
if (Ui::CheckboxWithHint("Collision proof", &state, nullptr, veh_nodmg))
pVeh->m_nPhysicalFlags.bCollisionProof = state;
state = !pVeh->m_nVehicleFlags.bEngineBroken || pVeh->m_nVehicleFlags.bEngineOn;
if (Ui::CheckboxWithHint("Engine on", &state, nullptr, !is_driver))
{
pVeh->m_nVehicleFlags.bEngineBroken = !state;
pVeh->m_nVehicleFlags.bEngineOn = state;
}
state = pVeh->m_nPhysicalFlags.bExplosionProof;
if (Ui::CheckboxWithHint("Explosion proof", &state, nullptr, veh_nodmg))
pVeh->m_nPhysicalFlags.bExplosionProof = state;
state = pVeh->m_nPhysicalFlags.bFireProof;
if (Ui::CheckboxWithHint("Fire proof", &state, nullptr, veh_nodmg))
pVeh->m_nPhysicalFlags.bFireProof = state;
ImGui::NextColumn();
state = !pVeh->m_bIsVisible;
if (Ui::CheckboxWithHint("Invisible car", &state, nullptr, !is_driver))
pVeh->m_bIsVisible = !state;
state = !pVeh->ms_forceVehicleLightsOff;
if (Ui::CheckboxWithHint("Lights on", &state, nullptr, !is_driver))
pVeh->ms_forceVehicleLightsOff = !state;
state = pVeh->m_nDoorLock == CARLOCK_LOCKED_PLAYER_INSIDE;
if (Ui::CheckboxWithHint("Lock doors", &state, nullptr, !is_driver))
{
if (state)
pVeh->m_nDoorLock = CARLOCK_LOCKED_PLAYER_INSIDE;
else
pVeh->m_nDoorLock = CARLOCK_UNLOCKED;
}
state = pVeh->m_nPhysicalFlags.bMeeleProof;
if (Ui::CheckboxWithHint("Melee proof", &state, nullptr, veh_nodmg))
pVeh->m_nPhysicalFlags.bMeeleProof = state;
ImGui::Columns(1);
}
ImGui::EndChild();
ImGui::EndTabItem();
}
@ -677,7 +728,7 @@ void Vehicle::Main()
{
ImGui::Spacing();
ImGui::BeginChild("MenusChild");
Ui::EditFloat("Density multiplier", 0x8A5B20, 0, 1, 10);
if (ImGui::CollapsingHeader("Enter nearest vehicle as"))
{
CPlayerPed *player = FindPlayerPed();
@ -727,58 +778,13 @@ void Vehicle::Main()
ImGui::Spacing();
ImGui::Separator();
}
if (player && player->m_pVehicle)
{
CVehicle *veh = player->m_pVehicle;
int hveh = CPools::GetVehicleRef(veh);
Ui::EditFloat("Density multiplier", 0x8A5B20, 0, 1, 10);
Ui::EditFloat("Dirt level", (int)veh + 0x4B0, 0, 7.5, 15);
if (ImGui::CollapsingHeader("Damage flags"))
{
ImGui::Spacing();
ImGui::TextWrapped("Flags apply to this vehicle only");
ImGui::Spacing();
bool no_dmg_flag = veh->m_nVehicleFlags.bCanBeDamaged;
bool state = is_driver && (!no_dmg_flag);
ImGui::Spacing();
ImGui::SameLine();
if (Ui::CheckboxWithHint("No damage", &state, nullptr, !is_driver))
veh->m_nVehicleFlags.bCanBeDamaged = !state;
ImGui::Spacing();
ImGui::Columns(2, 0, false);
state = is_driver && (veh->m_nPhysicalFlags.bBulletProof);
if (Ui::CheckboxWithHint("Bullet proof", &state, nullptr, !no_dmg_flag))
veh->m_nPhysicalFlags.bBulletProof = state;
state = is_driver && (veh->m_nPhysicalFlags.bCollisionProof);
if (Ui::CheckboxWithHint("Collision proof", &state, nullptr, !no_dmg_flag))
veh->m_nPhysicalFlags.bCollisionProof = state;
state = is_driver && (veh->m_nPhysicalFlags.bExplosionProof);
if (Ui::CheckboxWithHint("Explosion proof", &state, nullptr, !no_dmg_flag))
veh->m_nPhysicalFlags.bExplosionProof = state;
ImGui::NextColumn();
state = is_driver && (veh->m_nPhysicalFlags.bFireProof);
if (Ui::CheckboxWithHint("Fire proof", &state, nullptr, !no_dmg_flag))
veh->m_nPhysicalFlags.bFireProof = state;
state = is_driver && (veh->m_nPhysicalFlags.bMeeleProof);
if (Ui::CheckboxWithHint("Melee proof", &state, nullptr, !no_dmg_flag))
veh->m_nPhysicalFlags.bMeeleProof = state;
ImGui::Columns(1);
ImGui::Spacing();
ImGui::Separator();
}
if (veh->m_nVehicleClass == VEHICLE_AUTOMOBILE && ImGui::CollapsingHeader("Doors"))
{
ImGui::Columns(2, 0, false);

View File

@ -9,7 +9,7 @@ private:
static bool dont_fall_bike;
static bool veh_heavy;
static bool veh_watertight;
static bool veh_nodmg;
static int door_menu_button;
static std::string door_names[6];

View File

@ -3,7 +3,7 @@
std::string Globals::header_id = "";
int Globals::last_key_timer = 0;
ImVec2 Globals::menu_size = ImVec2(screen::GetScreenWidth()/4, screen::GetScreenHeight()/1.2);
std::string Globals::menu_title = std::string("Cheat Menu v") + std::string(MENU_VERSION);
std::string Globals::menu_title = std::string("Cheat Menu v") + std::string(MENU_VERSION) + " (" BUILD_NUMBER + ")";
ImVec2 Globals::font_screen_size = ImVec2(-1, -1);
bool Globals::show_menu = false;
bool Globals::init_done = false;
@ -11,5 +11,5 @@ Renderer Globals::renderer = Render_Unknown;
ID3D11Device *Globals::device11 = nullptr;
std::string Globals::menu_path = paths::GetPluginDirPathA();
CJson config = CJson("config", true);
std::ofstream flog = std::ofstream("CheatMenu.log");
CJson config = CJson("config");

View File

@ -6,6 +6,8 @@
#define MENU_VERSION "2.5-beta"
#define BUILD_NUMBER "20201220"
#define STB_IMAGE_IMPLEMENTATION
#define DISCORD_INVITE "https://discord.gg/ZzW7kmf"
#define GITHUB_LINK "https://github.com/user-grinch/Cheat-Menu"
#include <d3d9.h>
#include <d3d11.h>