From 47d1dab0c276ff74239e6f63711347e969fb948a Mon Sep 17 00:00:00 2001 From: Grinch_ Date: Tue, 22 Dec 2020 02:24:07 +0600 Subject: [PATCH] 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 --- src/CMakeLists.txt | 2 - src/CheatMenu.cpp | 22 ++++-- src/CustomWidgets.cpp | 90 ---------------------- src/CustomWidgets.h | 7 -- src/Hook.cpp | 14 +++- src/Json.cpp | 56 +++++++++++--- src/Json.h | 9 ++- src/Menu.cpp | 99 +++++++++++++----------- src/Player.cpp | 9 +-- src/Teleport.cpp | 22 +++--- src/Ui.cpp | 136 ++++++++++++++++++++++++++++++--- src/Ui.h | 4 +- src/Util.cpp | 1 - src/Vehicle.cpp | 172 ++++++++++++++++++++++-------------------- src/Vehicle.h | 2 +- src/pch.cpp | 4 +- src/pch.h | 2 + 17 files changed, 366 insertions(+), 285 deletions(-) delete mode 100644 src/CustomWidgets.cpp delete mode 100644 src/CustomWidgets.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 06e55dd..9bb43a7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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" diff --git a/src/CheatMenu.cpp b/src/CheatMenu.cpp index 03cb8ec..6ea78d7 100644 --- a/src/CheatMenu.cpp +++ b/src/CheatMenu.cpp @@ -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("window.sizeX", screen::GetScreenWidth() / 4.0f); - Globals::menu_size.y = config.GetValue("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; }; } diff --git a/src/CustomWidgets.cpp b/src/CustomWidgets.cpp deleted file mode 100644 index 6509a2c..0000000 --- a/src/CustomWidgets.cpp +++ /dev/null @@ -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; -} diff --git a/src/CustomWidgets.h b/src/CustomWidgets.h deleted file mode 100644 index 586c0c7..0000000 --- a/src/CustomWidgets.h +++ /dev/null @@ -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); -}; - diff --git a/src/Hook.cpp b/src/Hook.cpp index 96bc9cb..0000e25 100644 --- a/src/Hook.cpp +++ b/src/Hook.cpp @@ -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 } diff --git a/src/Json.cpp b/src/Json.cpp index 00bd4cb..f65bb35 100644 --- a/src/Json.cpp +++ b/src/Json.cpp @@ -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& 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(); + } + 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 diff --git a/src/Json.h b/src/Json.h index 5eafc70..a6da729 100644 --- a/src/Json.h +++ b/src/Json.h @@ -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 T GetValue(std::string&& key, T&& default_val) { @@ -24,7 +27,7 @@ public: while (getline(ss, line, '.')) json = &((*json)[line]); - + // json library bugs with bool, using int instead if (typeid(T) == typeid(bool)) { @@ -42,6 +45,7 @@ public: Allows to save values in json hierarchy using '.' Example: "Menu.Window.X" */ + template 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(); }; diff --git a/src/Menu.cpp b/src/Menu.cpp index 3d6ee6f..4d9b40d 100644 --- a/src/Menu.cpp +++ b/src/Menu.cpp @@ -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(); } diff --git a/src/Player.cpp b/src/Player.cpp index 1510977..ce5e4d5 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -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")) { diff --git a/src/Teleport.cpp b/src/Teleport.cpp index 0b8a7f2..af759cf 100644 --- a/src/Teleport.cpp +++ b/src/Teleport.cpp @@ -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(); diff --git a/src/Ui.cpp b/src/Ui.cpp index 4053aff..946696a 100644 --- a/src/Ui.cpp +++ b/src/Ui.cpp @@ -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) diff --git a/src/Ui.h b/src/Ui.h index 44e1e3a..fb731e3 100644 --- a/src/Ui.h +++ b/src/Ui.h @@ -30,7 +30,7 @@ public: std::function function; std::string value; }; - + static void CenterdText(const std::string& text); static bool ColorButton(int color_id, std::vector &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); diff --git a/src/Util.cpp b/src/Util.cpp index d37313a..aa0f603 100644 --- a/src/Util.cpp +++ b/src/Util.cpp @@ -33,7 +33,6 @@ void Util::LoadTexturesInDirRecursive(const char *path, const char *file_ext,std { store_vec.push_back(std::make_unique()); 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); diff --git a/src/Vehicle.cpp b/src/Vehicle.cpp index c79b7f0..1ffd0b1 100644 --- a/src/Vehicle.cpp +++ b/src/Vehicle.cpp @@ -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(hveh, veh_heavy); Command(hveh, veh_watertight); @@ -579,8 +590,12 @@ void Vehicle::Main() if (ImGui::Button("Fix vehicle", ImVec2(Ui::GetSize(3)))) { - if (Command(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); diff --git a/src/Vehicle.h b/src/Vehicle.h index 7efbec8..95d41fa 100644 --- a/src/Vehicle.h +++ b/src/Vehicle.h @@ -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]; diff --git a/src/pch.cpp b/src/pch.cpp index a35329d..10a2000 100644 --- a/src/pch.cpp +++ b/src/pch.cpp @@ -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"); diff --git a/src/pch.h b/src/pch.h index 48621b7..f8b4af8 100644 --- a/src/pch.h +++ b/src/pch.h @@ -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 #include