diff --git a/Amalgam/src/Features/Configs/Configs.cpp b/Amalgam/src/Features/Configs/Configs.cpp index ad410a91..cc65aa88 100644 --- a/Amalgam/src/Features/Configs/Configs.cpp +++ b/Amalgam/src/Features/Configs/Configs.cpp @@ -461,7 +461,7 @@ bool CConfigs::LoadConfig(const std::string& configName, bool bNotify) } } - H::Fonts.Reload(Vars::Menu::DPI.Map[DEFAULT_BIND]); + H::Fonts.Reload(Vars::Menu::Scale.Map[DEFAULT_BIND]); sCurrentConfig = configName; sCurrentVisuals = ""; if (bNotify) diff --git a/Amalgam/src/Features/CritHack/CritHack.cpp b/Amalgam/src/Features/CritHack/CritHack.cpp index f794a0b1..b03e832e 100644 --- a/Amalgam/src/Features/CritHack/CritHack.cpp +++ b/Amalgam/src/Features/CritHack/CritHack.cpp @@ -437,14 +437,14 @@ void CCritHack::Draw(CTFPlayer* pLocal) const auto& fFont = H::Fonts.GetFont(FONT_INDICATORS); EAlign align = ALIGN_TOP; - if (x <= (100 + 50 * Vars::Menu::DPI.Value)) + if (x <= (100 + 50 * Vars::Menu::Scale.Value)) { - x -= 42 * Vars::Menu::DPI.Value; + x -= 42 * Vars::Menu::Scale.Value; align = ALIGN_TOPLEFT; } - else if (x >= H::Draw.m_nScreenW - (100 + 50 * Vars::Menu::DPI.Value)) + else if (x >= H::Draw.m_nScreenW - (100 + 50 * Vars::Menu::Scale.Value)) { - x += 42 * Vars::Menu::DPI.Value; + x += 42 * Vars::Menu::Scale.Value; align = ALIGN_TOPRIGHT; } @@ -458,11 +458,11 @@ void CCritHack::Draw(CTFPlayer* pLocal) if (tStorage.m_flDamage > 0) { if (pLocal->IsCritBoosted()) - H::Draw.String(fFont, x, y, { 100, 255, 255, 255 }, align, "Crit Boosted"); + H::Draw.StringOutlined(fFont, x, y, { 100, 255, 255, 255 }, { 0, 0, 0, 255 }, align, "Crit Boosted"); else if (pWeapon->m_flCritTime() > flTickBase) { const float flTime = pWeapon->m_flCritTime() - flTickBase; - H::Draw.String(fFont, x, y, { 100, 255, 255, 255 }, align, std::format("Streaming crits {:.1f}s", flTime).c_str()); + H::Draw.StringOutlined(fFont, x, y, { 100, 255, 255, 255 }, { 0, 0, 0, 255 }, align, std::format("Streaming crits {:.1f}s", flTime).c_str()); } else if (!m_bCritBanned) { @@ -471,34 +471,34 @@ void CCritHack::Draw(CTFPlayer* pLocal) if (bRapidFire && flTickBase < pWeapon->m_flLastRapidFireCritCheckTime() + 1.f) { const float flTime = pWeapon->m_flLastRapidFireCritCheckTime() + 1.f - flTickBase; - H::Draw.String(fFont, x, y, Vars::Menu::Theme::Active.Value, align, std::format("Wait {:.1f}s", flTime).c_str()); + H::Draw.StringOutlined(fFont, x, y, Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value, align, std::format("Wait {:.1f}s", flTime).c_str()); } else - H::Draw.String(fFont, x, y, { 150, 255, 150, 255 }, align, "Crit Ready"); + H::Draw.StringOutlined(fFont, x, y, { 150, 255, 150, 255 }, { 0, 0, 0, 255 }, align, "Crit Ready"); } else { const int shots = -tStorage.m_iAvailableCrits; - H::Draw.String(fFont, x, y, { 255, 150, 150, 255 }, align, shots == 1 ? std::format("Crit in {} shot", shots).c_str() : std::format("Crit in {}{} shots", shots, shots == 100 ? "+" : "").c_str()); + H::Draw.StringOutlined(fFont, x, y, { 255, 150, 150, 255 }, { 0, 0, 0, 255 }, align, shots == 1 ? std::format("Crit in {} shot", shots).c_str() : std::format("Crit in {}{} shots", shots, shots == 100 ? "+" : "").c_str()); } } else - H::Draw.String(fFont, x, y, { 255, 150, 150, 255 }, align, std::format("Deal {} damage", m_iDamageTilUnban).c_str()); + H::Draw.StringOutlined(fFont, x, y, { 255, 150, 150, 255 }, { 0, 0, 0, 255 }, align, std::format("Deal {} damage", m_iDamageTilUnban).c_str()); - H::Draw.String(fFont, x, y + fFont.m_nTall + 1, Vars::Menu::Theme::Active.Value, align, std::format("{} / {} potential crits", std::max(tStorage.m_iAvailableCrits, 0), tStorage.m_iPotentialCrits).c_str()); + H::Draw.StringOutlined(fFont, x, y + fFont.m_nTall + 1, Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value, align, std::format("{} / {} potential crits", std::max(tStorage.m_iAvailableCrits, 0), tStorage.m_iPotentialCrits).c_str()); } else - H::Draw.String(fFont, x, y, Vars::Menu::Theme::Active.Value, align, "Calculating"); + H::Draw.StringOutlined(fFont, x, y, Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value, align, "Calculating"); if (Vars::Debug::Info.Value) { - H::Draw.String(fFont, x, y + fFont.m_nTall * 3, {}, align, std::format("AllDamage: {}, CritDamage: {}", m_iAllDamage, m_iCritDamage).c_str()); - H::Draw.String(fFont, x, y + fFont.m_nTall * 4, {}, align, std::format("Bucket: {}", pWeapon->m_flCritTokenBucket()).c_str()); - H::Draw.String(fFont, x, y + fFont.m_nTall * 5, {}, align, std::format("Damage: {}, Cost: {}", tStorage.m_flDamage, tStorage.m_flCost).c_str()); - H::Draw.String(fFont, x, y + fFont.m_nTall * 6, {}, align, std::format("Shots: {}, Crits: {}", pWeapon->m_nCritChecks(), pWeapon->m_nCritSeedRequests()).c_str()); - H::Draw.String(fFont, x, y + fFont.m_nTall * 7, {}, align, std::format("CritBanned: {}, DamageTilUnban: {}", m_bCritBanned, m_iDamageTilUnban).c_str()); - H::Draw.String(fFont, x, y + fFont.m_nTall * 8, {}, align, std::format("CritChance: {:.2f} ({:.2f})", m_flCritChance, m_flCritChance + 0.1f).c_str()); - H::Draw.String(fFont, x, y + fFont.m_nTall * 9, {}, align, std::format("Force: {}, Skip: {}", tStorage.m_vCritCommands.size(), tStorage.m_vSkipCommands.size()).c_str()); + H::Draw.StringOutlined(fFont, x, y + fFont.m_nTall * 3, {}, { 0, 0, 0, 255 }, align, std::format("AllDamage: {}, CritDamage: {}", m_iAllDamage, m_iCritDamage).c_str()); + H::Draw.StringOutlined(fFont, x, y + fFont.m_nTall * 4, {}, { 0, 0, 0, 255 }, align, std::format("Bucket: {}", pWeapon->m_flCritTokenBucket()).c_str()); + H::Draw.StringOutlined(fFont, x, y + fFont.m_nTall * 5, {}, { 0, 0, 0, 255 }, align, std::format("Damage: {}, Cost: {}", tStorage.m_flDamage, tStorage.m_flCost).c_str()); + H::Draw.StringOutlined(fFont, x, y + fFont.m_nTall * 6, {}, { 0, 0, 0, 255 }, align, std::format("Shots: {}, Crits: {}", pWeapon->m_nCritChecks(), pWeapon->m_nCritSeedRequests()).c_str()); + H::Draw.StringOutlined(fFont, x, y + fFont.m_nTall * 7, {}, { 0, 0, 0, 255 }, align, std::format("CritBanned: {}, DamageTilUnban: {}", m_bCritBanned, m_iDamageTilUnban).c_str()); + H::Draw.StringOutlined(fFont, x, y + fFont.m_nTall * 8, {}, { 0, 0, 0, 255 }, align, std::format("CritChance: {:.2f} ({:.2f})", m_flCritChance, m_flCritChance + 0.1f).c_str()); + H::Draw.StringOutlined(fFont, x, y + fFont.m_nTall * 9, {}, { 0, 0, 0, 255 }, align, std::format("Force: {}, Skip: {}", tStorage.m_vCritCommands.size(), tStorage.m_vSkipCommands.size()).c_str()); } } } \ No newline at end of file diff --git a/Amalgam/src/Features/ImGui/Menu/Components.h b/Amalgam/src/Features/ImGui/Menu/Components.h index ccfaf3c3..29aa3134 100644 --- a/Amalgam/src/Features/ImGui/Menu/Components.h +++ b/Amalgam/src/Features/ImGui/Menu/Components.h @@ -7,6 +7,14 @@ #include #include +enum FTabs_ +{ + FTabs_None = 0, + FTabs_Vertical = 1 << 0, + FTabs_HorizontalIcons = 1 << 1, + //FTabs_PageStyle = 1 << 2 +}; + enum FText_ { FText_None = 0, @@ -103,18 +111,32 @@ namespace ImGui { vDisabled.push_back(Disabled = bDisabled); } - inline void PopDisabled() + inline void PopDisabled(int count = 1) { - vDisabled.pop_back(); + int iSize = int(vDisabled.size()); + if (iSize < count) + { + IM_ASSERT_USER_ERROR(iSize > count, "Calling PopDisabled() too many times: stack underflow."); + count = iSize; + } + for (int i = 0; i < count; i++) + vDisabled.pop_back(); Disabled = !vDisabled.empty() ? vDisabled.back() : false; } inline void PushTransparent(bool bTransparent) { vTransparent.push_back(Transparent = bTransparent); } - inline void PopTransparent() + inline void PopTransparent(int count = 1) { - vTransparent.pop_back(); + int iSize = int(vTransparent.size()); + if (iSize < count) + { + IM_ASSERT_USER_ERROR(iSize > count, "Calling PopTransparent() too many times: stack underflow."); + count = iSize; + } + for (int i = 0; i < count; i++) + vTransparent.pop_back(); Transparent = !vTransparent.empty() ? vTransparent.back() : false; } @@ -379,7 +401,7 @@ namespace ImGui } // widgets - inline bool FTabs(std::vector vEntries, int* pVar, const ImVec2 vSize, const ImVec2 vPos, bool bVertical = false, std::vector vIcons = {}) + inline bool FTabs(std::vector vEntries, int* pVar, const ImVec2 vSize, const ImVec2 vPos, int iFlags = FTabs_None, std::vector vIcons = {}) { if (vIcons.size() && vIcons.size() != vEntries.size()) return false; @@ -387,6 +409,10 @@ namespace ImGui ImDrawList* pDrawList = GetWindowDrawList(); const int iOriginalTab = pVar ? *pVar : 0; + bool bVertical = iFlags & FTabs_Vertical; + bool bHorizontalIcons = iFlags & FTabs_HorizontalIcons; + //bool bPageStyle = iFlags & FTabs_PageStyle; + for (size_t i = 0; i < vEntries.size(); i++) { ImVec2 vNewPos = bVertical ? ImVec2(vPos.x, vPos.y + vSize.y * i) : ImVec2(vPos.x + vSize.x * i, vPos.y); @@ -414,13 +440,29 @@ namespace ImGui ImVec2 vOriginalPos = GetCursorPos(); std::string sStripped = StripDoubleHash(vEntries[i]); ImVec2 vTextSize = CalcTextSize(sStripped.c_str()); - ImVec2 vTextPos = { vNewPos.x + (vSize.x - vTextSize.x) / 2, vNewPos.y + (vSize.y - vTextSize.y) / 2 + (vIcons.empty() ? 0 : 10) }; - SetCursorPos(vTextPos); - TextUnformatted(sStripped.c_str()); if (!vIcons.empty()) { - SetCursorPos({ vNewPos.x + vSize.x / 2 - 8, vNewPos.y + vSize.x / 2 - 14 }); - IconImage(vIcons[i]); + if (!bHorizontalIcons) + { + SetCursorPos({ vNewPos.x + (vSize.x - vTextSize.x) / 2, vNewPos.y + (vSize.y - vTextSize.y) / 2 + 10 }); + TextUnformatted(sStripped.c_str()); + + SetCursorPos({ vNewPos.x + vSize.x / 2 - 8, vNewPos.y + vSize.y / 2 - 18 }); + IconImage(vIcons[i]); + } + else + { + SetCursorPos({ vNewPos.x + (vSize.x - vTextSize.x) / 2 + 10, vNewPos.y + (vSize.y - vTextSize.y) / 2 }); + TextUnformatted(sStripped.c_str()); + + SetCursorPos({ vNewPos.x + vSize.x / 2 - vTextSize.x / 2 - 12, vNewPos.y + vSize.y / 2 - 9 }); + IconImage(vIcons[i]); + } + } + else + { + SetCursorPos({ vNewPos.x + (vSize.x - vTextSize.x) / 2, vNewPos.y + (vSize.y - vTextSize.y) / 2 }); + TextUnformatted(sStripped.c_str()); } SetCursorPos(vOriginalPos); @@ -869,7 +911,7 @@ namespace ImGui { ImVec2 vOriginalPos2 = GetCursorPos(); SetCursorPos({ vOriginalPos2.x + 16, vOriginalPos2.y - 1 }); - if (IconButton(vValues[i] == -1 ? ICON_MD_ADD_CIRCLE : ICON_MD_REMOVE_CIRCLE, false, { 0, 0, 0, 0 }) && pModified) + if (IconButton(vValues[i] == -1 ? ICON_MD_ADD_CIRCLE : ICON_MD_REMOVE_CIRCLE, false, {}) && pModified) *pModified = vValues[i]; SetCursorPos(vOriginalPos2); } @@ -1901,8 +1943,8 @@ namespace ImGui OpenPopup(var.m_sName.c_str());\ staticVal = val;\ }\ - SetNextWindowSize({ 300, 0 });\ PushStyleColor(ImGuiCol_PopupBg, F::Render.Foreground.Value);\ + SetNextWindowSize({ 300, 0 });\ bool bPopup = BeginPopup(var.m_sName.c_str());\ PopStyleColor();\ if (bPopup)\ @@ -1933,7 +1975,6 @@ namespace ImGui PopTransparent();\ EndPopup();\ }\ - SetNextWindowSize({ 0, 0 });\ }\ if (pHovered) *pHovered = bHovered;\ return bReturn;\ diff --git a/Amalgam/src/Features/ImGui/Menu/Menu.cpp b/Amalgam/src/Features/ImGui/Menu/Menu.cpp index 7f665ba7..f4a3b7fd 100644 --- a/Amalgam/src/Features/ImGui/Menu/Menu.cpp +++ b/Amalgam/src/Features/ImGui/Menu/Menu.cpp @@ -17,86 +17,68 @@ void CMenu::DrawMenu() { using namespace ImGui; - ImVec2 mainWindowPos = {}; - ImVec2 mainWindowSize = {}; + ImVec2 vMainWindowPos = {}; + ImVec2 vMainWindowSize = {}; - SetNextWindowSize(ImVec2(750, 500), ImGuiCond_FirstUseEver); - PushStyleVar(ImGuiStyleVar_WindowMinSize, { 750, 500 }); - if (Begin("MainWindow", nullptr, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoTitleBar)) + SetNextWindowSize({ 762, 512 }, ImGuiCond_FirstUseEver); + PushStyleVar(ImGuiStyleVar_WindowMinSize, { 762, 512 }); + if (Begin("Background", nullptr, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoTitleBar)) { - const auto windowPos = mainWindowPos = GetWindowPos(); - const auto windowSize = mainWindowSize = GetWindowSize(); + auto vWindowPos = vMainWindowPos = GetWindowPos(); + auto vWindowSize = vMainWindowSize = GetWindowSize(); - // Main tabs - FTabs({ "AIMBOT", "VISUALS", "MISC", "LOGS", "SETTINGS" }, &CurrentTab, TabSize, { 0, SubTabSize.y }, true, { ICON_MD_GROUP, ICON_MD_IMAGE, ICON_MD_PUBLIC, ICON_MD_MENU_BOOK, ICON_MD_SETTINGS }); - - // Sub tabs - switch (CurrentTab) + SetCursorPos({ 8, 8 }); + PushStyleVar(ImGuiStyleVar_ChildRounding, 3.f); + PushStyleColor(ImGuiCol_ChildBg, F::Render.Background.Value); + if (BeginChild("Main", { vWindowSize.x - 16, vWindowSize.y - 16 }, false, ImGuiWindowFlags_AlwaysUseWindowPadding)) { - case 0: FTabs({ "GENERAL", "HVH" }, &CurrentAimbotTab, SubTabSize, { TabSize.x, 0 }); break; - case 1: FTabs({ "ESP", "CHAMS", "GLOW", "MISC##", "RADAR", "MENU" }, &CurrentVisualsTab, SubTabSize, { TabSize.x, 0 }); break; - case 2: FTabs({ "MISC##" }, nullptr, SubTabSize, { TabSize.x, 0 }); break; - case 3: FTabs({ "LOGS##", "SETTINGS##" }, &CurrentLogsTab, SubTabSize, { TabSize.x, 0 }); break; - case 4: FTabs({ "CONFIG", "BINDS", "PLAYERLIST", "MATERIALS" }, &CurrentConfigTab, SubTabSize, { TabSize.x, 0 }); break; - } + vWindowPos = GetWindowPos(); + vWindowSize = GetWindowSize(); - // Main content - SetCursorPos({ TabSize.x, SubTabSize.y }); - PushStyleVar(ImGuiStyleVar_WindowPadding, { 8.f, 8.f }); - PushStyleColor(ImGuiCol_ChildBg, {}); - if (BeginChild("Content", { windowSize.x - TabSize.x, windowSize.y - SubTabSize.y }, false, ImGuiWindowFlags_AlwaysUseWindowPadding)) - { - PushStyleColor(ImGuiCol_ChildBg, F::Render.Foreground.Value); - PushStyleVar(ImGuiStyleVar_ChildRounding, 3.f); - - switch (CurrentTab) + if (!Vars::Menu::CheatName.Value.empty()) { - case 0: MenuAimbot(); break; - case 1: MenuVisuals(); break; - case 2: MenuMisc(); break; - case 3: MenuLogs(); break; - case 4: MenuSettings(); break; + auto vDrawPos = GetDrawPos(); + auto pDrawList = GetWindowDrawList(); + + const auto textSize = CalcTextSize(Vars::Menu::CheatName.Value.c_str()); + pDrawList->AddRectFilled({ vDrawPos.x + vWindowSize.x - textSize.x - 24, vDrawPos.y + 8 }, { vDrawPos.x + vWindowSize.x - 8, vDrawPos.y + 32 }, F::Render.Foreground, 3); + pDrawList->AddText(F::Render.FontRegular, F::Render.FontRegular->FontSize, { vDrawPos.x + vWindowSize.x - textSize.x - 16.f, vDrawPos.y + 13.f }, F::Render.Accent, Vars::Menu::CheatName.Value.c_str()); } - PopStyleVar(); + static int iCurrentTab = 0; + FTabs({ "AIMBOT", "VISUALS", "MISC", "LOGS", "SETTINGS" }, &iCurrentTab, { 100, 40 }, { 0, 0 }, FTabs_HorizontalIcons, { ICON_MD_GROUP, ICON_MD_IMAGE, ICON_MD_PUBLIC, ICON_MD_MENU_BOOK, ICON_MD_SETTINGS }); + + SetCursorPos({ 0, 40 }); + PushStyleColor(ImGuiCol_ChildBg, {}); + if (BeginChild("Page", { vWindowSize.x, vWindowSize.y - 40 }, false, ImGuiWindowFlags_AlwaysUseWindowPadding)) + { + switch (iCurrentTab) + { + case 0: MenuAimbot(); break; + case 1: MenuVisuals(); break; + case 2: MenuMisc(); break; + case 3: MenuLogs(); break; + case 4: MenuSettings(); break; + } + } EndChild(); PopStyleColor(); } EndChild(); PopStyleColor(); PopStyleVar(); - // End End(); } PopStyleVar(); - // Title Text - if (Vars::Menu::CheatName.Value.length()) - { - PushFont(F::Render.FontTitle); - const auto textSize = CalcTextSize(Vars::Menu::CheatName.Value.c_str()); - SetNextWindowSize({ std::min(textSize.x + 26.f, mainWindowSize.x), 40.f }); - SetNextWindowPos({ mainWindowPos.x, mainWindowPos.y - 48.f }); - PushStyleVar(ImGuiStyleVar_WindowMinSize, { 40.f, 40.f }); - if (Begin("TitleWindow", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoFocusOnAppearing)) - { - const auto windowPos = GetWindowPos(); - GetWindowDrawList()->AddText(F::Render.FontTitle, F::Render.FontTitle->FontSize, { windowPos.x + 13.f, windowPos.y + 10.f }, F::Render.Accent, Vars::Menu::CheatName.Value.c_str()); - - End(); - } - PopStyleVar(); - PopFont(); - } - // Bind Text Bind_t tBind; if (F::Binds.GetBind(CurrentBind, &tBind)) { const auto textSize = CalcTextSize(std::format("Editing for condition {}", tBind.Name).c_str()); - SetNextWindowSize({ std::min(textSize.x + 56.f, mainWindowSize.x), 40.f }); - SetNextWindowPos({ mainWindowPos.x, mainWindowPos.y + mainWindowSize.y + 8.f }); + SetNextWindowSize({ std::min(textSize.x + 56.f, vMainWindowSize.x), 40.f }); + SetNextWindowPos({ vMainWindowPos.x, vMainWindowPos.y + vMainWindowSize.y + 8.f }); PushStyleVar(ImGuiStyleVar_WindowMinSize, { 40.f, 40.f }); - if (Begin("ConditionWindow", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoTitleBar)) + if (Begin("Bind", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoTitleBar)) { const auto windowPos = GetWindowPos(); const auto preSize = CalcTextSize("Editing for condition "); @@ -119,256 +101,270 @@ void CMenu::MenuAimbot() { using namespace ImGui; - switch (CurrentAimbotTab) + const auto vWindowSize = GetWindowSize(); + static int iCurrentTab = 0; + FTabs({ "GENERAL", "HVH" }, &iCurrentTab, { 100, 40 }, { 0, 0 }); + + SetCursorPos({ 0, 40 }); + PushStyleVar(ImGuiStyleVar_WindowPadding, { 8.f, 8.f }); + if (BeginChild("Content", { vWindowSize.x, vWindowSize.y - 40 }, false, ImGuiWindowFlags_AlwaysUseWindowPadding)) { + PushStyleColor(ImGuiCol_ChildBg, F::Render.Foreground.Value); + + switch (iCurrentTab) + { // General - case 0: - if (BeginTable("AimbotTable", 2)) - { - /* Column 1 */ - TableNextColumn(); - if (Section("General")) + case 0: + if (BeginTable("AimbotTable", 2)) { - FDropdown("Aim type", Vars::Aimbot::General::AimType, { "Off", "Plain", "Smooth", "Silent" }, {}, FDropdown_Left); - FDropdown("Target selection", Vars::Aimbot::General::TargetSelection, { "FOV", "Distance" }, {}, FDropdown_Right); - FDropdown("Target", Vars::Aimbot::General::Target, { "Players", "Sentries", "Dispensers", "Teleporters", "Stickies", "NPCs", "Bombs" }, {}, FDropdown_Multi | FDropdown_Left); - FDropdown("Ignore", Vars::Aimbot::General::Ignore, { "Invulnerable", "Cloaked", "Dead Ringer", "Vaccinator", "Unsimulated players", "Disguised", "Taunting" }, {}, FDropdown_Multi | FDropdown_Right); - FSlider("Aim FOV", Vars::Aimbot::General::AimFOV, 0.f, 180.f, 1.f, "%g", FSlider_Clamp | FSlider_Precision); - PushTransparent(FGet(Vars::Aimbot::General::AimType) != Vars::Aimbot::General::AimTypeEnum::Smooth); - FSlider("Smoothing## Hitscan", Vars::Aimbot::General::Smoothing, 0.f, 100.f, 1.f, "%g%%", FSlider_Clamp | FSlider_Precision); - PopTransparent(); - FSlider("Max targets", Vars::Aimbot::General::MaxTargets, 1, 6, 1, "%i", FSlider_Min); - PushTransparent(!(FGet(Vars::Aimbot::General::Ignore) & Vars::Aimbot::General::IgnoreEnum::Cloaked)); - FSlider("Ignore cloak", Vars::Aimbot::General::IgnoreCloakPercentage, 0, 100, 10, "%d%%", FSlider_Clamp); - PopTransparent(); - PushTransparent(!(FGet(Vars::Aimbot::General::Ignore) & Vars::Aimbot::General::IgnoreEnum::Unsimulated)); - FSlider("Tick tolerance", Vars::Aimbot::General::TickTolerance, 0, 21, 1, "%i", FSlider_Clamp); - PopTransparent(); - FColorPicker("Aimbot FOV circle", Vars::Colors::FOVCircle); - FToggle("Autoshoot", Vars::Aimbot::General::AutoShoot, FToggle_Left); - FToggle("FOV Circle", Vars::Aimbot::General::FOVCircle, FToggle_Right); - FToggle("Force crits", Vars::CritHack::ForceCrits, FToggle_Left); - FToggle("Avoid random crits", Vars::CritHack::AvoidRandom, FToggle_Right); - FToggle("Always melee crit", Vars::CritHack::AlwaysMeleeCrit, FToggle_Left); - FToggle("No spread", Vars::Aimbot::General::NoSpread, FToggle_Right); - } EndSection(); - if (Vars::Debug::Info.Value) - { - if (Section("debug## aimbot")) + /* Column 1 */ + TableNextColumn(); + if (Section("General")) { - FSlider("hitscan peek", Vars::Aimbot::General::HitscanPeek, 0, 5); - FToggle("peek dt only", Vars::Aimbot::General::PeekDTOnly); - FTooltip("this should probably stay on if you want to be able to\ntarget hitboxes other than the highest priority one"); - FSlider("offset## nospread", Vars::Aimbot::General::NoSpreadOffset, -1.f, 1.f, 0.5f, "%g", FSlider_Precision); - FSlider("average", Vars::Aimbot::General::NoSpreadAverage, 1, 25); - FDropdown("aim holds fire", Vars::Aimbot::General::AimHoldsFire, { "false", "minigun only", "always" }); + FDropdown("Aim type", Vars::Aimbot::General::AimType, { "Off", "Plain", "Smooth", "Silent" }, {}, FDropdown_Left); + FDropdown("Target selection", Vars::Aimbot::General::TargetSelection, { "FOV", "Distance" }, {}, FDropdown_Right); + FDropdown("Target", Vars::Aimbot::General::Target, { "Players", "Sentries", "Dispensers", "Teleporters", "Stickies", "NPCs", "Bombs" }, {}, FDropdown_Multi | FDropdown_Left); + FDropdown("Ignore", Vars::Aimbot::General::Ignore, { "Invulnerable", "Cloaked", "Dead Ringer", "Vaccinator", "Unsimulated players", "Disguised", "Taunting" }, {}, FDropdown_Multi | FDropdown_Right); + FSlider("Aim FOV", Vars::Aimbot::General::AimFOV, 0.f, 180.f, 1.f, "%g", FSlider_Clamp | FSlider_Precision); + PushTransparent(FGet(Vars::Aimbot::General::AimType) != Vars::Aimbot::General::AimTypeEnum::Smooth); + FSlider("Smoothing## Hitscan", Vars::Aimbot::General::Smoothing, 0.f, 100.f, 1.f, "%g%%", FSlider_Clamp | FSlider_Precision); + PopTransparent(); + FSlider("Max targets", Vars::Aimbot::General::MaxTargets, 1, 6, 1, "%i", FSlider_Min); + PushTransparent(!(FGet(Vars::Aimbot::General::Ignore) & Vars::Aimbot::General::IgnoreEnum::Cloaked)); + FSlider("Ignore cloak", Vars::Aimbot::General::IgnoreCloakPercentage, 0, 100, 10, "%d%%", FSlider_Clamp); + PopTransparent(); + PushTransparent(!(FGet(Vars::Aimbot::General::Ignore) & Vars::Aimbot::General::IgnoreEnum::Unsimulated)); + FSlider("Tick tolerance", Vars::Aimbot::General::TickTolerance, 0, 21, 1, "%i", FSlider_Clamp); + PopTransparent(); + FColorPicker("Aimbot FOV circle", Vars::Colors::FOVCircle); + FToggle("Autoshoot", Vars::Aimbot::General::AutoShoot, FToggle_Left); + FToggle("FOV Circle", Vars::Aimbot::General::FOVCircle, FToggle_Right); + FToggle("Force crits", Vars::CritHack::ForceCrits, FToggle_Left); + FToggle("Avoid random crits", Vars::CritHack::AvoidRandom, FToggle_Right); + FToggle("Always melee crit", Vars::CritHack::AlwaysMeleeCrit, FToggle_Left); + FToggle("No spread", Vars::Aimbot::General::NoSpread, FToggle_Right); } EndSection(); - } - if (Section("Backtrack")) - { - FToggle("Enabled", Vars::Backtrack::Enabled, FToggle_Left); - FToggle("Prefer on shot", Vars::Backtrack::PreferOnShot, FToggle_Right); - FSlider("Fake latency", Vars::Backtrack::Latency, 0, F::Backtrack.m_flMaxUnlag * 1000, 5, "%i", FSlider_Clamp); // unreliable above 1000 - ping probably - FSlider("Fake interp", Vars::Backtrack::Interp, 0, F::Backtrack.m_flMaxUnlag * 1000, 5, "%i", FSlider_Clamp | FSlider_Precision); - FSlider("Window", Vars::Backtrack::Window, 1, 200, 5, "%i", FSlider_Clamp); - } EndSection(); - if (Vars::Debug::Info.Value) - { - if (Section("debug## backtrack")) + if (Vars::Debug::Info.Value) { - FSlider("offset", Vars::Backtrack::Offset, -1, 1); - } EndSection(); - } - if (Section("Auto Heal")) - { - FToggle("Auto heal", Vars::Aimbot::Healing::AutoHeal, FToggle_Left); - FToggle("Friends only", Vars::Aimbot::Healing::FriendsOnly, FToggle_Right); - FToggle("Activate on voice", Vars::Aimbot::Healing::ActivateOnVoice, FToggle_Left); - } EndSection(); - - /* Column 2 */ - TableNextColumn(); - if (Section("Hitscan")) - { - FDropdown("Hitboxes", Vars::Aimbot::Hitscan::Hitboxes, { "Head", "Body", "Pelvis", "Arms", "Legs" }, { 1 << 0, 1 << 2, 1 << 1, 1 << 3, 1 << 4 }, FDropdown_Multi); - FDropdown("Modifiers## Hitscan", Vars::Aimbot::Hitscan::Modifiers, { "Tapfire", "Wait for headshot", "Wait for charge", "Scoped only", "Auto scope", "Bodyaim if lethal", "Extinguish team" }, {}, FDropdown_Multi); - FSlider("Point scale", Vars::Aimbot::Hitscan::PointScale, 0.f, 100.f, 5.f, "%g%%", FSlider_Clamp | FSlider_Precision); - PushTransparent(!(FGet(Vars::Aimbot::Hitscan::Modifiers) & Vars::Aimbot::Hitscan::ModifiersEnum::Tapfire)); - FSlider("Tapfire distance", Vars::Aimbot::Hitscan::TapFireDist, 250.f, 1000.f, 50.f, "%g", FSlider_Min | FSlider_Precision); - PopTransparent(); - } EndSection(); - if (Section("Projectile")) - { - FDropdown("Predict", Vars::Aimbot::Projectile::StrafePrediction, { "Air strafing", "Ground strafing" }, {}, FDropdown_Multi | FDropdown_Left); - FDropdown("Splash", Vars::Aimbot::Projectile::SplashPrediction, { "Off", "Include", "Prefer", "Only" }, {}, FDropdown_Right); - FDropdown("Auto detonate", Vars::Aimbot::Projectile::AutoDetonate, { "Stickies", "Flares" }, {}, FDropdown_Multi | FDropdown_Left); - FDropdown("Auto airblast", Vars::Aimbot::Projectile::AutoAirblast, { "Off", "Legit", "Rage" }, {}, FDropdown_Right); - FDropdown("Modifiers## Projectile", Vars::Aimbot::Projectile::Modifiers, { "Charge shot", "Cancel charge", "Bodyaim if lethal", "Use prime time" }, {}, FDropdown_Multi); - FSlider("Max simulation time", Vars::Aimbot::Projectile::PredictionTime, 0.1f, 10.f, 0.25f, "%gs", FSlider_Min | FSlider_Precision); - PushTransparent(!FGet(Vars::Aimbot::Projectile::StrafePrediction)); - FSlider("Hit chance", Vars::Aimbot::Projectile::Hitchance, 0.f, 100.f, 5.f, "%g%%", FSlider_Clamp | FSlider_Precision); - PopTransparent(); - FSlider("Autodet radius", Vars::Aimbot::Projectile::AutodetRadius, 0.f, 100.f, 5.f, "%g%%", FSlider_Clamp | FSlider_Precision); - FSlider("Splash radius", Vars::Aimbot::Projectile::SplashRadius, 0.f, 100.f, 5.f, "%g%%", FSlider_Clamp | FSlider_Precision); - PushTransparent(!FGet(Vars::Aimbot::Projectile::AutoRelease)); - FSlider("Auto release", Vars::Aimbot::Projectile::AutoRelease, 0.f, 100.f, 5.f, "%g%%", FSlider_Clamp | FSlider_Precision); - PopTransparent(); - } EndSection(); - if (Vars::Debug::Info.Value) - { - if (Section("debug## projectile")) - { - FText("\nground"); - FSlider("samples##ground", Vars::Aimbot::Projectile::GroundSamples, 3, 66, 1, "%i", FSlider_Left); - FSlider("straight fuzzy value##ground", Vars::Aimbot::Projectile::GroundStraightFuzzyValue, 0.f, 500.f, 25.f, "%g", FSlider_Right | FSlider_Precision); - FSlider("low min samples##ground", Vars::Aimbot::Projectile::GroundLowMinimumSamples, 3, 66, 1, "%i", FSlider_Left); - FSlider("high min samples##ground", Vars::Aimbot::Projectile::GroundHighMinimumSamples, 3, 66, 1, "%i", FSlider_Right); - FSlider("low min distance##ground", Vars::Aimbot::Projectile::GroundLowMinimumDistance, 0.f, 10000.f, 100.f, "%g", FSlider_Left | FSlider_Min | FSlider_Precision); - FSlider("high min distance##ground", Vars::Aimbot::Projectile::GroundHighMinimumDistance, 0.f, 10000.f, 100.f, "%g", FSlider_Right | FSlider_Min | FSlider_Precision); - - FText("air"); - FSlider("samples##air", Vars::Aimbot::Projectile::AirSamples, 3, 66, 1, "%i", FSlider_Left); - FSlider("straight fuzzy value##air", Vars::Aimbot::Projectile::AirStraightFuzzyValue, 0.f, 500.f, 25.f, "%g", FSlider_Right | FSlider_Precision); - FSlider("low min samples##air", Vars::Aimbot::Projectile::AirLowMinimumSamples, 3, 66, 1, "%i", FSlider_Left); - FSlider("high min samples##air", Vars::Aimbot::Projectile::AirHighMinimumSamples, 3, 66, 1, "%i", FSlider_Right); - FSlider("low min distance##air", Vars::Aimbot::Projectile::AirLowMinimumDistance, 0.f, 10000.f, 100.f, "%g", FSlider_Left | FSlider_Min | FSlider_Precision); - FSlider("high min distance##air", Vars::Aimbot::Projectile::AirHighMinimumDistance, 0.f, 10000.f, 100.f, "%g", FSlider_Right | FSlider_Min | FSlider_Precision); - - FText(""); - FSlider("velocity average count", Vars::Aimbot::Projectile::VelocityAverageCount, 1, 10, 1, "%i", FSlider_Left); - FSlider("vertical shift", Vars::Aimbot::Projectile::VerticalShift, 0.f, 10.f, 0.5f, "%g", FSlider_Right | FSlider_Min | FSlider_Precision); - FSlider("huntsman lerp", Vars::Aimbot::Projectile::HuntsmanLerp, 0.f, 100.f, 1.f, "%g%%", FSlider_Left | FSlider_Clamp | FSlider_Precision); - FSlider("latency offset", Vars::Aimbot::Projectile::LatencyOffset, -1.f, 1.f, 0.1f, "%g", FSlider_Right | FSlider_Precision); - FSlider("hull increase", Vars::Aimbot::Projectile::HullIncrease, 0.f, 3.f, 0.5f, "%g", FSlider_Left | FSlider_Min | FSlider_Precision); - FSlider("drag override", Vars::Aimbot::Projectile::DragOverride, 0.f, 1.f, 0.01f, "%g", FSlider_Right | FSlider_Min | FSlider_Precision); - FSlider("time override", Vars::Aimbot::Projectile::TimeOverride, 0.f, 1.f, 0.01f, "%g", FSlider_Left | FSlider_Min | FSlider_Precision); - FToggle("splash grates", Vars::Aimbot::Projectile::SplashGrates, FToggle_Left); - FToggle("splash rocket", Vars::Aimbot::Projectile::SplashRocket, FToggle_Right); - FTooltip("special splash type for rockets, more expensive"); - FSlider("splash points", Vars::Aimbot::Projectile::SplashPoints, 1, 400, 5, "%i", FSlider_Min); - FSlider("direct splash count", Vars::Aimbot::Projectile::SplashCountDirect, 1, 100, 1, "%i", FSlider_Left | FSlider_Min); - FSlider("arc splash count", Vars::Aimbot::Projectile::SplashCountArc, 1, 100, 1, "%i", FSlider_Right | FSlider_Min); - FSlider("delta count", Vars::Aimbot::Projectile::DeltaCount, 1, 5, 1, "%i", FSlider_Left); - FDropdown("delta mode", Vars::Aimbot::Projectile::DeltaMode, { "average", "max" }, {}, FDropdown_Right); - } EndSection(); - } - if (Section("Melee")) - { - FToggle("Auto backstab", Vars::Aimbot::Melee::AutoBackstab, FToggle_Left); - FToggle("Ignore razorback", Vars::Aimbot::Melee::IgnoreRazorback, FToggle_Right); - FToggle("Swing prediction", Vars::Aimbot::Melee::SwingPrediction, FToggle_Left); - FToggle("Whip teammates", Vars::Aimbot::Melee::WhipTeam, FToggle_Right); - } EndSection(); - if (Vars::Debug::Info.Value) - { - if (Section("debug## melee")) - { - FSlider("swing ticks", Vars::Aimbot::Melee::SwingTicks, 10, 14); - FToggle("backstab account ping", Vars::Aimbot::Melee::BackstabAccountPing, FToggle_Left); - FToggle("backstab double test", Vars::Aimbot::Melee::BackstabDoubleTest, FToggle_Right); + if (Section("debug## aimbot")) + { + FSlider("hitscan peek", Vars::Aimbot::General::HitscanPeek, 0, 5); + FToggle("peek dt only", Vars::Aimbot::General::PeekDTOnly); + FTooltip("this should probably stay on if you want to be able to\ntarget hitboxes other than the highest priority one"); + FSlider("offset## nospread", Vars::Aimbot::General::NoSpreadOffset, -1.f, 1.f, 0.5f, "%g", FSlider_Precision); + FSlider("average", Vars::Aimbot::General::NoSpreadAverage, 1, 25); + FDropdown("aim holds fire", Vars::Aimbot::General::AimHoldsFire, { "false", "minigun only", "always" }); + } EndSection(); } - EndSection(); + if (Section("Backtrack")) + { + FToggle("Enabled", Vars::Backtrack::Enabled, FToggle_Left); + FToggle("Prefer on shot", Vars::Backtrack::PreferOnShot, FToggle_Right); + FSlider("Fake latency", Vars::Backtrack::Latency, 0, F::Backtrack.m_flMaxUnlag * 1000, 5, "%i", FSlider_Clamp); // unreliable above 1000 - ping probably + FSlider("Fake interp", Vars::Backtrack::Interp, 0, F::Backtrack.m_flMaxUnlag * 1000, 5, "%i", FSlider_Clamp | FSlider_Precision); + FSlider("Window", Vars::Backtrack::Window, 1, 200, 5, "%i", FSlider_Clamp); + } EndSection(); + if (Vars::Debug::Info.Value) + { + if (Section("debug## backtrack")) + { + FSlider("offset", Vars::Backtrack::Offset, -1, 1); + } EndSection(); + } + if (Section("Auto Heal")) + { + FToggle("Auto heal", Vars::Aimbot::Healing::AutoHeal, FToggle_Left); + FToggle("Friends only", Vars::Aimbot::Healing::FriendsOnly, FToggle_Right); + FToggle("Activate on voice", Vars::Aimbot::Healing::ActivateOnVoice, FToggle_Left); + } EndSection(); + + /* Column 2 */ + TableNextColumn(); + if (Section("Hitscan")) + { + FDropdown("Hitboxes", Vars::Aimbot::Hitscan::Hitboxes, { "Head", "Body", "Pelvis", "Arms", "Legs" }, { 1 << 0, 1 << 2, 1 << 1, 1 << 3, 1 << 4 }, FDropdown_Multi); + FDropdown("Modifiers## Hitscan", Vars::Aimbot::Hitscan::Modifiers, { "Tapfire", "Wait for headshot", "Wait for charge", "Scoped only", "Auto scope", "Bodyaim if lethal", "Extinguish team" }, {}, FDropdown_Multi); + FSlider("Point scale", Vars::Aimbot::Hitscan::PointScale, 0.f, 100.f, 5.f, "%g%%", FSlider_Clamp | FSlider_Precision); + PushTransparent(!(FGet(Vars::Aimbot::Hitscan::Modifiers) & Vars::Aimbot::Hitscan::ModifiersEnum::Tapfire)); + FSlider("Tapfire distance", Vars::Aimbot::Hitscan::TapFireDist, 250.f, 1000.f, 50.f, "%g", FSlider_Min | FSlider_Precision); + PopTransparent(); + } EndSection(); + if (Section("Projectile")) + { + FDropdown("Predict", Vars::Aimbot::Projectile::StrafePrediction, { "Air strafing", "Ground strafing" }, {}, FDropdown_Multi | FDropdown_Left); + FDropdown("Splash", Vars::Aimbot::Projectile::SplashPrediction, { "Off", "Include", "Prefer", "Only" }, {}, FDropdown_Right); + FDropdown("Auto detonate", Vars::Aimbot::Projectile::AutoDetonate, { "Stickies", "Flares" }, {}, FDropdown_Multi | FDropdown_Left); + FDropdown("Auto airblast", Vars::Aimbot::Projectile::AutoAirblast, { "Off", "Legit", "Rage" }, {}, FDropdown_Right); + FDropdown("Modifiers## Projectile", Vars::Aimbot::Projectile::Modifiers, { "Charge shot", "Cancel charge", "Bodyaim if lethal", "Use prime time" }, {}, FDropdown_Multi); + FSlider("Max simulation time", Vars::Aimbot::Projectile::PredictionTime, 0.1f, 10.f, 0.25f, "%gs", FSlider_Min | FSlider_Precision); + PushTransparent(!FGet(Vars::Aimbot::Projectile::StrafePrediction)); + FSlider("Hit chance", Vars::Aimbot::Projectile::Hitchance, 0.f, 100.f, 5.f, "%g%%", FSlider_Clamp | FSlider_Precision); + PopTransparent(); + FSlider("Autodet radius", Vars::Aimbot::Projectile::AutodetRadius, 0.f, 100.f, 5.f, "%g%%", FSlider_Clamp | FSlider_Precision); + FSlider("Splash radius", Vars::Aimbot::Projectile::SplashRadius, 0.f, 100.f, 5.f, "%g%%", FSlider_Clamp | FSlider_Precision); + PushTransparent(!FGet(Vars::Aimbot::Projectile::AutoRelease)); + FSlider("Auto release", Vars::Aimbot::Projectile::AutoRelease, 0.f, 100.f, 5.f, "%g%%", FSlider_Clamp | FSlider_Precision); + PopTransparent(); + } EndSection(); + if (Vars::Debug::Info.Value) + { + if (Section("debug## projectile")) + { + FText("\nground"); + FSlider("samples##ground", Vars::Aimbot::Projectile::GroundSamples, 3, 66, 1, "%i", FSlider_Left); + FSlider("straight fuzzy value##ground", Vars::Aimbot::Projectile::GroundStraightFuzzyValue, 0.f, 500.f, 25.f, "%g", FSlider_Right | FSlider_Precision); + FSlider("low min samples##ground", Vars::Aimbot::Projectile::GroundLowMinimumSamples, 3, 66, 1, "%i", FSlider_Left); + FSlider("high min samples##ground", Vars::Aimbot::Projectile::GroundHighMinimumSamples, 3, 66, 1, "%i", FSlider_Right); + FSlider("low min distance##ground", Vars::Aimbot::Projectile::GroundLowMinimumDistance, 0.f, 10000.f, 100.f, "%g", FSlider_Left | FSlider_Min | FSlider_Precision); + FSlider("high min distance##ground", Vars::Aimbot::Projectile::GroundHighMinimumDistance, 0.f, 10000.f, 100.f, "%g", FSlider_Right | FSlider_Min | FSlider_Precision); + + FText("air"); + FSlider("samples##air", Vars::Aimbot::Projectile::AirSamples, 3, 66, 1, "%i", FSlider_Left); + FSlider("straight fuzzy value##air", Vars::Aimbot::Projectile::AirStraightFuzzyValue, 0.f, 500.f, 25.f, "%g", FSlider_Right | FSlider_Precision); + FSlider("low min samples##air", Vars::Aimbot::Projectile::AirLowMinimumSamples, 3, 66, 1, "%i", FSlider_Left); + FSlider("high min samples##air", Vars::Aimbot::Projectile::AirHighMinimumSamples, 3, 66, 1, "%i", FSlider_Right); + FSlider("low min distance##air", Vars::Aimbot::Projectile::AirLowMinimumDistance, 0.f, 10000.f, 100.f, "%g", FSlider_Left | FSlider_Min | FSlider_Precision); + FSlider("high min distance##air", Vars::Aimbot::Projectile::AirHighMinimumDistance, 0.f, 10000.f, 100.f, "%g", FSlider_Right | FSlider_Min | FSlider_Precision); + + FText(""); + FSlider("velocity average count", Vars::Aimbot::Projectile::VelocityAverageCount, 1, 10, 1, "%i", FSlider_Left); + FSlider("vertical shift", Vars::Aimbot::Projectile::VerticalShift, 0.f, 10.f, 0.5f, "%g", FSlider_Right | FSlider_Min | FSlider_Precision); + FSlider("huntsman lerp", Vars::Aimbot::Projectile::HuntsmanLerp, 0.f, 100.f, 1.f, "%g%%", FSlider_Left | FSlider_Clamp | FSlider_Precision); + FSlider("latency offset", Vars::Aimbot::Projectile::LatencyOffset, -1.f, 1.f, 0.1f, "%g", FSlider_Right | FSlider_Precision); + FSlider("hull increase", Vars::Aimbot::Projectile::HullIncrease, 0.f, 3.f, 0.5f, "%g", FSlider_Left | FSlider_Min | FSlider_Precision); + FSlider("drag override", Vars::Aimbot::Projectile::DragOverride, 0.f, 1.f, 0.01f, "%g", FSlider_Right | FSlider_Min | FSlider_Precision); + FSlider("time override", Vars::Aimbot::Projectile::TimeOverride, 0.f, 1.f, 0.01f, "%g", FSlider_Left | FSlider_Min | FSlider_Precision); + FToggle("splash grates", Vars::Aimbot::Projectile::SplashGrates, FToggle_Left); + FToggle("splash rocket", Vars::Aimbot::Projectile::SplashRocket, FToggle_Right); + FTooltip("special splash type for rockets, more expensive"); + FSlider("splash points", Vars::Aimbot::Projectile::SplashPoints, 1, 400, 5, "%i", FSlider_Min); + FSlider("direct splash count", Vars::Aimbot::Projectile::SplashCountDirect, 1, 100, 1, "%i", FSlider_Left | FSlider_Min); + FSlider("arc splash count", Vars::Aimbot::Projectile::SplashCountArc, 1, 100, 1, "%i", FSlider_Right | FSlider_Min); + FSlider("delta count", Vars::Aimbot::Projectile::DeltaCount, 1, 5, 1, "%i", FSlider_Left); + FDropdown("delta mode", Vars::Aimbot::Projectile::DeltaMode, { "average", "max" }, {}, FDropdown_Right); + } EndSection(); + } + if (Section("Melee")) + { + FToggle("Auto backstab", Vars::Aimbot::Melee::AutoBackstab, FToggle_Left); + FToggle("Ignore razorback", Vars::Aimbot::Melee::IgnoreRazorback, FToggle_Right); + FToggle("Swing prediction", Vars::Aimbot::Melee::SwingPrediction, FToggle_Left); + FToggle("Whip teammates", Vars::Aimbot::Melee::WhipTeam, FToggle_Right); + } EndSection(); + if (Vars::Debug::Info.Value) + { + if (Section("debug## melee")) + { + FSlider("swing ticks", Vars::Aimbot::Melee::SwingTicks, 10, 14); + FToggle("backstab account ping", Vars::Aimbot::Melee::BackstabAccountPing, FToggle_Left); + FToggle("backstab double test", Vars::Aimbot::Melee::BackstabDoubleTest, FToggle_Right); + } + EndSection(); + } + + EndTable(); } - - EndTable(); - } - break; + break; // HvH - case 1: - if (BeginTable("HvHTable", 2)) - { - /* Column 1 */ - TableNextColumn(); - if (Section("Doubletap")) + case 1: + if (BeginTable("HvHTable", 2)) { - FToggle("Doubletap", Vars::CL_Move::Doubletap::Doubletap, FToggle_Left); - FToggle("Warp", Vars::CL_Move::Doubletap::Warp, FToggle_Right); - FToggle("Recharge ticks", Vars::CL_Move::Doubletap::RechargeTicks, FToggle_Left); - FToggle("Anti-warp", Vars::CL_Move::Doubletap::AntiWarp, FToggle_Right); - FSlider("Tick limit", Vars::CL_Move::Doubletap::TickLimit, 2, 22, 1, "%i", FSlider_Clamp); - FSlider("Warp rate", Vars::CL_Move::Doubletap::WarpRate, 2, 22, 1, "%i", FSlider_Clamp); - FSlider("Passive recharge", Vars::CL_Move::Doubletap::PassiveRecharge, 0, 67, 1, "%i", FSlider_Clamp); - } EndSection(); - if (Section("Fakelag")) - { - FDropdown("Fakelag", Vars::CL_Move::Fakelag::Fakelag, { "Off", "Plain", "Random", "Adaptive" }, {}, FSlider_Left); - FDropdown("Options", Vars::CL_Move::Fakelag::Options, { "Only moving", "On unduck", "Not airborne" }, {}, FDropdown_Multi | FSlider_Right); - PushTransparent(FGet(Vars::CL_Move::Fakelag::Fakelag) != Vars::CL_Move::Fakelag::FakelagEnum::Plain); - FSlider("Plain ticks", Vars::CL_Move::Fakelag::PlainTicks, 1, 22, 1, "%i", FSlider_Clamp | FSlider_Left); - PopTransparent(); - PushTransparent(FGet(Vars::CL_Move::Fakelag::Fakelag) != Vars::CL_Move::Fakelag::FakelagEnum::Random); - FSlider("Random ticks", Vars::CL_Move::Fakelag::RandomTicks, 1, 22, 1, "%i - %i", FSlider_Clamp | FSlider_Right); - PopTransparent(); - FToggle("Unchoke on attack", Vars::CL_Move::Fakelag::UnchokeOnAttack, FToggle_Left); - FToggle("Retain blastjump", Vars::CL_Move::Fakelag::RetainBlastJump, FToggle_Right); - } EndSection(); - if (Section("Anti Aim")) - { - FToggle("Enabled", Vars::AntiHack::AntiAim::Enabled); - FDropdown("Real pitch", Vars::AntiHack::AntiAim::PitchReal, { "None", "Up", "Down", "Zero", "Jitter", "Reverse jitter" }, {}, FDropdown_Left); - FDropdown("Fake pitch", Vars::AntiHack::AntiAim::PitchFake, { "None", "Up", "Down", "Jitter", "Reverse jitter" }, {}, FDropdown_Right); - FDropdown("Real yaw", Vars::AntiHack::AntiAim::YawReal, { "Forward", "Left", "Right", "Backwards", "Edge", "Jitter", "Spin" }, {}, FDropdown_Left); - FDropdown("Fake yaw", Vars::AntiHack::AntiAim::YawFake, { "Forward", "Left", "Right", "Backwards", "Edge", "Jitter", "Spin" }, {}, FDropdown_Right); - FDropdown("Real offset", Vars::AntiHack::AntiAim::RealYawMode, { "View", "Target" }, {}, FDropdown_Left); - FDropdown("Fake offset", Vars::AntiHack::AntiAim::FakeYawMode, { "View", "Target" }, {}, FDropdown_Right); - FSlider("Real offset## Offset", Vars::AntiHack::AntiAim::RealYawOffset, -180, 180, 5, "%i", FSlider_Left | FSlider_Clamp | FSlider_Precision); - FSlider("Fake offset## Offset", Vars::AntiHack::AntiAim::FakeYawOffset, -180, 180, 5, "%i", FSlider_Right | FSlider_Clamp | FSlider_Precision); - PushTransparent(FGet(Vars::AntiHack::AntiAim::YawReal) != Vars::AntiHack::AntiAim::YawEnum::Edge && FGet(Vars::AntiHack::AntiAim::YawReal) != Vars::AntiHack::AntiAim::YawEnum::Jitter); - FSlider("Real value", Vars::AntiHack::AntiAim::RealYawValue, -180, 180.f, 5.f, "%g", FSlider_Left | FSlider_Clamp | FSlider_Precision); - PopTransparent(); - PushTransparent(FGet(Vars::AntiHack::AntiAim::YawFake) != Vars::AntiHack::AntiAim::YawEnum::Edge && FGet(Vars::AntiHack::AntiAim::YawFake) != Vars::AntiHack::AntiAim::YawEnum::Jitter); - FSlider("Fake value", Vars::AntiHack::AntiAim::FakeYawValue, -180.f, 180.f, 5.f, "%g", FSlider_Right | FSlider_Clamp | FSlider_Precision); - PopTransparent(); - PushTransparent(FGet(Vars::AntiHack::AntiAim::YawFake) != Vars::AntiHack::AntiAim::YawEnum::Spin && FGet(Vars::AntiHack::AntiAim::YawReal) != Vars::AntiHack::AntiAim::YawEnum::Spin); - FSlider("Spin speed", Vars::AntiHack::AntiAim::SpinSpeed, -30.f, 30.f, 1.f, "%g", FSlider_Left | FSlider_Precision); - PopTransparent(); - SetCursorPos({ GetWindowSize().x / 2 + 4, GetCursorPosY() - 24 }); - FToggle("Minwalk", Vars::AntiHack::AntiAim::MinWalk, FToggle_Left); - FToggle("Anti-overlap", Vars::AntiHack::AntiAim::AntiOverlap, FToggle_Left); - FToggle("Hide pitch on shot", Vars::AntiHack::AntiAim::InvalidShootPitch, FToggle_Right); - } EndSection(); - - /* Column 2 */ - TableNextColumn(); - if (Section("Resolver")) - { - FToggle("Enabled", Vars::AntiHack::Resolver::Resolver, FToggle_Left); - PushTransparent(!FGet(Vars::AntiHack::Resolver::Resolver)); - FToggle("Ignore in-air", Vars::AntiHack::Resolver::IgnoreAirborne, FToggle_Right); - PopTransparent(); - } EndSection(); - if (Section("Auto Peek")) - { - FToggle("Auto peek", Vars::CL_Move::AutoPeek); - } EndSection(); - if (Section("Speedhack")) - { - FToggle("Speedhack", Vars::CL_Move::SpeedEnabled); - PushTransparent(!FGet(Vars::CL_Move::SpeedEnabled)); - FSlider("SpeedHack factor", Vars::CL_Move::SpeedFactor, 1, 50, 1); - PopTransparent(); - } EndSection(); - if (Section("Cheater Detection")) - { - PushTransparent(!FGet(Vars::CheaterDetection::Methods)); - FDropdown("Detection methods", Vars::CheaterDetection::Methods, { "Invalid pitch", "Packet choking", "Aim flicking", "Duck Speed" }, {}, FDropdown_Multi); - FSlider("Detections required", Vars::CheaterDetection::DetectionsRequired, 10, 50, 1); - - PushTransparent(!(FGet(Vars::CheaterDetection::Methods) & Vars::CheaterDetection::MethodsEnum::PacketChoking)); - FSlider("Minimum choking", Vars::CheaterDetection::MinimumChoking, 4, 22, 1); + /* Column 1 */ + TableNextColumn(); + if (Section("Doubletap")) + { + FToggle("Doubletap", Vars::CL_Move::Doubletap::Doubletap, FToggle_Left); + FToggle("Warp", Vars::CL_Move::Doubletap::Warp, FToggle_Right); + FToggle("Recharge ticks", Vars::CL_Move::Doubletap::RechargeTicks, FToggle_Left); + FToggle("Anti-warp", Vars::CL_Move::Doubletap::AntiWarp, FToggle_Right); + FSlider("Tick limit", Vars::CL_Move::Doubletap::TickLimit, 2, 22, 1, "%i", FSlider_Clamp); + FSlider("Warp rate", Vars::CL_Move::Doubletap::WarpRate, 2, 22, 1, "%i", FSlider_Clamp); + FSlider("Passive recharge", Vars::CL_Move::Doubletap::PassiveRecharge, 0, 67, 1, "%i", FSlider_Clamp); + } EndSection(); + if (Section("Fakelag")) + { + FDropdown("Fakelag", Vars::CL_Move::Fakelag::Fakelag, { "Off", "Plain", "Random", "Adaptive" }, {}, FSlider_Left); + FDropdown("Options", Vars::CL_Move::Fakelag::Options, { "Only moving", "On unduck", "Not airborne" }, {}, FDropdown_Multi | FSlider_Right); + PushTransparent(FGet(Vars::CL_Move::Fakelag::Fakelag) != Vars::CL_Move::Fakelag::FakelagEnum::Plain); + FSlider("Plain ticks", Vars::CL_Move::Fakelag::PlainTicks, 1, 22, 1, "%i", FSlider_Clamp | FSlider_Left); PopTransparent(); - - PushTransparent(!(FGet(Vars::CheaterDetection::Methods) & Vars::CheaterDetection::MethodsEnum::AimFlicking)); - FSlider("Minimum flick angle", Vars::CheaterDetection::MinimumFlick, 10.f, 30.f, 1.f, "%.0f", FSlider_Left); - FSlider("Maximum noise", Vars::CheaterDetection::MaximumNoise, 1.f, 10.f, 1.f, "%.0f", FSlider_Right); + PushTransparent(FGet(Vars::CL_Move::Fakelag::Fakelag) != Vars::CL_Move::Fakelag::FakelagEnum::Random); + FSlider("Random ticks", Vars::CL_Move::Fakelag::RandomTicks, 1, 22, 1, "%i - %i", FSlider_Clamp | FSlider_Right); PopTransparent(); - PopTransparent(); - } EndSection(); + FToggle("Unchoke on attack", Vars::CL_Move::Fakelag::UnchokeOnAttack, FToggle_Left); + FToggle("Retain blastjump", Vars::CL_Move::Fakelag::RetainBlastJump, FToggle_Right); + } EndSection(); + if (Section("Anti Aim")) + { + FToggle("Enabled", Vars::AntiHack::AntiAim::Enabled); + FDropdown("Real pitch", Vars::AntiHack::AntiAim::PitchReal, { "None", "Up", "Down", "Zero", "Jitter", "Reverse jitter" }, {}, FDropdown_Left); + FDropdown("Fake pitch", Vars::AntiHack::AntiAim::PitchFake, { "None", "Up", "Down", "Jitter", "Reverse jitter" }, {}, FDropdown_Right); + FDropdown("Real yaw", Vars::AntiHack::AntiAim::YawReal, { "Forward", "Left", "Right", "Backwards", "Edge", "Jitter", "Spin" }, {}, FDropdown_Left); + FDropdown("Fake yaw", Vars::AntiHack::AntiAim::YawFake, { "Forward", "Left", "Right", "Backwards", "Edge", "Jitter", "Spin" }, {}, FDropdown_Right); + FDropdown("Real offset", Vars::AntiHack::AntiAim::RealYawMode, { "View", "Target" }, {}, FDropdown_Left); + FDropdown("Fake offset", Vars::AntiHack::AntiAim::FakeYawMode, { "View", "Target" }, {}, FDropdown_Right); + FSlider("Real offset## Offset", Vars::AntiHack::AntiAim::RealYawOffset, -180, 180, 5, "%i", FSlider_Left | FSlider_Clamp | FSlider_Precision); + FSlider("Fake offset## Offset", Vars::AntiHack::AntiAim::FakeYawOffset, -180, 180, 5, "%i", FSlider_Right | FSlider_Clamp | FSlider_Precision); + PushTransparent(FGet(Vars::AntiHack::AntiAim::YawReal) != Vars::AntiHack::AntiAim::YawEnum::Edge && FGet(Vars::AntiHack::AntiAim::YawReal) != Vars::AntiHack::AntiAim::YawEnum::Jitter); + FSlider("Real value", Vars::AntiHack::AntiAim::RealYawValue, -180, 180.f, 5.f, "%g", FSlider_Left | FSlider_Clamp | FSlider_Precision); + PopTransparent(); + PushTransparent(FGet(Vars::AntiHack::AntiAim::YawFake) != Vars::AntiHack::AntiAim::YawEnum::Edge && FGet(Vars::AntiHack::AntiAim::YawFake) != Vars::AntiHack::AntiAim::YawEnum::Jitter); + FSlider("Fake value", Vars::AntiHack::AntiAim::FakeYawValue, -180.f, 180.f, 5.f, "%g", FSlider_Right | FSlider_Clamp | FSlider_Precision); + PopTransparent(); + PushTransparent(FGet(Vars::AntiHack::AntiAim::YawFake) != Vars::AntiHack::AntiAim::YawEnum::Spin && FGet(Vars::AntiHack::AntiAim::YawReal) != Vars::AntiHack::AntiAim::YawEnum::Spin); + FSlider("Spin speed", Vars::AntiHack::AntiAim::SpinSpeed, -30.f, 30.f, 1.f, "%g", FSlider_Left | FSlider_Precision); + PopTransparent(); + SetCursorPos({ GetWindowSize().x / 2 + 4, GetCursorPosY() - 24 }); + FToggle("Minwalk", Vars::AntiHack::AntiAim::MinWalk, FToggle_Left); + FToggle("Anti-overlap", Vars::AntiHack::AntiAim::AntiOverlap, FToggle_Left); + FToggle("Hide pitch on shot", Vars::AntiHack::AntiAim::InvalidShootPitch, FToggle_Right); + } EndSection(); - EndTable(); + /* Column 2 */ + TableNextColumn(); + if (Section("Resolver")) + { + FToggle("Enabled", Vars::AntiHack::Resolver::Resolver, FToggle_Left); + PushTransparent(!FGet(Vars::AntiHack::Resolver::Resolver)); + FToggle("Ignore in-air", Vars::AntiHack::Resolver::IgnoreAirborne, FToggle_Right); + PopTransparent(); + } EndSection(); + if (Section("Auto Peek")) + { + FToggle("Auto peek", Vars::CL_Move::AutoPeek); + } EndSection(); + if (Section("Speedhack")) + { + FToggle("Speedhack", Vars::CL_Move::SpeedEnabled); + PushTransparent(!FGet(Vars::CL_Move::SpeedEnabled)); + FSlider("SpeedHack factor", Vars::CL_Move::SpeedFactor, 1, 50, 1); + PopTransparent(); + } EndSection(); + if (Section("Cheater Detection")) + { + PushTransparent(!FGet(Vars::CheaterDetection::Methods)); + FDropdown("Detection methods", Vars::CheaterDetection::Methods, { "Invalid pitch", "Packet choking", "Aim flicking", "Duck Speed" }, {}, FDropdown_Multi); + FSlider("Detections required", Vars::CheaterDetection::DetectionsRequired, 10, 50, 1); + + PushTransparent(!(FGet(Vars::CheaterDetection::Methods) & Vars::CheaterDetection::MethodsEnum::PacketChoking)); + FSlider("Minimum choking", Vars::CheaterDetection::MinimumChoking, 4, 22, 1); + PopTransparent(); + + PushTransparent(!(FGet(Vars::CheaterDetection::Methods) & Vars::CheaterDetection::MethodsEnum::AimFlicking)); + FSlider("Minimum flick angle", Vars::CheaterDetection::MinimumFlick, 10.f, 30.f, 1.f, "%.0f", FSlider_Left); + FSlider("Maximum noise", Vars::CheaterDetection::MaximumNoise, 1.f, 10.f, 1.f, "%.0f", FSlider_Right); + PopTransparent(); + PopTransparent(); + } EndSection(); + + EndTable(); + } + break; } - break; - } + + PopStyleColor(); + } EndChild(); + PopStyleVar(); } /* Tab: Visuals */ @@ -376,527 +372,541 @@ void CMenu::MenuVisuals() { using namespace ImGui; - switch (CurrentVisualsTab) + const auto vWindowSize = GetWindowSize(); + static int iCurrentTab = 0; + FTabs({ "ESP", "CHAMS", "GLOW", "MISC##", "RADAR", "MENU" }, &iCurrentTab, { 100, 40 }, { 0, 0 }); + + SetCursorPos({ 0, 40 }); + PushStyleVar(ImGuiStyleVar_WindowPadding, { 8.f, 8.f }); + if (BeginChild("Content", { vWindowSize.x, vWindowSize.y - 40 }, false, ImGuiWindowFlags_AlwaysUseWindowPadding)) { + PushStyleColor(ImGuiCol_ChildBg, F::Render.Foreground.Value); + + switch (iCurrentTab) + { // ESP - case 0: - if (BeginTable("VisualsESPTable", 2)) - { - /* Column 1 */ - TableNextColumn(); - if (Section("ESP")) + case 0: + if (BeginTable("VisualsESPTable", 2)) { - FDropdown("Draw", Vars::ESP::Draw, { "Players", "Buildings", "Projectiles", "Objective", "NPCs", "Health", "Ammo", "Money", "Powerups", "Bombs", "Spellbook", "Gargoyle" }, {}, FDropdown_Multi); - PushTransparent(!(FGet(Vars::ESP::Draw) & Vars::ESP::DrawEnum::Players)); - FDropdown("Player", Vars::ESP::Player, { "Enemy", "Team", "Local", "Friends", "Prioritized", "##Divider", "Name", "Box", "Distance", "Bones", "Health bar", "Health text", "Uber bar", "Uber text", "Class icon", "Class text", "Weapon icon", "Weapon text", "Priority", "Labels", "Buffs", "Debuffs", "Misc", "Lag compensation", "Ping", "KDR" }, {}, FDropdown_Multi); - PopTransparent(); - PushTransparent(!(FGet(Vars::ESP::Draw) & Vars::ESP::DrawEnum::Buildings)); - FDropdown("Building", Vars::ESP::Building, { "Enemy", "Team", "Local", "Friends", "Prioritized", "##Divider", "Name", "Box", "Distance", "Health bar", "Health text", "Owner", "Level", "Flags" }, {}, FDropdown_Multi); - PopTransparent(); - PushTransparent(!(FGet(Vars::ESP::Draw) & Vars::ESP::DrawEnum::Projectiles)); - FDropdown("Projectile", Vars::ESP::Projectile, { "Enemy", "Team", "Local", "Friends", "Prioritized", "##Divider", "Name", "Box", "Distance", "Flags" }, {}, FDropdown_Multi); - PopTransparent(); - PushTransparent(!(FGet(Vars::ESP::Draw) & Vars::ESP::DrawEnum::Objective)); - FDropdown("Objective", Vars::ESP::Objective, { "Enemy", "Team", "##Divider", "Name", "Box", "Distance", "Flags", "Intel return time" }, {}, FDropdown_Multi); - PopTransparent(); - } EndSection(); - - /* Column 2 */ - TableNextColumn(); - if (Section("Colors")) - { - FToggle("Relative colors", Vars::Colors::Relative); - if (FGet(Vars::Colors::Relative)) + /* Column 1 */ + TableNextColumn(); + if (Section("ESP")) { - FColorPicker("Enemy color", Vars::Colors::Enemy, 0, FColorPicker_Left); - FColorPicker("Team color", Vars::Colors::Team, 0, FColorPicker_Middle | FColorPicker_SameLine); - } - else - { - FColorPicker("RED color", Vars::Colors::TeamRed, 0, FColorPicker_Left); - FColorPicker("BLU color", Vars::Colors::TeamBlu, 0, FColorPicker_Middle | FColorPicker_SameLine); - } - - FColorPicker("Health bar top", Vars::Colors::HealthBar, false, 0, FColorPicker_Left); - FColorPicker("Health bar bottom", Vars::Colors::HealthBar, true, 0, FColorPicker_Middle | FColorPicker_SameLine); - FColorPicker("Uber bar", Vars::Colors::UberBar, 0, FColorPicker_Left); - FColorPicker("Invulnerable color", Vars::Colors::Invulnerable, 0, FColorPicker_Middle | FColorPicker_SameLine); - FColorPicker("Overheal color", Vars::Colors::Overheal, 0, FColorPicker_Left); - FColorPicker("Cloaked color", Vars::Colors::Cloak, 0, FColorPicker_Middle | FColorPicker_SameLine); - FColorPicker("Local color", Vars::Colors::Local, 0, FColorPicker_Left); - FColorPicker("Target color", Vars::Colors::Target, 0, FColorPicker_Middle | FColorPicker_SameLine); - - FColorPicker("Healthpack color", Vars::Colors::Health, 0, FColorPicker_Left); - FColorPicker("Ammopack color", Vars::Colors::Ammo, 0, FColorPicker_Middle | FColorPicker_SameLine); - FColorPicker("Money color", Vars::Colors::Money, 0, FColorPicker_Left); - FColorPicker("Powerup color", Vars::Colors::Powerup, 0, FColorPicker_Middle | FColorPicker_SameLine); - FColorPicker("NPC color", Vars::Colors::NPC, 0, FColorPicker_Left); - FColorPicker("Halloween color", Vars::Colors::Halloween, 0, FColorPicker_Middle | FColorPicker_SameLine); - - FSlider("Active alpha", Vars::ESP::ActiveAlpha, 0, 255, 5, "%i", FSlider_Clamp); - FSlider("Dormant alpha", Vars::ESP::DormantAlpha, 0, 255, 5, "%i", FSlider_Clamp); - FSlider("Dormant decay", Vars::ESP::DormantTime, 0.015f, 5.0f, 0.1f, "%gs", FSlider_Left | FSlider_Min | FSlider_Precision); - FToggle("Dormant priority only", Vars::ESP::DormantPriority, FToggle_Right); Dummy({ 0, 8 }); - } EndSection(); - - EndTable(); - } - break; - // Chams - case 1: - if (BeginTable("VisualsChamsTable", 2)) - { - /* Column 1 */ - TableNextColumn(); - if (Section("Friendly")) - { - FToggle("Players", Vars::Chams::Friendly::Players, FToggle_Left); - FToggle("Ragdolls", Vars::Chams::Friendly::Ragdolls, FToggle_Right); - FToggle("Buildings", Vars::Chams::Friendly::Buildings, FToggle_Left); - FToggle("Projectiles", Vars::Chams::Friendly::Projectiles, FToggle_Right); - - FMDropdown("Visible material", Vars::Chams::Friendly::Visible, FDropdown_Left); - FMDropdown("Occluded material", Vars::Chams::Friendly::Occluded, FDropdown_Right); - } EndSection(); - if (Section("Enemy")) - { - FToggle("Players", Vars::Chams::Enemy::Players, FToggle_Left); - FToggle("Ragdolls", Vars::Chams::Enemy::Ragdolls, FToggle_Right); - FToggle("Buildings", Vars::Chams::Enemy::Buildings, FToggle_Left); - FToggle("Projectiles", Vars::Chams::Enemy::Projectiles, FToggle_Right); - - FMDropdown("Visible material", Vars::Chams::Enemy::Visible, FDropdown_Left); - FMDropdown("Occluded material", Vars::Chams::Enemy::Occluded, FDropdown_Right); - } EndSection(); - if (Section("World")) - { - FToggle("NPCs", Vars::Chams::World::NPCs, FToggle_Left); - FToggle("Pickups", Vars::Chams::World::Pickups, FToggle_Right); - FToggle("Objective", Vars::Chams::World::Objective, FToggle_Left); - FToggle("Powerups", Vars::Chams::World::Powerups, FToggle_Right); - FToggle("Bombs", Vars::Chams::World::Bombs, FToggle_Left); - FToggle("Halloween", Vars::Chams::World::Halloween, FToggle_Right); - - FMDropdown("Visible material", Vars::Chams::World::Visible, FDropdown_Left); - FMDropdown("Occluded material", Vars::Chams::World::Occluded, FDropdown_Right); - } EndSection(); - - /* Column 2 */ - TableNextColumn(); - if (Section("Player")) - { - FToggle("Local", Vars::Chams::Player::Local, FToggle_Left); - FToggle("Friend", Vars::Chams::Player::Friend, FToggle_Right); - FToggle("Priority", Vars::Chams::Player::Priority, FToggle_Left); - - FMDropdown("Visible material", Vars::Chams::Player::Visible, FDropdown_Left); - FMDropdown("Occluded material", Vars::Chams::Player::Occluded, FDropdown_Right); - } EndSection(); - if (Section("Backtrack")) - { - FToggle("Enabled", Vars::Chams::Backtrack::Enabled, FToggle_Left); - SameLine(GetWindowSize().x / 2 + 4); SetCursorPosY(GetCursorPosY() - 24); - FDropdown("Draw", Vars::Chams::Backtrack::Draw, { "Last", "Last + first", "All" }, {}, FDropdown_Left); - - FMDropdown("Material", Vars::Chams::Backtrack::Visible, FDropdown_None); - } EndSection(); - if (Section("Fake Angle")) - { - FToggle("Enabled", Vars::Chams::FakeAngle::Enabled); - - FMDropdown("Material", Vars::Chams::FakeAngle::Visible, FDropdown_None); - } EndSection(); - if (Section("Viewmodel")) - { - FToggle("Weapon", Vars::Chams::Viewmodel::Weapon, FToggle_Left); - FToggle("Hands", Vars::Chams::Viewmodel::Hands, FToggle_Right); - - FMDropdown("Weapon material", Vars::Chams::Viewmodel::WeaponVisible, FDropdown_Left); - FMDropdown("Hands material", Vars::Chams::Viewmodel::HandsVisible, FDropdown_Right); - } EndSection(); - - EndTable(); - } - break; - // Glow - case 2: - if (BeginTable("VisualsGlowTable", 2)) - { - /* Column 1 */ - TableNextColumn(); - if (Section("Friendly")) - { - FToggle("Players", Vars::Glow::Friendly::Players, FToggle_Left); - FToggle("Ragdolls", Vars::Glow::Friendly::Ragdolls, FToggle_Right); - FToggle("Buildings", Vars::Glow::Friendly::Buildings, FToggle_Left); - FToggle("Projectiles", Vars::Glow::Friendly::Projectiles, FToggle_Right); - - PushTransparent(!FGet(Vars::Glow::Friendly::Stencil)); - FSlider("Stencil scale## Friendly", Vars::Glow::Friendly::Stencil, 0, 10, 1, "%i", FSlider_Left | FSlider_Min); - PopTransparent(); - PushTransparent(!FGet(Vars::Glow::Friendly::Blur)); - FSlider("Blur scale## Friendly", Vars::Glow::Friendly::Blur, 0, 10, 1, "%i", FSlider_Right | FSlider_Min); - PopTransparent(); - } EndSection(); - if (Section("Enemy")) - { - FToggle("Players", Vars::Glow::Enemy::Players, FToggle_Left); - FToggle("Ragdolls", Vars::Glow::Enemy::Ragdolls, FToggle_Right); - FToggle("Buildings", Vars::Glow::Enemy::Buildings, FToggle_Left); - FToggle("Projectiles", Vars::Glow::Enemy::Projectiles, FToggle_Right); - - PushTransparent(!FGet(Vars::Glow::Enemy::Stencil)); - FSlider("Stencil scale## Enemy", Vars::Glow::Enemy::Stencil, 0, 10, 1, "%i", FSlider_Left | FSlider_Min); - PopTransparent(); - PushTransparent(!FGet(Vars::Glow::Enemy::Blur)); - FSlider("Blur scale## Enemy", Vars::Glow::Enemy::Blur, 0, 10, 1, "%i", FSlider_Right | FSlider_Min); - PopTransparent(); - } EndSection(); - if (Section("World")) - { - FToggle("NPCs", Vars::Glow::World::NPCs, FToggle_Left); - FToggle("Pickups", Vars::Glow::World::Pickups, FToggle_Right); - FToggle("Objective", Vars::Glow::World::Objective, FToggle_Left); - FToggle("Powerups", Vars::Glow::World::Powerups, FToggle_Right); - FToggle("Bombs", Vars::Glow::World::Bombs, FToggle_Left); - FToggle("Halloween", Vars::Glow::World::Halloween, FToggle_Right); - - PushTransparent(!FGet(Vars::Glow::World::Stencil)); - FSlider("Stencil scale## World", Vars::Glow::World::Stencil, 0, 10, 1, "%i", FSlider_Left | FSlider_Min); - PopTransparent(); - PushTransparent(!FGet(Vars::Glow::World::Blur)); - FSlider("Blur scale## World", Vars::Glow::World::Blur, 0, 10, 1, "%i", FSlider_Right | FSlider_Min); - PopTransparent(); - } EndSection(); - - /* Column 2 */ - TableNextColumn(); - if (Section("Player")) - { - FToggle("Local", Vars::Glow::Player::Local, FToggle_Left); - FToggle("Friend", Vars::Glow::Player::Friend, FToggle_Right); - FToggle("Priority", Vars::Glow::Player::Priority, FToggle_Left); - - PushTransparent(!FGet(Vars::Glow::Player::Stencil)); - FSlider("Stencil scale## Player", Vars::Glow::Player::Stencil, 0, 10, 1, "%i", FSlider_Left | FSlider_Min); - PopTransparent(); - PushTransparent(!FGet(Vars::Glow::Player::Blur)); - FSlider("Blur scale## Player", Vars::Glow::Player::Blur, 0, 10, 1, "%i", FSlider_Right | FSlider_Min); - PopTransparent(); - } EndSection(); - if (Section("Backtrack")) - { - FToggle("Enabled", Vars::Glow::Backtrack::Enabled, FToggle_Left); - SameLine(GetWindowSize().x / 2 + 4); SetCursorPosY(GetCursorPosY() - 24); - FDropdown("Draw", Vars::Glow::Backtrack::Draw, { "Last", "Last + first", "All" }, {}, FDropdown_Left); - - PushTransparent(!FGet(Vars::Glow::Backtrack::Stencil)); - FSlider("Stencil scale## Backtrack", Vars::Glow::Backtrack::Stencil, 0, 10, 1, "%i", FSlider_Left | FSlider_Min); - PopTransparent(); - PushTransparent(!FGet(Vars::Glow::Backtrack::Blur)); - FSlider("Blur scale## Backtrack", Vars::Glow::Backtrack::Blur, 0, 10, 1, "%i", FSlider_Right | FSlider_Min); - PopTransparent(); - } EndSection(); - if (Section("Fake Angle")) - { - FToggle("Enabled", Vars::Glow::FakeAngle::Enabled); - - PushTransparent(!FGet(Vars::Glow::FakeAngle::Stencil)); - FSlider("Stencil scale## FakeAngle", Vars::Glow::FakeAngle::Stencil, 0, 10, 1, "%i", FSlider_Left | FSlider_Min); - PopTransparent(); - PushTransparent(!FGet(Vars::Glow::FakeAngle::Blur)); - FSlider("Blur scale## FakeAngle", Vars::Glow::FakeAngle::Blur, 0, 10, 1, "%i", FSlider_Right | FSlider_Min); - PopTransparent(); - } EndSection(); - if (Section("Viewmodel")) - { - FToggle("Weapon", Vars::Glow::Viewmodel::Weapon, FToggle_Left); - FToggle("Hands", Vars::Glow::Viewmodel::Hands, FToggle_Right); - - PushTransparent(!FGet(Vars::Glow::Viewmodel::Stencil)); - FSlider("Stencil scale## Viewmodel", Vars::Glow::Viewmodel::Stencil, 0, 10, 1, "%i", FSlider_Left | FSlider_Min); - PopTransparent(); - PushTransparent(!FGet(Vars::Glow::Viewmodel::Blur)); - FSlider("Blur scale## Viewmodel", Vars::Glow::Viewmodel::Blur, 0, 10, 1, "%i", FSlider_Right | FSlider_Min); - PopTransparent(); - } EndSection(); - - EndTable(); - } - break; - // Misc - case 3: - if (BeginTable("VisualsMiscTable", 2)) - { - /* Column 1 */ - TableNextColumn(); - if (Section("Removals")) - { - FToggle("Scope", Vars::Visuals::Removals::Scope, FToggle_Left); - FToggle("Interpolation", Vars::Visuals::Removals::Interpolation, FToggle_Right); - FToggle("Disguises", Vars::Visuals::Removals::Disguises, FToggle_Left); - FToggle("Screen overlays", Vars::Visuals::Removals::ScreenOverlays, FToggle_Right); - FToggle("Taunts", Vars::Visuals::Removals::Taunts, FToggle_Left); - FToggle("Screen effects", Vars::Visuals::Removals::ScreenEffects, FToggle_Right); - FToggle("View punch", Vars::Visuals::Removals::ViewPunch, FToggle_Left); - FToggle("Angle forcing", Vars::Visuals::Removals::AngleForcing, FToggle_Right); - FToggle("MOTD", Vars::Visuals::Removals::MOTD, FToggle_Left); - FToggle("Convar queries", Vars::Visuals::Removals::ConvarQueries, FToggle_Right); - FToggle("Post processing", Vars::Visuals::Removals::PostProcessing, FToggle_Left); - FToggle("DSP", Vars::Visuals::Removals::DSP, FToggle_Right); - } EndSection(); - if (Section("UI")) - { - FDropdown("Streamer mode", Vars::Visuals::UI::StreamerMode, { "Off", "Local", "Friends", "All" }, {}, FDropdown_Left); - FDropdown("Chat tags", Vars::Visuals::UI::ChatTags, { "Local", "Friends", "Assigned" }, {}, FDropdown_Right | FDropdown_Multi); - FSlider("Field of view", Vars::Visuals::UI::FieldOfView, 0, 160, 1, "%i"); - FSlider("Zoomed field of view", Vars::Visuals::UI::ZoomFieldOfView, 0, 160, 1, "%i"); - FToggle("Reveal scoreboard", Vars::Visuals::UI::RevealScoreboard, FToggle_Left); - FToggle("Scoreboard utility", Vars::Visuals::UI::ScoreboardUtility, FToggle_Right); - FToggle("Scoreboard colors", Vars::Visuals::UI::ScoreboardColors, FToggle_Left); - FToggle("Clean screenshots", Vars::Visuals::UI::CleanScreenshots, FToggle_Right); - FToggle("Sniper sightlines", Vars::Visuals::UI::SniperSightlines, FToggle_Left); - FToggle("Pickup timers", Vars::Visuals::UI::PickupTimers, FToggle_Right); - } EndSection(); - if (Section("Viewmodel")) - { - FToggle("Crosshair aim position", Vars::Visuals::Viewmodel::CrosshairAim, FToggle_Left); - FToggle("Viewmodel aim position", Vars::Visuals::Viewmodel::ViewmodelAim, FToggle_Right); - FSlider("Offset X", Vars::Visuals::Viewmodel::OffsetX, -45, 45, 5, "%i", FSlider_Precision); - FSlider("Offset Y", Vars::Visuals::Viewmodel::OffsetY, -45, 45, 5, "%i", FSlider_Precision); - FSlider("Offset Z", Vars::Visuals::Viewmodel::OffsetZ, -45, 45, 5, "%i", FSlider_Precision); - FSlider("Roll", Vars::Visuals::Viewmodel::Roll, -180, 180, 5, "%i", FSlider_Clamp | FSlider_Precision); - PushTransparent(!FGet(Vars::Visuals::Viewmodel::SwayScale) || !FGet(Vars::Visuals::Viewmodel::SwayInterp)); - FSlider("Sway scale", Vars::Visuals::Viewmodel::SwayScale, 0.f, 5.f, 0.5f, "%g", FSlider_Left | FSlider_Min | FSlider_Precision); - FSlider("Sway interp", Vars::Visuals::Viewmodel::SwayInterp, 0.f, 1.f, 0.1f, "%g", FSlider_Right | FSlider_Min | FSlider_Precision); - PopTransparent(); - } EndSection(); - if (Section("Particles")) - { - // https://developer.valvesoftware.com/wiki/Team_Fortress_2/Particles - // https://forums.alliedmods.net/showthread.php?t=127111 - FSDropdown("Bullet trail", Vars::Visuals::Particles::BulletTrail, { "Off", "Machina", "C.A.P.P.E.R", "Short Circuit", "Merasmus ZAP", "Merasmus ZAP 2", "Big Nasty", "Distortion Trail", "Black Ink", "Line", "Beam" }, FDropdown_Left | FSDropdown_Custom); - FSDropdown("Crit trail", Vars::Visuals::Particles::CritTrail, { "Off", "Machina", "C.A.P.P.E.R", "Short Circuit", "Merasmus ZAP", "Merasmus ZAP 2", "Big Nasty", "Distortion Trail", "Black Ink", "Line", "Beam" }, FDropdown_Right | FSDropdown_Custom); - FSDropdown("Medigun beam", Vars::Visuals::Particles::MedigunBeam, { "Off", "None", "Uber", "Dispenser", "Passtime", "Bombonomicon", "White", "Orange" }, FDropdown_Left | FSDropdown_Custom); - FSDropdown("Medigun charge", Vars::Visuals::Particles::MedigunCharge, { "Off", "None", "Electrocuted", "Halloween", "Fireball", "Teleport", "Burning", "Scorching", "Purple energy", "Green energy", "Nebula", "Purple stars", "Green stars", "Sunbeams", "Spellbound", "Purple sparks", "Yellow sparks", "Green zap", "Yellow zap", "Plasma", "Frostbite", "Time warp", "Purple souls", "Green souls", "Bubbles", "Hearts" }, FDropdown_Right | FSDropdown_Custom); - FSDropdown("Projectile trail", Vars::Visuals::Particles::ProjectileTrail, { "Off", "None", "Rocket", "Critical", "Energy", "Charged", "Ray", "Fireball", "Teleport", "Fire", "Flame", "Sparks", "Flare", "Trail", "Health", "Smoke", "Bubbles", "Halloween", "Monoculus", "Sparkles", "Rainbow" }, FDropdown_Left | FSDropdown_Custom); - FDropdown("Spell footsteps", Vars::Visuals::Particles::SpellFootsteps, { "Off", "Color", "Team", "Halloween" }, {}, FDropdown_Right, -10); - FColorPicker("Spell footstep", Vars::Colors::SpellFootstep, 0, FColorPicker_Dropdown); - FToggle("Draw icons through walls", Vars::Visuals::Particles::DrawIconsThroughWalls); - FToggle("Draw damage numbers through walls", Vars::Visuals::Particles::DrawDamageNumbersThroughWalls); - } EndSection(); - if (Section("Ragdolls")) - { - FToggle("No ragdolls", Vars::Visuals::Ragdolls::NoRagdolls, FToggle_Left); - FToggle("No gibs", Vars::Visuals::Ragdolls::NoGib, FToggle_Right); - FToggle("Mods", Vars::Visuals::Ragdolls::Enabled, FToggle_Left); - PushTransparent(!FGet(Vars::Visuals::Ragdolls::Enabled)); - FToggle("Enemy only", Vars::Visuals::Ragdolls::EnemyOnly, FToggle_Right); - FDropdown("Ragdoll effects", Vars::Visuals::Ragdolls::Effects, { "Burning", "Electrocuted", "Ash", "Dissolve" }, {}, FDropdown_Multi | FDropdown_Left); - FDropdown("Ragdoll model", Vars::Visuals::Ragdolls::Type, { "None", "Gold", "Ice" }, {}, FDropdown_Right); - FSlider("Ragdoll force", Vars::Visuals::Ragdolls::Force, -10.f, 10.f, 0.5f, "%g", FSlider_Precision); - FSlider("Horizontal force", Vars::Visuals::Ragdolls::ForceHorizontal, -10.f, 10.f, 0.5f, "%g", FSlider_Precision); - FSlider("Vertical force", Vars::Visuals::Ragdolls::ForceVertical, -10.f, 10.f, 0.5f, "%g", FSlider_Precision); - PopTransparent(); - } EndSection(); - - /* Column 2 */ - TableNextColumn(); - if (Section("Bullet")) - { - FColorPicker("Bullet tracer color", Vars::Colors::Bullet); - FToggle("Bullet tracers", Vars::Visuals::Bullet::Enabled); - } EndSection(); - if (Section("Simulation")) - { - FDropdown("Player path", Vars::Visuals::Simulation::PlayerPath, { "Off", "Line", "Separators", "Spaced" }, {}, FDropdown_Left, -20); - FColorPicker("Player path", Vars::Colors::PlayerPath, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); FColorPicker("Player path clipped", Vars::Colors::PlayerPathClipped, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); - FDropdown("Projectile path", Vars::Visuals::Simulation::ProjectilePath, { "Off", "Line", "Separators", "Spaced" }, {}, FDropdown_Right, -20); - FColorPicker("Projectile path", Vars::Colors::ProjectilePath, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); FColorPicker("Projectile path clipped", Vars::Colors::ProjectilePathClipped, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); - FDropdown("Trajectory path", Vars::Visuals::Simulation::TrajectoryPath, { "Off", "Line", "Separators", "Spaced" }, {}, FDropdown_Left, -20); - FColorPicker("Trajectory path", Vars::Colors::TrajectoryPath, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); FColorPicker("Trajectory path clipped", Vars::Colors::TrajectoryPathClipped, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); - FDropdown("Shot path", Vars::Visuals::Simulation::ShotPath, { "Off", "Line", "Separators", "Spaced" }, {}, FDropdown_Right, -20); - FColorPicker("Shot path", Vars::Colors::ShotPath, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); FColorPicker("Shot path clipped", Vars::Colors::ShotPathClipped, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); - FDropdown("Splash radius", Vars::Visuals::Simulation::SplashRadius, { "Simulation", "##Divider", "Priority", "Enemy", "Team", "Local", "Friends", "##Divider", "Rockets", "Stickies", "Pipes", "Scorch shot", "##Divider", "Trace" }, {}, FDropdown_Multi, -20); - FColorPicker("Splash radius", Vars::Colors::SplashRadius, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); FColorPicker("Splash radius clipped", Vars::Colors::SplashRadiusClipped, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); - FToggle("Timed", Vars::Visuals::Simulation::Timed, FToggle_Left); - FToggle("Box", Vars::Visuals::Simulation::Box, FToggle_Right); - FToggle("Swing prediction lines", Vars::Visuals::Simulation::SwingLines, FToggle_Left); - FToggle("Projectile camera", Vars::Visuals::Simulation::ProjectileCamera, FToggle_Right); - } EndSection(); - if (Vars::Debug::Info.Value) - { - if (Section("debug")) - { - FToggle("overwrite", Vars::Visuals::Trajectory::Overwrite); - FSlider("off x", Vars::Visuals::Trajectory::OffX, -25.f, 25.f, 0.5f, "%g", FSlider_Precision); - FSlider("off y", Vars::Visuals::Trajectory::OffY, -25.f, 25.f, 0.5f, "%g", FSlider_Precision); - FSlider("off z", Vars::Visuals::Trajectory::OffZ, -25.f, 25.f, 0.5f, "%g", FSlider_Precision); - FToggle("pipes", Vars::Visuals::Trajectory::Pipes); - FSlider("hull", Vars::Visuals::Trajectory::Hull, 0.f, 10.f, 0.5f, "%g", FSlider_Min | FSlider_Precision); - FSlider("speed", Vars::Visuals::Trajectory::Speed, 0.f, 5000.f, 50.f, "%g", FSlider_Min | FSlider_Precision); - FSlider("gravity", Vars::Visuals::Trajectory::Gravity, 0.f, 1.f, 0.1f, "%g", FSlider_Precision); - FToggle("no spin", Vars::Visuals::Trajectory::NoSpin); - FSlider("lifetime", Vars::Visuals::Trajectory::LifeTime, 0.f, 10.f, 0.1f, "%g", FSlider_Min | FSlider_Precision); - FSlider("up vel", Vars::Visuals::Trajectory::UpVelocity, 0.f, 1000.f, 50.f, "%g", FSlider_Precision); - FSlider("ang vel x", Vars::Visuals::Trajectory::AngVelocityX, -1000.f, 1000.f, 50.f, "%g", FSlider_Precision); - FSlider("ang vel y", Vars::Visuals::Trajectory::AngVelocityY, -1000.f, 1000.f, 50.f, "%g", FSlider_Precision); - FSlider("ang vel z", Vars::Visuals::Trajectory::AngVelocityZ, -1000.f, 1000.f, 50.f, "%g", FSlider_Precision); - FSlider("drag", Vars::Visuals::Trajectory::Drag, 0.f, 2.f, 0.1f, "%g", FSlider_Precision); - FSlider("drag x", Vars::Visuals::Trajectory::DragBasisX, 0.f, 0.1f, 0.01f, "%.15g", FSlider_Precision); - FSlider("drag y", Vars::Visuals::Trajectory::DragBasisY, 0.f, 0.1f, 0.01f, "%.15g", FSlider_Precision); - FSlider("drag z", Vars::Visuals::Trajectory::DragBasisZ, 0.f, 0.1f, 0.01f, "%.15g", FSlider_Precision); - FSlider("ang drag x", Vars::Visuals::Trajectory::AngDragBasisX, 0.f, 0.1f, 0.01f, "%.15g", FSlider_Precision); - FSlider("ang drag y", Vars::Visuals::Trajectory::AngDragBasisY, 0.f, 0.1f, 0.01f, "%.15g", FSlider_Precision); - FSlider("ang drag z", Vars::Visuals::Trajectory::AngDragBasisZ, 0.f, 0.1f, 0.01f, "%.15g", FSlider_Precision); - FSlider("max vel", Vars::Visuals::Trajectory::MaxVelocity, 0.f, 4000.f, 50.f, "%g", FSlider_Min | FSlider_Precision); - FSlider("max ang vel", Vars::Visuals::Trajectory::MaxAngularVelocity, 0.f, 7200.f, 50.f, "%g", FSlider_Min | FSlider_Precision); + FDropdown("Draw", Vars::ESP::Draw, { "Players", "Buildings", "Projectiles", "Objective", "NPCs", "Health", "Ammo", "Money", "Powerups", "Bombs", "Spellbook", "Gargoyle" }, {}, FDropdown_Multi); + PushTransparent(!(FGet(Vars::ESP::Draw) & Vars::ESP::DrawEnum::Players)); + FDropdown("Player", Vars::ESP::Player, { "Enemy", "Team", "Local", "Friends", "Prioritized", "##Divider", "Name", "Box", "Distance", "Bones", "Health bar", "Health text", "Uber bar", "Uber text", "Class icon", "Class text", "Weapon icon", "Weapon text", "Priority", "Labels", "Buffs", "Debuffs", "Misc", "Lag compensation", "Ping", "KDR" }, {}, FDropdown_Multi); + PopTransparent(); + PushTransparent(!(FGet(Vars::ESP::Draw) & Vars::ESP::DrawEnum::Buildings)); + FDropdown("Building", Vars::ESP::Building, { "Enemy", "Team", "Local", "Friends", "Prioritized", "##Divider", "Name", "Box", "Distance", "Health bar", "Health text", "Owner", "Level", "Flags" }, {}, FDropdown_Multi); + PopTransparent(); + PushTransparent(!(FGet(Vars::ESP::Draw) & Vars::ESP::DrawEnum::Projectiles)); + FDropdown("Projectile", Vars::ESP::Projectile, { "Enemy", "Team", "Local", "Friends", "Prioritized", "##Divider", "Name", "Box", "Distance", "Flags" }, {}, FDropdown_Multi); + PopTransparent(); + PushTransparent(!(FGet(Vars::ESP::Draw) & Vars::ESP::DrawEnum::Objective)); + FDropdown("Objective", Vars::ESP::Objective, { "Enemy", "Team", "##Divider", "Name", "Box", "Distance", "Flags", "Intel return time" }, {}, FDropdown_Multi); + PopTransparent(); } EndSection(); + + /* Column 2 */ + TableNextColumn(); + if (Section("Colors")) + { + FToggle("Relative colors", Vars::Colors::Relative); + if (FGet(Vars::Colors::Relative)) + { + FColorPicker("Enemy color", Vars::Colors::Enemy, 0, FColorPicker_Left); + FColorPicker("Team color", Vars::Colors::Team, 0, FColorPicker_Middle | FColorPicker_SameLine); + } + else + { + FColorPicker("RED color", Vars::Colors::TeamRed, 0, FColorPicker_Left); + FColorPicker("BLU color", Vars::Colors::TeamBlu, 0, FColorPicker_Middle | FColorPicker_SameLine); + } + + FColorPicker("Health bar top", Vars::Colors::HealthBar, false, 0, FColorPicker_Left); + FColorPicker("Health bar bottom", Vars::Colors::HealthBar, true, 0, FColorPicker_Middle | FColorPicker_SameLine); + FColorPicker("Uber bar", Vars::Colors::UberBar, 0, FColorPicker_Left); + FColorPicker("Invulnerable color", Vars::Colors::Invulnerable, 0, FColorPicker_Middle | FColorPicker_SameLine); + FColorPicker("Overheal color", Vars::Colors::Overheal, 0, FColorPicker_Left); + FColorPicker("Cloaked color", Vars::Colors::Cloak, 0, FColorPicker_Middle | FColorPicker_SameLine); + FColorPicker("Local color", Vars::Colors::Local, 0, FColorPicker_Left); + FColorPicker("Target color", Vars::Colors::Target, 0, FColorPicker_Middle | FColorPicker_SameLine); + + FColorPicker("Healthpack color", Vars::Colors::Health, 0, FColorPicker_Left); + FColorPicker("Ammopack color", Vars::Colors::Ammo, 0, FColorPicker_Middle | FColorPicker_SameLine); + FColorPicker("Money color", Vars::Colors::Money, 0, FColorPicker_Left); + FColorPicker("Powerup color", Vars::Colors::Powerup, 0, FColorPicker_Middle | FColorPicker_SameLine); + FColorPicker("NPC color", Vars::Colors::NPC, 0, FColorPicker_Left); + FColorPicker("Halloween color", Vars::Colors::Halloween, 0, FColorPicker_Middle | FColorPicker_SameLine); + + FSlider("Active alpha", Vars::ESP::ActiveAlpha, 0, 255, 5, "%i", FSlider_Clamp); + FSlider("Dormant alpha", Vars::ESP::DormantAlpha, 0, 255, 5, "%i", FSlider_Clamp); + FSlider("Dormant decay", Vars::ESP::DormantTime, 0.015f, 5.0f, 0.1f, "%gs", FSlider_Left | FSlider_Min | FSlider_Precision); + FToggle("Dormant priority only", Vars::ESP::DormantPriority, FToggle_Right); Dummy({ 0, 8 }); + } EndSection(); + + EndTable(); } - if (Section("Hitbox")) + break; + // Chams + case 1: + if (BeginTable("VisualsChamsTable", 2)) { - FDropdown("Enabled", Vars::Visuals::Hitbox::Enabled, { "On shot", "On hit" }, {}, FDropdown_Multi, -80); - FColorPicker("Target edge color", Vars::Colors::TargetHitboxEdge, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); - FColorPicker("Target face color", Vars::Colors::TargetHitboxFace, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); - SameLine(); Dummy({ 2, 0 }); - FColorPicker("Bone edge color", Vars::Colors::BoneHitboxEdge, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); - FColorPicker("Bone face color", Vars::Colors::BoneHitboxFace, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); - SameLine(); Dummy({ 2, 0 }); - FColorPicker("Bound edge color", Vars::Colors::BoundHitboxEdge, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); - FColorPicker("Bound face color", Vars::Colors::BoundHitboxFace, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); - } EndSection(); - if (Section("Thirdperson")) - { - FToggle("Thirdperson", Vars::Visuals::ThirdPerson::Enabled, FToggle_Left); - FToggle("Thirdperson crosshair", Vars::Visuals::ThirdPerson::Crosshair, FToggle_Right); - FSlider("Thirdperson distance", Vars::Visuals::ThirdPerson::Distance, 0.f, 500.f, 5.f, "%g", FSlider_Precision); - FSlider("Thirdperson right", Vars::Visuals::ThirdPerson::Right, -500.f, 500.f, 5.f, "%g", FSlider_Precision); - FSlider("Thirdperson up", Vars::Visuals::ThirdPerson::Up, -500.f, 500.f, 5.f, "%g", FSlider_Precision); - } EndSection(); - if (Section("Out of FOV arrows")) - { - FToggle("Enabled", Vars::Visuals::FOVArrows::Enabled); - FSlider("Offset", Vars::Visuals::FOVArrows::Offset, 0, 500, 25, "%i", FSlider_Min | FSlider_Precision); - FSlider("Max distance", Vars::Visuals::FOVArrows::MaxDist, 0.f, 5000.f, 50.f, "%g", FSlider_Min | FSlider_Precision); - } EndSection(); - if (Section("World")) - { - FSDropdown("World texture", Vars::Visuals::World::WorldTexture, { "Default", "Dev", "Camo", "Black", "White", "Flat" }, FSDropdown_Custom); - FDropdown("Modulations", Vars::Visuals::World::Modulations, { "World", "Sky", "Prop", "Particle", "Fog" }, {}, FDropdown_Left | FDropdown_Multi); - static std::vector skyNames = { - "Off", "sky_tf2_04", "sky_upward", "sky_dustbowl_01", "sky_goldrush_01", "sky_granary_01", "sky_well_01", "sky_gravel_01", "sky_badlands_01", - "sky_hydro_01", "sky_night_01", "sky_nightfall_01", "sky_trainyard_01", "sky_stormfront_01", "sky_morningsnow_01","sky_alpinestorm_01", - "sky_harvest_01", "sky_harvest_night_01", "sky_halloween", "sky_halloween_night_01", "sky_halloween_night2014_01", "sky_island_01", "sky_rainbow_01" - }; - FSDropdown("Skybox changer", Vars::Visuals::World::SkyboxChanger, skyNames, FSDropdown_Custom | FDropdown_Right); - PushTransparent(!(FGet(Vars::Visuals::World::Modulations) & Vars::Visuals::World::ModulationsEnum::World)); - FColorPicker("World modulation", Vars::Colors::WorldModulation, 0, FColorPicker_Left); - PopTransparent(); - PushTransparent(!(FGet(Vars::Visuals::World::Modulations) & Vars::Visuals::World::ModulationsEnum::Sky)); - FColorPicker("Sky modulation", Vars::Colors::SkyModulation, 0, FColorPicker_Middle | FColorPicker_SameLine); - PopTransparent(); - PushTransparent(!(FGet(Vars::Visuals::World::Modulations) & Vars::Visuals::World::ModulationsEnum::Prop)); - FColorPicker("Prop modulation", Vars::Colors::PropModulation, 0, FColorPicker_Left); - PopTransparent(); - PushTransparent(!(FGet(Vars::Visuals::World::Modulations) & Vars::Visuals::World::ModulationsEnum::Particle)); - FColorPicker("Particle modulation", Vars::Colors::ParticleModulation, 0, FColorPicker_Middle | FColorPicker_SameLine); - PopTransparent(); - PushTransparent(!(FGet(Vars::Visuals::World::Modulations) & Vars::Visuals::World::ModulationsEnum::Fog)); - FColorPicker("Fog modulation", Vars::Colors::FogModulation, 0, FColorPicker_Left); - PopTransparent(); - FToggle("Near prop fade", Vars::Visuals::World::NearPropFade, FToggle_Left); - FToggle("No prop fade", Vars::Visuals::World::NoPropFade, FToggle_Right); - } EndSection(); + /* Column 1 */ + TableNextColumn(); + if (Section("Friendly")) + { + FToggle("Players", Vars::Chams::Friendly::Players, FToggle_Left); + FToggle("Ragdolls", Vars::Chams::Friendly::Ragdolls, FToggle_Right); + FToggle("Buildings", Vars::Chams::Friendly::Buildings, FToggle_Left); + FToggle("Projectiles", Vars::Chams::Friendly::Projectiles, FToggle_Right); - EndTable(); - } - break; + FMDropdown("Visible material", Vars::Chams::Friendly::Visible, FDropdown_Left); + FMDropdown("Occluded material", Vars::Chams::Friendly::Occluded, FDropdown_Right); + } EndSection(); + if (Section("Enemy")) + { + FToggle("Players", Vars::Chams::Enemy::Players, FToggle_Left); + FToggle("Ragdolls", Vars::Chams::Enemy::Ragdolls, FToggle_Right); + FToggle("Buildings", Vars::Chams::Enemy::Buildings, FToggle_Left); + FToggle("Projectiles", Vars::Chams::Enemy::Projectiles, FToggle_Right); + + FMDropdown("Visible material", Vars::Chams::Enemy::Visible, FDropdown_Left); + FMDropdown("Occluded material", Vars::Chams::Enemy::Occluded, FDropdown_Right); + } EndSection(); + if (Section("World")) + { + FToggle("NPCs", Vars::Chams::World::NPCs, FToggle_Left); + FToggle("Pickups", Vars::Chams::World::Pickups, FToggle_Right); + FToggle("Objective", Vars::Chams::World::Objective, FToggle_Left); + FToggle("Powerups", Vars::Chams::World::Powerups, FToggle_Right); + FToggle("Bombs", Vars::Chams::World::Bombs, FToggle_Left); + FToggle("Halloween", Vars::Chams::World::Halloween, FToggle_Right); + + FMDropdown("Visible material", Vars::Chams::World::Visible, FDropdown_Left); + FMDropdown("Occluded material", Vars::Chams::World::Occluded, FDropdown_Right); + } EndSection(); + + /* Column 2 */ + TableNextColumn(); + if (Section("Player")) + { + FToggle("Local", Vars::Chams::Player::Local, FToggle_Left); + FToggle("Friend", Vars::Chams::Player::Friend, FToggle_Right); + FToggle("Priority", Vars::Chams::Player::Priority, FToggle_Left); + + FMDropdown("Visible material", Vars::Chams::Player::Visible, FDropdown_Left); + FMDropdown("Occluded material", Vars::Chams::Player::Occluded, FDropdown_Right); + } EndSection(); + if (Section("Backtrack")) + { + FToggle("Enabled", Vars::Chams::Backtrack::Enabled, FToggle_Left); + SameLine(GetWindowSize().x / 2 + 4); SetCursorPosY(GetCursorPosY() - 24); + FDropdown("Draw", Vars::Chams::Backtrack::Draw, { "Last", "Last + first", "All" }, {}, FDropdown_Left); + + FMDropdown("Material", Vars::Chams::Backtrack::Visible, FDropdown_None); + } EndSection(); + if (Section("Fake Angle")) + { + FToggle("Enabled", Vars::Chams::FakeAngle::Enabled); + + FMDropdown("Material", Vars::Chams::FakeAngle::Visible, FDropdown_None); + } EndSection(); + if (Section("Viewmodel")) + { + FToggle("Weapon", Vars::Chams::Viewmodel::Weapon, FToggle_Left); + FToggle("Hands", Vars::Chams::Viewmodel::Hands, FToggle_Right); + + FMDropdown("Weapon material", Vars::Chams::Viewmodel::WeaponVisible, FDropdown_Left); + FMDropdown("Hands material", Vars::Chams::Viewmodel::HandsVisible, FDropdown_Right); + } EndSection(); + + EndTable(); + } + break; + // Glow + case 2: + if (BeginTable("VisualsGlowTable", 2)) + { + /* Column 1 */ + TableNextColumn(); + if (Section("Friendly")) + { + FToggle("Players", Vars::Glow::Friendly::Players, FToggle_Left); + FToggle("Ragdolls", Vars::Glow::Friendly::Ragdolls, FToggle_Right); + FToggle("Buildings", Vars::Glow::Friendly::Buildings, FToggle_Left); + FToggle("Projectiles", Vars::Glow::Friendly::Projectiles, FToggle_Right); + + PushTransparent(!FGet(Vars::Glow::Friendly::Stencil)); + FSlider("Stencil scale## Friendly", Vars::Glow::Friendly::Stencil, 0, 10, 1, "%i", FSlider_Left | FSlider_Min); + PopTransparent(); + PushTransparent(!FGet(Vars::Glow::Friendly::Blur)); + FSlider("Blur scale## Friendly", Vars::Glow::Friendly::Blur, 0, 10, 1, "%i", FSlider_Right | FSlider_Min); + PopTransparent(); + } EndSection(); + if (Section("Enemy")) + { + FToggle("Players", Vars::Glow::Enemy::Players, FToggle_Left); + FToggle("Ragdolls", Vars::Glow::Enemy::Ragdolls, FToggle_Right); + FToggle("Buildings", Vars::Glow::Enemy::Buildings, FToggle_Left); + FToggle("Projectiles", Vars::Glow::Enemy::Projectiles, FToggle_Right); + + PushTransparent(!FGet(Vars::Glow::Enemy::Stencil)); + FSlider("Stencil scale## Enemy", Vars::Glow::Enemy::Stencil, 0, 10, 1, "%i", FSlider_Left | FSlider_Min); + PopTransparent(); + PushTransparent(!FGet(Vars::Glow::Enemy::Blur)); + FSlider("Blur scale## Enemy", Vars::Glow::Enemy::Blur, 0, 10, 1, "%i", FSlider_Right | FSlider_Min); + PopTransparent(); + } EndSection(); + if (Section("World")) + { + FToggle("NPCs", Vars::Glow::World::NPCs, FToggle_Left); + FToggle("Pickups", Vars::Glow::World::Pickups, FToggle_Right); + FToggle("Objective", Vars::Glow::World::Objective, FToggle_Left); + FToggle("Powerups", Vars::Glow::World::Powerups, FToggle_Right); + FToggle("Bombs", Vars::Glow::World::Bombs, FToggle_Left); + FToggle("Halloween", Vars::Glow::World::Halloween, FToggle_Right); + + PushTransparent(!FGet(Vars::Glow::World::Stencil)); + FSlider("Stencil scale## World", Vars::Glow::World::Stencil, 0, 10, 1, "%i", FSlider_Left | FSlider_Min); + PopTransparent(); + PushTransparent(!FGet(Vars::Glow::World::Blur)); + FSlider("Blur scale## World", Vars::Glow::World::Blur, 0, 10, 1, "%i", FSlider_Right | FSlider_Min); + PopTransparent(); + } EndSection(); + + /* Column 2 */ + TableNextColumn(); + if (Section("Player")) + { + FToggle("Local", Vars::Glow::Player::Local, FToggle_Left); + FToggle("Friend", Vars::Glow::Player::Friend, FToggle_Right); + FToggle("Priority", Vars::Glow::Player::Priority, FToggle_Left); + + PushTransparent(!FGet(Vars::Glow::Player::Stencil)); + FSlider("Stencil scale## Player", Vars::Glow::Player::Stencil, 0, 10, 1, "%i", FSlider_Left | FSlider_Min); + PopTransparent(); + PushTransparent(!FGet(Vars::Glow::Player::Blur)); + FSlider("Blur scale## Player", Vars::Glow::Player::Blur, 0, 10, 1, "%i", FSlider_Right | FSlider_Min); + PopTransparent(); + } EndSection(); + if (Section("Backtrack")) + { + FToggle("Enabled", Vars::Glow::Backtrack::Enabled, FToggle_Left); + SameLine(GetWindowSize().x / 2 + 4); SetCursorPosY(GetCursorPosY() - 24); + FDropdown("Draw", Vars::Glow::Backtrack::Draw, { "Last", "Last + first", "All" }, {}, FDropdown_Left); + + PushTransparent(!FGet(Vars::Glow::Backtrack::Stencil)); + FSlider("Stencil scale## Backtrack", Vars::Glow::Backtrack::Stencil, 0, 10, 1, "%i", FSlider_Left | FSlider_Min); + PopTransparent(); + PushTransparent(!FGet(Vars::Glow::Backtrack::Blur)); + FSlider("Blur scale## Backtrack", Vars::Glow::Backtrack::Blur, 0, 10, 1, "%i", FSlider_Right | FSlider_Min); + PopTransparent(); + } EndSection(); + if (Section("Fake Angle")) + { + FToggle("Enabled", Vars::Glow::FakeAngle::Enabled); + + PushTransparent(!FGet(Vars::Glow::FakeAngle::Stencil)); + FSlider("Stencil scale## FakeAngle", Vars::Glow::FakeAngle::Stencil, 0, 10, 1, "%i", FSlider_Left | FSlider_Min); + PopTransparent(); + PushTransparent(!FGet(Vars::Glow::FakeAngle::Blur)); + FSlider("Blur scale## FakeAngle", Vars::Glow::FakeAngle::Blur, 0, 10, 1, "%i", FSlider_Right | FSlider_Min); + PopTransparent(); + } EndSection(); + if (Section("Viewmodel")) + { + FToggle("Weapon", Vars::Glow::Viewmodel::Weapon, FToggle_Left); + FToggle("Hands", Vars::Glow::Viewmodel::Hands, FToggle_Right); + + PushTransparent(!FGet(Vars::Glow::Viewmodel::Stencil)); + FSlider("Stencil scale## Viewmodel", Vars::Glow::Viewmodel::Stencil, 0, 10, 1, "%i", FSlider_Left | FSlider_Min); + PopTransparent(); + PushTransparent(!FGet(Vars::Glow::Viewmodel::Blur)); + FSlider("Blur scale## Viewmodel", Vars::Glow::Viewmodel::Blur, 0, 10, 1, "%i", FSlider_Right | FSlider_Min); + PopTransparent(); + } EndSection(); + + EndTable(); + } + break; + // Misc + case 3: + if (BeginTable("VisualsMiscTable", 2)) + { + /* Column 1 */ + TableNextColumn(); + if (Section("Removals")) + { + FToggle("Scope", Vars::Visuals::Removals::Scope, FToggle_Left); + FToggle("Interpolation", Vars::Visuals::Removals::Interpolation, FToggle_Right); + FToggle("Disguises", Vars::Visuals::Removals::Disguises, FToggle_Left); + FToggle("Screen overlays", Vars::Visuals::Removals::ScreenOverlays, FToggle_Right); + FToggle("Taunts", Vars::Visuals::Removals::Taunts, FToggle_Left); + FToggle("Screen effects", Vars::Visuals::Removals::ScreenEffects, FToggle_Right); + FToggle("View punch", Vars::Visuals::Removals::ViewPunch, FToggle_Left); + FToggle("Angle forcing", Vars::Visuals::Removals::AngleForcing, FToggle_Right); + FToggle("MOTD", Vars::Visuals::Removals::MOTD, FToggle_Left); + FToggle("Convar queries", Vars::Visuals::Removals::ConvarQueries, FToggle_Right); + FToggle("Post processing", Vars::Visuals::Removals::PostProcessing, FToggle_Left); + FToggle("DSP", Vars::Visuals::Removals::DSP, FToggle_Right); + } EndSection(); + if (Section("UI")) + { + FDropdown("Streamer mode", Vars::Visuals::UI::StreamerMode, { "Off", "Local", "Friends", "All" }, {}, FDropdown_Left); + FDropdown("Chat tags", Vars::Visuals::UI::ChatTags, { "Local", "Friends", "Assigned" }, {}, FDropdown_Right | FDropdown_Multi); + FSlider("Field of view", Vars::Visuals::UI::FieldOfView, 0, 160, 1, "%i"); + FSlider("Zoomed field of view", Vars::Visuals::UI::ZoomFieldOfView, 0, 160, 1, "%i"); + FToggle("Reveal scoreboard", Vars::Visuals::UI::RevealScoreboard, FToggle_Left); + FToggle("Scoreboard utility", Vars::Visuals::UI::ScoreboardUtility, FToggle_Right); + FToggle("Scoreboard colors", Vars::Visuals::UI::ScoreboardColors, FToggle_Left); + FToggle("Clean screenshots", Vars::Visuals::UI::CleanScreenshots, FToggle_Right); + FToggle("Sniper sightlines", Vars::Visuals::UI::SniperSightlines, FToggle_Left); + FToggle("Pickup timers", Vars::Visuals::UI::PickupTimers, FToggle_Right); + } EndSection(); + if (Section("Viewmodel")) + { + FToggle("Crosshair aim position", Vars::Visuals::Viewmodel::CrosshairAim, FToggle_Left); + FToggle("Viewmodel aim position", Vars::Visuals::Viewmodel::ViewmodelAim, FToggle_Right); + FSlider("Offset X", Vars::Visuals::Viewmodel::OffsetX, -45, 45, 5, "%i", FSlider_Precision); + FSlider("Offset Y", Vars::Visuals::Viewmodel::OffsetY, -45, 45, 5, "%i", FSlider_Precision); + FSlider("Offset Z", Vars::Visuals::Viewmodel::OffsetZ, -45, 45, 5, "%i", FSlider_Precision); + FSlider("Roll", Vars::Visuals::Viewmodel::Roll, -180, 180, 5, "%i", FSlider_Clamp | FSlider_Precision); + PushTransparent(!FGet(Vars::Visuals::Viewmodel::SwayScale) || !FGet(Vars::Visuals::Viewmodel::SwayInterp)); + FSlider("Sway scale", Vars::Visuals::Viewmodel::SwayScale, 0.f, 5.f, 0.5f, "%g", FSlider_Left | FSlider_Min | FSlider_Precision); + FSlider("Sway interp", Vars::Visuals::Viewmodel::SwayInterp, 0.f, 1.f, 0.1f, "%g", FSlider_Right | FSlider_Min | FSlider_Precision); + PopTransparent(); + } EndSection(); + if (Section("Particles")) + { + // https://developer.valvesoftware.com/wiki/Team_Fortress_2/Particles + // https://forums.alliedmods.net/showthread.php?t=127111 + FSDropdown("Bullet trail", Vars::Visuals::Particles::BulletTrail, { "Off", "Machina", "C.A.P.P.E.R", "Short Circuit", "Merasmus ZAP", "Merasmus ZAP 2", "Big Nasty", "Distortion Trail", "Black Ink", "Line", "Beam" }, FDropdown_Left | FSDropdown_Custom); + FSDropdown("Crit trail", Vars::Visuals::Particles::CritTrail, { "Off", "Machina", "C.A.P.P.E.R", "Short Circuit", "Merasmus ZAP", "Merasmus ZAP 2", "Big Nasty", "Distortion Trail", "Black Ink", "Line", "Beam" }, FDropdown_Right | FSDropdown_Custom); + FSDropdown("Medigun beam", Vars::Visuals::Particles::MedigunBeam, { "Off", "None", "Uber", "Dispenser", "Passtime", "Bombonomicon", "White", "Orange" }, FDropdown_Left | FSDropdown_Custom); + FSDropdown("Medigun charge", Vars::Visuals::Particles::MedigunCharge, { "Off", "None", "Electrocuted", "Halloween", "Fireball", "Teleport", "Burning", "Scorching", "Purple energy", "Green energy", "Nebula", "Purple stars", "Green stars", "Sunbeams", "Spellbound", "Purple sparks", "Yellow sparks", "Green zap", "Yellow zap", "Plasma", "Frostbite", "Time warp", "Purple souls", "Green souls", "Bubbles", "Hearts" }, FDropdown_Right | FSDropdown_Custom); + FSDropdown("Projectile trail", Vars::Visuals::Particles::ProjectileTrail, { "Off", "None", "Rocket", "Critical", "Energy", "Charged", "Ray", "Fireball", "Teleport", "Fire", "Flame", "Sparks", "Flare", "Trail", "Health", "Smoke", "Bubbles", "Halloween", "Monoculus", "Sparkles", "Rainbow" }, FDropdown_Left | FSDropdown_Custom); + FDropdown("Spell footsteps", Vars::Visuals::Particles::SpellFootsteps, { "Off", "Color", "Team", "Halloween" }, {}, FDropdown_Right, -10); + FColorPicker("Spell footstep", Vars::Colors::SpellFootstep, 0, FColorPicker_Dropdown); + FToggle("Draw icons through walls", Vars::Visuals::Particles::DrawIconsThroughWalls); + FToggle("Draw damage numbers through walls", Vars::Visuals::Particles::DrawDamageNumbersThroughWalls); + } EndSection(); + if (Section("Ragdolls")) + { + FToggle("No ragdolls", Vars::Visuals::Ragdolls::NoRagdolls, FToggle_Left); + FToggle("No gibs", Vars::Visuals::Ragdolls::NoGib, FToggle_Right); + FToggle("Mods", Vars::Visuals::Ragdolls::Enabled, FToggle_Left); + PushTransparent(!FGet(Vars::Visuals::Ragdolls::Enabled)); + FToggle("Enemy only", Vars::Visuals::Ragdolls::EnemyOnly, FToggle_Right); + FDropdown("Ragdoll effects", Vars::Visuals::Ragdolls::Effects, { "Burning", "Electrocuted", "Ash", "Dissolve" }, {}, FDropdown_Multi | FDropdown_Left); + FDropdown("Ragdoll model", Vars::Visuals::Ragdolls::Type, { "None", "Gold", "Ice" }, {}, FDropdown_Right); + FSlider("Ragdoll force", Vars::Visuals::Ragdolls::Force, -10.f, 10.f, 0.5f, "%g", FSlider_Precision); + FSlider("Horizontal force", Vars::Visuals::Ragdolls::ForceHorizontal, -10.f, 10.f, 0.5f, "%g", FSlider_Precision); + FSlider("Vertical force", Vars::Visuals::Ragdolls::ForceVertical, -10.f, 10.f, 0.5f, "%g", FSlider_Precision); + PopTransparent(); + } EndSection(); + + /* Column 2 */ + TableNextColumn(); + if (Section("Bullet")) + { + FColorPicker("Bullet tracer color", Vars::Colors::Bullet); + FToggle("Bullet tracers", Vars::Visuals::Bullet::Enabled); + } EndSection(); + if (Section("Simulation")) + { + FDropdown("Player path", Vars::Visuals::Simulation::PlayerPath, { "Off", "Line", "Separators", "Spaced" }, {}, FDropdown_Left, -20); + FColorPicker("Player path", Vars::Colors::PlayerPath, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); FColorPicker("Player path clipped", Vars::Colors::PlayerPathClipped, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); + FDropdown("Projectile path", Vars::Visuals::Simulation::ProjectilePath, { "Off", "Line", "Separators", "Spaced" }, {}, FDropdown_Right, -20); + FColorPicker("Projectile path", Vars::Colors::ProjectilePath, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); FColorPicker("Projectile path clipped", Vars::Colors::ProjectilePathClipped, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); + FDropdown("Trajectory path", Vars::Visuals::Simulation::TrajectoryPath, { "Off", "Line", "Separators", "Spaced" }, {}, FDropdown_Left, -20); + FColorPicker("Trajectory path", Vars::Colors::TrajectoryPath, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); FColorPicker("Trajectory path clipped", Vars::Colors::TrajectoryPathClipped, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); + FDropdown("Shot path", Vars::Visuals::Simulation::ShotPath, { "Off", "Line", "Separators", "Spaced" }, {}, FDropdown_Right, -20); + FColorPicker("Shot path", Vars::Colors::ShotPath, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); FColorPicker("Shot path clipped", Vars::Colors::ShotPathClipped, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); + FDropdown("Splash radius", Vars::Visuals::Simulation::SplashRadius, { "Simulation", "##Divider", "Priority", "Enemy", "Team", "Local", "Friends", "##Divider", "Rockets", "Stickies", "Pipes", "Scorch shot", "##Divider", "Trace" }, {}, FDropdown_Multi, -20); + FColorPicker("Splash radius", Vars::Colors::SplashRadius, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); FColorPicker("Splash radius clipped", Vars::Colors::SplashRadiusClipped, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); + FToggle("Timed", Vars::Visuals::Simulation::Timed, FToggle_Left); + FToggle("Box", Vars::Visuals::Simulation::Box, FToggle_Right); + FToggle("Swing prediction lines", Vars::Visuals::Simulation::SwingLines, FToggle_Left); + FToggle("Projectile camera", Vars::Visuals::Simulation::ProjectileCamera, FToggle_Right); + } EndSection(); + if (Vars::Debug::Info.Value) + { + if (Section("debug")) + { + FToggle("overwrite", Vars::Visuals::Trajectory::Overwrite); + FSlider("off x", Vars::Visuals::Trajectory::OffX, -25.f, 25.f, 0.5f, "%g", FSlider_Precision); + FSlider("off y", Vars::Visuals::Trajectory::OffY, -25.f, 25.f, 0.5f, "%g", FSlider_Precision); + FSlider("off z", Vars::Visuals::Trajectory::OffZ, -25.f, 25.f, 0.5f, "%g", FSlider_Precision); + FToggle("pipes", Vars::Visuals::Trajectory::Pipes); + FSlider("hull", Vars::Visuals::Trajectory::Hull, 0.f, 10.f, 0.5f, "%g", FSlider_Min | FSlider_Precision); + FSlider("speed", Vars::Visuals::Trajectory::Speed, 0.f, 5000.f, 50.f, "%g", FSlider_Min | FSlider_Precision); + FSlider("gravity", Vars::Visuals::Trajectory::Gravity, 0.f, 1.f, 0.1f, "%g", FSlider_Precision); + FToggle("no spin", Vars::Visuals::Trajectory::NoSpin); + FSlider("lifetime", Vars::Visuals::Trajectory::LifeTime, 0.f, 10.f, 0.1f, "%g", FSlider_Min | FSlider_Precision); + FSlider("up vel", Vars::Visuals::Trajectory::UpVelocity, 0.f, 1000.f, 50.f, "%g", FSlider_Precision); + FSlider("ang vel x", Vars::Visuals::Trajectory::AngVelocityX, -1000.f, 1000.f, 50.f, "%g", FSlider_Precision); + FSlider("ang vel y", Vars::Visuals::Trajectory::AngVelocityY, -1000.f, 1000.f, 50.f, "%g", FSlider_Precision); + FSlider("ang vel z", Vars::Visuals::Trajectory::AngVelocityZ, -1000.f, 1000.f, 50.f, "%g", FSlider_Precision); + FSlider("drag", Vars::Visuals::Trajectory::Drag, 0.f, 2.f, 0.1f, "%g", FSlider_Precision); + FSlider("drag x", Vars::Visuals::Trajectory::DragBasisX, 0.f, 0.1f, 0.01f, "%.15g", FSlider_Precision); + FSlider("drag y", Vars::Visuals::Trajectory::DragBasisY, 0.f, 0.1f, 0.01f, "%.15g", FSlider_Precision); + FSlider("drag z", Vars::Visuals::Trajectory::DragBasisZ, 0.f, 0.1f, 0.01f, "%.15g", FSlider_Precision); + FSlider("ang drag x", Vars::Visuals::Trajectory::AngDragBasisX, 0.f, 0.1f, 0.01f, "%.15g", FSlider_Precision); + FSlider("ang drag y", Vars::Visuals::Trajectory::AngDragBasisY, 0.f, 0.1f, 0.01f, "%.15g", FSlider_Precision); + FSlider("ang drag z", Vars::Visuals::Trajectory::AngDragBasisZ, 0.f, 0.1f, 0.01f, "%.15g", FSlider_Precision); + FSlider("max vel", Vars::Visuals::Trajectory::MaxVelocity, 0.f, 4000.f, 50.f, "%g", FSlider_Min | FSlider_Precision); + FSlider("max ang vel", Vars::Visuals::Trajectory::MaxAngularVelocity, 0.f, 7200.f, 50.f, "%g", FSlider_Min | FSlider_Precision); + } EndSection(); + } + if (Section("Hitbox")) + { + FDropdown("Enabled", Vars::Visuals::Hitbox::Enabled, { "On shot", "On hit" }, {}, FDropdown_Multi, -80); + FColorPicker("Target edge color", Vars::Colors::TargetHitboxEdge, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); + FColorPicker("Target face color", Vars::Colors::TargetHitboxFace, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); + SameLine(); Dummy({ 2, 0 }); + FColorPicker("Bone edge color", Vars::Colors::BoneHitboxEdge, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); + FColorPicker("Bone face color", Vars::Colors::BoneHitboxFace, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); + SameLine(); Dummy({ 2, 0 }); + FColorPicker("Bound edge color", Vars::Colors::BoundHitboxEdge, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); + FColorPicker("Bound face color", Vars::Colors::BoundHitboxFace, 0, FColorPicker_Dropdown | FColorPicker_Tooltip); + } EndSection(); + if (Section("Thirdperson")) + { + FToggle("Thirdperson", Vars::Visuals::ThirdPerson::Enabled, FToggle_Left); + FToggle("Thirdperson crosshair", Vars::Visuals::ThirdPerson::Crosshair, FToggle_Right); + FSlider("Thirdperson distance", Vars::Visuals::ThirdPerson::Distance, 0.f, 500.f, 5.f, "%g", FSlider_Precision); + FSlider("Thirdperson right", Vars::Visuals::ThirdPerson::Right, -500.f, 500.f, 5.f, "%g", FSlider_Precision); + FSlider("Thirdperson up", Vars::Visuals::ThirdPerson::Up, -500.f, 500.f, 5.f, "%g", FSlider_Precision); + } EndSection(); + if (Section("Out of FOV arrows")) + { + FToggle("Enabled", Vars::Visuals::FOVArrows::Enabled); + FSlider("Offset", Vars::Visuals::FOVArrows::Offset, 0, 500, 25, "%i", FSlider_Min | FSlider_Precision); + FSlider("Max distance", Vars::Visuals::FOVArrows::MaxDist, 0.f, 5000.f, 50.f, "%g", FSlider_Min | FSlider_Precision); + } EndSection(); + if (Section("World")) + { + FSDropdown("World texture", Vars::Visuals::World::WorldTexture, { "Default", "Dev", "Camo", "Black", "White", "Flat" }, FSDropdown_Custom); + FDropdown("Modulations", Vars::Visuals::World::Modulations, { "World", "Sky", "Prop", "Particle", "Fog" }, {}, FDropdown_Left | FDropdown_Multi); + static std::vector skyNames = { + "Off", "sky_tf2_04", "sky_upward", "sky_dustbowl_01", "sky_goldrush_01", "sky_granary_01", "sky_well_01", "sky_gravel_01", "sky_badlands_01", + "sky_hydro_01", "sky_night_01", "sky_nightfall_01", "sky_trainyard_01", "sky_stormfront_01", "sky_morningsnow_01","sky_alpinestorm_01", + "sky_harvest_01", "sky_harvest_night_01", "sky_halloween", "sky_halloween_night_01", "sky_halloween_night2014_01", "sky_island_01", "sky_rainbow_01" + }; + FSDropdown("Skybox changer", Vars::Visuals::World::SkyboxChanger, skyNames, FSDropdown_Custom | FDropdown_Right); + PushTransparent(!(FGet(Vars::Visuals::World::Modulations) & Vars::Visuals::World::ModulationsEnum::World)); + FColorPicker("World modulation", Vars::Colors::WorldModulation, 0, FColorPicker_Left); + PopTransparent(); + PushTransparent(!(FGet(Vars::Visuals::World::Modulations) & Vars::Visuals::World::ModulationsEnum::Sky)); + FColorPicker("Sky modulation", Vars::Colors::SkyModulation, 0, FColorPicker_Middle | FColorPicker_SameLine); + PopTransparent(); + PushTransparent(!(FGet(Vars::Visuals::World::Modulations) & Vars::Visuals::World::ModulationsEnum::Prop)); + FColorPicker("Prop modulation", Vars::Colors::PropModulation, 0, FColorPicker_Left); + PopTransparent(); + PushTransparent(!(FGet(Vars::Visuals::World::Modulations) & Vars::Visuals::World::ModulationsEnum::Particle)); + FColorPicker("Particle modulation", Vars::Colors::ParticleModulation, 0, FColorPicker_Middle | FColorPicker_SameLine); + PopTransparent(); + PushTransparent(!(FGet(Vars::Visuals::World::Modulations) & Vars::Visuals::World::ModulationsEnum::Fog)); + FColorPicker("Fog modulation", Vars::Colors::FogModulation, 0, FColorPicker_Left); + PopTransparent(); + FToggle("Near prop fade", Vars::Visuals::World::NearPropFade, FToggle_Left); + FToggle("No prop fade", Vars::Visuals::World::NoPropFade, FToggle_Right); + } EndSection(); + + EndTable(); + } + break; // Radar - case 4: - if (BeginTable("VisualsRadarTable", 2)) - { - /* Column 1 */ - TableNextColumn(); - if (Section("Main")) + case 4: + if (BeginTable("VisualsRadarTable", 2)) { - FToggle("Enabled", Vars::Radar::Main::Enabled, FToggle_Left); - FToggle("Draw out of range", Vars::Radar::Main::AlwaysDraw, FToggle_Right); - FDropdown("Style", Vars::Radar::Main::Style, { "Circle", "Rectangle" }); - FSlider("Range", Vars::Radar::Main::Range, 50, 3000, 50, "%i", FSlider_Precision); - FSlider("Background alpha", Vars::Radar::Main::BackAlpha, 0, 255, 1, "%i", FSlider_Clamp); - FSlider("Line alpha", Vars::Radar::Main::LineAlpha, 0, 255, 1, "%i", FSlider_Clamp); - } EndSection(); - if (Section("Player")) - { - FToggle("Enabled", Vars::Radar::Players::Enabled, FToggle_Left); - FToggle("Background", Vars::Radar::Players::Background, FToggle_Right); - FDropdown("Draw", Vars::Radar::Players::Draw, { "Local", "Enemy", "Team", "Friends", "Prioritized", "Cloaked" }, {}, FDropdown_Multi | FDropdown_Left); - FDropdown("Icon", Vars::Radar::Players::IconType, { "Icons", "Portraits", "Avatar" }, {}, FDropdown_Right); - FSlider("Icon size## Player", Vars::Radar::Players::IconSize, 12, 30, 2); - FToggle("Health bar", Vars::Radar::Players::Health, FToggle_Left); - FToggle("Height indicator", Vars::Radar::Players::Height, FToggle_Right); - } EndSection(); + /* Column 1 */ + TableNextColumn(); + if (Section("Main")) + { + FToggle("Enabled", Vars::Radar::Main::Enabled, FToggle_Left); + FToggle("Draw out of range", Vars::Radar::Main::AlwaysDraw, FToggle_Right); + FDropdown("Style", Vars::Radar::Main::Style, { "Circle", "Rectangle" }); + FSlider("Range", Vars::Radar::Main::Range, 50, 3000, 50, "%i", FSlider_Precision); + FSlider("Background alpha", Vars::Radar::Main::BackAlpha, 0, 255, 1, "%i", FSlider_Clamp); + FSlider("Line alpha", Vars::Radar::Main::LineAlpha, 0, 255, 1, "%i", FSlider_Clamp); + } EndSection(); + if (Section("Player")) + { + FToggle("Enabled", Vars::Radar::Players::Enabled, FToggle_Left); + FToggle("Background", Vars::Radar::Players::Background, FToggle_Right); + FDropdown("Draw", Vars::Radar::Players::Draw, { "Local", "Enemy", "Team", "Friends", "Prioritized", "Cloaked" }, {}, FDropdown_Multi | FDropdown_Left); + FDropdown("Icon", Vars::Radar::Players::IconType, { "Icons", "Portraits", "Avatar" }, {}, FDropdown_Right); + FSlider("Icon size## Player", Vars::Radar::Players::IconSize, 12, 30, 2); + FToggle("Health bar", Vars::Radar::Players::Health, FToggle_Left); + FToggle("Height indicator", Vars::Radar::Players::Height, FToggle_Right); + } EndSection(); - /* Column 2 */ - TableNextColumn(); - if (Section("Building")) - { - FToggle("Enabled", Vars::Radar::Buildings::Enabled, FToggle_Left); - FToggle("Background", Vars::Radar::Buildings::Background, FToggle_Right); - FDropdown("Draw", Vars::Radar::Buildings::Draw, { "Local", "Enemy", "Team", "Friends", "Prioritized" }, {}, FDropdown_Multi); - FSlider("Icon size## Building", Vars::Radar::Buildings::IconSize, 12, 30, 2); - FToggle("Health bar", Vars::Radar::Buildings::Health); - } EndSection(); - if (Section("World")) - { - FToggle("Enabled", Vars::Radar::World::Enabled, FToggle_Left); - FToggle("Background", Vars::Radar::World::Background, FToggle_Right); - FDropdown("Draw", Vars::Radar::World::Draw, { "Health", "Ammo", "Money", "Bombs", "Powerup", "Spellbook", "Gargoyle" }, {}, FDropdown_Multi); - FSlider("Icon size## World", Vars::Radar::World::IconSize, 12, 30, 2); - } EndSection(); + /* Column 2 */ + TableNextColumn(); + if (Section("Building")) + { + FToggle("Enabled", Vars::Radar::Buildings::Enabled, FToggle_Left); + FToggle("Background", Vars::Radar::Buildings::Background, FToggle_Right); + FDropdown("Draw", Vars::Radar::Buildings::Draw, { "Local", "Enemy", "Team", "Friends", "Prioritized" }, {}, FDropdown_Multi); + FSlider("Icon size## Building", Vars::Radar::Buildings::IconSize, 12, 30, 2); + FToggle("Health bar", Vars::Radar::Buildings::Health); + } EndSection(); + if (Section("World")) + { + FToggle("Enabled", Vars::Radar::World::Enabled, FToggle_Left); + FToggle("Background", Vars::Radar::World::Background, FToggle_Right); + FDropdown("Draw", Vars::Radar::World::Draw, { "Health", "Ammo", "Money", "Bombs", "Powerup", "Spellbook", "Gargoyle" }, {}, FDropdown_Multi); + FSlider("Icon size## World", Vars::Radar::World::IconSize, 12, 30, 2); + } EndSection(); - EndTable(); - } - break; + EndTable(); + } + break; // Menu - case 5: - { - if (BeginTable("MenuTable", 2)) + case 5: { - /* Column 1 */ - TableNextColumn(); - if (Section("General")) + if (BeginTable("MenuTable", 2)) { - FColorPicker("Accent color", Vars::Menu::Theme::Accent, 0, FColorPicker_Left); - FColorPicker("Foremost color", Vars::Menu::Theme::Foremost, 0, FColorPicker_Middle | FColorPicker_SameLine); - FColorPicker("Background color", Vars::Menu::Theme::Background, 0, FColorPicker_Left); - FColorPicker("Foreground color", Vars::Menu::Theme::Foreground, 0, FColorPicker_Middle | FColorPicker_SameLine); - FColorPicker("Active color", Vars::Menu::Theme::Active, 0, FColorPicker_Left); - FColorPicker("Inactive color", Vars::Menu::Theme::Inactive, 0, FColorPicker_Middle | FColorPicker_SameLine); + /* Column 1 */ + TableNextColumn(); - FSDropdown("Cheat title", Vars::Menu::CheatName, {}, FSDropdown_AutoUpdate | FDropdown_Left); - FSDropdown("Chat info prefix", Vars::Menu::CheatPrefix, {}, FDropdown_Right); - FKeybind("Menu primary key", Vars::Menu::MenuPrimaryKey.Map[DEFAULT_BIND], FButton_Left | FKeybind_AllowMenu); - FKeybind("Menu secondary key", Vars::Menu::MenuSecondaryKey.Map[DEFAULT_BIND], FButton_Right | FButton_SameLine | FKeybind_AllowMenu); - if (Vars::Menu::MenuPrimaryKey.Map[DEFAULT_BIND] == VK_LBUTTON) - Vars::Menu::MenuPrimaryKey.Map[DEFAULT_BIND] = VK_INSERT; - if (Vars::Menu::MenuSecondaryKey.Map[DEFAULT_BIND] == VK_LBUTTON) - Vars::Menu::MenuSecondaryKey.Map[DEFAULT_BIND] = VK_F3; - } EndSection(); - if (Section("Indicators")) - { - FDropdown("Indicators", Vars::Menu::Indicators, { "Ticks", "Crit hack", "Spectators", "Ping", "Conditions", "Seed prediction" }, {}, FDropdown_Multi); - if (FSlider("DPI", Vars::Menu::DPI, 0.75f, 2.f, 0.25f, "%g", FSlider_Precision)) - H::Fonts.Reload(Vars::Menu::DPI.Map[DEFAULT_BIND]); - } EndSection(); + if (Section("General")) + { + FColorPicker("Accent color", Vars::Menu::Theme::Accent, 0, FColorPicker_Left); + FColorPicker("Background color", Vars::Menu::Theme::Background, 0, FColorPicker_Middle | FColorPicker_SameLine); + FColorPicker("Active color", Vars::Menu::Theme::Active, 0, FColorPicker_Left); + FColorPicker("Inactive color", Vars::Menu::Theme::Inactive, 0, FColorPicker_Middle | FColorPicker_SameLine); - /* Column 2 */ - TableNextColumn(); + FSDropdown("Cheat title", Vars::Menu::CheatName, {}, FSDropdown_AutoUpdate | FDropdown_Left); + FSDropdown("Chat info prefix", Vars::Menu::CheatPrefix, {}, FDropdown_Right); + FKeybind("Menu primary key", Vars::Menu::MenuPrimaryKey.Map[DEFAULT_BIND], FButton_Left | FKeybind_AllowMenu); + FKeybind("Menu secondary key", Vars::Menu::MenuSecondaryKey.Map[DEFAULT_BIND], FButton_Right | FButton_SameLine | FKeybind_AllowMenu); + if (Vars::Menu::MenuPrimaryKey.Map[DEFAULT_BIND] == VK_LBUTTON) + Vars::Menu::MenuPrimaryKey.Map[DEFAULT_BIND] = VK_INSERT; + if (Vars::Menu::MenuSecondaryKey.Map[DEFAULT_BIND] == VK_LBUTTON) + Vars::Menu::MenuSecondaryKey.Map[DEFAULT_BIND] = VK_F3; + } EndSection(); - EndTable(); + /* Column 2 */ + TableNextColumn(); + if (Section("Indicators")) + { + FDropdown("Indicators", Vars::Menu::Indicators, { "Ticks", "Crit hack", "Spectators", "Ping", "Conditions", "Seed prediction" }, {}, FDropdown_Multi); + if (FSlider("Scale", Vars::Menu::Scale, 0.75f, 2.f, 0.25f, "%g", FSlider_Precision)) + H::Fonts.Reload(Vars::Menu::Scale.Map[DEFAULT_BIND]); + FToggle("Cheap text", Vars::Menu::CheapText); + } EndSection(); + + EndTable(); + } } - } - } + } + + PopStyleColor(); + } EndChild(); + PopStyleVar(); } /* Tab: Misc */ @@ -904,118 +914,136 @@ void CMenu::MenuMisc() { using namespace ImGui; - if (BeginTable("MiscTable", 2)) + const auto vWindowSize = GetWindowSize(); + static int iCurrentTab = 0; + FTabs({ "MISC##" }, &iCurrentTab, { 100, 40 }, { 0, 0 }); + + SetCursorPos({ 0, 40 }); + PushStyleVar(ImGuiStyleVar_WindowPadding, { 8.f, 8.f }); + if (BeginChild("Content", { vWindowSize.x, vWindowSize.y - 40 }, false, ImGuiWindowFlags_AlwaysUseWindowPadding)) { - /* Column 1 */ - TableNextColumn(); - if (Section("Movement")) + PushStyleColor(ImGuiCol_ChildBg, F::Render.Foreground.Value); + + switch (iCurrentTab) { - FDropdown("Autostrafe", Vars::Misc::Movement::AutoStrafe, { "Off", "Legit", "Directional" }); - PushTransparent(FGet(Vars::Misc::Movement::AutoStrafe) != Vars::Misc::Movement::AutoStrafeEnum::Directional); - FSlider("Autostrafe turn scale", Vars::Misc::Movement::AutoStrafeTurnScale, 0.f, 1.f, 0.1f, "%g", FSlider_Clamp | FSlider_Precision); - PopTransparent(); - FToggle("Bunnyhop", Vars::Misc::Movement::Bunnyhop, FToggle_Left); - FToggle("Auto jumpbug", Vars::Misc::Movement::AutoJumpbug, FToggle_Right); // this is unreliable without setups, do not depend on it! - FToggle("Auto rocketjump", Vars::Misc::Movement::AutoRocketJump, FToggle_Left); - FToggle("Auto ctap", Vars::Misc::Movement::AutoCTap, FToggle_Right); - FToggle("Fast stop", Vars::Misc::Movement::FastStop, FToggle_Left); - FToggle("Fast accelerate", Vars::Misc::Movement::FastAccel, FToggle_Right); - FToggle("No push", Vars::Misc::Movement::NoPush, FToggle_Left); - FToggle("Crouch speed", Vars::Misc::Movement::CrouchSpeed, FToggle_Right); - FToggle("Movement lock", Vars::Misc::Movement::MovementLock, FToggle_Left); - } EndSection(); - if (Vars::Debug::Info.Value) - { - if (Section("debug")) + case 0: + if (BeginTable("MiscTable", 2)) { - FSlider("timing offset", Vars::Misc::Movement::TimingOffset, 0, 3); - FSlider("choke count", Vars::Misc::Movement::ChokeCount, 0, 3); - FSlider("apply timing offset above", Vars::Misc::Movement::ApplyAbove, 0, 8); - } EndSection(); - } - if (Section("Exploits")) - { - FToggle("Cheats bypass", Vars::Misc::Exploits::CheatsBypass, FToggle_Left); - FToggle("Pure bypass", Vars::Misc::Exploits::BypassPure, FToggle_Right); - FToggle("Ping reducer", Vars::Misc::Exploits::PingReducer, FToggle_Left); - PushTransparent(!FGet(Vars::Misc::Exploits::PingReducer)); - FSlider("cl_cmdrate", Vars::Misc::Exploits::PingTarget, 1, 66, 1, "%i", FSlider_Right | FSlider_Clamp); - PopTransparent(); - SetCursorPosY(GetCursorPosY() - 8); - FToggle("Equip region unlock", Vars::Misc::Exploits::EquipRegionUnlock, FToggle_Left); - } EndSection(); - if (Vars::Debug::Info.Value) - { - if (Section("Convar spoofer")) - { - static std::string sName = "", sValue = ""; - - FSDropdown("Convar", &sName, {}, FDropdown_Left); - FSDropdown("Value", &sValue, {}, FDropdown_Right); - if (FButton("Send")) + /* Column 1 */ + TableNextColumn(); + if (Section("Movement")) { - if (auto pNetChan = static_cast(I::EngineClient->GetNetChannelInfo())) + FDropdown("Autostrafe", Vars::Misc::Movement::AutoStrafe, { "Off", "Legit", "Directional" }); + PushTransparent(FGet(Vars::Misc::Movement::AutoStrafe) != Vars::Misc::Movement::AutoStrafeEnum::Directional); + FSlider("Autostrafe turn scale", Vars::Misc::Movement::AutoStrafeTurnScale, 0.f, 1.f, 0.1f, "%g", FSlider_Clamp | FSlider_Precision); + PopTransparent(); + FToggle("Bunnyhop", Vars::Misc::Movement::Bunnyhop, FToggle_Left); + FToggle("Auto jumpbug", Vars::Misc::Movement::AutoJumpbug, FToggle_Right); // this is unreliable without setups, do not depend on it! + FToggle("Auto rocketjump", Vars::Misc::Movement::AutoRocketJump, FToggle_Left); + FToggle("Auto ctap", Vars::Misc::Movement::AutoCTap, FToggle_Right); + FToggle("Fast stop", Vars::Misc::Movement::FastStop, FToggle_Left); + FToggle("Fast accelerate", Vars::Misc::Movement::FastAccel, FToggle_Right); + FToggle("No push", Vars::Misc::Movement::NoPush, FToggle_Left); + FToggle("Crouch speed", Vars::Misc::Movement::CrouchSpeed, FToggle_Right); + FToggle("Movement lock", Vars::Misc::Movement::MovementLock, FToggle_Left); + } EndSection(); + if (Vars::Debug::Info.Value) + { + if (Section("debug")) { - SDK::Output("Convar", std::format("Sent {} as {}", sName, sValue).c_str(), Vars::Menu::Theme::Accent.Value); - NET_SetConVar cmd(sName.c_str(), sValue.c_str()); - pNetChan->SendNetMsg(cmd); - - sName = sValue = ""; - } + FSlider("timing offset", Vars::Misc::Movement::TimingOffset, 0, 3); + FSlider("choke count", Vars::Misc::Movement::ChokeCount, 0, 3); + FSlider("apply timing offset above", Vars::Misc::Movement::ApplyAbove, 0, 8); + } EndSection(); } - } EndSection(); + if (Section("Exploits")) + { + FToggle("Cheats bypass", Vars::Misc::Exploits::CheatsBypass, FToggle_Left); + FToggle("Pure bypass", Vars::Misc::Exploits::BypassPure, FToggle_Right); + FToggle("Ping reducer", Vars::Misc::Exploits::PingReducer, FToggle_Left); + PushTransparent(!FGet(Vars::Misc::Exploits::PingReducer)); + FSlider("cl_cmdrate", Vars::Misc::Exploits::PingTarget, 1, 66, 1, "%i", FSlider_Right | FSlider_Clamp); + PopTransparent(); + SetCursorPosY(GetCursorPosY() - 8); + FToggle("Equip region unlock", Vars::Misc::Exploits::EquipRegionUnlock, FToggle_Left); + } EndSection(); + if (Vars::Debug::Info.Value) + { + if (Section("Convar spoofer")) + { + static std::string sName = "", sValue = ""; + + FSDropdown("Convar", &sName, {}, FDropdown_Left); + FSDropdown("Value", &sValue, {}, FDropdown_Right); + if (FButton("Send")) + { + if (auto pNetChan = static_cast(I::EngineClient->GetNetChannelInfo())) + { + SDK::Output("Convar", std::format("Sent {} as {}", sName, sValue).c_str(), Vars::Menu::Theme::Accent.Value); + NET_SetConVar cmd(sName.c_str(), sValue.c_str()); + pNetChan->SendNetMsg(cmd); + + sName = sValue = ""; + } + } + } EndSection(); + } + if (Section("Automation")) + { + FDropdown("Anti-backstab", Vars::Misc::Automation::AntiBackstab, { "Off", "Yaw", "Pitch", "Fake" }); // pitch/fake _might_ slip up some auto backstabs + FToggle("Anti-AFK", Vars::Misc::Automation::AntiAFK, FToggle_Left); + FToggle("Anti autobalance", Vars::Misc::Automation::AntiAutobalance, FToggle_Right); + FToggle("Auto accept item drops", Vars::Misc::Automation::AcceptItemDrops, FToggle_Left); + FToggle("Taunt control", Vars::Misc::Automation::TauntControl, FToggle_Right); + FToggle("Kart control", Vars::Misc::Automation::KartControl, FToggle_Left); + FToggle("Backpack expander", Vars::Misc::Automation::BackpackExpander, FToggle_Right); + } EndSection(); + + /* Column 2 */ + TableNextColumn(); + if (Section("Sound")) + { + FDropdown("Block", Vars::Misc::Sound::Block, { "Footsteps", "Noisemaker", "Frying pan" }, {}, FDropdown_Multi); + FToggle("Giant weapon sounds", Vars::Misc::Sound::GiantWeaponSounds, FToggle_Left); + FToggle("Hitsound always", Vars::Misc::Sound::HitsoundAlways, FToggle_Right); + } EndSection(); + if (Section("Game")) + { + FToggle("Network fix", Vars::Misc::Game::NetworkFix, FToggle_Left); + FToggle("Prediction error jitter fix", Vars::Misc::Game::PredictionErrorJitterFix, FToggle_Right); + FToggle("Bones optimization", Vars::Misc::Game::SetupBonesOptimization, FToggle_Left); + FToggle("F2P chat bypass", Vars::Misc::Game::F2PChatBypass, FToggle_Right); + } EndSection(); + if (Section("Queueing")) + { + FDropdown("Force regions", Vars::Misc::Queueing::ForceRegions, + { "Atlanta", "Chicago", "Texas", "Los Angeles", "Moses Lake", "New York", "Seattle", "Virginia", "##Divider", "Amsterdam", "Frankfurt", "Helsinki", "London", "Madrid", "Paris", "Stockholm", "Vienna", "Warsaw", "##Divider", "Buenos Aires", "Lima", "Santiago", "Sao Paulo", "##Divider", "Bombay", "Chennai", "Dubai", "Hong Kong", "Madras", "Mumbai", "Seoul", "Singapore", "Tokyo", "Sydney", "##Divider", "Johannesburg" }, + {}, FDropdown_Multi + ); + FToggle("Freeze queue", Vars::Misc::Queueing::FreezeQueue, FToggle_Left); + FToggle("Auto queue", Vars::Misc::Queueing::AutoCasualQueue, FToggle_Right); + } EndSection(); + if (Section("Mann vs. Machine")) + { + FToggle("Instant respawn", Vars::Misc::MannVsMachine::InstantRespawn, FToggle_Left); + FToggle("Instant revive", Vars::Misc::MannVsMachine::InstantRevive, FToggle_Right); + } EndSection(); + if (Section("Steam RPC")) + { + FToggle("Steam RPC", Vars::Misc::Steam::EnableRPC, FToggle_Left); + FToggle("Override in menu", Vars::Misc::Steam::OverrideMenu, FToggle_Right); + FDropdown("Match group", Vars::Misc::Steam::MatchGroup, { "Special Event", "MvM Mann Up", "Competitive", "Casual", "MvM Boot Camp" }, {}, FDropdown_Left); + FSDropdown("Map text", Vars::Misc::Steam::MapText, {}, FSDropdown_Custom | FDropdown_Right); + FSlider("Group size", Vars::Misc::Steam::GroupSize, 0, 6); + } EndSection(); + + EndTable(); + } } - if (Section("Automation")) - { - FDropdown("Anti-backstab", Vars::Misc::Automation::AntiBackstab, { "Off", "Yaw", "Pitch", "Fake" }); // pitch/fake _might_ slip up some auto backstabs - FToggle("Anti-AFK", Vars::Misc::Automation::AntiAFK, FToggle_Left); - FToggle("Anti autobalance", Vars::Misc::Automation::AntiAutobalance, FToggle_Right); - FToggle("Auto accept item drops", Vars::Misc::Automation::AcceptItemDrops, FToggle_Left); - FToggle("Taunt control", Vars::Misc::Automation::TauntControl, FToggle_Right); - FToggle("Kart control", Vars::Misc::Automation::KartControl, FToggle_Left); - FToggle("Backpack expander", Vars::Misc::Automation::BackpackExpander, FToggle_Right); - } EndSection(); - /* Column 2 */ - TableNextColumn(); - if (Section("Sound")) - { - FDropdown("Block", Vars::Misc::Sound::Block, { "Footsteps", "Noisemaker", "Frying pan" }, {}, FDropdown_Multi); - FToggle("Giant weapon sounds", Vars::Misc::Sound::GiantWeaponSounds, FToggle_Left); - FToggle("Hitsound always", Vars::Misc::Sound::HitsoundAlways, FToggle_Right); - } EndSection(); - if (Section("Game")) - { - FToggle("Network fix", Vars::Misc::Game::NetworkFix, FToggle_Left); - FToggle("Prediction error jitter fix", Vars::Misc::Game::PredictionErrorJitterFix, FToggle_Right); - FToggle("Bones optimization", Vars::Misc::Game::SetupBonesOptimization, FToggle_Left); - FToggle("F2P chat bypass", Vars::Misc::Game::F2PChatBypass, FToggle_Right); - } EndSection(); - if (Section("Queueing")) - { - FDropdown("Force regions", Vars::Misc::Queueing::ForceRegions, - { "Atlanta", "Chicago", "Texas", "Los Angeles", "Moses Lake", "New York", "Seattle", "Virginia", "##Divider", "Amsterdam", "Frankfurt", "Helsinki", "London", "Madrid", "Paris", "Stockholm", "Vienna", "Warsaw", "##Divider", "Buenos Aires", "Lima", "Santiago", "Sao Paulo", "##Divider", "Bombay", "Chennai", "Dubai", "Hong Kong", "Madras", "Mumbai", "Seoul", "Singapore", "Tokyo", "Sydney", "##Divider", "Johannesburg" }, - {}, FDropdown_Multi - ); - FToggle("Freeze queue", Vars::Misc::Queueing::FreezeQueue, FToggle_Left); - FToggle("Auto queue", Vars::Misc::Queueing::AutoCasualQueue, FToggle_Right); - } EndSection(); - if (Section("Mann vs. Machine")) - { - FToggle("Instant respawn", Vars::Misc::MannVsMachine::InstantRespawn, FToggle_Left); - FToggle("Instant revive", Vars::Misc::MannVsMachine::InstantRevive, FToggle_Right); - } EndSection(); - if (Section("Steam RPC")) - { - FToggle("Steam RPC", Vars::Misc::Steam::EnableRPC, FToggle_Left); - FToggle("Override in menu", Vars::Misc::Steam::OverrideMenu, FToggle_Right); - FDropdown("Match group", Vars::Misc::Steam::MatchGroup, { "Special Event", "MvM Mann Up", "Competitive", "Casual", "MvM Boot Camp" }, {}, FDropdown_Left); - FSDropdown("Map text", Vars::Misc::Steam::MapText, {}, FSDropdown_Custom | FDropdown_Right); - FSlider("Group size", Vars::Misc::Steam::GroupSize, 0, 6); - } EndSection(); - - EndTable(); - } + PopStyleColor(); + } EndChild(); + PopStyleVar(); } /* Tab: Settings */ @@ -1023,72 +1051,86 @@ void CMenu::MenuLogs() { using namespace ImGui; - switch (CurrentLogsTab) + const auto vWindowSize = GetWindowSize(); + static int iCurrentTab = 0; + FTabs({ "LOGS##", "SETTINGS##" }, &iCurrentTab, { 100, 40 }, { 0, 0 }); + + SetCursorPos({ 0, 40 }); + PushStyleVar(ImGuiStyleVar_WindowPadding, { 8.f, 8.f }); + if (BeginChild("Content", { vWindowSize.x, vWindowSize.y - 40 }, false, ImGuiWindowFlags_AlwaysUseWindowPadding)) { - // Logs - case 0: - // Eventually put all logs here, regardless of any settings - break; - // Settings - case 1: - if (BeginTable("ConfigSettingsTable", 2)) + PushStyleColor(ImGuiCol_ChildBg, F::Render.Foreground.Value); + + switch (iCurrentTab) { - /* Column 1 */ - TableNextColumn(); - if (Section("Logging")) + // Logs + case 0: + // Eventually put logs here + break; + // Settings + case 1: + if (BeginTable("ConfigSettingsTable", 2)) { - FDropdown("Logs", Vars::Logging::Logs, { "Vote start", "Vote cast", "Class changes", "Damage", "Cheat detection", "Tags", "Aliases" }, {}, FDropdown_Multi); - FSlider("Notification time", Vars::Logging::Lifetime, 0.5f, 5.f, 0.5f, "%g"); - } EndSection(); - if (Section("Vote Start")) - { - PushTransparent(!(FGet(Vars::Logging::Logs) & Vars::Logging::LogsEnum::VoteStart)); - FDropdown("Log to", Vars::Logging::VoteStart::LogTo, { "Toasts", "Chat", "Party", "Console" }, { 1 << 0, 1 << 1, 1 << 2, 1 << 3 }, FDropdown_Multi); - PopTransparent(); - } EndSection(); - if (Section("Vote Cast")) - { - PushTransparent(!(FGet(Vars::Logging::Logs) & Vars::Logging::LogsEnum::VoteCast)); - FDropdown("Log to", Vars::Logging::VoteCast::LogTo, { "Toasts", "Chat", "Party", "Console" }, { 1 << 0, 1 << 1, 1 << 2, 1 << 3 }, FDropdown_Multi); - PopTransparent(); - } EndSection(); - if (Section("Class Change")) - { - PushTransparent(!(FGet(Vars::Logging::Logs) & Vars::Logging::LogsEnum::ClassChanges)); - FDropdown("Log to", Vars::Logging::ClassChange::LogTo, { "Toasts", "Chat", "Party", "Console" }, { 1 << 0, 1 << 1, 1 << 2, 1 << 3 }, FDropdown_Multi); - PopTransparent(); - } EndSection(); + /* Column 1 */ + TableNextColumn(); + if (Section("Logging")) + { + FDropdown("Logs", Vars::Logging::Logs, { "Vote start", "Vote cast", "Class changes", "Damage", "Cheat detection", "Tags", "Aliases" }, {}, FDropdown_Multi); + FSlider("Notification time", Vars::Logging::Lifetime, 0.5f, 5.f, 0.5f, "%g"); + } EndSection(); + if (Section("Vote Start")) + { + PushTransparent(!(FGet(Vars::Logging::Logs) & Vars::Logging::LogsEnum::VoteStart)); + FDropdown("Log to", Vars::Logging::VoteStart::LogTo, { "Toasts", "Chat", "Party", "Console" }, { 1 << 0, 1 << 1, 1 << 2, 1 << 3 }, FDropdown_Multi); + PopTransparent(); + } EndSection(); + if (Section("Vote Cast")) + { + PushTransparent(!(FGet(Vars::Logging::Logs) & Vars::Logging::LogsEnum::VoteCast)); + FDropdown("Log to", Vars::Logging::VoteCast::LogTo, { "Toasts", "Chat", "Party", "Console" }, { 1 << 0, 1 << 1, 1 << 2, 1 << 3 }, FDropdown_Multi); + PopTransparent(); + } EndSection(); + if (Section("Class Change")) + { + PushTransparent(!(FGet(Vars::Logging::Logs) & Vars::Logging::LogsEnum::ClassChanges)); + FDropdown("Log to", Vars::Logging::ClassChange::LogTo, { "Toasts", "Chat", "Party", "Console" }, { 1 << 0, 1 << 1, 1 << 2, 1 << 3 }, FDropdown_Multi); + PopTransparent(); + } EndSection(); - /* Column 2 */ - TableNextColumn(); - if (Section("Damage")) - { - PushTransparent(!(FGet(Vars::Logging::Logs) & Vars::Logging::LogsEnum::Damage)); - FDropdown("Log to", Vars::Logging::Damage::LogTo, { "Toasts", "Chat", "Party", "Console" }, { 1 << 0, 1 << 1, 1 << 2, 1 << 3 }, FDropdown_Multi); - PopTransparent(); - } EndSection(); - if (Section("Cheat Detection")) - { - PushTransparent(!(FGet(Vars::Logging::Logs) & Vars::Logging::LogsEnum::CheatDetection)); - FDropdown("Log to", Vars::Logging::CheatDetection::LogTo, { "Toasts", "Chat", "Party", "Console" }, { 1 << 0, 1 << 1, 1 << 2, 1 << 3 }, FDropdown_Multi); - PopTransparent(); - } EndSection(); - if (Section("Tags")) - { - PushTransparent(!(FGet(Vars::Logging::Logs) & Vars::Logging::LogsEnum::Tags)); - FDropdown("Log to", Vars::Logging::Tags::LogTo, { "Toasts", "Chat", "Party", "Console" }, { 1 << 0, 1 << 1, 1 << 2, 1 << 3 }, FDropdown_Multi); - PopTransparent(); - } EndSection(); - if (Section("Aliases")) - { - PushTransparent(!(FGet(Vars::Logging::Logs) & Vars::Logging::LogsEnum::Aliases)); - FDropdown("Log to", Vars::Logging::Aliases::LogTo, { "Toasts", "Chat", "Party", "Console" }, { 1 << 0, 1 << 1, 1 << 2, 1 << 3 }, FDropdown_Multi); - PopTransparent(); - } EndSection(); + /* Column 2 */ + TableNextColumn(); + if (Section("Damage")) + { + PushTransparent(!(FGet(Vars::Logging::Logs) & Vars::Logging::LogsEnum::Damage)); + FDropdown("Log to", Vars::Logging::Damage::LogTo, { "Toasts", "Chat", "Party", "Console" }, { 1 << 0, 1 << 1, 1 << 2, 1 << 3 }, FDropdown_Multi); + PopTransparent(); + } EndSection(); + if (Section("Cheat Detection")) + { + PushTransparent(!(FGet(Vars::Logging::Logs) & Vars::Logging::LogsEnum::CheatDetection)); + FDropdown("Log to", Vars::Logging::CheatDetection::LogTo, { "Toasts", "Chat", "Party", "Console" }, { 1 << 0, 1 << 1, 1 << 2, 1 << 3 }, FDropdown_Multi); + PopTransparent(); + } EndSection(); + if (Section("Tags")) + { + PushTransparent(!(FGet(Vars::Logging::Logs) & Vars::Logging::LogsEnum::Tags)); + FDropdown("Log to", Vars::Logging::Tags::LogTo, { "Toasts", "Chat", "Party", "Console" }, { 1 << 0, 1 << 1, 1 << 2, 1 << 3 }, FDropdown_Multi); + PopTransparent(); + } EndSection(); + if (Section("Aliases")) + { + PushTransparent(!(FGet(Vars::Logging::Logs) & Vars::Logging::LogsEnum::Aliases)); + FDropdown("Log to", Vars::Logging::Aliases::LogTo, { "Toasts", "Chat", "Party", "Console" }, { 1 << 0, 1 << 1, 1 << 2, 1 << 3 }, FDropdown_Multi); + PopTransparent(); + } EndSection(); - EndTable(); + EndTable(); + } } - } + + PopStyleColor(); + } EndChild(); + PopStyleVar(); } /* Tab: Config */ @@ -1096,161 +1138,89 @@ void CMenu::MenuSettings() { using namespace ImGui; - switch (CurrentConfigTab) + const auto vWindowSize = GetWindowSize(); + static int iCurrentTab = 0; + FTabs({ "CONFIG", "BINDS", "PLAYERLIST", "MATERIALS" }, &iCurrentTab, { 100, 40 }, { 0, 0 }); + + SetCursorPos({ 0, 40 }); + PushStyleVar(ImGuiStyleVar_WindowPadding, { 8.f, 8.f }); + if (BeginChild("Content", { vWindowSize.x, vWindowSize.y - 40 }, false, ImGuiWindowFlags_AlwaysUseWindowPadding)) { - // Settings - case 0: - if (BeginTable("ConfigSettingsTable", 2)) + PushStyleColor(ImGuiCol_ChildBg, F::Render.Foreground.Value); + + switch (iCurrentTab) { - /* Column 1 */ - TableNextColumn(); - if (Section("Config")) + // Settings + case 0: + if (BeginTable("ConfigSettingsTable", 2)) { - if (FButton("Configs folder", FButton_Left)) - ShellExecuteA(NULL, NULL, F::Configs.sConfigPath.c_str(), NULL, NULL, SW_SHOWNORMAL); - if (FButton("Visuals folder", FButton_Right | FButton_SameLine)) - ShellExecuteA(NULL, NULL, F::Configs.sVisualsPath.c_str(), NULL, NULL, SW_SHOWNORMAL); - - FTabs({ "GENERAL", "VISUALS", }, &CurrentConfigType, { GetColumnWidth() / 2 + 2, SubTabSize.y }, { 6, GetCursorPos().y }, false); - - switch (CurrentConfigType) + /* Column 1 */ + TableNextColumn(); + if (Section("Config")) { + if (FButton("Configs folder", FButton_Left)) + ShellExecuteA(NULL, NULL, F::Configs.sConfigPath.c_str(), NULL, NULL, SW_SHOWNORMAL); + if (FButton("Visuals folder", FButton_Right | FButton_SameLine)) + ShellExecuteA(NULL, NULL, F::Configs.sVisualsPath.c_str(), NULL, NULL, SW_SHOWNORMAL); + + static int iCurrentType = 0; + FTabs({ "GENERAL", "VISUALS", }, &iCurrentType, { GetColumnWidth() / 2 + 2, 40 }, { 6, GetCursorPos().y }, false); + + switch (iCurrentType) + { // General - case 0: - { - static std::string newName; - FSDropdown("Config name", &newName, {}, FSDropdown_AutoUpdate | FDropdown_Left); - if (FButton("Create", FButton_Fit | FButton_SameLine | FButton_Large) && newName.length() > 0) + case 0: { - if (!std::filesystem::exists(F::Configs.sConfigPath + "\\" + newName)) - F::Configs.SaveConfig(newName); - newName.clear(); - } - - for (auto& entry : std::filesystem::directory_iterator(F::Configs.sConfigPath)) - { - if (!entry.is_regular_file() || entry.path().extension() != F::Configs.sConfigExtension) - continue; - - std::string configName = entry.path().filename().string(); - configName.erase(configName.end() - F::Configs.sConfigExtension.size(), configName.end()); - - const auto current = GetCursorPos().y; - - SetCursorPos({ 14, current + 11 }); - TextColored(configName == F::Configs.sCurrentConfig ? F::Render.Active.Value : F::Render.Inactive.Value, configName.c_str()); - - int o = 26; - - SetCursorPos({ GetWindowSize().x - o, current + 9 }); - if (IconButton(ICON_MD_DELETE)) - OpenPopup(std::format("Confirmation## DeleteConfig{}", configName).c_str()); - o += 25; - - SetCursorPos({ GetWindowSize().x - o, current + 9 }); - if (IconButton(ICON_MD_SAVE)) + static std::string newName; + FSDropdown("Config name", &newName, {}, FSDropdown_AutoUpdate | FDropdown_Left); + if (FButton("Create", FButton_Fit | FButton_SameLine | FButton_Large) && newName.length() > 0) { - if (configName != F::Configs.sCurrentConfig || F::Configs.sCurrentVisuals.length()) - OpenPopup(std::format("Confirmation## SaveConfig{}", configName).c_str()); - else - F::Configs.SaveConfig(configName); + if (!std::filesystem::exists(F::Configs.sConfigPath + "\\" + newName)) + F::Configs.SaveConfig(newName); + newName.clear(); } - o += 25; - SetCursorPos({ GetWindowSize().x - o, current + 9 }); - if (IconButton(ICON_MD_DOWNLOAD)) - F::Configs.LoadConfig(configName); - - if (BeginPopupModal(std::format("Confirmation## SaveConfig{}", configName).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) + for (auto& entry : std::filesystem::directory_iterator(F::Configs.sConfigPath)) { - Text(std::format("Do you really want to override '{}'?", configName).c_str()); + if (!entry.is_regular_file() || entry.path().extension() != F::Configs.sConfigExtension) + continue; - if (FButton("Yes, override", FButton_Left)) + std::string configName = entry.path().filename().string(); + configName.erase(configName.end() - F::Configs.sConfigExtension.size(), configName.end()); + + const auto current = GetCursorPos().y; + + SetCursorPos({ 14, current + 11 }); + TextColored(configName == F::Configs.sCurrentConfig ? F::Render.Active.Value : F::Render.Inactive.Value, configName.c_str()); + + int o = 26; + + SetCursorPos({ GetWindowSize().x - o, current + 9 }); + if (IconButton(ICON_MD_DELETE)) + OpenPopup(std::format("Confirmation## DeleteConfig{}", configName).c_str()); + o += 25; + + SetCursorPos({ GetWindowSize().x - o, current + 9 }); + if (IconButton(ICON_MD_SAVE)) { - F::Configs.SaveConfig(configName); - CloseCurrentPopup(); + if (configName != F::Configs.sCurrentConfig || F::Configs.sCurrentVisuals.length()) + OpenPopup(std::format("Confirmation## SaveConfig{}", configName).c_str()); + else + F::Configs.SaveConfig(configName); } - if (FButton("No", FButton_Right | FButton_SameLine)) - CloseCurrentPopup(); + o += 25; - EndPopup(); - } + SetCursorPos({ GetWindowSize().x - o, current + 9 }); + if (IconButton(ICON_MD_DOWNLOAD)) + F::Configs.LoadConfig(configName); - if (BeginPopupModal(std::format("Confirmation## DeleteConfig{}", configName).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) - { - Text(std::format("Do you really want to delete '{}'?", configName).c_str()); - - if (FButton("Yes, delete", FButton_Left)) - { - F::Configs.RemoveConfig(configName); - CloseCurrentPopup(); - } - if (FButton("No", FButton_Right | FButton_SameLine)) - CloseCurrentPopup(); - - EndPopup(); - } - - SetCursorPos({ 6, current }); DebugDummy({ 0, 28 }); - } - break; - } - // Visuals - case 1: - { - static std::string newName; - FSDropdown("Config name", &newName, {}, FSDropdown_AutoUpdate | FDropdown_Left); - if (FButton("Create", FButton_Fit | FButton_SameLine | FButton_Large) && newName.length() > 0) - { - if (!std::filesystem::exists(F::Configs.sVisualsPath + "\\" + newName)) - F::Configs.SaveVisual(newName); - newName.clear(); - } - - for (auto& entry : std::filesystem::directory_iterator(F::Configs.sVisualsPath)) - { - if (!entry.is_regular_file() || entry.path().extension() != F::Configs.sConfigExtension) - continue; - - std::string configName = entry.path().filename().string(); - configName.erase(configName.end() - F::Configs.sConfigExtension.size(), configName.end()); - - const auto current = GetCursorPos().y; - - SetCursorPos({ 14, current + 11 }); - TextColored(configName == F::Configs.sCurrentVisuals ? F::Render.Active.Value : F::Render.Inactive.Value, configName.c_str()); - - int o = 26; - - SetCursorPos({ GetWindowSize().x - o, current + 9 }); - if (IconButton(ICON_MD_DELETE)) - OpenPopup(std::format("Confirmation## DeleteVisual{}", configName).c_str()); - o += 25; - - SetCursorPos({ GetWindowSize().x - o, current + 9 }); - if (IconButton(ICON_MD_SAVE)) - { - if (configName != F::Configs.sCurrentVisuals) - OpenPopup(std::format("Confirmation## SaveVisual{}", configName).c_str()); - else - F::Configs.SaveVisual(configName); - } - o += 25; - - SetCursorPos({ GetWindowSize().x - o, current + 9 }); - if (IconButton(ICON_MD_DOWNLOAD)) - F::Configs.LoadVisual(configName); - - // Dialogs - { - // Save config dialog - if (BeginPopupModal(std::format("Confirmation## SaveVisual{}", configName).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) + if (BeginPopupModal(std::format("Confirmation## SaveConfig{}", configName).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) { Text(std::format("Do you really want to override '{}'?", configName).c_str()); if (FButton("Yes, override", FButton_Left)) { - F::Configs.SaveVisual(configName); + F::Configs.SaveConfig(configName); CloseCurrentPopup(); } if (FButton("No", FButton_Right | FButton_SameLine)) @@ -1259,14 +1229,13 @@ void CMenu::MenuSettings() EndPopup(); } - // Delete config dialog - if (BeginPopupModal(std::format("Confirmation## DeleteVisual{}", configName).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) + if (BeginPopupModal(std::format("Confirmation## DeleteConfig{}", configName).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) { Text(std::format("Do you really want to delete '{}'?", configName).c_str()); if (FButton("Yes, delete", FButton_Left)) { - F::Configs.RemoveVisual(configName); + F::Configs.RemoveConfig(configName); CloseCurrentPopup(); } if (FButton("No", FButton_Right | FButton_SameLine)) @@ -1274,974 +1243,1062 @@ void CMenu::MenuSettings() EndPopup(); } + + SetCursorPos({ 6, current }); DebugDummy({ 0, 28 }); + } + break; + } + // Visuals + case 1: + { + static std::string newName; + FSDropdown("Config name", &newName, {}, FSDropdown_AutoUpdate | FDropdown_Left); + if (FButton("Create", FButton_Fit | FButton_SameLine | FButton_Large) && newName.length() > 0) + { + if (!std::filesystem::exists(F::Configs.sVisualsPath + "\\" + newName)) + F::Configs.SaveVisual(newName); + newName.clear(); + } + + for (auto& entry : std::filesystem::directory_iterator(F::Configs.sVisualsPath)) + { + if (!entry.is_regular_file() || entry.path().extension() != F::Configs.sConfigExtension) + continue; + + std::string configName = entry.path().filename().string(); + configName.erase(configName.end() - F::Configs.sConfigExtension.size(), configName.end()); + + const auto current = GetCursorPos().y; + + SetCursorPos({ 14, current + 11 }); + TextColored(configName == F::Configs.sCurrentVisuals ? F::Render.Active.Value : F::Render.Inactive.Value, configName.c_str()); + + int o = 26; + + SetCursorPos({ GetWindowSize().x - o, current + 9 }); + if (IconButton(ICON_MD_DELETE)) + OpenPopup(std::format("Confirmation## DeleteVisual{}", configName).c_str()); + o += 25; + + SetCursorPos({ GetWindowSize().x - o, current + 9 }); + if (IconButton(ICON_MD_SAVE)) + { + if (configName != F::Configs.sCurrentVisuals) + OpenPopup(std::format("Confirmation## SaveVisual{}", configName).c_str()); + else + F::Configs.SaveVisual(configName); + } + o += 25; + + SetCursorPos({ GetWindowSize().x - o, current + 9 }); + if (IconButton(ICON_MD_DOWNLOAD)) + F::Configs.LoadVisual(configName); + + // Dialogs + { + // Save config dialog + if (BeginPopupModal(std::format("Confirmation## SaveVisual{}", configName).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) + { + Text(std::format("Do you really want to override '{}'?", configName).c_str()); + + if (FButton("Yes, override", FButton_Left)) + { + F::Configs.SaveVisual(configName); + CloseCurrentPopup(); + } + if (FButton("No", FButton_Right | FButton_SameLine)) + CloseCurrentPopup(); + + EndPopup(); + } + + // Delete config dialog + if (BeginPopupModal(std::format("Confirmation## DeleteVisual{}", configName).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) + { + Text(std::format("Do you really want to delete '{}'?", configName).c_str()); + + if (FButton("Yes, delete", FButton_Left)) + { + F::Configs.RemoveVisual(configName); + CloseCurrentPopup(); + } + if (FButton("No", FButton_Right | FButton_SameLine)) + CloseCurrentPopup(); + + EndPopup(); + } + } + + SetCursorPos({ 6, current }); DebugDummy({ 0, 28 }); + } + } + } + } EndSection(); + SetCursorPosX(GetCursorPosX() + 8); + PushStyleColor(ImGuiCol_Text, F::Render.Inactive.Value); + Text("Built @ %s, %s", __DATE__, __TIME__); + PopStyleColor(); + + /* Column 2 */ + TableNextColumn(); + if (Section("Debug")) + { + FToggle("Debug info", Vars::Debug::Info, FToggle_Left); + FToggle("Debug logging", Vars::Debug::Logging, FToggle_Right); + FToggle("Show server hitboxes", Vars::Debug::ServerHitbox, FToggle_Left); FTooltip("Only localhost servers"); + FToggle("Anti aim lines", Vars::Debug::AntiAimLines, FToggle_Right); + #ifdef DEBUG_TRACES + FToggle("Visualize traces", Vars::Debug::VisualizeTraces, FToggle_Left); + FToggle("Visualize trace hits", Vars::Debug::VisualizeTraceHits, FToggle_Right); + #endif + } EndSection(); + if (Section("Extra")) + { + if (FButton("cl_fullupdate", FButton_Left)) + I::EngineClient->ClientCmd_Unrestricted("cl_fullupdate"); + if (FButton("retry", FButton_Right | FButton_SameLine)) + I::EngineClient->ClientCmd_Unrestricted("retry"); + if (FButton("Console", FButton_Left)) + I::EngineClient->ClientCmd_Unrestricted("toggleconsole"); + if (FButton("Fix Chams", FButton_Right | FButton_SameLine)) + F::Materials.ReloadMaterials(); + + if (!I::EngineClient->IsConnected()) + { + if (FButton("Unlock achievements", FButton_Left)) + OpenPopup("UnlockAchievements"); + if (FButton("Lock achievements", FButton_Right | FButton_SameLine)) + OpenPopup("LockAchievements"); + + if (BeginPopupModal("UnlockAchievements", nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) + { + Text("Do you really want to unlock all achievements?"); + + if (FButton("Yes, unlock", FButton_Left)) + { + F::Misc.UnlockAchievements(); + CloseCurrentPopup(); + } + if (FButton("No", FButton_Right | FButton_SameLine)) + CloseCurrentPopup(); + + EndPopup(); + } + if (BeginPopupModal("LockAchievements", nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) + { + Text("Do you really want to lock all achievements?"); + + if (FButton("Yes, lock", FButton_Left)) + { + F::Misc.LockAchievements(); + CloseCurrentPopup(); + } + if (FButton("No", FButton_Right | FButton_SameLine)) + CloseCurrentPopup(); + + EndPopup(); + } + } + if (Vars::Debug::Info.Value) + { + if (FButton("Restore lines", FButton_Left)) + F::Visuals.RestoreLines(); + if (FButton("Restore paths", FButton_Right | FButton_SameLine)) + F::Visuals.RestorePaths(); + if (FButton("Restore boxes", FButton_Left)) + F::Visuals.RestoreBoxes(); + } + } EndSection(); + + EndTable(); + } + break; + // Binds + case 1: + if (Section("Settings")) + { + FToggle("Show bind window", Vars::Menu::ShowBinds, FToggle_Left); + FToggle("Menu shows binds", Vars::Menu::MenuShowsBinds, FToggle_Right); + } EndSection(); + if (Section("Binds")) + { + static int iBind = DEFAULT_BIND; + static Bind_t tBind = {}; + + static int bParent = false; + if (bParent) + SetMouseCursor(ImGuiMouseCursor_Hand); + + if (BeginTable("BindsTable", 2)) + { + /* Column 1 */ + TableNextColumn(); SetCursorPos({ GetCursorPos().x - 8, GetCursorPos().y - 8 }); + if (BeginChild("BindsTableTable1", { GetColumnWidth() + 4, 104 }, false, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_NoBackground)) + { + FSDropdown("Name", &tBind.Name, {}, FSDropdown_AutoUpdate | FDropdown_Left); + { + auto sParent = bParent ? "..." : tBind.Parent != DEFAULT_BIND && tBind.Parent < F::Binds.vBinds.size() ? F::Binds.vBinds[tBind.Parent].Name : "None"; + if (FButton(std::format("Parent: {}", sParent).c_str(), FButton_Right | FButton_SameLine | FButton_Large | FButton_NoUpper)) + bParent = 2; + } + FDropdown("Type", &tBind.Type, { "Key", "Class", "Weapon type" }, {}, FDropdown_Left); + switch (tBind.Type) + { + case 0: tBind.Info = std::min(tBind.Info, 2); FDropdown("Behavior", &tBind.Info, { "Hold", "Toggle", "Double click" }, {}, FDropdown_Right); break; + case 1: tBind.Info = std::min(tBind.Info, 8); FDropdown("Class", &tBind.Info, { "Scout", "Soldier", "Pyro", "Demoman", "Heavy", "Engineer", "Medic", "Sniper", "Spy" }, {}, FDropdown_Right); break; + case 2: tBind.Info = std::min(tBind.Info, 2); FDropdown("Weapon type", &tBind.Info, { "Hitscan", "Projectile", "Melee" }, {}, FDropdown_Right); break; + } + } EndChild(); + + /* Column 2 */ + TableNextColumn(); SetCursorPos({ GetCursorPos().x - 4, GetCursorPos().y - 8 }); + if (BeginChild("BindsTableTable2", { GetColumnWidth() + 8, 104 }, false, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_NoBackground)) + { + int iNot = tBind.Not; + FDropdown("While", &iNot, { "Active", "Not active" }, {}, FDropdown_Left); + tBind.Not = iNot; + int iVisible = tBind.Visible; + FDropdown("Visibility", &iVisible, { "Visible", "Hidden" }, { 1, 0 }, FDropdown_Right); + tBind.Visible = iVisible; + if (tBind.Type == 0) + FKeybind("Key", tBind.Key, FButton_Large, -96); + + // create/modify button + bool bCreate = false, bClear = false, bMatch = false, bParent = true; + if (tBind.Parent != DEFAULT_BIND) + bParent = F::Binds.vBinds.size() > tBind.Parent; + + SetCursorPos({ GetWindowSize().x - 96, 64 }); + PushStyleColor(ImGuiCol_Button, F::Render.Foremost.Value); + PushStyleColor(ImGuiCol_ButtonActive, F::Render.Foremost.Value); + if (bParent && (!tBind.Type ? tBind.Key : true)) + { + PushStyleColor(ImGuiCol_ButtonHovered, F::Render.ForemostLight.Value); + bCreate = Button("##CreateButton", { 40, 40 }); + } + else + { + PushStyleColor(ImGuiCol_ButtonHovered, F::Render.Foremost.Value); + Button("##CreateButton", { 40, 40 }); + } + PopStyleColor(3); + SetCursorPos({ GetWindowSize().x - 83, 76 }); + if (bParent && (!tBind.Type ? tBind.Key : true)) + { + bMatch = iBind != DEFAULT_BIND && F::Binds.vBinds.size() > iBind; + IconImage(bMatch ? ICON_MD_SETTINGS : ICON_MD_ADD); + } + else + { + PushTransparent(true); + IconImage(ICON_MD_ADD); + PopTransparent(); + } + + // clear button + SetCursorPos({ GetWindowSize().x - 48, 64 }); + PushStyleColor(ImGuiCol_Button, F::Render.Foremost.Value); + PushStyleColor(ImGuiCol_ButtonHovered, F::Render.ForemostLight.Value); + PushStyleColor(ImGuiCol_ButtonActive, F::Render.Foremost.Value); + bClear = Button("##ClearButton", { 40, 40 }); + PopStyleColor(3); + SetCursorPos({ GetWindowSize().x - 35, 76 }); + IconImage(ICON_MD_CLEAR); + + if (bCreate) + F::Binds.AddBind(iBind, tBind); + if (bCreate || bClear) + { + iBind = DEFAULT_BIND; + tBind = {}; + } + } EndChild(); + + EndTable(); + } + + PushStyleColor(ImGuiCol_Text, F::Render.Inactive.Value); + SetCursorPos({ 14, 128 }); FText("Binds"); + PopStyleColor(); + + auto vBinds = F::Binds.vBinds; // intentional copy + std::function getBinds = [&](int iParent, int x, int y) + { + for (auto it = vBinds.begin(); it != vBinds.end(); it++) + { + int _iBind = std::distance(vBinds.begin(), it); + auto& _tBind = *it; + if (iParent != _tBind.Parent) + continue; + + y++; + + std::string sType; std::string sBehavior; + switch (_tBind.Type) + { + // key + case 0: + switch (_tBind.Info) + { + case 0: { sType = "hold"; break; } + case 1: { sType = "toggle"; break; } + case 2: { sType = "double"; break; } + } + sBehavior = VK2STR(_tBind.Key); + break; + // class + case 1: + sType = "class"; + switch (_tBind.Info) + { + case 0: { sBehavior = "scout"; break; } + case 1: { sBehavior = "soldier"; break; } + case 2: { sBehavior = "pyro"; break; } + case 3: { sBehavior = "demoman"; break; } + case 4: { sBehavior = "heavy"; break; } + case 5: { sBehavior = "engineer"; break; } + case 6: { sBehavior = "medic"; break; } + case 7: { sBehavior = "sniper"; break; } + case 8: { sBehavior = "spy"; break; } + } + break; + // weapon type + case 2: + sType = "weapon"; + switch (_tBind.Info) + { + case 0: { sBehavior = "hitscan"; break; } + case 1: { sBehavior = "projectile"; break; } + case 2: { sBehavior = "melee"; break; } + } + } + if (_tBind.Not) + sType = std::format("not {}", sType); + + bool bClicked = false, bDelete = false, bEdit = false, bVisibility = false, bNot = false; + + const ImVec2 vOriginalPos = { 8.f + 28 * x, 108.f + 36.f * y }; + + // background + const float flWidth = GetWindowSize().x - 16 - 28 * x; const auto vWindowPos = GetWindowPos(); + GetWindowDrawList()->AddRectFilled({ vWindowPos.x + vOriginalPos.x, vWindowPos.y + vOriginalPos.y }, { vWindowPos.x + vOriginalPos.x + flWidth, vWindowPos.y + vOriginalPos.y + 28 }, F::Render.Foremost, 3); + + // text + SetCursorPos({ vOriginalPos.x + 10, vOriginalPos.y + 7 }); + TextUnformatted(_tBind.Name.c_str()); + + SetCursorPos({ vOriginalPos.x + (flWidth - 105) * (1.f / 3), vOriginalPos.y + 7 }); + TextUnformatted(sType.c_str()); + + SetCursorPos({ vOriginalPos.x + (flWidth - 105) * (2.f / 3), vOriginalPos.y + 7 }); + TextUnformatted(sBehavior.c_str()); + + // buttons + SetCursorPos({ vOriginalPos.x + flWidth - 22, vOriginalPos.y + 5 }); + bDelete = IconButton(ICON_MD_DELETE); + + SetCursorPos({ vOriginalPos.x + flWidth - 47, vOriginalPos.y + 5 }); + bEdit = IconButton(ICON_MD_EDIT); + + SetCursorPos({ vOriginalPos.x + flWidth - 72, vOriginalPos.y + 5 }); + bVisibility = IconButton(_tBind.Visible ? ICON_MD_VISIBILITY : ICON_MD_VISIBILITY_OFF); + + SetCursorPos({ vOriginalPos.x + flWidth - 97, vOriginalPos.y + 5 }); + bNot = IconButton(!_tBind.Not ? ICON_MD_CODE : ICON_MD_CODE_OFF); + + SetCursorPos(vOriginalPos); + bClicked = Button(std::format("##{}", _iBind).c_str(), { flWidth, 28 }); + + if (bClicked) + { + if (bParent) + { + bParent = false; + tBind.Parent = _iBind; + } + else + { + iBind = _iBind; + tBind = _tBind; + } + } + if (bDelete) + OpenPopup(std::format("Confirmation## DeleteCond{}", _iBind).c_str()); + if (BeginPopupModal(std::format("Confirmation## DeleteCond{}", _iBind).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) + { + Text(std::format("Do you really want to delete '{}'{}?", _tBind.Name, F::Binds.HasChildren(_iBind) ? " and all of its children" : "").c_str()); + + if (FButton("Yes", FButton_Left)) + { + F::Binds.RemoveBind(_iBind); + CloseCurrentPopup(); + + iBind = DEFAULT_BIND; + tBind = {}; + } + if (FButton("No", FButton_Right | FButton_SameLine)) + CloseCurrentPopup(); + + EndPopup(); + } + if (bEdit) + CurrentBind = CurrentBind != _iBind ? _iBind : DEFAULT_BIND; + if (bVisibility) + F::Binds.vBinds[_iBind].Visible = !_tBind.Visible; + if (bNot) + F::Binds.vBinds[_iBind].Not = !_tBind.Not; + + y = getBinds(_iBind, x + 1, y); + } + + return y; + }; + getBinds(DEFAULT_BIND, 0, 0); + + if (bParent == 2) // dumb + bParent = 1; + else if (bParent && IsMouseReleased(ImGuiMouseButton_Left)) + { + bParent = false; + tBind.Parent = DEFAULT_BIND; + } + } EndSection(); + break; + // PlayerList + case 2: + if (Section("Players")) + { + if (I::EngineClient->IsInGame()) + { + std::lock_guard lock(F::PlayerUtils.m_mutex); + const auto& playerCache = F::PlayerUtils.m_vPlayerCache; + + auto getTeamColor = [](int team, bool alive) + { + switch (team) + { + case 3: return Color_t(50, 75, 100, alive ? 255 : 127); + case 2: return Color_t(125, 50, 50, alive ? 255 : 127); + } + return Color_t(100, 100, 100, 255); + }; + auto drawPlayer = [getTeamColor](const ListPlayer& player, int x, int y) + { + bool bClicked = false, bAdd = false, bAlias = false, bPitch = false, bYaw = false; + + const Color_t teamColor = getTeamColor(player.Team, player.Alive); + const ImColor imColor = ColorToVec(teamColor); + + const ImVec2 vOriginalPos = { x ? GetWindowSize().x / 2 + 4.f : 8.f, 32.f + 36.f * y }; + + // background + const float flWidth = GetWindowSize().x / 2 - 12; const auto vWindowPos = GetWindowPos(); + GetWindowDrawList()->AddRectFilled({ vWindowPos.x + vOriginalPos.x, vWindowPos.y + vOriginalPos.y }, { vWindowPos.x + vOriginalPos.x + flWidth, vWindowPos.y + vOriginalPos.y + 28 }, imColor, 3); + + // text + icons + if (player.Local) + { + SetCursorPos({ vOriginalPos.x + 7, vOriginalPos.y + 5 }); + IconImage(ICON_MD_PERSON); + } + else if (player.Friend) + { + SetCursorPos({ vOriginalPos.x + 7, vOriginalPos.y + 5 }); + IconImage(ICON_MD_GROUP); + } + int lOffset = player.Local || player.Friend ? 29 : 10; + SetCursorPos({ vOriginalPos.x + lOffset, vOriginalPos.y + 7 }); + TextUnformatted(player.Name); + lOffset += CalcTextSize(player.Name).x + 8; + + // buttons + if (!player.Fake) + { + bool bResolver = Vars::AntiHack::Resolver::Resolver.Value && !player.Local; + + // right + SetCursorPos({ vOriginalPos.x + flWidth - 22, vOriginalPos.y + 5 }); + bAlias = IconButton(ICON_MD_EDIT); + + SetCursorPos({ vOriginalPos.x + flWidth - 42, vOriginalPos.y + 5 }); + bAdd = IconButton(ICON_MD_ADD); + + if (bResolver) + { + SetCursorPos({ vOriginalPos.x + flWidth - 62, vOriginalPos.y + 5 }); + bYaw = IconButton(ICON_MD_ARROW_FORWARD); + + SetCursorPos({ vOriginalPos.x + flWidth - 82, vOriginalPos.y + 5 }); + bPitch = IconButton(ICON_MD_ARROW_UPWARD); + } + + // tag bar + SetCursorPos({ vOriginalPos.x + lOffset, vOriginalPos.y }); + if (BeginChild(std::format("TagBar{}", player.FriendsID).c_str(), { flWidth - lOffset - (bResolver ? 88 : 48), 28 }, false, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoBackground)) + { + PushFont(F::Render.FontSmall); + + const auto childPos = GetWindowPos(); + float tOffset = 0; + for (auto& iID : F::PlayerUtils.m_mPlayerTags[player.FriendsID]) + { + auto pTag = F::PlayerUtils.GetTag(iID); + if (!pTag) + continue; + + const ImColor tagColor = ColorToVec(pTag->Color); + const float tagWidth = CalcTextSize(pTag->Name.c_str()).x + 25; + const ImVec2 tagPos = { tOffset, 4 }; + + PushStyleColor(ImGuiCol_Text, IsColorBright(tagColor) ? ImVec4{ 0, 0, 0, 1 } : ImVec4{ 1, 1, 1, 1 }); + + GetWindowDrawList()->AddRectFilled({ childPos.x + tagPos.x, childPos.y + tagPos.y }, { childPos.x + tagPos.x + tagWidth, childPos.y + tagPos.y + 20 }, tagColor, 3); + SetCursorPos({ tagPos.x + 5, tagPos.y + 4 }); + TextUnformatted(pTag->Name.c_str()); + SetCursorPos({ tagPos.x + tagWidth - 18, tagPos.y + 2 }); + if (IconButton(ICON_MD_CANCEL)) + F::PlayerUtils.RemoveTag(player.FriendsID, iID, true, player.Name); + + PopStyleColor(); + + tOffset += tagWidth + 4; + } + PopFont(); + } EndChild(); + + //bClicked = IsItemClicked(); + bClicked = IsItemHovered() && IsMouseClicked(ImGuiMouseButton_Right) || bClicked; + + SetCursorPos(vOriginalPos); + /*bClicked = */Button(std::format("##{}", player.Name).c_str(), { flWidth, 28 }) || bClicked; + bClicked = IsItemHovered() && IsMouseClicked(ImGuiMouseButton_Right) || bClicked; + } + + SetCursorPos(vOriginalPos); + DebugDummy({ 0, 28 }); + + if (bClicked) + OpenPopup(std::format("Clicked{}", player.FriendsID).c_str()); + else if (bAdd) + OpenPopup(std::format("Add{}", player.FriendsID).c_str()); + else if (bAlias) + OpenPopup(std::format("Alias{}", player.FriendsID).c_str()); + else if (bPitch) + OpenPopup(std::format("Pitch{}", player.FriendsID).c_str()); + else if (bYaw) + OpenPopup(std::format("Yaw{}", player.FriendsID).c_str()); + + // popups + if (BeginPopup(std::format("Clicked{}", player.FriendsID).c_str())) + { + PushStyleVar(ImGuiStyleVar_ItemSpacing, { 8, 8 }); + + if (FSelectable("Profile")) + I::SteamFriends->ActivateGameOverlayToUser("steamid", CSteamID(player.FriendsID, k_EUniversePublic, k_EAccountTypeIndividual)); + + if (FSelectable("History")) + I::SteamFriends->ActivateGameOverlayToWebPage(std::format("https://steamhistory.net/id/{}", CSteamID(player.FriendsID, k_EUniversePublic, k_EAccountTypeIndividual).ConvertToUint64()).c_str()); + + if (!player.Local && FSelectable("Votekick")) + I::ClientState->SendStringCmd(std::format("callvote kick {}", player.UserID).c_str()); + + PopStyleVar(); + EndPopup(); + } + else if (BeginPopup(std::format("Add{}", player.FriendsID).c_str())) + { + PushStyleVar(ImGuiStyleVar_ItemSpacing, { 8, 8 }); + + int iID = -1; + for (auto& tTag : F::PlayerUtils.m_vTags) + { + iID++; + + if (!tTag.Assignable || F::PlayerUtils.HasTag(player.FriendsID, iID)) + continue; + + auto imColor = ColorToVec(tTag.Color); + PushStyleColor(ImGuiCol_Text, imColor); + imColor.x /= 3; imColor.y /= 3; imColor.z /= 3; + if (FSelectable(tTag.Name.c_str(), imColor)) + F::PlayerUtils.AddTag(player.FriendsID, iID, true, player.Name); + PopStyleColor(); + } + + PopStyleVar(); + EndPopup(); + } + else if (BeginPopup(std::format("Alias{}", player.FriendsID).c_str())) + { + PushStyleVar(ImGuiStyleVar_ItemSpacing, { 8, 8 }); + + FText("Alias"); + + bool bHasAlias = F::PlayerUtils.m_mPlayerAliases.contains(player.FriendsID); + static std::string sInput = ""; + + PushStyleVar(ImGuiStyleVar_FramePadding, { 8, 8 }); + PushItemWidth(150); + bool bEnter = InputText("##Alias", &sInput, ImGuiInputTextFlags_EnterReturnsTrue); + if (!IsItemFocused()) + sInput = bHasAlias ? F::PlayerUtils.m_mPlayerAliases[player.FriendsID] : ""; + PopItemWidth(); + PopStyleVar(); + + if (bEnter) + { + if (sInput.empty() && F::PlayerUtils.m_mPlayerAliases.contains(player.FriendsID)) + { + F::Records.AliasChanged(player.Name, "Removed", F::PlayerUtils.m_mPlayerAliases[player.FriendsID]); + + auto find = F::PlayerUtils.m_mPlayerAliases.find(player.FriendsID); + if (find != F::PlayerUtils.m_mPlayerAliases.end()) + F::PlayerUtils.m_mPlayerAliases.erase(find); + F::PlayerUtils.m_bSavePlayers = true; + } + else + { + F::PlayerUtils.m_mPlayerAliases[player.FriendsID] = sInput; + F::PlayerUtils.m_bSavePlayers = true; + + F::Records.AliasChanged(player.Name, bHasAlias ? "Changed" : "Added", sInput); + } + } + + PopStyleVar(); + EndPopup(); + } + else if (BeginPopup(std::format("Pitch{}", player.FriendsID).c_str())) + { + PushStyleVar(ImGuiStyleVar_ItemSpacing, { 8, 8 }); + + for (size_t i = 0; i < F::PlayerUtils.m_vListPitch.size(); i++) + { + if (FSelectable(F::PlayerUtils.m_vListPitch[i])) + F::Resolver.mResolverMode[player.FriendsID].second = int(i); + } + + PopStyleVar(); + EndPopup(); + } + else if (BeginPopup(std::format("Yaw{}", player.FriendsID).c_str())) + { + PushStyleVar(ImGuiStyleVar_ItemSpacing, { 8, 8 }); + + for (size_t i = 0; i < F::PlayerUtils.m_vListYaw.size(); i++) + { + if (FSelectable(F::PlayerUtils.m_vListYaw[i])) + F::Resolver.mResolverMode[player.FriendsID].second = int(i); + } + + PopStyleVar(); + EndPopup(); + } + }; + + // display players + std::vector vBlu, vRed, vOther; + for (auto& player : playerCache) + { + switch (player.Team) + { + case 3: vBlu.push_back(player); break; + case 2: vRed.push_back(player); break; + default: vOther.push_back(player); break; + } + } + + if (vBlu.size() < vRed.size()) // display whichever one has more last + { + for (size_t i = 0; i < vBlu.size(); i++) + drawPlayer(vBlu[i], 0, int(i)); + for (size_t i = 0; i < vRed.size(); i++) + drawPlayer(vRed[i], 1, int(i)); + } + else + { + for (size_t i = 0; i < vRed.size(); i++) + drawPlayer(vRed[i], 1, int(i)); + for (size_t i = 0; i < vBlu.size(); i++) + drawPlayer(vBlu[i], 0, int(i)); + } + size_t iMax = std::max(vBlu.size(), vRed.size()); + for (size_t i = 0; i < vOther.size(); i++) + drawPlayer(vOther[i], i % 2, int(iMax + i / 2)); + } + else + { + SetCursorPos({ 18, 39 }); + Text("Not ingame"); + DebugDummy({ 0, 8 }); + } + } EndSection(); + if (Section("Tags")) + { + static int iID = -1; + static PriorityLabel_t tTag = {}; + + if (BeginTable("TagTable", 2)) + { + /* Column 1 */ + TableNextColumn(); SetCursorPos({ GetCursorPos().x - 8, GetCursorPos().y - 8 }); + if (BeginChild("TagTable1", { GetColumnWidth() + 4, 56 }, false, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_NoBackground)) + { + FSDropdown("Name", &tTag.Name, {}, FSDropdown_AutoUpdate | FDropdown_Left, -10); + FColorPicker("Color", &tTag.Color, 0, FColorPicker_Dropdown); + + PushDisabled(iID == DEFAULT_TAG || iID == IGNORED_TAG); + int iLabel = Disabled ? 0 : tTag.Label; + FDropdown("Type", &iLabel, { "Priority", "Label" }, {}, FDropdown_Right); + tTag.Label = iLabel; + if (Disabled) + tTag.Label = false; + PopDisabled(); + } EndChild(); + + /* Column 2 */ + TableNextColumn(); SetCursorPos({ GetCursorPos().x - 4, GetCursorPos().y - 8 }); + if (BeginChild("TagTable2", { GetColumnWidth() + 8, 56 }, false, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_NoBackground)) + { + PushTransparent(tTag.Label); // transparent if we want a label, user can still use to sort + SetCursorPosY(GetCursorPos().y + 12); + FSlider("Priority", &tTag.Priority, -10, 10, 1, "%i", FSlider_Left); + PopTransparent(); + + // create/modify button + bool bCreate = false, bClear = false; + + SetCursorPos({ GetWindowSize().x - 96, 16 }); + PushStyleColor(ImGuiCol_Button, F::Render.Foremost.Value); + PushStyleColor(ImGuiCol_ButtonActive, F::Render.Foremost.Value); + if (tTag.Name.length()) + { + PushStyleColor(ImGuiCol_ButtonHovered, F::Render.ForemostLight.Value); + bCreate = Button("##CreateButton", { 40, 40 }); + } + else + { + PushStyleColor(ImGuiCol_ButtonHovered, F::Render.Foremost.Value); + Button("##CreateButton", { 40, 40 }); + } + PopStyleColor(3); + SetCursorPos({ GetWindowSize().x - 83, 28 }); + PushTransparent(tTag.Name.empty()); + IconImage(iID != -1 ? ICON_MD_SETTINGS : ICON_MD_ADD); + PopTransparent(); + + // clear button + SetCursorPos({ GetWindowSize().x - 48, 16 }); + PushStyleColor(ImGuiCol_Button, F::Render.Foremost.Value); + PushStyleColor(ImGuiCol_ButtonHovered, F::Render.ForemostLight.Value); + PushStyleColor(ImGuiCol_ButtonActive, F::Render.Foremost.Value); + bClear = Button("##ClearButton", { 40, 40 }); + PopStyleColor(3); + SetCursorPos({ GetWindowSize().x - 35, 28 }); + IconImage(ICON_MD_CLEAR); + + if (bCreate) + { + F::PlayerUtils.m_bSaveTags = true; + if (iID > -1 || iID < F::PlayerUtils.m_vTags.size()) + { + F::PlayerUtils.m_vTags[iID].Name = tTag.Name; + F::PlayerUtils.m_vTags[iID].Color = tTag.Color; + F::PlayerUtils.m_vTags[iID].Priority = tTag.Priority; + F::PlayerUtils.m_vTags[iID].Label = tTag.Label; + } + else + F::PlayerUtils.m_vTags.push_back(tTag); + } + if (bCreate || bClear) + { + iID = -1; + tTag = {}; + } + } EndChild(); + + EndTable(); + } + + auto drawTag = [](std::vector::iterator it, PriorityLabel_t& _tTag, int y) + { + int _iID = std::distance(F::PlayerUtils.m_vTags.begin(), it); + + bool bClicked = false, bDelete = false; + + ImColor imColor = ColorToVec(_tTag.Color); + imColor.Value.x /= 3; imColor.Value.y /= 3; imColor.Value.z /= 3; + + const ImVec2 vOriginalPos = { _tTag.Label ? GetWindowSize().x * 2 / 3 + 4.f : 8.f, 96.f + 36.f * y }; + + // background + const float flWidth = GetWindowSize().x * (_tTag.Label ? 1.f / 3 : 2.f / 3) - 12; const auto vWindowPos = GetWindowPos(); + GetWindowDrawList()->AddRectFilled({ vWindowPos.x + vOriginalPos.x, vWindowPos.y + vOriginalPos.y }, { vWindowPos.x + vOriginalPos.x + flWidth, vWindowPos.y + vOriginalPos.y + 28 }, imColor, 3); + + // text + SetCursorPos({ vOriginalPos.x + 10, vOriginalPos.y + 7 }); + TextUnformatted(_tTag.Name.c_str()); + + if (!_tTag.Label) + { + SetCursorPos({ vOriginalPos.x + flWidth / 2, vOriginalPos.y + 7 }); + TextUnformatted(std::format("{}", _tTag.Priority).c_str()); + } + + // buttons + SetCursorPos({ vOriginalPos.x + flWidth - 22, vOriginalPos.y + 5 }); + if (!_tTag.Locked) + bDelete = IconButton(ICON_MD_DELETE); + else + { + switch (_iID) + { + //case DEFAULT_TAG: // no image + case IGNORED_TAG: IconImage(ICON_MD_DO_NOT_DISTURB); break; + case CHEATER_TAG: IconImage(ICON_MD_FLAG); break; + case FRIEND_TAG: IconImage(ICON_MD_GROUP); + } + } + + SetCursorPos(vOriginalPos); + bClicked = Button(std::format("##{}", _tTag.Name).c_str(), { flWidth, 28 }); + + if (bClicked) + { + iID = _iID; + tTag.Name = _tTag.Name; + tTag.Color = _tTag.Color; + tTag.Priority = _tTag.Priority; + tTag.Label = _tTag.Label; + } + if (bDelete) + OpenPopup(std::format("Confirmation## DeleteTag{}", _iID).c_str()); + if (BeginPopupModal(std::format("Confirmation## DeleteTag{}", _iID).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) + { + Text(std::format("Do you really want to delete '{}'?", _tTag.Name).c_str()); + + if (FButton("Yes", FButton_Left)) + { + F::PlayerUtils.m_vTags.erase(it); + F::PlayerUtils.m_bSaveTags = F::PlayerUtils.m_bSavePlayers = true; + + for (auto& [friendsID, vTags] : F::PlayerUtils.m_mPlayerTags) + { + for (auto it = vTags.begin(); it != vTags.end();) + { + if (_iID == *it) + vTags.erase(it); + else + { + if (_iID < *it) + (*it)--; + it++; + } + } + } + + if (iID == _iID) + { + iID = -1; + tTag = {}; + } + else if (iID > _iID) + iID--; + + CloseCurrentPopup(); + } + if (FButton("No", FButton_Right | FButton_SameLine)) + CloseCurrentPopup(); + + EndPopup(); + } + }; + + PushStyleColor(ImGuiCol_Text, F::Render.Inactive.Value); + SetCursorPos({ 14, 80 }); FText("Priorities"); + SetCursorPos({ GetWindowSize().x * 2 / 3 + 10, 80 }); FText("Labels"); + PopStyleColor(); + + std::vector::iterator, PriorityLabel_t>> vPriorities = {}, vLabels = {}; + for (auto it = F::PlayerUtils.m_vTags.begin(); it != F::PlayerUtils.m_vTags.end(); it++) + { + auto& _tTag = *it; + + if (!_tTag.Label) + vPriorities.push_back({ it, _tTag }); + else + vLabels.push_back({ it, _tTag }); + } + + std::sort(vPriorities.begin(), vPriorities.end(), [&](const auto& a, const auto& b) -> bool + { + // override for default tag + if (std::distance(F::PlayerUtils.m_vTags.begin(), a.first) == DEFAULT_TAG) + return true; + if (std::distance(F::PlayerUtils.m_vTags.begin(), b.first) == DEFAULT_TAG) + return false; + + // sort by priority if unequal + if (a.second.Priority != b.second.Priority) + return a.second.Priority > b.second.Priority; + + return a.second.Name < b.second.Name; + }); + std::sort(vLabels.begin(), vLabels.end(), [&](const auto& a, const auto& b) -> bool + { + // sort by priority if unequal + if (a.second.Priority != b.second.Priority) + return a.second.Priority > b.second.Priority; + + return a.second.Name < b.second.Name; + }); + + // display tags + int iPriorities = 0, iLabels = 0; + for (auto& pair : vPriorities) + { + drawTag(pair.first, pair.second, iPriorities); + iPriorities++; + } + for (auto& pair : vLabels) + { + drawTag(pair.first, pair.second, iLabels); + iLabels++; + } + SetCursorPos({ 0, 60.f + 36.f * std::max(iPriorities, iLabels) }); DebugDummy({ 0, 28 }); + } EndSection(); + break; + // Materials + case 3: + if (BeginTable("MaterialsTable", 2)) + { + /* Column 1 */ + TableNextColumn(); + if (Section("Manager")) + { + static std::string newName; + FSDropdown("Material name", &newName, {}, FSDropdown_AutoUpdate | FDropdown_Left); + if (FButton("Create", FButton_Fit | FButton_SameLine | FButton_Large) && newName.length() > 0) + { + F::Materials.AddMaterial(newName); + newName.clear(); + } + + if (FButton("Folder", FButton_Fit | FButton_SameLine | FButton_Large)) + ShellExecuteA(nullptr, "open", MaterialFolder.c_str(), nullptr, nullptr, SW_SHOWDEFAULT); + + std::vector> vMaterials; + for (auto& [sName, mat] : F::Materials.mChamMaterials) + vMaterials.push_back({ sName, mat }); + + std::sort(vMaterials.begin(), vMaterials.end(), [&](const auto& a, const auto& b) -> bool + { + // override for none material + if (FNV1A::Hash32(a.first.c_str()) == FNV1A::Hash32Const("None")) + return true; + if (FNV1A::Hash32(b.first.c_str()) == FNV1A::Hash32Const("None")) + return false; + + // keep locked materials higher + if (a.second.bLocked && !b.second.bLocked) + return true; + if (!a.second.bLocked && b.second.bLocked) + return false; + + return a.first < b.first; + }); + + for (auto& pair : vMaterials) + { + const auto current = GetCursorPos().y; + + SetCursorPos({ 14, current + 11 }); + TextColored(pair.second.bLocked ? F::Render.Inactive.Value : F::Render.Active.Value, pair.first.c_str()); + + int o = 26; + + if (!pair.second.bLocked) + { + SetCursorPos({ GetWindowSize().x - o, current + 9 }); + if (IconButton(ICON_MD_DELETE)) + OpenPopup(std::format("Confirmation## DeleteMat{}", pair.first).c_str()); + if (BeginPopupModal(std::format("Confirmation## DeleteMat{}", pair.first).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) + { + Text(std::format("Do you really want to delete '{}'?", pair.first).c_str()); + + if (FButton("Yes", FButton_Left)) + { + F::Materials.RemoveMaterial(pair.first); + CloseCurrentPopup(); + } + if (FButton("No", FButton_Right | FButton_SameLine)) + CloseCurrentPopup(); + + EndPopup(); + } + o += 25; + } + + SetCursorPos({ GetWindowSize().x - o, current + 9 }); + if (IconButton(ICON_MD_EDIT)) + { + CurrentMaterial = pair.first; + LockedMaterial = pair.second.bLocked; + + TextEditor.SetText(F::Materials.GetVMT(CurrentMaterial)); + TextEditor.SetReadOnly(LockedMaterial); } SetCursorPos({ 6, current }); DebugDummy({ 0, 28 }); } - } - } - } EndSection(); - SetCursorPosX(GetCursorPosX() + 8); - PushStyleColor(ImGuiCol_Text, F::Render.Inactive.Value); - Text("Built @ %s, %s", __DATE__, __TIME__); - PopStyleColor(); - - /* Column 2 */ - TableNextColumn(); - if (Section("Debug")) - { - FToggle("Debug info", Vars::Debug::Info, FToggle_Left); - FToggle("Debug logging", Vars::Debug::Logging, FToggle_Right); - FToggle("Show server hitboxes", Vars::Debug::ServerHitbox, FToggle_Left); FTooltip("Only localhost servers"); - FToggle("Anti aim lines", Vars::Debug::AntiAimLines, FToggle_Right); -#ifdef DEBUG_TRACES - FToggle("Visualize traces", Vars::Debug::VisualizeTraces, FToggle_Left); - FToggle("Visualize trace hits", Vars::Debug::VisualizeTraceHits, FToggle_Right); -#endif - } EndSection(); - if (Section("Extra")) - { - if (FButton("cl_fullupdate", FButton_Left)) - I::EngineClient->ClientCmd_Unrestricted("cl_fullupdate"); - if (FButton("retry", FButton_Right | FButton_SameLine)) - I::EngineClient->ClientCmd_Unrestricted("retry"); - if (FButton("Console", FButton_Left)) - I::EngineClient->ClientCmd_Unrestricted("toggleconsole"); - if (FButton("Fix Chams", FButton_Right | FButton_SameLine)) - F::Materials.ReloadMaterials(); - - if (!I::EngineClient->IsConnected()) - { - if (FButton("Unlock achievements", FButton_Left)) - OpenPopup("UnlockAchievements"); - if (FButton("Lock achievements", FButton_Right | FButton_SameLine)) - OpenPopup("LockAchievements"); - - if (BeginPopupModal("UnlockAchievements", nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) - { - Text("Do you really want to unlock all achievements?"); - - if (FButton("Yes, unlock", FButton_Left)) - { - F::Misc.UnlockAchievements(); - CloseCurrentPopup(); - } - if (FButton("No", FButton_Right | FButton_SameLine)) - CloseCurrentPopup(); - - EndPopup(); - } - if (BeginPopupModal("LockAchievements", nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) - { - Text("Do you really want to lock all achievements?"); - - if (FButton("Yes, lock", FButton_Left)) - { - F::Misc.LockAchievements(); - CloseCurrentPopup(); - } - if (FButton("No", FButton_Right | FButton_SameLine)) - CloseCurrentPopup(); - - EndPopup(); - } - } - if (Vars::Debug::Info.Value) - { - if (FButton("Restore lines", FButton_Left)) - F::Visuals.RestoreLines(); - if (FButton("Restore paths", FButton_Right | FButton_SameLine)) - F::Visuals.RestorePaths(); - if (FButton("Restore boxes", FButton_Left)) - F::Visuals.RestoreBoxes(); - } - } EndSection(); - - EndTable(); - } - break; - // Binds - case 1: - if (Section("Settings")) - { - FToggle("Show bind window", Vars::Menu::ShowBinds, FToggle_Left); - FToggle("Menu shows binds", Vars::Menu::MenuShowsBinds, FToggle_Right); - } EndSection(); - if (Section("Binds")) - { - static int iBind = DEFAULT_BIND; - static Bind_t tBind = {}; - - static int bParent = false; - if (bParent) - SetMouseCursor(ImGuiMouseCursor_Hand); - - if (BeginTable("BindsTable", 2)) - { - /* Column 1 */ - TableNextColumn(); SetCursorPos({ GetCursorPos().x - 8, GetCursorPos().y - 8 }); - if (BeginChild("BindsTableTable1", { GetColumnWidth() + 4, 104 }, false, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_NoBackground)) - { - FSDropdown("Name", &tBind.Name, {}, FSDropdown_AutoUpdate | FDropdown_Left); - { - auto sParent = bParent ? "..." : tBind.Parent != DEFAULT_BIND && tBind.Parent < F::Binds.vBinds.size() ? F::Binds.vBinds[tBind.Parent].Name : "None"; - if (FButton(std::format("Parent: {}", sParent).c_str(), FButton_Right | FButton_SameLine | FButton_Large | FButton_NoUpper)) - bParent = 2; - } - FDropdown("Type", &tBind.Type, { "Key", "Class", "Weapon type" }, {}, FDropdown_Left); - switch (tBind.Type) - { - case 0: tBind.Info = std::min(tBind.Info, 2); FDropdown("Behavior", &tBind.Info, { "Hold", "Toggle", "Double click" }, {}, FDropdown_Right); break; - case 1: tBind.Info = std::min(tBind.Info, 8); FDropdown("Class", &tBind.Info, { "Scout", "Soldier", "Pyro", "Demoman", "Heavy", "Engineer", "Medic", "Sniper", "Spy" }, {}, FDropdown_Right); break; - case 2: tBind.Info = std::min(tBind.Info, 2); FDropdown("Weapon type", &tBind.Info, { "Hitscan", "Projectile", "Melee" }, {}, FDropdown_Right); break; - } - } EndChild(); - - /* Column 2 */ - TableNextColumn(); SetCursorPos({ GetCursorPos().x - 4, GetCursorPos().y - 8 }); - if (BeginChild("BindsTableTable2", { GetColumnWidth() + 8, 104 }, false, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_NoBackground)) - { - int iNot = tBind.Not; - FDropdown("While", &iNot, { "Active", "Not active" }, {}, FDropdown_Left); - tBind.Not = iNot; - int iVisible = tBind.Visible; - FDropdown("Visibility", &iVisible, { "Visible", "Hidden" }, { 1, 0 }, FDropdown_Right); - tBind.Visible = iVisible; - if (tBind.Type == 0) - FKeybind("Key", tBind.Key, FButton_Large, -96); - - // create/modify button - bool bCreate = false, bClear = false, bMatch = false, bParent = true; - if (tBind.Parent != DEFAULT_BIND) - bParent = F::Binds.vBinds.size() > tBind.Parent; - - SetCursorPos({ GetWindowSize().x - 96, 64 }); - PushStyleColor(ImGuiCol_Button, F::Render.Foremost.Value); - PushStyleColor(ImGuiCol_ButtonActive, F::Render.Foremost.Value); - if (bParent && (!tBind.Type ? tBind.Key : true)) - { - PushStyleColor(ImGuiCol_ButtonHovered, F::Render.ForemostLight.Value); - bCreate = Button("##CreateButton", { 40, 40 }); - } - else - { - PushStyleColor(ImGuiCol_ButtonHovered, F::Render.Foremost.Value); - Button("##CreateButton", { 40, 40 }); - } - PopStyleColor(3); - SetCursorPos({ GetWindowSize().x - 83, 76 }); - if (bParent && (!tBind.Type ? tBind.Key : true)) - { - bMatch = iBind != DEFAULT_BIND && F::Binds.vBinds.size() > iBind; - IconImage(bMatch ? ICON_MD_SETTINGS : ICON_MD_ADD); - } - else - { - PushTransparent(true); - IconImage(ICON_MD_ADD); - PopTransparent(); - } - - // clear button - SetCursorPos({ GetWindowSize().x - 48, 64 }); - PushStyleColor(ImGuiCol_Button, F::Render.Foremost.Value); - PushStyleColor(ImGuiCol_ButtonHovered, F::Render.ForemostLight.Value); - PushStyleColor(ImGuiCol_ButtonActive, F::Render.Foremost.Value); - bClear = Button("##ClearButton", { 40, 40 }); - PopStyleColor(3); - SetCursorPos({ GetWindowSize().x - 35, 76 }); - IconImage(ICON_MD_CLEAR); - - if (bCreate) - F::Binds.AddBind(iBind, tBind); - if (bCreate || bClear) - { - iBind = DEFAULT_BIND; - tBind = {}; - } - } EndChild(); - - EndTable(); - } - - PushStyleColor(ImGuiCol_Text, F::Render.Inactive.Value); - SetCursorPos({ 14, 128 }); FText("Binds"); - PopStyleColor(); - - auto vBinds = F::Binds.vBinds; // intentional copy - std::function getBinds = [&](int iParent, int x, int y) - { - for (auto it = vBinds.begin(); it != vBinds.end(); it++) - { - int _iBind = std::distance(vBinds.begin(), it); - auto& _tBind = *it; - if (iParent != _tBind.Parent) - continue; - - y++; - - std::string sType; std::string sBehavior; - switch (_tBind.Type) - { - // key - case 0: - switch (_tBind.Info) - { - case 0: { sType = "hold"; break; } - case 1: { sType = "toggle"; break; } - case 2: { sType = "double"; break; } - } - sBehavior = VK2STR(_tBind.Key); - break; - // class - case 1: - sType = "class"; - switch (_tBind.Info) - { - case 0: { sBehavior = "scout"; break; } - case 1: { sBehavior = "soldier"; break; } - case 2: { sBehavior = "pyro"; break; } - case 3: { sBehavior = "demoman"; break; } - case 4: { sBehavior = "heavy"; break; } - case 5: { sBehavior = "engineer"; break; } - case 6: { sBehavior = "medic"; break; } - case 7: { sBehavior = "sniper"; break; } - case 8: { sBehavior = "spy"; break; } - } - break; - // weapon type - case 2: - sType = "weapon"; - switch (_tBind.Info) - { - case 0: { sBehavior = "hitscan"; break; } - case 1: { sBehavior = "projectile"; break; } - case 2: { sBehavior = "melee"; break; } - } - } - if (_tBind.Not) - sType = std::format("not {}", sType); - - bool bClicked = false, bDelete = false, bEdit = false, bVisibility = false, bNot = false; - - const ImVec2 vOriginalPos = { 8.f + 28 * x, 108.f + 36.f * y }; - - // background - const float flWidth = GetWindowSize().x - 16 - 28 * x; const auto vWindowPos = GetWindowPos(); - GetWindowDrawList()->AddRectFilled({ vWindowPos.x + vOriginalPos.x, vWindowPos.y + vOriginalPos.y }, { vWindowPos.x + vOriginalPos.x + flWidth, vWindowPos.y + vOriginalPos.y + 28 }, F::Render.Foremost, 3); - - // text - SetCursorPos({ vOriginalPos.x + 10, vOriginalPos.y + 7 }); - TextUnformatted(_tBind.Name.c_str()); - - SetCursorPos({ vOriginalPos.x + (flWidth - 105) * (1.f / 3), vOriginalPos.y + 7 }); - TextUnformatted(sType.c_str()); - - SetCursorPos({ vOriginalPos.x + (flWidth - 105) * (2.f / 3), vOriginalPos.y + 7 }); - TextUnformatted(sBehavior.c_str()); - - // buttons - SetCursorPos({ vOriginalPos.x + flWidth - 22, vOriginalPos.y + 5 }); - bDelete = IconButton(ICON_MD_DELETE); - - SetCursorPos({ vOriginalPos.x + flWidth - 47, vOriginalPos.y + 5 }); - bEdit = IconButton(ICON_MD_EDIT); - - SetCursorPos({ vOriginalPos.x + flWidth - 72, vOriginalPos.y + 5 }); - bVisibility = IconButton(_tBind.Visible ? ICON_MD_VISIBILITY : ICON_MD_VISIBILITY_OFF); - - SetCursorPos({ vOriginalPos.x + flWidth - 97, vOriginalPos.y + 5 }); - bNot = IconButton(!_tBind.Not ? ICON_MD_CODE : ICON_MD_CODE_OFF); - - SetCursorPos(vOriginalPos); - bClicked = Button(std::format("##{}", _iBind).c_str(), { flWidth, 28 }); - - if (bClicked) - { - if (bParent) - { - bParent = false; - tBind.Parent = _iBind; - } - else - { - iBind = _iBind; - tBind = _tBind; - } - } - if (bDelete) - OpenPopup(std::format("Confirmation## DeleteCond{}", _iBind).c_str()); - if (BeginPopupModal(std::format("Confirmation## DeleteCond{}", _iBind).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) - { - Text(std::format("Do you really want to delete '{}'{}?", _tBind.Name, F::Binds.HasChildren(_iBind) ? " and all of its children" : "").c_str()); - - if (FButton("Yes", FButton_Left)) - { - F::Binds.RemoveBind(_iBind); - CloseCurrentPopup(); - - iBind = DEFAULT_BIND; - tBind = {}; - } - if (FButton("No", FButton_Right | FButton_SameLine)) - CloseCurrentPopup(); - - EndPopup(); - } - if (bEdit) - CurrentBind = CurrentBind != _iBind ? _iBind : DEFAULT_BIND; - if (bVisibility) - F::Binds.vBinds[_iBind].Visible = !_tBind.Visible; - if (bNot) - F::Binds.vBinds[_iBind].Not = !_tBind.Not; - - y = getBinds(_iBind, x + 1, y); - } - - return y; - }; - getBinds(DEFAULT_BIND, 0, 0); - - if (bParent == 2) // dumb - bParent = 1; - else if (bParent && IsMouseReleased(ImGuiMouseButton_Left)) - { - bParent = false; - tBind.Parent = DEFAULT_BIND; - } - } EndSection(); - break; - // PlayerList - case 2: - if (Section("Players")) - { - if (I::EngineClient->IsInGame()) - { - std::lock_guard lock(F::PlayerUtils.m_mutex); - const auto& playerCache = F::PlayerUtils.m_vPlayerCache; - - auto getTeamColor = [](int team, bool alive) - { - switch (team) - { - case 3: return Color_t(50, 75, 100, alive ? 255 : 127); - case 2: return Color_t(125, 50, 50, alive ? 255 : 127); - } - return Color_t(100, 100, 100, 255); - }; - auto drawPlayer = [getTeamColor](const ListPlayer& player, int x, int y) - { - bool bClicked = false, bAdd = false, bAlias = false, bPitch = false, bYaw = false; - - const Color_t teamColor = getTeamColor(player.Team, player.Alive); - const ImColor imColor = ColorToVec(teamColor); - - const ImVec2 vOriginalPos = { x ? GetWindowSize().x / 2 + 4.f : 8.f, 32.f + 36.f * y }; - - // background - const float flWidth = GetWindowSize().x / 2 - 12; const auto vWindowPos = GetWindowPos(); - GetWindowDrawList()->AddRectFilled({ vWindowPos.x + vOriginalPos.x, vWindowPos.y + vOriginalPos.y }, { vWindowPos.x + vOriginalPos.x + flWidth, vWindowPos.y + vOriginalPos.y + 28 }, imColor, 3); - - // text + icons - if (player.Local) - { - SetCursorPos({ vOriginalPos.x + 7, vOriginalPos.y + 5 }); - IconImage(ICON_MD_PERSON); - } - else if (player.Friend) - { - SetCursorPos({ vOriginalPos.x + 7, vOriginalPos.y + 5 }); - IconImage(ICON_MD_GROUP); - } - int lOffset = player.Local || player.Friend ? 29 : 10; - SetCursorPos({ vOriginalPos.x + lOffset, vOriginalPos.y + 7 }); - TextUnformatted(player.Name); - lOffset += CalcTextSize(player.Name).x + 8; - - // buttons - if (!player.Fake) - { - bool bResolver = Vars::AntiHack::Resolver::Resolver.Value && !player.Local; - - // right - SetCursorPos({ vOriginalPos.x + flWidth - 22, vOriginalPos.y + 5 }); - bAlias = IconButton(ICON_MD_EDIT); - - SetCursorPos({ vOriginalPos.x + flWidth - 42, vOriginalPos.y + 5 }); - bAdd = IconButton(ICON_MD_ADD); - - if (bResolver) - { - SetCursorPos({ vOriginalPos.x + flWidth - 62, vOriginalPos.y + 5 }); - bYaw = IconButton(ICON_MD_ARROW_FORWARD); - - SetCursorPos({ vOriginalPos.x + flWidth - 82, vOriginalPos.y + 5 }); - bPitch = IconButton(ICON_MD_ARROW_UPWARD); - } - - // tag bar - SetCursorPos({ vOriginalPos.x + lOffset, vOriginalPos.y }); - if (BeginChild(std::format("TagBar{}", player.FriendsID).c_str(), { flWidth - lOffset - (bResolver ? 88 : 48), 28 }, false, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoBackground)) - { - PushFont(F::Render.FontSmall); - - const auto childPos = GetWindowPos(); - float tOffset = 0; - for (auto& iID : F::PlayerUtils.m_mPlayerTags[player.FriendsID]) - { - auto pTag = F::PlayerUtils.GetTag(iID); - if (!pTag) - continue; - - const ImColor tagColor = ColorToVec(pTag->Color); - const float tagWidth = CalcTextSize(pTag->Name.c_str()).x + 25; - const ImVec2 tagPos = { tOffset, 4 }; - - PushStyleColor(ImGuiCol_Text, IsColorBright(tagColor) ? ImVec4{ 0, 0, 0, 1 } : ImVec4{ 1, 1, 1, 1 }); - - GetWindowDrawList()->AddRectFilled({ childPos.x + tagPos.x, childPos.y + tagPos.y }, { childPos.x + tagPos.x + tagWidth, childPos.y + tagPos.y + 20 }, tagColor, 3); - SetCursorPos({ tagPos.x + 5, tagPos.y + 4 }); - TextUnformatted(pTag->Name.c_str()); - SetCursorPos({ tagPos.x + tagWidth - 18, tagPos.y + 2 }); - if (IconButton(ICON_MD_CANCEL)) - F::PlayerUtils.RemoveTag(player.FriendsID, iID, true, player.Name); - - PopStyleColor(); - - tOffset += tagWidth + 4; - } - PopFont(); - } EndChild(); - - //bClicked = IsItemClicked(); - bClicked = IsItemHovered() && IsMouseClicked(ImGuiMouseButton_Right) || bClicked; - - SetCursorPos(vOriginalPos); - /*bClicked = */Button(std::format("##{}", player.Name).c_str(), { flWidth, 28 }) || bClicked; - bClicked = IsItemHovered() && IsMouseClicked(ImGuiMouseButton_Right) || bClicked; - } - - SetCursorPos(vOriginalPos); - DebugDummy({ 0, 28 }); - - if (bClicked) - OpenPopup(std::format("Clicked{}", player.FriendsID).c_str()); - else if (bAdd) - OpenPopup(std::format("Add{}", player.FriendsID).c_str()); - else if (bAlias) - OpenPopup(std::format("Alias{}", player.FriendsID).c_str()); - else if (bPitch) - OpenPopup(std::format("Pitch{}", player.FriendsID).c_str()); - else if (bYaw) - OpenPopup(std::format("Yaw{}", player.FriendsID).c_str()); - - // popups - if (BeginPopup(std::format("Clicked{}", player.FriendsID).c_str())) - { - PushStyleVar(ImGuiStyleVar_ItemSpacing, { 8, 8 }); - - if (FSelectable("Profile")) - I::SteamFriends->ActivateGameOverlayToUser("steamid", CSteamID(player.FriendsID, k_EUniversePublic, k_EAccountTypeIndividual)); - - if (FSelectable("History")) - I::SteamFriends->ActivateGameOverlayToWebPage(std::format("https://steamhistory.net/id/{}", CSteamID(player.FriendsID, k_EUniversePublic, k_EAccountTypeIndividual).ConvertToUint64()).c_str()); - - if (!player.Local && FSelectable("Votekick")) - I::ClientState->SendStringCmd(std::format("callvote kick {}", player.UserID).c_str()); - - PopStyleVar(); - EndPopup(); - } - else if (BeginPopup(std::format("Add{}", player.FriendsID).c_str())) - { - PushStyleVar(ImGuiStyleVar_ItemSpacing, { 8, 8 }); - - int iID = -1; - for (auto& tTag : F::PlayerUtils.m_vTags) - { - iID++; - - if (!tTag.Assignable || F::PlayerUtils.HasTag(player.FriendsID, iID)) - continue; - - auto imColor = ColorToVec(tTag.Color); - PushStyleColor(ImGuiCol_Text, imColor); - imColor.x /= 3; imColor.y /= 3; imColor.z /= 3; - if (FSelectable(tTag.Name.c_str(), imColor)) - F::PlayerUtils.AddTag(player.FriendsID, iID, true, player.Name); - PopStyleColor(); - } - - PopStyleVar(); - EndPopup(); - } - else if (BeginPopup(std::format("Alias{}", player.FriendsID).c_str())) - { - PushStyleVar(ImGuiStyleVar_ItemSpacing, { 8, 8 }); - - FText("Alias"); - - bool bHasAlias = F::PlayerUtils.m_mPlayerAliases.contains(player.FriendsID); - static std::string sInput = ""; - - PushStyleVar(ImGuiStyleVar_FramePadding, { 8, 8 }); - PushItemWidth(150); - bool bEnter = InputText("##Alias", &sInput, ImGuiInputTextFlags_EnterReturnsTrue); - if (!IsItemFocused()) - sInput = bHasAlias ? F::PlayerUtils.m_mPlayerAliases[player.FriendsID] : ""; - PopItemWidth(); - PopStyleVar(); - - if (bEnter) - { - if (sInput.empty() && F::PlayerUtils.m_mPlayerAliases.contains(player.FriendsID)) - { - F::Records.AliasChanged(player.Name, "Removed", F::PlayerUtils.m_mPlayerAliases[player.FriendsID]); - - auto find = F::PlayerUtils.m_mPlayerAliases.find(player.FriendsID); - if (find != F::PlayerUtils.m_mPlayerAliases.end()) - F::PlayerUtils.m_mPlayerAliases.erase(find); - F::PlayerUtils.m_bSavePlayers = true; - } - else - { - F::PlayerUtils.m_mPlayerAliases[player.FriendsID] = sInput; - F::PlayerUtils.m_bSavePlayers = true; - - F::Records.AliasChanged(player.Name, bHasAlias ? "Changed" : "Added", sInput); - } - } - - PopStyleVar(); - EndPopup(); - } - else if (BeginPopup(std::format("Pitch{}", player.FriendsID).c_str())) - { - PushStyleVar(ImGuiStyleVar_ItemSpacing, { 8, 8 }); - - for (size_t i = 0; i < F::PlayerUtils.m_vListPitch.size(); i++) - { - if (FSelectable(F::PlayerUtils.m_vListPitch[i])) - F::Resolver.mResolverMode[player.FriendsID].second = int(i); - } - - PopStyleVar(); - EndPopup(); - } - else if (BeginPopup(std::format("Yaw{}", player.FriendsID).c_str())) - { - PushStyleVar(ImGuiStyleVar_ItemSpacing, { 8, 8 }); - - for (size_t i = 0; i < F::PlayerUtils.m_vListYaw.size(); i++) - { - if (FSelectable(F::PlayerUtils.m_vListYaw[i])) - F::Resolver.mResolverMode[player.FriendsID].second = int(i); - } - - PopStyleVar(); - EndPopup(); - } - }; - - // display players - std::vector vBlu, vRed, vOther; - for (auto& player : playerCache) - { - switch (player.Team) - { - case 3: vBlu.push_back(player); break; - case 2: vRed.push_back(player); break; - default: vOther.push_back(player); break; - } - } - - if (vBlu.size() < vRed.size()) // display whichever one has more last - { - for (size_t i = 0; i < vBlu.size(); i++) - drawPlayer(vBlu[i], 0, int(i)); - for (size_t i = 0; i < vRed.size(); i++) - drawPlayer(vRed[i], 1, int(i)); - } - else - { - for (size_t i = 0; i < vRed.size(); i++) - drawPlayer(vRed[i], 1, int(i)); - for (size_t i = 0; i < vBlu.size(); i++) - drawPlayer(vBlu[i], 0, int(i)); - } - size_t iMax = std::max(vBlu.size(), vRed.size()); - for (size_t i = 0; i < vOther.size(); i++) - drawPlayer(vOther[i], i % 2, int(iMax + i / 2)); - } - else - { - SetCursorPos({ 18, 39 }); - Text("Not ingame"); - DebugDummy({ 0, 8 }); - } - } EndSection(); - if (Section("Tags")) - { - static int iID = -1; - static PriorityLabel_t tTag = {}; - - if (BeginTable("TagTable", 2)) - { - /* Column 1 */ - TableNextColumn(); SetCursorPos({ GetCursorPos().x - 8, GetCursorPos().y - 8 }); - if (BeginChild("TagTable1", { GetColumnWidth() + 4, 56 }, false, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_NoBackground)) - { - FSDropdown("Name", &tTag.Name, {}, FSDropdown_AutoUpdate | FDropdown_Left, -10); - FColorPicker("Color", &tTag.Color, 0, FColorPicker_Dropdown); - - PushDisabled(iID == DEFAULT_TAG || iID == IGNORED_TAG); - int iLabel = Disabled ? 0 : tTag.Label; - FDropdown("Type", &iLabel, { "Priority", "Label" }, {}, FDropdown_Right); - tTag.Label = iLabel; - if (Disabled) - tTag.Label = false; - PopDisabled(); - } EndChild(); - - /* Column 2 */ - TableNextColumn(); SetCursorPos({ GetCursorPos().x - 4, GetCursorPos().y - 8 }); - if (BeginChild("TagTable2", { GetColumnWidth() + 8, 56 }, false, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_NoBackground)) - { - PushTransparent(tTag.Label); // transparent if we want a label, user can still use to sort - SetCursorPosY(GetCursorPos().y + 12); - FSlider("Priority", &tTag.Priority, -10, 10, 1, "%i", FSlider_Left); - PopTransparent(); - - // create/modify button - bool bCreate = false, bClear = false; - - SetCursorPos({ GetWindowSize().x - 96, 16 }); - PushStyleColor(ImGuiCol_Button, F::Render.Foremost.Value); - PushStyleColor(ImGuiCol_ButtonActive, F::Render.Foremost.Value); - if (tTag.Name.length()) - { - PushStyleColor(ImGuiCol_ButtonHovered, F::Render.ForemostLight.Value); - bCreate = Button("##CreateButton", { 40, 40 }); - } - else - { - PushStyleColor(ImGuiCol_ButtonHovered, F::Render.Foremost.Value); - Button("##CreateButton", { 40, 40 }); - } - PopStyleColor(3); - SetCursorPos({ GetWindowSize().x - 83, 28 }); - PushTransparent(tTag.Name.empty()); - IconImage(iID != -1 ? ICON_MD_SETTINGS : ICON_MD_ADD); - PopTransparent(); - - // clear button - SetCursorPos({ GetWindowSize().x - 48, 16 }); - PushStyleColor(ImGuiCol_Button, F::Render.Foremost.Value); - PushStyleColor(ImGuiCol_ButtonHovered, F::Render.ForemostLight.Value); - PushStyleColor(ImGuiCol_ButtonActive, F::Render.Foremost.Value); - bClear = Button("##ClearButton", { 40, 40 }); - PopStyleColor(3); - SetCursorPos({ GetWindowSize().x - 35, 28 }); - IconImage(ICON_MD_CLEAR); - - if (bCreate) - { - F::PlayerUtils.m_bSaveTags = true; - if (iID > -1 || iID < F::PlayerUtils.m_vTags.size()) - { - F::PlayerUtils.m_vTags[iID].Name = tTag.Name; - F::PlayerUtils.m_vTags[iID].Color = tTag.Color; - F::PlayerUtils.m_vTags[iID].Priority = tTag.Priority; - F::PlayerUtils.m_vTags[iID].Label = tTag.Label; - } - else - F::PlayerUtils.m_vTags.push_back(tTag); - } - if (bCreate || bClear) - { - iID = -1; - tTag = {}; - } - } EndChild(); - - EndTable(); - } - - auto drawTag = [](std::vector::iterator it, PriorityLabel_t& _tTag, int y) - { - int _iID = std::distance(F::PlayerUtils.m_vTags.begin(), it); - - bool bClicked = false, bDelete = false; - - ImColor imColor = ColorToVec(_tTag.Color); - imColor.Value.x /= 3; imColor.Value.y /= 3; imColor.Value.z /= 3; - - const ImVec2 vOriginalPos = { _tTag.Label ? GetWindowSize().x * 2 / 3 + 4.f : 8.f, 96.f + 36.f * y }; - - // background - const float flWidth = GetWindowSize().x * (_tTag.Label ? 1.f / 3 : 2.f / 3) - 12; const auto vWindowPos = GetWindowPos(); - GetWindowDrawList()->AddRectFilled({ vWindowPos.x + vOriginalPos.x, vWindowPos.y + vOriginalPos.y }, { vWindowPos.x + vOriginalPos.x + flWidth, vWindowPos.y + vOriginalPos.y + 28 }, imColor, 3); - - // text - SetCursorPos({ vOriginalPos.x + 10, vOriginalPos.y + 7 }); - TextUnformatted(_tTag.Name.c_str()); - - if (!_tTag.Label) - { - SetCursorPos({ vOriginalPos.x + flWidth / 2, vOriginalPos.y + 7 }); - TextUnformatted(std::format("{}", _tTag.Priority).c_str()); - } - - // buttons - SetCursorPos({ vOriginalPos.x + flWidth - 22, vOriginalPos.y + 5 }); - if (!_tTag.Locked) - bDelete = IconButton(ICON_MD_DELETE); - else - { - switch (_iID) - { - //case DEFAULT_TAG: // no image - case IGNORED_TAG: IconImage(ICON_MD_DO_NOT_DISTURB); break; - case CHEATER_TAG: IconImage(ICON_MD_FLAG); break; - case FRIEND_TAG: IconImage(ICON_MD_GROUP); - } - } - - SetCursorPos(vOriginalPos); - bClicked = Button(std::format("##{}", _tTag.Name).c_str(), { flWidth, 28 }); - - if (bClicked) - { - iID = _iID; - tTag.Name = _tTag.Name; - tTag.Color = _tTag.Color; - tTag.Priority = _tTag.Priority; - tTag.Label = _tTag.Label; - } - if (bDelete) - OpenPopup(std::format("Confirmation## DeleteTag{}", _iID).c_str()); - if (BeginPopupModal(std::format("Confirmation## DeleteTag{}", _iID).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) - { - Text(std::format("Do you really want to delete '{}'?", _tTag.Name).c_str()); - - if (FButton("Yes", FButton_Left)) - { - F::PlayerUtils.m_vTags.erase(it); - F::PlayerUtils.m_bSaveTags = F::PlayerUtils.m_bSavePlayers = true; - - for (auto& [friendsID, vTags] : F::PlayerUtils.m_mPlayerTags) - { - for (auto it = vTags.begin(); it != vTags.end();) - { - if (_iID == *it) - vTags.erase(it); - else - { - if (_iID < *it) - (*it)--; - it++; - } - } - } - - if (iID == _iID) - { - iID = -1; - tTag = {}; - } - else if (iID > _iID) - iID--; - - CloseCurrentPopup(); - } - if (FButton("No", FButton_Right | FButton_SameLine)) - CloseCurrentPopup(); - - EndPopup(); - } - }; - - PushStyleColor(ImGuiCol_Text, F::Render.Inactive.Value); - SetCursorPos({ 14, 80 }); FText("Priorities"); - SetCursorPos({ GetWindowSize().x * 2 / 3 + 10, 80 }); FText("Labels"); - PopStyleColor(); - - std::vector::iterator, PriorityLabel_t>> vPriorities = {}, vLabels = {}; - for (auto it = F::PlayerUtils.m_vTags.begin(); it != F::PlayerUtils.m_vTags.end(); it++) - { - auto& _tTag = *it; - - if (!_tTag.Label) - vPriorities.push_back({ it, _tTag }); - else - vLabels.push_back({ it, _tTag }); - } - - std::sort(vPriorities.begin(), vPriorities.end(), [&](const auto& a, const auto& b) -> bool - { - // override for default tag - if (std::distance(F::PlayerUtils.m_vTags.begin(), a.first) == DEFAULT_TAG) - return true; - if (std::distance(F::PlayerUtils.m_vTags.begin(), b.first) == DEFAULT_TAG) - return false; - - // sort by priority if unequal - if (a.second.Priority != b.second.Priority) - return a.second.Priority > b.second.Priority; - - return a.second.Name < b.second.Name; - }); - std::sort(vLabels.begin(), vLabels.end(), [&](const auto& a, const auto& b) -> bool - { - // sort by priority if unequal - if (a.second.Priority != b.second.Priority) - return a.second.Priority > b.second.Priority; - - return a.second.Name < b.second.Name; - }); - - // display tags - int iPriorities = 0, iLabels = 0; - for (auto& pair : vPriorities) - { - drawTag(pair.first, pair.second, iPriorities); - iPriorities++; - } - for (auto& pair : vLabels) - { - drawTag(pair.first, pair.second, iLabels); - iLabels++; - } - SetCursorPos({ 0, 60.f + 36.f * std::max(iPriorities, iLabels) }); DebugDummy({ 0, 28 }); - } EndSection(); - break; - // Materials - case 3: - if (BeginTable("MaterialsTable", 2)) - { - /* Column 1 */ - TableNextColumn(); - if (Section("Manager")) - { - static std::string newName; - FSDropdown("Material name", &newName, {}, FSDropdown_AutoUpdate | FDropdown_Left); - if (FButton("Create", FButton_Fit | FButton_SameLine | FButton_Large) && newName.length() > 0) - { - F::Materials.AddMaterial(newName); - newName.clear(); - } - - if (FButton("Folder", FButton_Fit | FButton_SameLine | FButton_Large)) - ShellExecuteA(nullptr, "open", MaterialFolder.c_str(), nullptr, nullptr, SW_SHOWDEFAULT); - - std::vector> vMaterials; - for (auto& [sName, mat] : F::Materials.mChamMaterials) - vMaterials.push_back({ sName, mat }); - - std::sort(vMaterials.begin(), vMaterials.end(), [&](const auto& a, const auto& b) -> bool - { - // override for none material - if (FNV1A::Hash32(a.first.c_str()) == FNV1A::Hash32Const("None")) - return true; - if (FNV1A::Hash32(b.first.c_str()) == FNV1A::Hash32Const("None")) - return false; - - // keep locked materials higher - if (a.second.bLocked && !b.second.bLocked) - return true; - if (!a.second.bLocked && b.second.bLocked) - return false; - - return a.first < b.first; - }); - - for (auto& pair : vMaterials) - { - const auto current = GetCursorPos().y; - - SetCursorPos({ 14, current + 11 }); - TextColored(pair.second.bLocked ? F::Render.Inactive.Value : F::Render.Active.Value, pair.first.c_str()); - - int o = 26; - - if (!pair.second.bLocked) - { - SetCursorPos({ GetWindowSize().x - o, current + 9 }); - if (IconButton(ICON_MD_DELETE)) - OpenPopup(std::format("Confirmation## DeleteMat{}", pair.first).c_str()); - if (BeginPopupModal(std::format("Confirmation## DeleteMat{}", pair.first).c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysUseWindowPadding)) - { - Text(std::format("Do you really want to delete '{}'?", pair.first).c_str()); - - if (FButton("Yes", FButton_Left)) - { - F::Materials.RemoveMaterial(pair.first); - CloseCurrentPopup(); - } - if (FButton("No", FButton_Right | FButton_SameLine)) - CloseCurrentPopup(); - - EndPopup(); - } - o += 25; - } - - SetCursorPos({ GetWindowSize().x - o, current + 9 }); - if (IconButton(ICON_MD_EDIT)) - { - CurrentMaterial = pair.first; - LockedMaterial = pair.second.bLocked; - - TextEditor.SetText(F::Materials.GetVMT(CurrentMaterial)); - TextEditor.SetReadOnly(LockedMaterial); - } - - SetCursorPos({ 6, current }); DebugDummy({ 0, 28 }); - } - } EndSection(); - - /* Column 2 */ - TableNextColumn(); - if (CurrentMaterial.length()) - { - auto count = std::ranges::count(TextEditor.GetText(), '\n'); // doesn't account for text editor size otherwise - if (Section("Editor", 81 + 15 * count, true)) - { - // Toolbar - if (!LockedMaterial) - { - if (FButton("Save", FButton_Fit)) - { - auto text = TextEditor.GetText(); - text.erase(text.end() - 1, text.end()); // get rid of random newline - F::Materials.EditMaterial(CurrentMaterial, text); - } - SameLine(); - } - if (FButton("Close", FButton_Fit)) - CurrentMaterial = ""; - SameLine(); SetCursorPosY(GetCursorPosY() + 27); - PushStyleColor(ImGuiCol_Text, F::Render.Inactive.Value); - FText(LockedMaterial ? std::format("Viewing: {}", CurrentMaterial).c_str() : std::format("Editing: {}", CurrentMaterial).c_str(), FText_Right); - PopStyleColor(); - - // Text editor - Dummy({ 0, 8 }); - - PushFont(F::Render.FontMono); - TextEditor.Render("TextEditor"); - PopFont(); } EndSection(); - } - EndTable(); + /* Column 2 */ + TableNextColumn(); + if (CurrentMaterial.length()) + { + auto count = std::ranges::count(TextEditor.GetText(), '\n'); // doesn't account for text editor size otherwise + if (Section("Editor", 81 + 15 * count, true)) + { + // Toolbar + if (!LockedMaterial) + { + if (FButton("Save", FButton_Fit)) + { + auto text = TextEditor.GetText(); + text.erase(text.end() - 1, text.end()); // get rid of random newline + F::Materials.EditMaterial(CurrentMaterial, text); + } + SameLine(); + } + if (FButton("Close", FButton_Fit)) + CurrentMaterial = ""; + SameLine(); SetCursorPosY(GetCursorPosY() + 27); + PushStyleColor(ImGuiCol_Text, F::Render.Inactive.Value); + FText(LockedMaterial ? std::format("Viewing: {}", CurrentMaterial).c_str() : std::format("Editing: {}", CurrentMaterial).c_str(), FText_Right); + PopStyleColor(); + + // Text editor + Dummy({ 0, 8 }); + + PushFont(F::Render.FontMono); + TextEditor.Render("TextEditor"); + PopFont(); + } EndSection(); + } + + EndTable(); + } + break; } - break; - } + + PopStyleColor(); + } EndChild(); + PopStyleVar(); } #pragma endregion -void CMenu::AddDraggable(const char* szTitle, ConfigVar& var, bool bShouldDraw) +void CMenu::AddDraggable(const char* sTitle, ConfigVar& var, bool bShouldDraw) { using namespace ImGui; @@ -2250,9 +2307,9 @@ void CMenu::AddDraggable(const char* szTitle, ConfigVar& var, bool bS static std::unordered_map> old = {}; DragBox_t info = FGet(var); - const float sizeX = 100.f * Vars::Menu::DPI.Map[DEFAULT_BIND], sizeY = 40.f * Vars::Menu::DPI.Map[DEFAULT_BIND]; + const float sizeX = 100.f * Vars::Menu::Scale.Map[DEFAULT_BIND], sizeY = 40.f * Vars::Menu::Scale.Map[DEFAULT_BIND]; SetNextWindowSize({ sizeX, sizeY }, ImGuiCond_Always); - if (!old.contains(szTitle) || info != old[szTitle].first || sizeX != old[szTitle].second) + if (!old.contains(sTitle) || info != old[sTitle].first || sizeX != old[sTitle].second) SetNextWindowPos({ float(info.x - sizeX / 2), float(info.y) }, ImGuiCond_Always); PushStyleColor(ImGuiCol_WindowBg, {}); @@ -2260,17 +2317,17 @@ void CMenu::AddDraggable(const char* szTitle, ConfigVar& var, bool bS PushStyleVar(ImGuiStyleVar_WindowRounding, 3); PushStyleVar(ImGuiStyleVar_WindowBorderSize, 1); PushStyleVar(ImGuiStyleVar_WindowMinSize, { sizeX, sizeY }); - if (Begin(szTitle, nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoFocusOnAppearing)) + if (Begin(sTitle, nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoFocusOnAppearing)) { const auto vWindowPos = GetWindowPos(); - info.x = vWindowPos.x + sizeX / 2; info.y = vWindowPos.y; old[szTitle] = { info, sizeX }; + info.x = vWindowPos.x + sizeX / 2; info.y = vWindowPos.y; old[sTitle] = { info, sizeX }; FSet(var, info); PushFont(F::Render.FontBlack); - auto size = CalcTextSize(szTitle); + auto size = CalcTextSize(sTitle); SetCursorPos({ (sizeX - size.x) * 0.5f, (sizeY - size.y) * 0.5f }); - Text(szTitle); + Text(sTitle); PopFont(); End(); @@ -2286,7 +2343,7 @@ void CMenu::DrawBinds() if ((IsOpen ? !FGet(Vars::Menu::ShowBinds) : !Vars::Menu::ShowBinds.Value) || !IsOpen && I::EngineVGui->IsGameUIVisible()) return; - static DragBox_t old = {}; + static DragBox_t old = { -2147483648, -2147483648 }; DragBox_t info = IsOpen ? FGet(Vars::Menu::BindsDisplay) : Vars::Menu::BindsDisplay.Value; if (info != old) SetNextWindowPos({ float(info.x), float(info.y) }, ImGuiCond_Always); @@ -2370,6 +2427,7 @@ void CMenu::DrawBinds() SetNextWindowSize({ std::max(titleWidth + infoWidth + stateWidth + 42, 56.f), 18.f * actives.size() + 38 }); PushStyleVar(ImGuiStyleVar_WindowMinSize, { 40.f, 40.f }); + PushStyleColor(ImGuiCol_WindowBg, F::Render.Background.Value); if (Begin("Binds", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_AlwaysAutoResize)) { const auto vWindowPos = GetWindowPos(); @@ -2404,6 +2462,7 @@ void CMenu::DrawBinds() End(); } + PopStyleColor(); PopStyleVar(); PopFont(); } @@ -2416,7 +2475,7 @@ void CMenu::DrawCameraWindow() if (!FGet(Vars::Visuals::Simulation::ProjectileCamera)) return; - static WindowBox_t old = {}; + static WindowBox_t old = { -2147483648, -2147483648 }; WindowBox_t info = FGet(Vars::Visuals::Simulation::ProjectileWindow); if (info != old) { @@ -2429,7 +2488,7 @@ void CMenu::DrawCameraWindow() PushStyleVar(ImGuiStyleVar_WindowRounding, 3); PushStyleVar(ImGuiStyleVar_WindowBorderSize, 1); PushStyleVar(ImGuiStyleVar_WindowMinSize, { 100.f, 100.f }); - if (Begin("Camera", nullptr, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoFocusOnAppearing)) + if (Begin("Camera", nullptr, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoFocusOnAppearing)) { const auto vWindowPos = GetWindowPos(); const auto winSize = GetWindowSize(); @@ -2457,7 +2516,7 @@ void CMenu::DrawRadar() if (!FGet(Vars::Radar::Main::Enabled)) return; - static WindowBox_t old = {}; + static WindowBox_t old = { -2147483648, -2147483648 }; WindowBox_t info = FGet(Vars::Radar::Main::Window); if (info != old) { @@ -2470,7 +2529,7 @@ void CMenu::DrawRadar() PushStyleVar(ImGuiStyleVar_WindowRounding, 3); PushStyleVar(ImGuiStyleVar_WindowBorderSize, 1); SetNextWindowSizeConstraints({ 100.f, 100.f }, { 1000.f, 1000.f }, SquareConstraints); - if (Begin("Radar", nullptr, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoFocusOnAppearing)) + if (Begin("Radar", nullptr, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoFocusOnAppearing)) { const ImVec2 vWindowPos = GetWindowPos(); const ImVec2 winSize = GetWindowSize(); @@ -2518,12 +2577,12 @@ void CMenu::Render() DrawCameraWindow(); DrawRadar(); - AddDraggable("Ticks", Vars::Menu::TicksDisplay, FGet(Vars::Menu::Indicators) & (1 << 0)); - AddDraggable("Crit hack", Vars::Menu::CritsDisplay, FGet(Vars::Menu::Indicators) & (1 << 1)); - AddDraggable("Spectators", Vars::Menu::SpectatorsDisplay, FGet(Vars::Menu::Indicators) & (1 << 2)); - AddDraggable("Ping", Vars::Menu::PingDisplay, FGet(Vars::Menu::Indicators) & (1 << 3)); - AddDraggable("Conditions", Vars::Menu::ConditionsDisplay, FGet(Vars::Menu::Indicators) & (1 << 4)); - AddDraggable("Seed prediction", Vars::Menu::SeedPredictionDisplay, FGet(Vars::Menu::Indicators) & (1 << 5)); + AddDraggable("Ticks", Vars::Menu::TicksDisplay, FGet(Vars::Menu::Indicators) & Vars::Menu::IndicatorsEnum::Ticks); + AddDraggable("Crit hack", Vars::Menu::CritsDisplay, FGet(Vars::Menu::Indicators) & Vars::Menu::IndicatorsEnum::CritHack); + AddDraggable("Spectators", Vars::Menu::SpectatorsDisplay, FGet(Vars::Menu::Indicators) & Vars::Menu::IndicatorsEnum::Spectators); + AddDraggable("Ping", Vars::Menu::PingDisplay, FGet(Vars::Menu::Indicators) & Vars::Menu::IndicatorsEnum::Ping); + AddDraggable("Conditions", Vars::Menu::ConditionsDisplay, FGet(Vars::Menu::Indicators) & Vars::Menu::IndicatorsEnum::Conditions); + AddDraggable("Seed prediction", Vars::Menu::SeedPredictionDisplay, FGet(Vars::Menu::Indicators) & Vars::Menu::IndicatorsEnum::SeedPrediction); F::Render.Cursor = GetMouseCursor(); } diff --git a/Amalgam/src/Features/ImGui/Menu/Menu.h b/Amalgam/src/Features/ImGui/Menu/Menu.h index 90600d0d..3ceded4f 100644 --- a/Amalgam/src/Features/ImGui/Menu/Menu.h +++ b/Amalgam/src/Features/ImGui/Menu/Menu.h @@ -13,22 +13,11 @@ class CMenu void MenuLogs(); void MenuSettings(); - void AddDraggable(const char* szTitle, ConfigVar& info, bool bShouldDraw); + void AddDraggable(const char* sTitle, ConfigVar& info, bool bShouldDraw); void DrawBinds(); void DrawCameraWindow(); void DrawRadar(); - int CurrentTab = 0; - - int CurrentAimbotTab = 0; - int CurrentVisualsTab = 0; - int CurrentLogsTab = 0; - int CurrentConfigTab = 0; - int CurrentConfigType = 0; - - ImVec2 TabSize = { 65, 72 }; - ImVec2 SubTabSize = { 90, 48 }; - // material editor stuff TextEditor TextEditor; std::string CurrentMaterial; diff --git a/Amalgam/src/Features/ImGui/Render.cpp b/Amalgam/src/Features/ImGui/Render.cpp index 16f05f1a..4a381ef1 100644 --- a/Amalgam/src/Features/ImGui/Render.cpp +++ b/Amalgam/src/Features/ImGui/Render.cpp @@ -44,9 +44,9 @@ void CRender::LoadColors() Accent = ColorToVec(Vars::Menu::Theme::Accent.Value); AccentLight = ImColor(Accent.Value.x * 1.1f, Accent.Value.y * 1.1f, Accent.Value.z * 1.1f, Accent.Value.w); - Background = ColorToVec(Vars::Menu::Theme::Background.Value); - Foreground = ColorToVec(Vars::Menu::Theme::Foreground.Value); - Foremost = ColorToVec(Vars::Menu::Theme::Foremost.Value); + Background = ColorToVec(Vars::Menu::Theme::Background.Value.Lerp({ 127, 127, 127, Vars::Menu::Theme::Background.Value.a }, 1.f / 9)); + Foreground = ColorToVec(Vars::Menu::Theme::Background.Value); + Foremost = ColorToVec(Vars::Menu::Theme::Background.Value.Lerp({ 127, 127, 127, Vars::Menu::Theme::Background.Value.a }, 2.f / 9)); ForemostLight = ImColor(Foremost.Value.x * 1.1f, Foremost.Value.y * 1.1f, Foremost.Value.z * 1.1f, Foremost.Value.w); Inactive = ColorToVec(Vars::Menu::Theme::Inactive.Value); Active = ColorToVec(Vars::Menu::Theme::Active.Value); @@ -70,7 +70,7 @@ void CRender::LoadColors() colors[ImGuiCol_SliderGrab] = Accent; colors[ImGuiCol_SliderGrabActive] = AccentLight; colors[ImGuiCol_Text] = Active; - colors[ImGuiCol_WindowBg] = Background; + colors[ImGuiCol_WindowBg] = Foreground; } void CRender::LoadStyle() @@ -117,7 +117,6 @@ void CRender::Initialize(IDirect3DDevice9* pDevice) FontBold = io.Fonts->AddFontFromFileTTF(R"(C:\Windows\Fonts\verdana.ttf)", 13.f, &fontConfig, fontRange); FontLarge = io.Fonts->AddFontFromFileTTF(R"(C:\Windows\Fonts\verdana.ttf)", 15.f, &fontConfig, fontRange); FontBlack = io.Fonts->AddFontFromFileTTF(R"(C:\Windows\Fonts\verdana.ttf)", 15.f, &fontConfig, fontRange); - FontTitle = io.Fonts->AddFontFromFileTTF(R"(C:\Windows\Fonts\verdana.ttf)", 20.f, &fontConfig, fontRange); FontMono = io.Fonts->AddFontFromFileTTF(R"(C:\Windows\Fonts\verdana.ttf)", 15.f, &fontConfig, fontRange); //FontSmall = io.Fonts->AddFontFromMemoryCompressedTTF(RobotoMedium_compressed_data, RobotoMedium_compressed_size, 11.f, &fontConfig, fontRange); @@ -125,7 +124,6 @@ void CRender::Initialize(IDirect3DDevice9* pDevice) //FontBold = io.Fonts->AddFontFromMemoryCompressedTTF(RobotoBold_compressed_data, RobotoBold_compressed_size, 13.f, &fontConfig, fontRange); //FontLarge = io.Fonts->AddFontFromMemoryCompressedTTF(RobotoMedium_compressed_data, RobotoMedium_compressed_size, 15.f, &fontConfig, fontRange); //FontBlack = io.Fonts->AddFontFromMemoryCompressedTTF(RobotoBlack_compressed_data, RobotoBlack_compressed_size, 15.f, &fontConfig, fontRange); - //FontTitle = io.Fonts->AddFontFromMemoryCompressedTTF(RobotoMedium_compressed_data, RobotoMedium_compressed_size, 20.f, &fontConfig, fontRange); //FontMono = io.Fonts->AddFontFromMemoryCompressedTTF(CascadiaMono_compressed_data, CascadiaMono_compressed_size, 15.f, &fontConfig, fontRange); ImFontConfig iconConfig; diff --git a/Amalgam/src/Features/ImGui/Render.h b/Amalgam/src/Features/ImGui/Render.h index 91b2e4a8..44e7f714 100644 --- a/Amalgam/src/Features/ImGui/Render.h +++ b/Amalgam/src/Features/ImGui/Render.h @@ -30,7 +30,6 @@ public: ImFont* FontBold = nullptr; ImFont* FontLarge = nullptr; ImFont* FontBlack = nullptr; - ImFont* FontTitle = nullptr; ImFont* FontMono = nullptr; ImFont* IconFontRegular = nullptr; diff --git a/Amalgam/src/Features/Visuals/ESP/ESP.cpp b/Amalgam/src/Features/Visuals/ESP/ESP.cpp index 76f1f10b..24c81cdc 100644 --- a/Amalgam/src/Features/Visuals/ESP/ESP.cpp +++ b/Amalgam/src/Features/Visuals/ESP/ESP.cpp @@ -67,19 +67,19 @@ void CESP::StorePlayers(CTFPlayer* pLocal) if (Vars::ESP::Player.Value & Vars::ESP::PlayerEnum::Distance && pPlayer != pLocal) { Vec3 vDelta = pPlayer->m_vecOrigin() - pLocal->m_vecOrigin(); - tCache.m_vText.push_back({ TextBottom, std::format("[{:.0f}M]", vDelta.Length2D() / 41), Vars::Menu::Theme::Active.Value }); + tCache.m_vText.push_back({ TextBottom, std::format("[{:.0f}M]", vDelta.Length2D() / 41), Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value }); } PlayerInfo_t pi{}; if (I::EngineClient->GetPlayerInfo(iIndex, &pi)) { if (Vars::ESP::Player.Value & Vars::ESP::PlayerEnum::Name) - tCache.m_vText.push_back({ TextTop, F::PlayerUtils.GetPlayerName(iIndex, pi.name), Vars::Menu::Theme::Active.Value }); + tCache.m_vText.push_back({ TextTop, F::PlayerUtils.GetPlayerName(iIndex, pi.name), Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value }); if (Vars::ESP::Player.Value & Vars::ESP::PlayerEnum::Priority) { if (auto pTag = F::PlayerUtils.GetSignificantTag(pi.friendsID, 1)) - tCache.m_vText.push_back({ TextTop, pTag->Name, pTag->Color }); + tCache.m_vText.push_back({ TextTop, pTag->Name, pTag->Color, H::Draw.IsColorBright(pTag->Color) ? Color_t(0, 0, 0, 255) : Color_t() }); } if (Vars::ESP::Player.Value & Vars::ESP::PlayerEnum::Labels) @@ -110,7 +110,7 @@ void CESP::StorePlayers(CTFPlayer* pLocal) }); for (auto& pTag : vTags) - tCache.m_vText.push_back({ TextRight, pTag->Name, pTag->Color }); + tCache.m_vText.push_back({ TextRight, pTag->Name, pTag->Color, H::Draw.IsColorBright(pTag->Color) ? Color_t(0, 0, 0, 255) : Color_t() }); } } } @@ -127,7 +127,7 @@ void CESP::StorePlayers(CTFPlayer* pLocal) tCache.m_flHealth = std::clamp(flHealth / flMaxHealth, 0.f, 1.f); } if (Vars::ESP::Player.Value & Vars::ESP::PlayerEnum::HealthText) - tCache.m_vText.push_back({ TextHealth, std::format("{}", flHealth), flHealth > flMaxHealth ? Vars::Colors::Overheal.Value : Vars::Menu::Theme::Active.Value}); + tCache.m_vText.push_back({ TextHealth, std::format("{}", flHealth), flHealth > flMaxHealth ? Vars::Colors::Overheal.Value : Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value }); if (iClassNum == TF_CLASS_MEDIC) { @@ -136,14 +136,14 @@ void CESP::StorePlayers(CTFPlayer* pLocal) tCache.m_flUber = std::clamp(pMediGun->As()->m_flChargeLevel(), 0.f, 1.f); tCache.m_bUberBar = Vars::ESP::Player.Value & Vars::ESP::PlayerEnum::UberBar; if (Vars::ESP::Player.Value & Vars::ESP::PlayerEnum::UberText) - tCache.m_vText.push_back({ TextUber, std::format("{:.0f}%%", tCache.m_flUber * 100.f), Vars::Menu::Theme::Active.Value }); + tCache.m_vText.push_back({ TextUber, std::format("{:.0f}%%", tCache.m_flUber * 100.f), Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value }); } } if (Vars::ESP::Player.Value & Vars::ESP::PlayerEnum::ClassIcon) tCache.m_iClassIcon = iClassNum - 1; if (Vars::ESP::Player.Value & Vars::ESP::PlayerEnum::ClassText) - tCache.m_vText.push_back({ TextRight, GetPlayerClass(iClassNum), Vars::Menu::Theme::Active.Value }); + tCache.m_vText.push_back({ TextRight, GetPlayerClass(iClassNum), Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value }); if (Vars::ESP::Player.Value & Vars::ESP::PlayerEnum::WeaponIcon && pWeapon) tCache.m_pWeaponIcon = pWeapon->GetWeaponIcon(); @@ -177,21 +177,21 @@ void CESP::StorePlayers(CTFPlayer* pLocal) } if (void* pCurItemData = fnGetEconItemViewByLoadoutSlot(pPlayer, iWeaponSlot, 0)) - tCache.m_vText.push_back({ TextBottom, SDK::ConvertWideToUTF8(fnGetItemName(pCurItemData)), Vars::Menu::Theme::Active.Value }); + tCache.m_vText.push_back({ TextBottom, SDK::ConvertWideToUTF8(fnGetItemName(pCurItemData)), Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value }); } if (Vars::Debug::Info.Value && !pPlayer->IsDormant() && pPlayer->entindex() != I::EngineClient->GetLocalPlayer()) { int iAverage = TIME_TO_TICKS(F::MoveSim.GetPredictedDelta(pPlayer)); int iCurrent = H::Entities.GetChoke(pPlayer); - tCache.m_vText.push_back({ TextRight, std::format("Lag {}, {}", iAverage, iCurrent), {} }); + tCache.m_vText.push_back({ TextRight, std::format("Lag {}, {}", iAverage, iCurrent), {}, { 0, 0, 0, 255 } }); } { if (Vars::ESP::Player.Value & Vars::ESP::PlayerEnum::LagCompensation && !pPlayer->IsDormant() && pPlayer != pLocal) { if (H::Entities.GetLagCompensation(pPlayer)) - tCache.m_vText.push_back({ TextRight, "LAGCOMP", { 255, 100, 100, 255 } }); + tCache.m_vText.push_back({ TextRight, "LAGCOMP", { 255, 100, 100, 255 }, { 0, 0, 0, 255 } }); } if (Vars::ESP::Player.Value & Vars::ESP::PlayerEnum::Ping && pResource && pPlayer != pLocal) @@ -201,7 +201,7 @@ void CESP::StorePlayers(CTFPlayer* pLocal) { int iPing = pResource->GetPing(pPlayer->entindex()); if (iPing && (iPing >= 200 || iPing <= 5)) - tCache.m_vText.push_back({ TextRight, std::format("{}MS", iPing), { 255, 100, 100, 255 } }); + tCache.m_vText.push_back({ TextRight, std::format("{}MS", iPing), { 255, 100, 100, 255 }, { 0, 0, 0, 255 } }); } } @@ -212,7 +212,7 @@ void CESP::StorePlayers(CTFPlayer* pLocal) { int iKDR = iKills / std::max(iDeaths, 1); if (iKDR >= 10) - tCache.m_vText.push_back({ TextRight, std::format("High KD [{} / {}]", iKills, iDeaths), { 255, 100, 100, 255 } }); + tCache.m_vText.push_back({ TextRight, std::format("High KD [{} / {}]", iKills, iDeaths), { 255, 100, 100, 255 }, { 0, 0, 0, 255 } }); } } @@ -226,9 +226,9 @@ void CESP::StorePlayers(CTFPlayer* pLocal) pWeapon && pWeapon->m_iItemDefinitionIndex() == Sniper_t_TheBushwacka ? bCrits = true : bMiniCrits = true; if (bCrits) - tCache.m_vText.push_back({ TextRight, "CRITS", { 255, 100, 100, 255 } }); + tCache.m_vText.push_back({ TextRight, "CRITS", { 255, 100, 100, 255 }, { 0, 0, 0, 255 } }); else if (bMiniCrits) - tCache.m_vText.push_back({ TextRight, "MINI-CRITS", { 255, 175, 0, 255 } }); + tCache.m_vText.push_back({ TextRight, "MINI-CRITS", { 255, 175, 0, 255 }, { 0, 0, 0, 255 } }); if (pPlayer->InCond(TF_COND_RADIUSHEAL) || pPlayer->InCond(TF_COND_HEALTH_BUFF) || @@ -237,94 +237,94 @@ void CESP::StorePlayers(CTFPlayer* pLocal) pPlayer->InCond(TF_COND_HALLOWEEN_QUICK_HEAL) || pPlayer->InCond(TF_COND_HALLOWEEN_HELL_HEAL) || pPlayer->IsBuffedByKing()) - tCache.m_vText.push_back({ TextRight, "HP+", Vars::Colors::Overheal.Value }); + tCache.m_vText.push_back({ TextRight, "HP+", Vars::Colors::Overheal.Value, { 0, 0, 0, 255 } }); else if (pPlayer->InCond(TF_COND_HEALTH_OVERHEALED)) - tCache.m_vText.push_back({ TextRight, "HP", Vars::Colors::Overheal.Value }); + tCache.m_vText.push_back({ TextRight, "HP", Vars::Colors::Overheal.Value, { 0, 0, 0, 255 } }); if (pPlayer->InCond(TF_COND_INVULNERABLE) || pPlayer->InCond(TF_COND_INVULNERABLE_HIDE_UNLESS_DAMAGED) || pPlayer->InCond(TF_COND_INVULNERABLE_USER_BUFF) || pPlayer->InCond(TF_COND_INVULNERABLE_CARD_EFFECT)) - tCache.m_vText.push_back({ TextRight, "UBER", Vars::Colors::UberBar.Value }); + tCache.m_vText.push_back({ TextRight, "UBER", Vars::Colors::UberBar.Value, { 0, 0, 0, 255 } }); else if (pPlayer->InCond(TF_COND_PHASE)) - tCache.m_vText.push_back({ TextRight, "BONK", { 255, 175, 0, 255 } }); + tCache.m_vText.push_back({ TextRight, "BONK", { 255, 175, 0, 255 }, { 0, 0, 0, 255 } }); /* vaccinator effects */ if (pPlayer->InCond(TF_COND_MEDIGUN_UBER_BULLET_RESIST) || pPlayer->InCond(TF_COND_BULLET_IMMUNE)) - tCache.m_vText.push_back({ TextRight, "BULLET+", { 255, 100, 100, 255 } }); + tCache.m_vText.push_back({ TextRight, "BULLET+", { 255, 100, 100, 255 }, { 0, 0, 0, 255 } }); else if (pPlayer->InCond(TF_COND_MEDIGUN_SMALL_BULLET_RESIST)) - tCache.m_vText.push_back({ TextRight, "BULLET", { 255, 100, 100, 255 } }); + tCache.m_vText.push_back({ TextRight, "BULLET", { 255, 100, 100, 255 }, { 0, 0, 0, 255 } }); if (pPlayer->InCond(TF_COND_MEDIGUN_UBER_BLAST_RESIST) || pPlayer->InCond(TF_COND_BLAST_IMMUNE)) - tCache.m_vText.push_back({ TextRight, "BLAST+", { 255, 100, 100, 255 } }); + tCache.m_vText.push_back({ TextRight, "BLAST+", { 255, 100, 100, 255 }, { 0, 0, 0, 255 } }); else if (pPlayer->InCond(TF_COND_MEDIGUN_SMALL_BLAST_RESIST)) - tCache.m_vText.push_back({ TextRight, "BLAST", { 255, 100, 100, 255 } }); + tCache.m_vText.push_back({ TextRight, "BLAST", { 255, 100, 100, 255 }, { 0, 0, 0, 255 } }); if (pPlayer->InCond(TF_COND_MEDIGUN_UBER_FIRE_RESIST) || pPlayer->InCond(TF_COND_FIRE_IMMUNE)) - tCache.m_vText.push_back({ TextRight, "FIRE+", { 255, 100, 100, 255 } }); + tCache.m_vText.push_back({ TextRight, "FIRE+", { 255, 100, 100, 255 }, { 0, 0, 0, 255 } }); else if (pPlayer->InCond(TF_COND_MEDIGUN_SMALL_FIRE_RESIST)) - tCache.m_vText.push_back({ TextRight, "FIRE", { 255, 100, 100, 255 } }); + tCache.m_vText.push_back({ TextRight, "FIRE", { 255, 100, 100, 255 }, { 0, 0, 0, 255 } }); if (pPlayer->InCond(TF_COND_OFFENSEBUFF)) - tCache.m_vText.push_back({ TextRight, "BANNER", tCache.m_tColor }); + tCache.m_vText.push_back({ TextRight, "BANNER", tCache.m_tColor, { 0, 0, 0, 255 } }); if (pPlayer->InCond(TF_COND_DEFENSEBUFF)) - tCache.m_vText.push_back({ TextRight, "BATTALIONS", tCache.m_tColor }); + tCache.m_vText.push_back({ TextRight, "BATTALIONS", tCache.m_tColor, { 0, 0, 0, 255 } }); if (pPlayer->InCond(TF_COND_REGENONDAMAGEBUFF)) - tCache.m_vText.push_back({ TextRight, "CONCH", tCache.m_tColor }); + tCache.m_vText.push_back({ TextRight, "CONCH", tCache.m_tColor, { 0, 0, 0, 255 } }); if (pPlayer->InCond(TF_COND_BLASTJUMPING)) - tCache.m_vText.push_back({ TextRight, "BLASTJUMP", { 255, 175, 0, 255 } }); + tCache.m_vText.push_back({ TextRight, "BLASTJUMP", { 255, 175, 0, 255 }, { 0, 0, 0, 255 } }); } // Debuffs if (Vars::ESP::Player.Value & Vars::ESP::PlayerEnum::Debuffs) { if (pPlayer->InCond(TF_COND_STUNNED)) - tCache.m_vText.push_back({ TextRight, "STUNNED", { 255, 175, 0, 255 } }); + tCache.m_vText.push_back({ TextRight, "STUNNED", { 255, 175, 0, 255 }, { 0, 0, 0, 255 } }); if (pPlayer->InCond(TF_COND_URINE)) - tCache.m_vText.push_back({ TextRight, "JARATE", { 255, 175, 0, 255 } }); + tCache.m_vText.push_back({ TextRight, "JARATE", { 255, 175, 0, 255 }, { 0, 0, 0, 255 } }); if (pPlayer->InCond(TF_COND_MARKEDFORDEATH) || pPlayer->InCond(TF_COND_MARKEDFORDEATH_SILENT)) - tCache.m_vText.push_back({ TextRight, "MARKED", { 255, 175, 0, 255 } }); + tCache.m_vText.push_back({ TextRight, "MARKED", { 255, 175, 0, 255 }, { 0, 0, 0, 255 } }); if (pPlayer->InCond(TF_COND_BURNING)) - tCache.m_vText.push_back({ TextRight, "BURN", { 255, 175, 0, 255 } }); + tCache.m_vText.push_back({ TextRight, "BURN", { 255, 175, 0, 255 }, { 0, 0, 0, 255 } }); if (pPlayer->InCond(TF_COND_MAD_MILK)) - tCache.m_vText.push_back({ TextRight, "MILK", { 255, 175, 0, 255 } }); + tCache.m_vText.push_back({ TextRight, "MILK", { 255, 175, 0, 255 }, { 0, 0, 0, 255 } }); } // Misc if (Vars::ESP::Player.Value & Vars::ESP::PlayerEnum::Misc) { if (Vars::Visuals::Removals::Taunts.Value && pPlayer->InCond(TF_COND_TAUNTING)) - tCache.m_vText.push_back({ TextRight, "TAUNT", { 255, 100, 200, 255 } }); + tCache.m_vText.push_back({ TextRight, "TAUNT", { 255, 100, 200, 255 }, { 0, 0, 0, 255 } }); if (pPlayer->m_bFeignDeathReady()) - tCache.m_vText.push_back({ TextRight, "DR", { 255, 175, 0, 255 } }); + tCache.m_vText.push_back({ TextRight, "DR", { 255, 175, 0, 255 }, { 0, 0, 0, 255 } }); if (pPlayer->InCond(TF_COND_AIMING) && pWeapon) { switch (pWeapon->GetWeaponID()) { case TF_WEAPON_MINIGUN: - tCache.m_vText.push_back({ TextRight, "REV", { 127, 127, 127, 255 } }); + tCache.m_vText.push_back({ TextRight, "REV", { 127, 127, 127, 255 }, { 0, 0, 0, 255 } }); break; case TF_WEAPON_COMPOUND_BOW: - tCache.m_vText.push_back({ TextRight, I::GlobalVars->curtime - pWeapon->As()->m_flChargeBeginTime() >= 1.f ? "CHARGED" : "CHARGING", { 255, 175, 0, 255 } }); + tCache.m_vText.push_back({ TextRight, I::GlobalVars->curtime - pWeapon->As()->m_flChargeBeginTime() >= 1.f ? "CHARGED" : "CHARGING", { 255, 175, 0, 255 }, { 0, 0, 0, 255 } }); break; case TF_WEAPON_PARTICLE_CANNON: - tCache.m_vText.push_back({ TextRight, "CHARGING", { 255, 175, 0, 255 } }); + tCache.m_vText.push_back({ TextRight, "CHARGING", { 255, 175, 0, 255 }, { 0, 0, 0, 255 } }); } } if (pPlayer->InCond(TF_COND_ZOOMED)) - tCache.m_vText.push_back({ TextRight, "ZOOM", { 255, 175, 0, 255 } }); + tCache.m_vText.push_back({ TextRight, "ZOOM", { 255, 175, 0, 255 }, { 0, 0, 0, 255 } }); if (pPlayer->InCond(TF_COND_STEALTHED) || pPlayer->InCond(TF_COND_STEALTHED_BLINK) || pPlayer->InCond(TF_COND_STEALTHED_USER_BUFF) || pPlayer->InCond(TF_COND_STEALTHED_USER_BUFF_FADING)) - tCache.m_vText.push_back({ TextRight, std::format("INVIS {:.0f}%%", pPlayer->GetInvisPercentage()), Vars::Colors::Cloak.Value }); + tCache.m_vText.push_back({ TextRight, std::format("INVIS {:.0f}%%", pPlayer->GetInvisPercentage()), Vars::Colors::Cloak.Value, { 0, 0, 0, 255 } }); if (pPlayer->InCond(TF_COND_DISGUISING) || pPlayer->InCond(TF_COND_DISGUISED)) - tCache.m_vText.push_back({ TextRight, "DISGUISE", { 255, 175, 0, 255 } }); + tCache.m_vText.push_back({ TextRight, "DISGUISE", { 255, 175, 0, 255 }, { 0, 0, 0, 255 } }); } } } @@ -369,7 +369,7 @@ void CESP::StoreBuildings(CTFPlayer* pLocal) if (Vars::ESP::Building.Value & Vars::ESP::BuildingEnum::Distance) { Vec3 vDelta = pEntity->m_vecOrigin() - pLocal->m_vecOrigin(); - tCache.m_vText.push_back({ TextBottom, std::format("[{:.0f}M]", vDelta.Length2D() / 41), Vars::Menu::Theme::Active.Value }); + tCache.m_vText.push_back({ TextBottom, std::format("[{:.0f}M]", vDelta.Length2D() / 41), Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value }); } if (Vars::ESP::Building.Value & Vars::ESP::BuildingEnum::Name) @@ -381,46 +381,46 @@ void CESP::StoreBuildings(CTFPlayer* pLocal) case ETFClassID::CObjectDispenser: szName = "Dispenser"; break; case ETFClassID::CObjectTeleporter: szName = pBuilding->m_iObjectMode() ? "Teleporter Exit" : "Teleporter Entrance"; } - tCache.m_vText.push_back({ TextTop, szName, Vars::Menu::Theme::Active.Value }); + tCache.m_vText.push_back({ TextTop, szName, Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value }); } float flHealth = pBuilding->m_iHealth(), flMaxHealth = pBuilding->m_iMaxHealth(); if (tCache.m_bHealthBar = Vars::ESP::Building.Value & Vars::ESP::BuildingEnum::HealthBar) tCache.m_flHealth = flHealth / flMaxHealth; if (Vars::ESP::Building.Value & Vars::ESP::BuildingEnum::HealthText) - tCache.m_vText.push_back({ TextHealth, std::format("{}", flHealth), Vars::Menu::Theme::Active.Value }); + tCache.m_vText.push_back({ TextHealth, std::format("{}", flHealth), Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value }); if (Vars::ESP::Building.Value & Vars::ESP::BuildingEnum::Owner && !pBuilding->m_bWasMapPlaced() && pOwner) { PlayerInfo_t pi{}; if (I::EngineClient->GetPlayerInfo(iIndex, &pi)) - tCache.m_vText.push_back({ TextTop, F::PlayerUtils.GetPlayerName(iIndex, pi.name), Vars::Menu::Theme::Active.Value }); + tCache.m_vText.push_back({ TextTop, F::PlayerUtils.GetPlayerName(iIndex, pi.name), Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value }); } if (Vars::ESP::Building.Value & Vars::ESP::BuildingEnum::Level && !bIsMini) - tCache.m_vText.push_back({ TextRight, std::format("{} / {}", pBuilding->m_iUpgradeLevel(), bIsMini ? 1 : 3), Vars::Menu::Theme::Active.Value}); + tCache.m_vText.push_back({ TextRight, std::format("{} / {}", pBuilding->m_iUpgradeLevel(), bIsMini ? 1 : 3), Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value }); if (Vars::ESP::Building.Value & Vars::ESP::BuildingEnum::Flags) { float flConstructed = pBuilding->m_flPercentageConstructed(); if (flConstructed < 1.f) - tCache.m_vText.push_back({ TextRight, std::format("{:.0f}%%", flConstructed * 100.f), { 255, 175, 0, 255 } }); + tCache.m_vText.push_back({ TextRight, std::format("{:.0f}%%", flConstructed * 100.f), { 255, 175, 0, 255 }, { 0, 0, 0, 255 } }); if (pBuilding->IsSentrygun() && pBuilding->As()->m_bPlayerControlled()) - tCache.m_vText.push_back({ TextRight, "WRANGLED", { 255, 100, 100, 255 } }); + tCache.m_vText.push_back({ TextRight, "WRANGLED", { 255, 100, 100, 255 }, { 0, 0, 0, 255 } }); if (pBuilding->m_bHasSapper()) - tCache.m_vText.push_back({ TextRight, "SAPPED", { 255, 175, 0, 255 } }); + tCache.m_vText.push_back({ TextRight, "SAPPED", { 255, 175, 0, 255 }, { 0, 0, 0, 255 } }); else if (pBuilding->m_bDisabled()) - tCache.m_vText.push_back({ TextRight, "DISABLED", { 255, 175, 0, 255 } }); + tCache.m_vText.push_back({ TextRight, "DISABLED", { 255, 175, 0, 255 }, { 0, 0, 0, 255 } }); if (pBuilding->IsSentrygun() && !pBuilding->m_bBuilding()) { int iShells, iMaxShells, iRockets, iMaxRockets; pBuilding->As()->GetAmmoCount(iShells, iMaxShells, iRockets, iMaxRockets); if (!iShells) - tCache.m_vText.push_back({ TextRight, "NO AMMO", { 127, 127, 127, 255 } }); + tCache.m_vText.push_back({ TextRight, "NO AMMO", { 127, 127, 127, 255 }, { 0, 0, 0, 255 } }); if (!bIsMini && !iRockets) - tCache.m_vText.push_back({ TextRight, "NO ROCKETS", { 127, 127, 127, 255 } }); + tCache.m_vText.push_back({ TextRight, "NO ROCKETS", { 127, 127, 127, 255 }, { 0, 0, 0, 255 } }); } } } @@ -521,7 +521,7 @@ void CESP::StoreProjectiles(CTFPlayer* pLocal) if (Vars::ESP::Projectile.Value & Vars::ESP::ProjectileEnum::Distance) { Vec3 vDelta = pEntity->m_vecOrigin() - pLocal->m_vecOrigin(); - tCache.m_vText.push_back({ TextBottom, std::format("[{:.0f}M]", vDelta.Length2D() / 41), Vars::Menu::Theme::Active.Value }); + tCache.m_vText.push_back({ TextBottom, std::format("[{:.0f}M]", vDelta.Length2D() / 41), Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value }); } if (Vars::ESP::Projectile.Value & Vars::ESP::ProjectileEnum::Name) @@ -571,7 +571,7 @@ void CESP::StoreProjectiles(CTFPlayer* pLocal) case ETFClassID::CTFProjectile_EnergyRing: szName = "Energy"; break; //case ETFClassID::CTFProjectile_Syringe: szName = "Syringe"; } - tCache.m_vText.push_back({ TextTop, szName, Vars::Menu::Theme::Active.Value }); + tCache.m_vText.push_back({ TextTop, szName, Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value }); } if (Vars::ESP::Projectile.Value & Vars::ESP::ProjectileEnum::Flags) @@ -599,7 +599,7 @@ void CESP::StoreObjective(CTFPlayer* pLocal) if (Vars::ESP::Objective.Value & Vars::ESP::ObjectiveEnum::Distance) { Vec3 vDelta = pEntity->m_vecOrigin() - pLocal->m_vecOrigin(); - tCache.m_vText.push_back({ TextBottom, std::format("[{:.0f}M]", vDelta.Length2D() / 41), Vars::Menu::Theme::Active.Value }); + tCache.m_vText.push_back({ TextBottom, std::format("[{:.0f}M]", vDelta.Length2D() / 41), Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value }); } switch (pEntity->GetClassID()) @@ -609,27 +609,27 @@ void CESP::StoreObjective(CTFPlayer* pLocal) auto pIntel = pEntity->As(); if (Vars::ESP::Objective.Value & Vars::ESP::ObjectiveEnum::Name) - tCache.m_vText.push_back({ TextTop, "Intel", Vars::Menu::Theme::Active.Value }); + tCache.m_vText.push_back({ TextTop, "Intel", Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value }); if (Vars::ESP::Objective.Value & Vars::ESP::ObjectiveEnum::Flags) { switch (pIntel->m_nFlagStatus()) { case TF_FLAGINFO_HOME: - tCache.m_vText.push_back({ TextRight, "HOME", { 255, 175, 0, 255 } }); + tCache.m_vText.push_back({ TextRight, "HOME", { 255, 175, 0, 255 }, { 0, 0, 0, 255 } }); break; case TF_FLAGINFO_DROPPED: - tCache.m_vText.push_back({ TextRight, "DROPPED", { 255, 175, 0, 255 } }); + tCache.m_vText.push_back({ TextRight, "DROPPED", { 255, 175, 0, 255 }, { 0, 0, 0, 255 } }); break; default: - tCache.m_vText.push_back({ TextRight, std::format("{}", pIntel->m_nFlagStatus()), { 255, 175, 0, 255 } }); + tCache.m_vText.push_back({ TextRight, std::format("{}", pIntel->m_nFlagStatus()), { 255, 175, 0, 255 }, { 0, 0, 0, 255 } }); } } if (Vars::ESP::Objective.Value & Vars::ESP::ObjectiveEnum::IntelReturnTime && pIntel->m_nFlagStatus() == TF_FLAGINFO_DROPPED) { float flReturnTime = std::max(pIntel->m_flResetTime() - TICKS_TO_TIME(I::ClientState->m_ClockDriftMgr.m_nServerTick), 0.f); - tCache.m_vText.push_back({ TextRight, std::format("RETURN {:.1f}S", pIntel->m_flResetTime() - TICKS_TO_TIME(I::ClientState->m_ClockDriftMgr.m_nServerTick)).c_str(), { 255, 175, 0, 255 } }); + tCache.m_vText.push_back({ TextRight, std::format("RETURN {:.1f}S", pIntel->m_flResetTime() - TICKS_TO_TIME(I::ClientState->m_ClockDriftMgr.m_nServerTick)).c_str(), { 255, 175, 0, 255 }, { 0, 0, 0, 255 } }); } break; @@ -656,7 +656,7 @@ void CESP::StoreWorld() case ETFClassID::CEyeballBoss: szName = "Monoculus"; } - tCache.m_vText.push_back({ TextTop, szName, Vars::Colors::NPC.Value }); + tCache.m_vText.push_back({ TextTop, szName, Vars::Colors::NPC.Value, Vars::Menu::Theme::Background.Value }); } } @@ -666,7 +666,7 @@ void CESP::StoreWorld() { WorldCache& tCache = m_mWorldCache[pEntity]; - tCache.m_vText.push_back({ TextTop, "Health", Vars::Colors::Health.Value }); + tCache.m_vText.push_back({ TextTop, "Health", Vars::Colors::Health.Value, Vars::Menu::Theme::Background.Value }); } } @@ -676,7 +676,7 @@ void CESP::StoreWorld() { WorldCache& tCache = m_mWorldCache[pEntity]; - tCache.m_vText.push_back({ TextTop, "Ammo", Vars::Colors::Ammo.Value }); + tCache.m_vText.push_back({ TextTop, "Ammo", Vars::Colors::Ammo.Value, Vars::Menu::Theme::Background.Value }); } } @@ -686,7 +686,7 @@ void CESP::StoreWorld() { WorldCache& tCache = m_mWorldCache[pEntity]; - tCache.m_vText.push_back({ TextTop, "Money", Vars::Colors::Money.Value }); + tCache.m_vText.push_back({ TextTop, "Money", Vars::Colors::Money.Value, Vars::Menu::Theme::Background.Value }); } } @@ -717,7 +717,7 @@ void CESP::StoreWorld() //case FNV1A::Hash32Const("models/pickups/pickup_powerup_uber.mdl"): szName = "16"; break; case FNV1A::Hash32Const("models/pickups/pickup_powerup_vampire.mdl"): szName = "Vampire"; } - tCache.m_vText.push_back({ TextTop, szName, Vars::Colors::Powerup.Value }); + tCache.m_vText.push_back({ TextTop, szName, Vars::Colors::Powerup.Value, Vars::Menu::Theme::Background.Value }); } } @@ -727,7 +727,7 @@ void CESP::StoreWorld() { WorldCache& tCache = m_mWorldCache[pEntity]; - tCache.m_vText.push_back({ TextTop, pEntity->GetClassID() == ETFClassID::CTFPumpkinBomb ? "Pumpkin Bomb" : "Bomb", Vars::Colors::Halloween.Value }); + tCache.m_vText.push_back({ TextTop, pEntity->GetClassID() == ETFClassID::CTFPumpkinBomb ? "Pumpkin Bomb" : "Bomb", Vars::Colors::Halloween.Value, Vars::Menu::Theme::Background.Value }); } } @@ -737,7 +737,7 @@ void CESP::StoreWorld() { WorldCache& tCache = m_mWorldCache[pEntity]; - tCache.m_vText.push_back({ TextTop, "Spellbook", Vars::Colors::Halloween.Value }); + tCache.m_vText.push_back({ TextTop, "Spellbook", Vars::Colors::Halloween.Value, Vars::Menu::Theme::Background.Value }); } } @@ -747,7 +747,7 @@ void CESP::StoreWorld() { WorldCache& tCache = m_mWorldCache[pEntity]; - tCache.m_vText.push_back({ TextTop, "Gargoyle", Vars::Colors::Halloween.Value }); + tCache.m_vText.push_back({ TextTop, "Gargoyle", Vars::Colors::Halloween.Value, Vars::Menu::Theme::Background.Value }); } } } @@ -816,40 +816,40 @@ void CESP::DrawPlayers() bOffset += 5; } - for (auto& [iMode, sText, tColor] : tCache.m_vText) + for (auto& [iMode, sText, tColor, tOutline] : tCache.m_vText) { switch (iMode) { case TextTop: - H::Draw.String(fFont, m, y - tOffset, tColor, ALIGN_BOTTOM, sText.c_str()); + H::Draw.StringOutlined(fFont, m, y - tOffset, tColor, tOutline, ALIGN_BOTTOM, sText.c_str()); tOffset += fFont.m_nTall + 2; break; case TextBottom: - H::Draw.String(fFont, m, b + bOffset, tColor, ALIGN_TOP, sText.c_str()); + H::Draw.StringOutlined(fFont, m, b + bOffset, tColor, tOutline, ALIGN_TOP, sText.c_str()); bOffset += fFont.m_nTall + 2; break; case TextRight: - H::Draw.String(fFont, r, y + rOffset, tColor, ALIGN_TOPLEFT, sText.c_str()); + H::Draw.StringOutlined(fFont, r, y + rOffset, tColor, tOutline, ALIGN_TOPLEFT, sText.c_str()); rOffset += fFont.m_nTall + 2; break; case TextHealth: - H::Draw.String(fFont, x - 5 - lOffset, y + h - h * std::min(tCache.m_flHealth, 1.f) - 2, tColor, ALIGN_TOPRIGHT, sText.c_str()); + H::Draw.StringOutlined(fFont, x - 5 - lOffset, y + h - h * std::min(tCache.m_flHealth, 1.f) - 2, tColor, tOutline, ALIGN_TOPRIGHT, sText.c_str()); break; case TextUber: - H::Draw.String(fFont, x + w + 4, y + h, tColor, ALIGN_TOPLEFT, sText.c_str()); + H::Draw.StringOutlined(fFont, x + w + 4, y + h, tColor, tOutline, ALIGN_TOPLEFT, sText.c_str()); } } if (tCache.m_iClassIcon) { - int size = 18 * Vars::Menu::DPI.Value; + int size = 18 * Vars::Menu::Scale.Value; H::Draw.Texture(x + w / 2, y - tOffset, size, size, tCache.m_iClassIcon, ALIGN_BOTTOM); } if (tCache.m_pWeaponIcon) { const float iw = tCache.m_pWeaponIcon->Width(), ih = tCache.m_pWeaponIcon->Height(); - const float scale = std::clamp(float(w) / std::max(iw, ih * 2), 0.25f, 0.75f) * Vars::Menu::DPI.Value; + const float scale = std::clamp(float(w) / std::max(iw, ih * 2), 0.25f, 0.75f) * Vars::Menu::Scale.Value; H::Draw.DrawHudTexture(x + float(w) / 2.f - iw / 2.f * scale, y + h + 1 + bOffset, scale, tCache.m_pWeaponIcon, Vars::Menu::Theme::Active.Value); } } @@ -884,24 +884,24 @@ void CESP::DrawBuildings() lOffset += 5; } - for (auto& [iMode, sText, tColor] : tCache.m_vText) + for (auto& [iMode, sText, tColor, tOutline] : tCache.m_vText) { switch (iMode) { case TextTop: - H::Draw.String(fFont, m, y - tOffset, tColor, ALIGN_BOTTOM, sText.c_str()); + H::Draw.StringOutlined(fFont, m, y - tOffset, tColor, tOutline, ALIGN_BOTTOM, sText.c_str()); tOffset += fFont.m_nTall + 2; break; case TextBottom: - H::Draw.String(fFont, m, b + bOffset, tColor, ALIGN_TOP, sText.c_str()); + H::Draw.StringOutlined(fFont, m, b + bOffset, tColor, tOutline, ALIGN_TOP, sText.c_str()); bOffset += fFont.m_nTall + 2; break; case TextRight: - H::Draw.String(fFont, r, y + rOffset, tColor, ALIGN_TOPLEFT, sText.c_str()); + H::Draw.StringOutlined(fFont, r, y + rOffset, tColor, tOutline, ALIGN_TOPLEFT, sText.c_str()); rOffset += fFont.m_nTall + 2; break; case TextHealth: - H::Draw.String(fFont, x - 5 - lOffset, y + h - h * std::min(tCache.m_flHealth, 1.f) - 2, tColor, ALIGN_TOPRIGHT, sText.c_str()); + H::Draw.StringOutlined(fFont, x - 5 - lOffset, y + h - h * std::min(tCache.m_flHealth, 1.f) - 2, tColor, tOutline, ALIGN_TOPRIGHT, sText.c_str()); break; } } @@ -927,20 +927,20 @@ void CESP::DrawWorld() if (tCache.m_bBox) H::Draw.LineRectOutline(x, y, w, h, tCache.m_tColor, { 0, 0, 0, 255 }); - for (auto& [iMode, sText, tColor] : tCache.m_vText) + for (auto& [iMode, sText, tColor, tOutline] : tCache.m_vText) { switch (iMode) { case TextTop: - H::Draw.String(fFont, m, y - tOffset, tColor, ALIGN_BOTTOM, sText.c_str()); + H::Draw.StringOutlined(fFont, m, y - tOffset, tColor, tOutline, ALIGN_BOTTOM, sText.c_str()); tOffset += fFont.m_nTall + 2; break; case TextBottom: - H::Draw.String(fFont, m, b + bOffset, tColor, ALIGN_TOP, sText.c_str()); + H::Draw.StringOutlined(fFont, m, b + bOffset, tColor, tOutline, ALIGN_TOP, sText.c_str()); bOffset += fFont.m_nTall + 2; break; case TextRight: - H::Draw.String(fFont, r, y + rOffset, tColor, ALIGN_TOPLEFT, sText.c_str()); + H::Draw.StringOutlined(fFont, r, y + rOffset, tColor, tOutline, ALIGN_TOPLEFT, sText.c_str()); rOffset += fFont.m_nTall + 2; } } diff --git a/Amalgam/src/Features/Visuals/ESP/ESP.h b/Amalgam/src/Features/Visuals/ESP/ESP.h index 6483e112..ecff77e0 100644 --- a/Amalgam/src/Features/Visuals/ESP/ESP.h +++ b/Amalgam/src/Features/Visuals/ESP/ESP.h @@ -13,7 +13,7 @@ enum TextMode struct PlayerCache { float m_flAlpha = 1.f; - std::vector> m_vText = {}; + std::vector> m_vText = {}; Color_t m_tColor = {}; bool m_bBox = false; bool m_bBones = false; @@ -29,7 +29,7 @@ struct PlayerCache struct BuildingCache { float m_flAlpha = 1.f; - std::vector> m_vText = {}; + std::vector> m_vText = {}; Color_t m_tColor = {}; bool m_bBox = false; @@ -40,7 +40,7 @@ struct BuildingCache struct WorldCache { float m_flAlpha = 1.f; - std::vector> m_vText = {}; + std::vector> m_vText = {}; Color_t m_tColor = {}; bool m_bBox = false; }; diff --git a/Amalgam/src/Features/Visuals/Glow/Glow.cpp b/Amalgam/src/Features/Visuals/Glow/Glow.cpp index ca091136..36b1419f 100644 --- a/Amalgam/src/Features/Visuals/Glow/Glow.cpp +++ b/Amalgam/src/Features/Visuals/Glow/Glow.cpp @@ -250,8 +250,8 @@ void CGlow::SetupEnd(Glow_t glow, IMatRenderContext* pRenderContext, IMaterial* } pRenderContext->DrawScreenSpaceRectangle(m_pMatHaloAddToScreen, -side, 0, w, h, 0.f, 0.f, w - 1, h - 1, w, h); pRenderContext->DrawScreenSpaceRectangle(m_pMatHaloAddToScreen, 0, -side, w, h, 0.f, 0.f, w - 1, h - 1, w, h); - pRenderContext->DrawScreenSpaceRectangle(m_pMatHaloAddToScreen, 0, side, w, h, 0.f, 0.f, w - 1, h - 1, w, h); pRenderContext->DrawScreenSpaceRectangle(m_pMatHaloAddToScreen, side, 0, w, h, 0.f, 0.f, w - 1, h - 1, w, h); + pRenderContext->DrawScreenSpaceRectangle(m_pMatHaloAddToScreen, 0, side, w, h, 0.f, 0.f, w - 1, h - 1, w, h); } if (glow.Blur) pRenderContext->DrawScreenSpaceRectangle(m_pMatHaloAddToScreen, 0, 0, w, h, 0.f, 0.f, w - 1, h - 1, w, h); diff --git a/Amalgam/src/Features/Visuals/Notifications/Notifications.cpp b/Amalgam/src/Features/Visuals/Notifications/Notifications.cpp index c0b78c92..d5e17e1d 100644 --- a/Amalgam/src/Features/Visuals/Notifications/Notifications.cpp +++ b/Amalgam/src/Features/Visuals/Notifications/Notifications.cpp @@ -1,5 +1,10 @@ #include "Notifications.h" +static float EaseInOutCubic(float x) +{ + return x < 0.5f ? 4.f * x * x * x : 1 - powf(-2.f * x + 2.f, 3.f) / 2.f; +} + void CNotifications::Add(const std::string& sText, float flLifeTime, float flPanTime) { vNotifications.push_back({ sText, float(SDK::PlatFloatTime()), flLifeTime, flPanTime }); @@ -8,7 +13,7 @@ void CNotifications::Add(const std::string& sText, float flLifeTime, float flPan void CNotifications::Draw() { while (vNotifications.size() > iMaxNotifySize) - vNotifications.erase(vNotifications.begin()); + vNotifications.pop_front(); for (auto it = vNotifications.begin(); it != vNotifications.end();) { @@ -21,28 +26,34 @@ void CNotifications::Draw() if (vNotifications.empty()) return; - int y = 2; + int y = 8; const auto& fFont = H::Fonts.GetFont(FONT_INDICATORS); for (auto& tNotification : vNotifications) { - int x = 2; + int x = 8; int w, h; I::MatSystemSurface->GetTextSize(fFont.m_dwFont, SDK::ConvertUtf8ToWide(tNotification.m_sText).c_str(), w, h); - w += 4; h += 4; + w += 23; h = 32; + float flEase = 0.f; if (float flPan = tNotification.m_flPanTime) { float flTime = SDK::PlatFloatTime(); float flCreate = tNotification.m_flCreateTime; float flLife = std::min(flTime - flCreate, flCreate + tNotification.m_flLifeTime - flTime); if (flLife < flPan) - x -= powf(Math::RemapValClamped(flLife, flPan, 0.f, 0.f, 1.f), 2.f) * w; + { + float flRatio = Math::RemapValClamped(flLife, flPan, 0.f, 0.f, 1.f); + flEase = EaseInOutCubic(flRatio); + x -= (w + 8) * flEase; + } } auto& cAccent = Vars::Menu::Theme::Accent.Value, & cActive = Vars::Menu::Theme::Active.Value, & cBackground = Vars::Menu::Theme::Background.Value; - H::Draw.Line(x, y, x, y + h, { cAccent.r, cAccent.g, cAccent.b, 255 }); - H::Draw.GradientRect(x + 1, y, w, h, { cBackground.r, cBackground.g, cBackground.b, 255 }, { cBackground.r, cBackground.g, cBackground.b, 0 }, true); - H::Draw.String(fFont, x + 6, y + 2, { cActive.r, cActive.g, cActive.b, 255 }, ALIGN_TOPLEFT, tNotification.m_sText.c_str()); + H::Draw.FillRect(x + 1, y + 1, 2, h - 2, { cAccent.r, cAccent.g, cAccent.b, 255 }); + H::Draw.GradientRect(x + 3, y + 1, w - 4, h - 2, { cBackground.r, cBackground.g, cBackground.b, 255 }, { cBackground.r, cBackground.g, cBackground.b, 127 }, true); + H::Draw.LineRect(x, y, w, h, { cBackground.r, cBackground.g, cBackground.b, 255 }); + H::Draw.StringOutlined(fFont, x + 13, y + 9, { cActive.r, cActive.g, cActive.b, 255 }, Vars::Menu::Theme::Background.Value, ALIGN_TOPLEFT, tNotification.m_sText.c_str()); - y += h + 2; + y += (h + 8) * (1.f - flEase); } } \ No newline at end of file diff --git a/Amalgam/src/Features/Visuals/Notifications/Notifications.h b/Amalgam/src/Features/Visuals/Notifications/Notifications.h index e1e67978..77b23b8e 100644 --- a/Amalgam/src/Features/Visuals/Notifications/Notifications.h +++ b/Amalgam/src/Features/Visuals/Notifications/Notifications.h @@ -11,11 +11,11 @@ struct Notification_t class CNotifications { - std::vector vNotifications; + std::deque vNotifications; unsigned iMaxNotifySize = 10; public: - void Add(const std::string& sText, float flLifeTime = Vars::Logging::Lifetime.Value, float flPanTime = 0.1f); + void Add(const std::string& sText, float flLifeTime = Vars::Logging::Lifetime.Value, float flPanTime = 0.2f); void Draw(); }; diff --git a/Amalgam/src/Features/Visuals/PlayerArrows/PlayerArrows.cpp b/Amalgam/src/Features/Visuals/PlayerArrows/PlayerArrows.cpp index 0db863f5..f01c5af0 100644 --- a/Amalgam/src/Features/Visuals/PlayerArrows/PlayerArrows.cpp +++ b/Amalgam/src/Features/Visuals/PlayerArrows/PlayerArrows.cpp @@ -65,12 +65,10 @@ void CPlayerArrows::DrawArrowTo(const Vec3& vecFromPos, const Vec3& vecToPos, Co const float _cos = cos(deg); const float _sin = sin(deg); - Vertex_t t1, t2, t3; - t1.Init({ cx + p1.x * _cos - p1.y * _sin, cy + p1.y * _cos + p1.x * _sin }); - t2.Init({ cx + p2.x * _cos - p2.y * _sin, cy + p2.y * _cos + p2.x * _sin }); - t3.Init({ cx + p3.x * _cos - p3.y * _sin, cy + p3.y * _cos + p3.x * _sin }); - std::array verts{ t1, t2, t3 }; - H::Draw.Polygon(3, verts.data(), color); + Vertex_t t1 = { { cx + p1.x * _cos - p1.y * _sin, cy + p1.y * _cos + p1.x * _sin } }; + Vertex_t t2 = { { cx + p2.x * _cos - p2.y * _sin, cy + p2.y * _cos + p2.x * _sin } }; + Vertex_t t3 = { { cx + p3.x * _cos - p3.y * _sin, cy + p3.y * _cos + p3.x * _sin } }; + H::Draw.FillPolygon({ t1, t2, t3 }, color); } void CPlayerArrows::Run(CTFPlayer* pLocal) diff --git a/Amalgam/src/Features/Visuals/Radar/Radar.cpp b/Amalgam/src/Features/Visuals/Radar/Radar.cpp index 440b53c5..55e03488 100644 --- a/Amalgam/src/Features/Visuals/Radar/Radar.cpp +++ b/Amalgam/src/Features/Visuals/Radar/Radar.cpp @@ -363,7 +363,7 @@ void CRadar::DrawPoints(CTFPlayer* pLocal) const int iOffset = z < 0 ? -5 : 5; const int yPos = z < 0 ? y - iBounds / 2 - 2 : y + iBounds / 2 + 2; - H::Draw.DrawFillTriangle({ Vec2(m, yPos), Vec2(m + iSize * 0.5f, yPos + iOffset), Vec2(m + iSize, yPos) }, drawColor); + H::Draw.FillPolygon({ Vec2(m, yPos), Vec2(m + iSize * 0.5f, yPos + iOffset), Vec2(m + iSize, yPos) }, drawColor); } } } diff --git a/Amalgam/src/Features/Visuals/SpectatorList/SpectatorList.cpp b/Amalgam/src/Features/Visuals/SpectatorList/SpectatorList.cpp index f92efff2..122a1dc4 100644 --- a/Amalgam/src/Features/Visuals/SpectatorList/SpectatorList.cpp +++ b/Amalgam/src/Features/Visuals/SpectatorList/SpectatorList.cpp @@ -76,15 +76,15 @@ void CSpectatorList::Run(CTFPlayer* pLocal) int y = Vars::Menu::SpectatorsDisplay.Value.y + 8; EAlign align = ALIGN_TOP; - if (x <= (100 + 50 * Vars::Menu::DPI.Value)) + if (x <= (100 + 50 * Vars::Menu::Scale.Value)) { // iconOffset = 36; - x -= 42 * Vars::Menu::DPI.Value; + x -= 42 * Vars::Menu::Scale.Value; align = ALIGN_TOPLEFT; } - else if (x >= H::Draw.m_nScreenW - (100 + 50 * Vars::Menu::DPI.Value)) + else if (x >= H::Draw.m_nScreenW - (100 + 50 * Vars::Menu::Scale.Value)) { - x += 42 * Vars::Menu::DPI.Value; + x += 42 * Vars::Menu::Scale.Value; align = ALIGN_TOPRIGHT; } //else @@ -95,7 +95,7 @@ void CSpectatorList::Run(CTFPlayer* pLocal) const auto& fFont = H::Fonts.GetFont(FONT_INDICATORS); - H::Draw.String(fFont, x, y, Vars::Menu::Theme::Accent.Value, align, "Spectating You:"); + H::Draw.StringOutlined(fFont, x, y, Vars::Menu::Theme::Accent.Value, Vars::Menu::Theme::Background.Value, align, "Spectating You:"); for (auto& Spectator : m_vSpectators) { y += fFont.m_nTall + 3; @@ -129,6 +129,6 @@ void CSpectatorList::Run(CTFPlayer* pLocal) color = { 255, 100, 100, 255 }; else if (FNV1A::Hash32(Spectator.m_sMode.c_str()) == FNV1A::Hash32Const("1st")) color = { 255, 200, 127, 255 }; - H::Draw.String(fFont, x + iconOffset, y, color, align, "%s - %s (respawn %ds)", Spectator.m_sName.c_str(), Spectator.m_sMode.c_str(), Spectator.m_iRespawnIn); + H::Draw.StringOutlined(fFont, x + iconOffset, y, color, Vars::Menu::Theme::Background.Value, align, "%s - %s (respawn %ds)", Spectator.m_sName.c_str(), Spectator.m_sMode.c_str(), Spectator.m_iRespawnIn); } } diff --git a/Amalgam/src/Features/Visuals/Visuals.cpp b/Amalgam/src/Features/Visuals/Visuals.cpp index 46ca1b9a..95a1441a 100644 --- a/Amalgam/src/Features/Visuals/Visuals.cpp +++ b/Amalgam/src/Features/Visuals/Visuals.cpp @@ -44,20 +44,20 @@ void CVisuals::DrawTicks(CTFPlayer* pLocal) const auto& fFont = H::Fonts.GetFont(FONT_INDICATORS); int iTicks = G::ShiftedTicks + G::ChokeAmount; - int iOffset = 7 + 12 * Vars::Menu::DPI.Value; + int iOffset = 7 + 12 * Vars::Menu::Scale.Value; float flRatio = float(std::clamp(iTicks, 0, G::MaxShift)) / G::MaxShift; - float flSizeX = 100 * Vars::Menu::DPI.Value, flSizeY = 12 * Vars::Menu::DPI.Value, flPosX = dtPos.x - flSizeX / 2, flPosY = dtPos.y + 5 + fFont.m_nTall; + float flSizeX = 100 * Vars::Menu::Scale.Value, flSizeY = 12 * Vars::Menu::Scale.Value, flPosX = dtPos.x - flSizeX / 2, flPosY = dtPos.y + 5 + fFont.m_nTall; - H::Draw.String(fFont, dtPos.x, dtPos.y + 2, Vars::Menu::Theme::Active.Value, ALIGN_TOP, "Ticks %d / %d", iTicks, G::MaxShift); + H::Draw.StringOutlined(fFont, dtPos.x, dtPos.y + 2, Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value, ALIGN_TOP, "Ticks %d / %d", iTicks, G::MaxShift); if (G::WaitForShift) - H::Draw.String(fFont, dtPos.x, dtPos.y + fFont.m_nTall + iOffset, Vars::Menu::Theme::Active.Value, ALIGN_TOP, "Not Ready"); + H::Draw.StringOutlined(fFont, dtPos.x, dtPos.y + fFont.m_nTall + iOffset, Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value, ALIGN_TOP, "Not Ready"); - H::Draw.LineRect(flPosX, dtPos.y + 5 + fFont.m_nTall, flSizeX, flSizeY, Vars::Menu::Theme::Accent.Value); + H::Draw.LineRoundRect(flPosX, dtPos.y + 5 + fFont.m_nTall, flSizeX, flSizeY, 3 * Vars::Menu::Scale.Value, Vars::Menu::Theme::Accent.Value, 16); if (flRatio) { - flSizeX -= 4, flSizeY -= 4, flPosX = dtPos.x - flSizeX / 2; - H::Draw.StartClipping(flPosX, flPosY, flSizeX * flRatio, flSizeY + 2 /*?*/); - H::Draw.FillRect(flPosX, flPosY + 2, flSizeX, flSizeY, Vars::Menu::Theme::Accent.Value); + flSizeX -= 4, flSizeY -= 4, flPosX = dtPos.x - flSizeX / 2, flPosY += 2; + H::Draw.StartClipping(flPosX, flPosY, flSizeX * flRatio, flSizeY); + H::Draw.FillRoundRect(flPosX, flPosY, flSizeX, flSizeY, 3 * Vars::Menu::Scale.Value, Vars::Menu::Theme::Accent.Value, 16); H::Draw.EndClipping(); } } @@ -89,22 +89,22 @@ void CVisuals::DrawOnScreenPing(CTFPlayer* pLocal) const auto& fFont = H::Fonts.GetFont(FONT_INDICATORS); EAlign align = ALIGN_TOP; - if (x <= (100 + 50 * Vars::Menu::DPI.Value)) + if (x <= (100 + 50 * Vars::Menu::Scale.Value)) { - x -= 42 * Vars::Menu::DPI.Value; + x -= 42 * Vars::Menu::Scale.Value; align = ALIGN_TOPLEFT; } - else if (x >= H::Draw.m_nScreenW - (100 + 50 * Vars::Menu::DPI.Value)) + else if (x >= H::Draw.m_nScreenW - (100 + 50 * Vars::Menu::Scale.Value)) { - x += 42 * Vars::Menu::DPI.Value; + x += 42 * Vars::Menu::Scale.Value; align = ALIGN_TOPRIGHT; } if (flFake || Vars::Backtrack::Interp.Value && Vars::Backtrack::Enabled.Value) - H::Draw.String(fFont, x, y, Vars::Menu::Theme::Active.Value, align, "Real %.0f (+ %.0f) ms", flLatency, flFake); + H::Draw.StringOutlined(fFont, x, y, Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value, align, "Real %.0f (+ %.0f) ms", flLatency, flFake); else - H::Draw.String(fFont, x, y, Vars::Menu::Theme::Active.Value, align, "Real %.0f ms", flLatency); - H::Draw.String(fFont, x, y += fFont.m_nTall + 1, Vars::Menu::Theme::Active.Value, align, "Scoreboard %d ms", iLatencyScoreboard); + H::Draw.StringOutlined(fFont, x, y, Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value, align, "Real %.0f ms", flLatency); + H::Draw.StringOutlined(fFont, x, y += fFont.m_nTall + 1, Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value, align, "Scoreboard %d ms", iLatencyScoreboard); } void CVisuals::DrawOnScreenConditions(CTFPlayer* pLocal) @@ -117,14 +117,14 @@ void CVisuals::DrawOnScreenConditions(CTFPlayer* pLocal) const auto& fFont = H::Fonts.GetFont(FONT_INDICATORS); EAlign align = ALIGN_TOP; - if (x <= (100 + 50 * Vars::Menu::DPI.Value)) + if (x <= (100 + 50 * Vars::Menu::Scale.Value)) { - x -= 42 * Vars::Menu::DPI.Value; + x -= 42 * Vars::Menu::Scale.Value; align = ALIGN_TOPLEFT; } - else if (x >= H::Draw.m_nScreenW - (100 + 50 * Vars::Menu::DPI.Value)) + else if (x >= H::Draw.m_nScreenW - (100 + 50 * Vars::Menu::Scale.Value)) { - x += 42 * Vars::Menu::DPI.Value; + x += 42 * Vars::Menu::Scale.Value; align = ALIGN_TOPRIGHT; } @@ -133,7 +133,7 @@ void CVisuals::DrawOnScreenConditions(CTFPlayer* pLocal) int offset = 0; for (const std::wstring& cond : conditionsVec) { - H::Draw.String(fFont, x, y + offset, Vars::Menu::Theme::Active.Value, align, cond.data()); + H::Draw.StringOutlined(fFont, x, y + offset, Vars::Menu::Theme::Active.Value, Vars::Menu::Theme::Background.Value, align, cond.data()); offset += fFont.m_nTall + 1; } } @@ -154,21 +154,21 @@ void CVisuals::DrawSeedPrediction(CTFPlayer* pLocal) const auto& fFont = H::Fonts.GetFont(FONT_INDICATORS); EAlign align = ALIGN_TOP; - if (x <= (100 + 50 * Vars::Menu::DPI.Value)) + if (x <= (100 + 50 * Vars::Menu::Scale.Value)) { - x -= 42 * Vars::Menu::DPI.Value; + x -= 42 * Vars::Menu::Scale.Value; align = ALIGN_TOPLEFT; } - else if (x >= H::Draw.m_nScreenW - (100 + 50 * Vars::Menu::DPI.Value)) + else if (x >= H::Draw.m_nScreenW - (100 + 50 * Vars::Menu::Scale.Value)) { - x += 42 * Vars::Menu::DPI.Value; + x += 42 * Vars::Menu::Scale.Value; align = ALIGN_TOPRIGHT; } const auto& cColor = F::NoSpreadHitscan.bSynced ? Vars::Menu::Theme::Active.Value : Vars::Menu::Theme::Inactive.Value; - H::Draw.String(fFont, x, y, cColor, align, std::format("Uptime {}", F::NoSpreadHitscan.GetFormat(F::NoSpreadHitscan.flServerTime)).c_str()); - H::Draw.String(fFont, x, y += fFont.m_nTall + 1, cColor, align, std::format("Mantissa step {}", F::NoSpreadHitscan.flMantissaStep).c_str()); + H::Draw.StringOutlined(fFont, x, y, cColor, Vars::Menu::Theme::Background.Value, align, std::format("Uptime {}", F::NoSpreadHitscan.GetFormat(F::NoSpreadHitscan.flServerTime)).c_str()); + H::Draw.StringOutlined(fFont, x, y += fFont.m_nTall + 1, cColor, Vars::Menu::Theme::Background.Value, align, std::format("Mantissa step {}", F::NoSpreadHitscan.flMantissaStep).c_str()); } std::deque SplashTrace(Vec3 vOrigin, float flRadius, Vec3 vNormal = { 0, 0, 1 }, bool bTrace = true, int iSegments = 32) @@ -488,23 +488,23 @@ void CVisuals::DrawDebugInfo(CTFPlayer* pLocal) if (pCmd) { - H::Draw.String(fFont, x, y += fFont.m_nTall + 1, {}, ALIGN_TOPLEFT, "View: (%.3f, %.3f, %.3f)", pCmd->viewangles.x, pCmd->viewangles.y, pCmd->viewangles.z); - H::Draw.String(fFont, x, y += fFont.m_nTall + 1, {}, ALIGN_TOPLEFT, "Move: (%.0f, %.0f, %.0f)", pCmd->forwardmove, pCmd->sidemove, pCmd->upmove); - H::Draw.String(fFont, x, y += fFont.m_nTall + 1, {}, ALIGN_TOPLEFT, "Buttons: %i", pCmd->buttons); + H::Draw.StringOutlined(fFont, x, y += fFont.m_nTall + 1, {}, { 0, 0, 0, 255 }, ALIGN_TOPLEFT, "View: (%.3f, %.3f, %.3f)", pCmd->viewangles.x, pCmd->viewangles.y, pCmd->viewangles.z); + H::Draw.StringOutlined(fFont, x, y += fFont.m_nTall + 1, {}, { 0, 0, 0, 255 }, ALIGN_TOPLEFT, "Move: (%.0f, %.0f, %.0f)", pCmd->forwardmove, pCmd->sidemove, pCmd->upmove); + H::Draw.StringOutlined(fFont, x, y += fFont.m_nTall + 1, {}, { 0, 0, 0, 255 }, ALIGN_TOPLEFT, "Buttons: %i", pCmd->buttons); } { Vec3 vOrigin = pLocal->m_vecOrigin(); - H::Draw.String(fFont, x, y += fFont.m_nTall + 1, {}, ALIGN_TOPLEFT, "Origin: (%.3f, %.3f, %.3f)", vOrigin.x, vOrigin.y, vOrigin.z); + H::Draw.StringOutlined(fFont, x, y += fFont.m_nTall + 1, {}, { 0, 0, 0, 255 }, ALIGN_TOPLEFT, "Origin: (%.3f, %.3f, %.3f)", vOrigin.x, vOrigin.y, vOrigin.z); } { Vec3 vVelocity = pLocal->m_vecVelocity(); - H::Draw.String(fFont, x, y += fFont.m_nTall + 1, {}, ALIGN_TOPLEFT, "Velocity: %.3f (%.3f, %.3f, %.3f)", vVelocity.Length(), vVelocity.x, vVelocity.y, vVelocity.z); + H::Draw.StringOutlined(fFont, x, y += fFont.m_nTall + 1, {}, { 0, 0, 0, 255 }, ALIGN_TOPLEFT, "Velocity: %.3f (%.3f, %.3f, %.3f)", vVelocity.Length(), vVelocity.x, vVelocity.y, vVelocity.z); } - H::Draw.String(fFont, x, y += fFont.m_nTall + 1, {}, ALIGN_TOPLEFT, std::format("Choke: {}, {}", G::Choking, I::ClientState->chokedcommands).c_str()); - H::Draw.String(fFont, x, y += fFont.m_nTall + 1, {}, ALIGN_TOPLEFT, std::format("Ticks: {}, {}", G::ShiftedTicks, G::ShiftedGoal).c_str()); - H::Draw.String(fFont, x, y += fFont.m_nTall + 1, {}, ALIGN_TOPLEFT, "Round state: %i", SDK::GetRoundState()); - H::Draw.String(fFont, x, y += fFont.m_nTall + 1, {}, ALIGN_TOPLEFT, "Tickcount: %i", pLocal->m_nTickBase()); - H::Draw.String(fFont, x, y += fFont.m_nTall + 1, {}, ALIGN_TOPLEFT, "Entities: %i (%i, %i)", I::ClientEntityList->GetMaxEntities(), I::ClientEntityList->GetHighestEntityIndex(), I::ClientEntityList->NumberOfEntities(false)); + H::Draw.StringOutlined(fFont, x, y += fFont.m_nTall + 1, {}, { 0, 0, 0, 255 }, ALIGN_TOPLEFT, std::format("Choke: {}, {}", G::Choking, I::ClientState->chokedcommands).c_str()); + H::Draw.StringOutlined(fFont, x, y += fFont.m_nTall + 1, {}, { 0, 0, 0, 255 }, ALIGN_TOPLEFT, std::format("Ticks: {}, {}", G::ShiftedTicks, G::ShiftedGoal).c_str()); + H::Draw.StringOutlined(fFont, x, y += fFont.m_nTall + 1, {}, { 0, 0, 0, 255 }, ALIGN_TOPLEFT, "Round state: %i", SDK::GetRoundState()); + H::Draw.StringOutlined(fFont, x, y += fFont.m_nTall + 1, {}, { 0, 0, 0, 255 }, ALIGN_TOPLEFT, "Tickcount: %i", pLocal->m_nTickBase()); + H::Draw.StringOutlined(fFont, x, y += fFont.m_nTall + 1, {}, { 0, 0, 0, 255 }, ALIGN_TOPLEFT, "Entities: %i (%i, %i)", I::ClientEntityList->GetMaxEntities(), I::ClientEntityList->GetHighestEntityIndex(), I::ClientEntityList->NumberOfEntities(false)); if (!pWeapon || !pCmd) return; @@ -514,11 +514,11 @@ void CVisuals::DrawDebugInfo(CTFPlayer* pLocal) float flSecondaryAttack = pWeapon->m_flNextSecondaryAttack(); float flAttack = pLocal->m_flNextAttack(); - H::Draw.String(fFont, x, y += (fFont.m_nTall + 1) * 2, {}, ALIGN_TOPLEFT, std::format("Attacking: {} ({})", G::Attacking, bool(pCmd->buttons & IN_ATTACK)).c_str()); - H::Draw.String(fFont, x, y += fFont.m_nTall + 1, {}, ALIGN_TOPLEFT, std::format("CanPrimaryAttack: {} ([{:.3f} | {:.3f}] <= {:.3f})", G::CanPrimaryAttack, flPrimaryAttack, flAttack, flTime).c_str()); - H::Draw.String(fFont, x, y += fFont.m_nTall + 1, {}, ALIGN_TOPLEFT, std::format("CanSecondaryAttack: {} ([{:.3f} | {:.3f}] <= {:.3f})", G::CanSecondaryAttack, flSecondaryAttack, flAttack, flTime).c_str()); - H::Draw.String(fFont, x, y += fFont.m_nTall + 1, {}, ALIGN_TOPLEFT, std::format("Attack: {:.3f}, {:.3f}; {:.3f}", flTime - flPrimaryAttack, flTime - flSecondaryAttack, flTime - flAttack).c_str()); - H::Draw.String(fFont, x, y += fFont.m_nTall + 1, {}, ALIGN_TOPLEFT, std::format("Reload: {} ({} || {} != 0)", G::Reloading, pWeapon->m_bInReload(), pWeapon->m_iReloadMode()).c_str()); + H::Draw.StringOutlined(fFont, x, y += (fFont.m_nTall + 1) * 2, {}, { 0, 0, 0, 255 }, ALIGN_TOPLEFT, std::format("Attacking: {} ({})", G::Attacking, bool(pCmd->buttons & IN_ATTACK)).c_str()); + H::Draw.StringOutlined(fFont, x, y += fFont.m_nTall + 1, {}, { 0, 0, 0, 255 }, ALIGN_TOPLEFT, std::format("CanPrimaryAttack: {} ([{:.3f} | {:.3f}] <= {:.3f})", G::CanPrimaryAttack, flPrimaryAttack, flAttack, flTime).c_str()); + H::Draw.StringOutlined(fFont, x, y += fFont.m_nTall + 1, {}, { 0, 0, 0, 255 }, ALIGN_TOPLEFT, std::format("CanSecondaryAttack: {} ([{:.3f} | {:.3f}] <= {:.3f})", G::CanSecondaryAttack, flSecondaryAttack, flAttack, flTime).c_str()); + H::Draw.StringOutlined(fFont, x, y += fFont.m_nTall + 1, {}, { 0, 0, 0, 255 }, ALIGN_TOPLEFT, std::format("Attack: {:.3f}, {:.3f}; {:.3f}", flTime - flPrimaryAttack, flTime - flSecondaryAttack, flTime - flAttack).c_str()); + H::Draw.StringOutlined(fFont, x, y += fFont.m_nTall + 1, {}, { 0, 0, 0, 255 }, ALIGN_TOPLEFT, std::format("Reload: {} ({} || {} != 0)", G::Reloading, pWeapon->m_bInReload(), pWeapon->m_iReloadMode()).c_str()); } } @@ -820,7 +820,7 @@ void CVisuals::PickupTimers() Vec3 vScreen; if (SDK::W2S(pickupData->Location, vScreen)) - H::Draw.String(H::Fonts.GetFont(FONT_ESP), vScreen.x, vScreen.y, color, ALIGN_CENTER, timerText.c_str()); + H::Draw.StringOutlined(H::Fonts.GetFont(FONT_ESP), vScreen.x, vScreen.y, color, Vars::Menu::Theme::Background.Value, ALIGN_CENTER, timerText.c_str()); ++pickupData; } diff --git a/Amalgam/src/Hooks/IEngineVGui_Paint.cpp b/Amalgam/src/Hooks/IEngineVGui_Paint.cpp index 79a44e7f..0e61d2b9 100644 --- a/Amalgam/src/Hooks/IEngineVGui_Paint.cpp +++ b/Amalgam/src/Hooks/IEngineVGui_Paint.cpp @@ -21,7 +21,7 @@ void Paint() // dumb FUCKN+IG CHeck for fonts int w = 0, h = 0; I::MatSystemSurface->GetTextSize(H::Fonts.GetFont(FONT_ESP).m_dwFont, L"", w, h); if (!h) - H::Fonts.Reload(Vars::Menu::DPI.Map[DEFAULT_BIND]); + H::Fonts.Reload(Vars::Menu::Scale.Map[DEFAULT_BIND]); F::Notifications.Draw(); diff --git a/Amalgam/src/SDK/Helpers/Draw/Draw.cpp b/Amalgam/src/SDK/Helpers/Draw/Draw.cpp index 951e009a..b0ce36ce 100644 --- a/Amalgam/src/SDK/Helpers/Draw/Draw.cpp +++ b/Amalgam/src/SDK/Helpers/Draw/Draw.cpp @@ -1,5 +1,6 @@ #include "Draw.h" +#include "../../Vars.h" #include "Icons.h" #include "../../Definitions/Interfaces.h" #include "../../../Utils/Math/Math.h" @@ -28,6 +29,11 @@ void CDraw::UpdateW2SMatrix() } } +bool CDraw::IsColorBright(const Color_t& clr) +{ + return clr.r + clr.g + clr.b > 510; +} + void CDraw::String(const Font_t& font, int x, int y, const Color_t& clr, const EAlign& align, const char* str, ...) { if (str == nullptr) @@ -98,12 +104,113 @@ void CDraw::String(const Font_t& font, int x, int y, const Color_t& clr, const E I::MatSystemSurface->DrawPrintText(wstr, int(wcslen(wstr))); } -void CDraw::Line(int x, int y, int x1, int y1, const Color_t& clr) +void CDraw::StringOutlined(const Font_t& font, int x, int y, const Color_t& clr, const Color_t& out, const EAlign& align, const char* str, ...) +{ + if (str == nullptr) + return; + + va_list va_alist; + char cbuffer[1024] = { '\0' }; + wchar_t wstr[1024] = { '\0' }; + + va_start(va_alist, str); + vsprintf_s(cbuffer, str, va_alist); + va_end(va_alist); + + wsprintfW(wstr, L"%hs", cbuffer); + + const auto dwFont = font.m_dwFont; + + int w = 0, h = 0; I::MatSystemSurface->GetTextSize(dwFont, wstr, w, h); + switch (align) + { + case ALIGN_TOPLEFT: break; + case ALIGN_TOP: x -= w / 2; break; + case ALIGN_TOPRIGHT: x -= w; break; + case ALIGN_LEFT: y -= h / 2; break; + case ALIGN_CENTER: x -= w / 2; y -= h / 2; break; + case ALIGN_RIGHT: x -= w; y -= h / 2; break; + case ALIGN_BOTTOMLEFT: y -= h; break; + case ALIGN_BOTTOM: x -= w / 2; y -= h; break; + case ALIGN_BOTTOMRIGHT: x -= w; y -= h; break; + } + + auto outline = out; + std::vector> vOutline = { { 1, 1 } }; + if (!Vars::Menu::CheapText.Value) + { + vOutline = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, -1 }, { 1, 1 }, { -1, 1 }, { 1, -1 } }; + outline.a /= 2; + } + for (auto& [x2, y2] : vOutline) + { + I::MatSystemSurface->DrawSetTextPos(x + x2, y + y2); + I::MatSystemSurface->DrawSetTextFont(dwFont); + I::MatSystemSurface->DrawSetTextColor(outline.r, outline.g, outline.b, outline.a); + I::MatSystemSurface->DrawPrintText(wstr, int(wcslen(wstr))); + } + + I::MatSystemSurface->DrawSetTextPos(x, y); + I::MatSystemSurface->DrawSetTextFont(dwFont); + I::MatSystemSurface->DrawSetTextColor(clr.r, clr.g, clr.b, clr.a); + I::MatSystemSurface->DrawPrintText(wstr, int(wcslen(wstr))); +} +void CDraw::StringOutlined(const Font_t& font, int x, int y, const Color_t& clr, const Color_t& out, const EAlign& align, const wchar_t* str, ...) +{ + if (str == nullptr) + return; + + va_list va_alist; + wchar_t wstr[1024] = { '\0' }; + + va_start(va_alist, str); + vswprintf_s(wstr, str, va_alist); + va_end(va_alist); + + const auto dwFont = font.m_dwFont; + + int w = 0, h = 0; I::MatSystemSurface->GetTextSize(dwFont, wstr, w, h); + switch (align) + { + case ALIGN_TOPLEFT: break; + case ALIGN_TOP: x -= w / 2; break; + case ALIGN_TOPRIGHT: x -= w; break; + case ALIGN_LEFT: y -= h / 2; break; + case ALIGN_CENTER: x -= w / 2; y -= h / 2; break; + case ALIGN_RIGHT: x -= w; y -= h / 2; break; + case ALIGN_BOTTOMLEFT: y -= h; break; + case ALIGN_BOTTOM: x -= w / 2; y -= h; break; + case ALIGN_BOTTOMRIGHT: x -= w; y -= h; break; + } + + auto outline = out; + std::vector> vOutline = { { 1, 1 } }; + if (!Vars::Menu::CheapText.Value) + { + vOutline = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, -1 }, { 1, 1 }, { -1, 1 }, { 1, -1 } }; + outline.a /= 2; + } + for (auto& [x2, y2] : vOutline) + { + I::MatSystemSurface->DrawSetTextPos(x + x2, y + y2); + I::MatSystemSurface->DrawSetTextFont(dwFont); + I::MatSystemSurface->DrawSetTextColor(outline.r, outline.g, outline.b, outline.a); + I::MatSystemSurface->DrawPrintText(wstr, int(wcslen(wstr))); + } + + I::MatSystemSurface->DrawSetTextPos(x, y); + I::MatSystemSurface->DrawSetTextFont(dwFont); + I::MatSystemSurface->DrawSetTextColor(clr.r, clr.g, clr.b, clr.a); + I::MatSystemSurface->DrawPrintText(wstr, int(wcslen(wstr))); +} + +void CDraw::Line(int x1, int y1, int x2, int y2, const Color_t& clr) { I::MatSystemSurface->DrawSetColor(clr.r, clr.g, clr.b, clr.a); - I::MatSystemSurface->DrawLine(x, y, x1, y1); + I::MatSystemSurface->DrawLine(x1, y1, x2, y2); } -void CDraw::Polygon(int count, Vertex_t* vertices, const Color_t& clr) + +void CDraw::FillPolygon(std::vector vertices, const Color_t& clr) { static int id = 0; if (!I::MatSystemSurface->IsTextureIDValid(id)) @@ -111,19 +218,17 @@ void CDraw::Polygon(int count, Vertex_t* vertices, const Color_t& clr) I::MatSystemSurface->DrawSetColor(clr.r, clr.g, clr.b, clr.a); I::MatSystemSurface->DrawSetTexture(id); - I::MatSystemSurface->DrawTexturedPolygon(count, vertices); + I::MatSystemSurface->DrawTexturedPolygon(int(vertices.size()), vertices.data()); } +void CDraw::LinePolygon(std::vector vertices, const Color_t& clr) +{ + static int id = 0; + if (!I::MatSystemSurface->IsTextureIDValid(id)) + id = I::MatSystemSurface->CreateNewTextureID(); -void CDraw::DrawFillTriangle(const std::array& points, const Color_t& clr) -{ - std::array vertices{ Vertex_t(points.at(0)), Vertex_t(points.at(1)), Vertex_t(points.at(2)) }; - Polygon(3, vertices.data(), clr); -} -void CDraw::DrawLineTriangle(const std::array& points, const Color_t& clr) -{ - Line(points.at(0).x, points.at(0).y, points.at(1).x, points.at(1).y, clr); - Line(points.at(1).x, points.at(1).y, points.at(2).x, points.at(2).y, clr); - Line(points.at(2).x, points.at(2).y, points.at(0).x, points.at(0).y, clr); + I::MatSystemSurface->DrawSetColor(clr.r, clr.g, clr.b, clr.a); + I::MatSystemSurface->DrawSetTexture(id); + I::MatSystemSurface->DrawTexturedPolyLine(vertices.data(), int(vertices.size())); } void CDraw::FillRect(int x, int y, int w, int h, const Color_t& clr) @@ -171,37 +276,59 @@ void CDraw::FillRectPercent(int x, int y, int w, int h, float t, const Color_t& FillRect(x - 1, y - 1, nw + 2, nh + 2, out); FillRect(x, y, nw, nh, clr); } -void CDraw::RoundRect(int x, int y, int w, int h, int radius, const Color_t& clr) +void CDraw::FillRoundRect(int x, int y, int w, int h, int radius, const Color_t& clr, int iCount) { - Vertex_t roundsquare[64]; + std::vector vertices = {}; + int _iCount = iCount / 4; + float flDelta = 90.f / _iCount; for (int i = 0; i < 4; i++) { const int _x = x + ((i < 2) ? (w - radius) : radius); const int _y = y + ((i % 3) ? (h - radius) : radius); const float a = 90.f * i; - - for (int j = 0; j < 16; j++) + for (int j = 0; j <= _iCount; j++) { - const float _a = DEG2RAD(a + j * 6.f); - - roundsquare[(i * 16) + j] = Vertex_t(Vector2D(_x + radius * sin(_a), _y - radius * cos(_a))); + const float _a = DEG2RAD(a + j * flDelta); + vertices.emplace_back(Vertex_t({ { _x + radius * sinf(_a), _y - radius * cosf(_a) } })); } } - Polygon(64, roundsquare, clr); + FillPolygon(vertices, clr); +} +void CDraw::LineRoundRect(int x, int y, int w, int h, int radius, const Color_t& clr, int iCount) +{ + std::vector vertices = {}; + + w -= 1, h -= 1; + int _iCount = iCount / 4; + float flDelta = 90.f / _iCount; + for (int i = 0; i < 4; i++) + { + const int _x = x + ((i < 2) ? (w - radius) : radius); + const int _y = y + ((i % 3) ? (h - radius) : radius); + + const float a = 90.f * i; + for (int j = 0; j <= _iCount; j++) + { + const float _a = DEG2RAD(a + j * flDelta); + vertices.emplace_back(Vertex_t({ { _x + radius * sinf(_a), _y - radius * cosf(_a) } })); + } + } + + LinePolygon(vertices, clr); } void CDraw::FillCircle(int x, int y, float radius, int segments, const Color_t clr) { - static std::vector vertices = {}; + std::vector vertices = {}; const float step = static_cast(PI) * 2.0f / segments; for (float a = 0; a < PI * 2.0f; a += step) - vertices.emplace_back(Vertex_t{ { radius * cosf(a) + x, radius * sinf(a) + y } }); + vertices.emplace_back(Vertex_t({ radius * cosf(a) + x, radius * sinf(a) + y })); - Polygon(segments, vertices.data(), clr); + FillPolygon(vertices, clr); vertices.clear(); } diff --git a/Amalgam/src/SDK/Helpers/Draw/Draw.h b/Amalgam/src/SDK/Helpers/Draw/Draw.h index 2f54b713..a3da949a 100644 --- a/Amalgam/src/SDK/Helpers/Draw/Draw.h +++ b/Amalgam/src/SDK/Helpers/Draw/Draw.h @@ -23,14 +23,16 @@ public: void UpdateScreenSize(); void UpdateW2SMatrix(); + bool IsColorBright(const Color_t& clr); + void String(const Font_t& font, int x, int y, const Color_t& clr, const EAlign& align, const char* str, ...); void String(const Font_t& font, int x, int y, const Color_t& clr, const EAlign& align, const wchar_t* str, ...); + void StringOutlined(const Font_t& font, int x, int y, const Color_t& clr, const Color_t& out, const EAlign& align, const char* str, ...); + void StringOutlined(const Font_t& font, int x, int y, const Color_t& clr, const Color_t& out, const EAlign& align, const wchar_t* str, ...); - void Line(int x, int y, int x1, int y1, const Color_t& clr); - void Polygon(int count, Vertex_t* vertices, const Color_t& clr); - - void DrawFillTriangle(const std::array& points, const Color_t& clr); - void DrawLineTriangle(const std::array& points, const Color_t& clr); + void Line(int x1, int y1, int x2, int y2, const Color_t& clr); + void FillPolygon(std::vector vertices, const Color_t& clr); + void LinePolygon(std::vector vertices, const Color_t& clr); void FillRect(int x, int y, int w, int h, const Color_t& clr); void LineRect(int x, int y, int w, int h, const Color_t& clr); @@ -38,7 +40,8 @@ public: void FillRectOutline(int x, int y, int w, int h, const Color_t& clr, const Color_t& out = { 0, 0, 0, 255 }); void LineRectOutline(int x, int y, int w, int h, const Color_t& clr, const Color_t& out = { 0, 0, 0, 255 }, bool inside = true); void FillRectPercent(int x, int y, int w, int h, float t, const Color_t& clr, const Color_t& out = { 0, 0, 0, 255 }, const EAlign& align = ALIGN_LEFT, bool adjust = false); - void RoundRect(int x, int y, int w, int h, int radius, const Color_t& clr); + void FillRoundRect(int x, int y, int w, int h, int radius, const Color_t& clr, int iCount = 64); + void LineRoundRect(int x, int y, int w, int h, int radius, const Color_t& clr, int iCount = 64); void FillCircle(int x, int y, float radius, int segments, Color_t clr); void LineCircle(int x, int y, float radius, int segments, const Color_t& clr); diff --git a/Amalgam/src/SDK/Helpers/Fonts/Fonts.cpp b/Amalgam/src/SDK/Helpers/Fonts/Fonts.cpp index 4246c1bd..95a87963 100644 --- a/Amalgam/src/SDK/Helpers/Fonts/Fonts.cpp +++ b/Amalgam/src/SDK/Helpers/Fonts/Fonts.cpp @@ -2,8 +2,8 @@ void CFonts::Reload(float flDPI) { - m_mapFonts[FONT_ESP] = { "Verdana", int(12.f * flDPI), FONTFLAG_OUTLINE, 0 }; - m_mapFonts[FONT_INDICATORS] = { "Verdana", int(13.f * flDPI), FONTFLAG_OUTLINE, 0 }; + m_mapFonts[FONT_ESP] = { "Verdana", int(12.f * flDPI), FONTFLAG_ANTIALIAS, 0 }; + m_mapFonts[FONT_INDICATORS] = { "Verdana", int(13.f * flDPI), FONTFLAG_ANTIALIAS, 0 }; for (auto& [_, fFont] : m_mapFonts) { diff --git a/Amalgam/src/SDK/Vars.h b/Amalgam/src/SDK/Vars.h index 1d06e3d2..85582895 100644 --- a/Amalgam/src/SDK/Vars.h +++ b/Amalgam/src/SDK/Vars.h @@ -103,7 +103,8 @@ namespace Vars CVar(ConditionsDisplay, DragBox_t(), NOBIND) CVar(SeedPredictionDisplay, DragBox_t(), NOBIND) - CVar(DPI, 1.f, NOBIND) + CVar(Scale, 1.f, NOBIND) + CVar(CheapText, false) SUBNAMESPACE_BEGIN(Theme) CVar(Accent, Color_t(255, 101, 101, 255), VISUAL)