From c3c30a3354c7932eb7f1091dc56295b9c6a1c421 Mon Sep 17 00:00:00 2001
From: rei-2 <174158077+rei-2@users.noreply.github.com>
Date: Sat, 20 Jun 2026 11:39:54 -0400
Subject: [PATCH] move notifications from surface to imgui add notification
icon support
---
Amalgam/Amalgam.vcxproj | 5 +-
Amalgam/Amalgam.vcxproj.filters | 5 +-
Amalgam/src/Core/Core.cpp | 10 +-
Amalgam/src/Features/Configs/Configs.cpp | 44 ++--
Amalgam/src/Features/ImGui/Easings/Easings.h | 192 ++++++++++++++++++
Amalgam/src/Features/ImGui/Menu/Components.h | 132 +++++++-----
Amalgam/src/Features/ImGui/Menu/Menu.cpp | 70 ++++---
.../ImGui/Notifications/Notifications.cpp | 142 +++++++++++++
.../ImGui/Notifications/Notifications.h | 26 +++
Amalgam/src/Features/ImGui/Render.cpp | 32 +--
Amalgam/src/Features/Output/Output.cpp | 62 +++---
Amalgam/src/Features/Players/PlayerCore.cpp | 14 +-
.../Visuals/Notifications/Notifications.cpp | 98 ---------
.../Visuals/Notifications/Notifications.h | 25 ---
Amalgam/src/Hooks/IEngineVGui_Paint.cpp | 18 +-
Amalgam/src/SDK/SDK.cpp | 8 +-
Amalgam/src/SDK/SDK.h | 99 ++++-----
Amalgam/src/SDK/Vars.h | 3 +-
.../ExceptionHandler/ExceptionHandler.cpp | 2 +-
19 files changed, 637 insertions(+), 350 deletions(-)
create mode 100644 Amalgam/src/Features/ImGui/Easings/Easings.h
create mode 100644 Amalgam/src/Features/ImGui/Notifications/Notifications.cpp
create mode 100644 Amalgam/src/Features/ImGui/Notifications/Notifications.h
delete mode 100644 Amalgam/src/Features/Visuals/Notifications/Notifications.cpp
delete mode 100644 Amalgam/src/Features/Visuals/Notifications/Notifications.h
diff --git a/Amalgam/Amalgam.vcxproj b/Amalgam/Amalgam.vcxproj
index 29e234f4..6d9e9405 100644
--- a/Amalgam/Amalgam.vcxproj
+++ b/Amalgam/Amalgam.vcxproj
@@ -950,7 +950,7 @@
-
+
@@ -1227,6 +1227,7 @@
+
@@ -1388,7 +1389,7 @@
-
+
diff --git a/Amalgam/Amalgam.vcxproj.filters b/Amalgam/Amalgam.vcxproj.filters
index 5d1efe10..b24f0678 100644
--- a/Amalgam/Amalgam.vcxproj.filters
+++ b/Amalgam/Amalgam.vcxproj.filters
@@ -9,7 +9,7 @@
-
+
@@ -225,7 +225,7 @@
-
+
@@ -625,6 +625,7 @@
+
diff --git a/Amalgam/src/Core/Core.cpp b/Amalgam/src/Core/Core.cpp
index 0a09334d..169ccb04 100644
--- a/Amalgam/src/Core/Core.cpp
+++ b/Amalgam/src/Core/Core.cpp
@@ -35,12 +35,12 @@ static inline bool CheckDXLevel()
/*
const char* sMessage = "You are running with graphics options that Amalgam does not support. -dxlevel must be at least 90.";
U::Core.AppendFailText(sMessage);
- SDK::Output("Amalgam", sMessage, DEFAULT_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", sMessage, ERROR_COLOR, OUTPUT_CONSOLE | OUTPUT_MENU | OUTPUT_DEBUG);
return false;
*/
const char* sMessage = "You are running with graphics options that Amalgam does not support. It is recommended for -dxlevel to be at least 90.";
- SDK::Output("Amalgam", sMessage, DEFAULT_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", sMessage, WARNING_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_WARNING);
}
return true;
@@ -74,7 +74,7 @@ void CCore::LogFailText()
}
catch (...) {}
- SDK::Output("Failed to load", m_ssFailStream.str().c_str(), {}, OUTPUT_DEBUG, MB_OK | MB_ICONERROR);
+ SDK::Output("Failed to load", m_ssFailStream.str().c_str(), {}, OUTPUT_DEBUG, nullptr, MB_OK | MB_ICONERROR);
}
void CCore::Load()
@@ -116,7 +116,7 @@ void CCore::Load()
H::Fonts.Reload();
F::Configs.LoadConfig(F::Configs.m_sCurrentConfig, false);
- SDK::Output("Amalgam", "Loaded", DEFAULT_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Loaded", INFO_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_INFO);
}
void CCore::Loop()
@@ -174,5 +174,5 @@ void CCore::Unload()
return;
}
- SDK::Output("Amalgam", "Unloaded", DEFAULT_COLOR, OUTPUT_CONSOLE | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Unloaded", INFO_COLOR, OUTPUT_CONSOLE | OUTPUT_DEBUG);
}
\ No newline at end of file
diff --git a/Amalgam/src/Features/Configs/Configs.cpp b/Amalgam/src/Features/Configs/Configs.cpp
index 2aa998f1..091520c3 100644
--- a/Amalgam/src/Features/Configs/Configs.cpp
+++ b/Amalgam/src/Features/Configs/Configs.cpp
@@ -392,7 +392,7 @@ static inline void LoadMain(BaseVar*& pBase, boost::property_tree::ptree& tTree)
}
}
else if (!(pVar->m_iFlags & NOSAVE))
- SDK::Output("Amalgam", std::format("{} not found", pVar->Name()).c_str(), ALTERNATE_COLOR, OUTPUT_CONSOLE | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", std::format("{} not found", pVar->Name()).c_str(), ERROR_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_CANCEL);
}
#define Load(t, j) if (IsType(t)) LoadMain(pBase, j);
@@ -486,11 +486,11 @@ bool CConfigs::SaveConfig(const std::string& sConfigName, bool bNotify)
m_sCurrentConfig = sConfigName; m_sCurrentVisuals = "";
if (bNotify)
- SDK::Output("Amalgam", std::format("Config {} saved", sConfigName).c_str(), DEFAULT_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", std::format("Config {} saved", sConfigName).c_str(), INFO_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_INFO);
}
catch (...)
{
- SDK::Output("Amalgam", "Save config failed", ALTERNATE_COLOR, OUTPUT_CONSOLE | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Save config failed", ERROR_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_CANCEL);
return false;
}
@@ -538,7 +538,7 @@ bool CConfigs::LoadConfig(const std::string& sConfigName, bool bNotify)
}
}
else
- SDK::Output("Amalgam", "Config binds not found", ALTERNATE_COLOR, OUTPUT_CONSOLE | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Config binds not found", ERROR_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_CANCEL);
if (auto tSub = tRead.get_child_optional("Vars");
tSub || (tSub = tRead.get_child_optional("ConVars")))
@@ -563,7 +563,7 @@ bool CConfigs::LoadConfig(const std::string& sConfigName, bool bNotify)
}
}
else
- SDK::Output("Amalgam", "Config vars not found", ALTERNATE_COLOR, OUTPUT_CONSOLE | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Config vars not found", ERROR_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_CANCEL);
if (auto tSub = tRead.get_child_optional("Groups"))
{
@@ -595,18 +595,18 @@ bool CConfigs::LoadConfig(const std::string& sConfigName, bool bNotify)
}
}
else
- SDK::Output("Amalgam", "Config groups not found", ALTERNATE_COLOR, OUTPUT_CONSOLE | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Config groups not found", ERROR_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_CANCEL);
F::Binds.SetVars(nullptr, nullptr, false);
H::Fonts.Reload();
m_sCurrentConfig = sConfigName; m_sCurrentVisuals = "";
if (bNotify)
- SDK::Output("Amalgam", std::format("Config {} loaded", sConfigName).c_str(), DEFAULT_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", std::format("Config {} loaded", sConfigName).c_str(), INFO_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_INFO);
}
catch (...)
{
- SDK::Output("Amalgam", "Load config failed", ALTERNATE_COLOR, OUTPUT_CONSOLE | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Load config failed", ERROR_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_CANCEL);
return false;
}
@@ -694,11 +694,11 @@ bool CConfigs::SaveVisual(const std::string& sConfigName, bool bNotify)
write_json(m_sVisualsPath + sConfigName + m_sConfigExtension, tWrite);
if (bNotify)
- SDK::Output("Amalgam", std::format("Visual config {} saved", sConfigName).c_str(), DEFAULT_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", std::format("Visual config {} saved", sConfigName).c_str(), INFO_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_INFO);
}
catch (...)
{
- SDK::Output("Amalgam", "Save visuals failed", ALTERNATE_COLOR, OUTPUT_CONSOLE | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Save visuals failed", ERROR_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_CANCEL);
return false;
}
return true;
@@ -739,7 +739,7 @@ bool CConfigs::LoadVisual(const std::string& sConfigName, bool bNotify)
}
}
else
- SDK::Output("Amalgam", "Config vars not found", ALTERNATE_COLOR, OUTPUT_CONSOLE | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Config vars not found", ERROR_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_CANCEL);
if (auto tSub = tRead.get_child_optional("Groups"))
{
@@ -771,17 +771,17 @@ bool CConfigs::LoadVisual(const std::string& sConfigName, bool bNotify)
}
}
else
- SDK::Output("Amalgam", "Config groups not found", ALTERNATE_COLOR, OUTPUT_CONSOLE | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Config groups not found", ERROR_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_CANCEL);
F::Binds.SetVars(nullptr, nullptr, false);
m_sCurrentVisuals = sConfigName;
if (bNotify)
- SDK::Output("Amalgam", std::format("Visual config {} loaded", sConfigName).c_str(), DEFAULT_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", std::format("Visual config {} loaded", sConfigName).c_str(), INFO_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_INFO);
}
catch (...)
{
- SDK::Output("Amalgam", "Load visuals failed", ALTERNATE_COLOR, OUTPUT_CONSOLE | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Load visuals failed", ERROR_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_CANCEL);
return false;
}
return true;
@@ -811,11 +811,11 @@ void CConfigs::DeleteConfig(const std::string& sConfigName, bool bNotify)
LoadConfig("default", false);
if (bNotify)
- SDK::Output("Amalgam", std::format("Config {} deleted", sConfigName).c_str(), DEFAULT_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", std::format("Config {} deleted", sConfigName).c_str(), INFO_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_INFO);
}
catch (...)
{
- SDK::Output("Amalgam", "Remove config failed", ALTERNATE_COLOR, OUTPUT_CONSOLE | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Remove config failed", ERROR_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_CANCEL);
}
}
@@ -850,11 +850,11 @@ void CConfigs::ResetConfig(const std::string& sConfigName, bool bNotify)
H::Fonts.Reload();
if (bNotify)
- SDK::Output("Amalgam", std::format("Config {} reset", sConfigName).c_str(), DEFAULT_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", std::format("Config {} reset", sConfigName).c_str(), INFO_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_INFO);
}
catch (...)
{
- SDK::Output("Amalgam", "Reset config failed", ALTERNATE_COLOR, OUTPUT_CONSOLE | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Reset config failed", ERROR_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_CANCEL);
}
}
@@ -865,11 +865,11 @@ void CConfigs::DeleteVisual(const std::string& sConfigName, bool bNotify)
std::filesystem::remove(m_sVisualsPath + sConfigName + m_sConfigExtension);
if (bNotify)
- SDK::Output("Amalgam", std::format("Visual config {} deleted", sConfigName).c_str(), DEFAULT_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", std::format("Visual config {} deleted", sConfigName).c_str(), INFO_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_INFO);
}
catch (...)
{
- SDK::Output("Amalgam", "Remove visuals failed", ALTERNATE_COLOR, OUTPUT_CONSOLE | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Remove visuals failed", ERROR_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_CANCEL);
}
}
@@ -902,10 +902,10 @@ void CConfigs::ResetVisual(const std::string& sConfigName, bool bNotify)
F::Binds.SetVars(nullptr, nullptr, false);
if (bNotify)
- SDK::Output("Amalgam", std::format("Visual config {} reset", sConfigName).c_str(), DEFAULT_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", std::format("Visual config {} reset", sConfigName).c_str(), INFO_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_INFO);
}
catch (...)
{
- SDK::Output("Amalgam", "Reset visuals failed", ALTERNATE_COLOR, OUTPUT_CONSOLE | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Reset visuals failed", ERROR_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_CANCEL);
}
}
\ No newline at end of file
diff --git a/Amalgam/src/Features/ImGui/Easings/Easings.h b/Amalgam/src/Features/ImGui/Easings/Easings.h
new file mode 100644
index 00000000..fe8d79fe
--- /dev/null
+++ b/Amalgam/src/Features/ImGui/Easings/Easings.h
@@ -0,0 +1,192 @@
+#pragma once
+#include "../../../Utils/Math/BaseMath.h"
+
+namespace Ease
+{
+ template inline T OutSine(T x)
+ {
+ return sin((x * Math::PI_V) / T(2));
+ }
+
+ template inline T InSine(T x)
+ {
+ return T(1) - cos((x * Math::PI_V) / T(2));
+ }
+
+ template inline T InOutSine(T x)
+ {
+ return -(cos(x * Math::PI_V) - T(1)) / T(2);
+ }
+
+ template inline T OutQuad(T x)
+ {
+ return T(1) - pow(T(1) - x, T(2));
+ }
+
+ template inline T InQuad(T x)
+ {
+ return pow(x, T(2));
+ }
+
+ template inline T InOutQuad(T x)
+ {
+ return x < T(0.5) ? T(2) * pow(x, T(2)) : T(1) - pow(-T(2) * x + T(2), T(2)) / T(2);
+ }
+
+ template inline T OutCubic(T x)
+ {
+ return T(1) - pow(T(1) - x, T(3));
+ }
+
+ template inline T InCubic(T x)
+ {
+ return pow(x, T(3));
+ }
+
+ template inline T InOutCubic(T x)
+ {
+ return x < T(0.5) ? T(4) * pow(x, T(3)) : T(1) - pow(-T(2) * x + T(2), T(3)) / T(2);
+ }
+
+ template inline T OutQuart(T x)
+ {
+ return T(1) - pow(T(1) - x, T(4));
+ }
+
+ template inline T InQuart(T x)
+ {
+ return pow(x, T(4));
+ }
+
+ template inline T InOutQuart(T x)
+ {
+ return x < T(0.5) ? T(8) * pow(x, T(4)) : T(1) - pow(-T(2) * x + T(2), T(4)) / T(2);
+ }
+
+ template inline T OutQuint(T x)
+ {
+ return T(1) - pow(T(1) - x, T(5));
+ }
+
+ template inline T InQuint(T x)
+ {
+ return pow(x, T(5));
+ }
+
+ template inline T InOutQuint(T x)
+ {
+ return x < T(0.5) ? T(16) * pow(x, T(5)) : T(1) - pow(-T(2) * x + T(2), T(5)) / T(2);
+ }
+
+ template inline T OutExpo(T x)
+ {
+ return x == T(1) ? T(1) : T(1) - pow(T(2), -T(10) * x);
+ }
+
+ template inline T InExpo(T x)
+ {
+ return x == T(0) ? T(0) : pow(T(2), T(10) * x - T(10));
+ }
+
+ template inline T InOutExpo(T x)
+ {
+ return x == T(0) ? T(0)
+ : x == T(1) ? T(1)
+ : x < T(0.5) ? pow(T(2), T(20) * x - T(10)) / T(2)
+ : (T(2) - pow(T(2), -T(20) * x + T(10))) / T(2);
+ }
+
+ template inline T OutCirc(T x)
+ {
+ return sqrt(T(1) - pow(x - T(1), T(2)));
+ }
+
+ template inline T InCirc(T x)
+ {
+ return T(1) - sqrt(T(1) - pow(x, T(2)));
+ }
+
+ template inline T InOutCirc(T x)
+ {
+ return x < T(0.5)
+ ? (T(1) - sqrt(T(1) - pow(T(2) * x, T(2)))) / T(2)
+ : (sqrt(T(1) - pow(-T(2) * x + T(2), T(2))) + T(1)) / T(2);
+ }
+
+ template inline T OutBack(T x)
+ {
+ constexpr T c1 = T(1.70158);
+ constexpr T c3 = c1 + T(1);
+
+ return T(1) + c3 * pow(x - T(1), T(3)) + c1 * pow(x - T(1), T(2));
+ }
+
+ template inline T InBack(T x)
+ {
+ constexpr T c1 = T(1.70158);
+ constexpr T c3 = c1 + T(1);
+
+ return c3 * pow(x, T(3)) - c1 * pow(x, T(2));
+ }
+
+ template inline T InOutBack(T x)
+ {
+ constexpr T c1 = T(1.70158);
+ constexpr T c2 = c1 * T(1.525);
+
+ return x < T(0.5)
+ ? (pow(T(2) * x, T(2)) * ((c2 + T(1)) * T(2) * x - c2)) / T(2)
+ : (pow(T(2) * x - T(2), T(2)) * ((c2 + T(1)) * (x * T(2) - T(2)) + c2) + T(2)) / T(2);
+ }
+
+ template inline T OutElastic(T x)
+ {
+ constexpr T c4 = (T(2) * Math::PI_V) / T(3);
+
+ return x == T(0) ? T(0)
+ : x == T(1) ? T(1)
+ : pow(T(2), -T(10) * x) * sin((x * T(10) - T(0.75)) * c4) + T(1);
+ }
+
+ template inline T InElastic(T x)
+ {
+ constexpr T c4 = (T(2) * Math::PI_V) / T(3);
+
+ return x == T(0) ? T(0)
+ : x == T(1) ? T(1)
+ : -pow(T(2), T(10) * x - T(10)) * sin((x * T(10) - T(10.75)) * c4);
+ }
+
+ template inline T InOutElastic(T x)
+ {
+ constexpr T c5 = (T(2) * Math::PI_V) / T(4.5);
+
+ return x == T(0) ? T(0)
+ : x == T(1) ? T(1)
+ : x < T(0.5) ? -(pow(T(2), T(20) * x - T(10)) * sin((T(20) * x - T(11.125)) * c5)) / T(2)
+ : (pow(T(2), -T(20) * x + T(10)) * sin((T(20) * x - T(11.125)) * c5)) / T(2) + T(1);
+ }
+
+ template inline T OutBounce(T x)
+ {
+ constexpr T n1 = T(7.5625);
+ constexpr T d1 = T(2.75);
+
+ return x < T(1) / d1 ? n1 * x * x
+ : x < T(2) / d1 ? n1 * (x -= T(1.5) / d1) * x + T(0.75)
+ : x < T(2.5) / d1 ? n1 * (x -= T(2.25) / d1) * x + T(0.9375)
+ : n1 * (x -= T(2.625) / d1) * x + T(0.984375);
+ }
+
+ template inline T InBounce(T x)
+ {
+ return T(1) - OutBounce(T(1) - x);
+ }
+
+ template inline T InOutBounce(T x)
+ {
+ return x < T(0.5)
+ ? (T(1) - OutBounce(T(1) - T(2) * x)) / T(2)
+ : (T(1) + OutBounce(T(2) * x - T(1))) / T(2);
+ }
+}
\ 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 fcc2080d..f2b44711 100644
--- a/Amalgam/src/Features/ImGui/Menu/Components.h
+++ b/Amalgam/src/Features/ImGui/Menu/Components.h
@@ -50,47 +50,47 @@ static inline ImVec2& operator/=(ImVec2& lhs, const ImVec2& rhs) { lhs.x /= rhs.
namespace ImGui
{
- std::unordered_map mActiveMap = {};
+ inline std::unordered_map ActiveMap = {};
- bool Disabled = false, Transparent = false;
- int CurrentBind = DEFAULT_BIND;
- bool Hovered = false;
+ inline bool Disabled = false, Transparent = false;
+ inline int CurrentBind = DEFAULT_BIND;
+ inline bool Hovered = false;
- std::vector vDisabled = {}, vTransparent = {};
+ inline std::vector DisabledVec = {}, TransparentVec = {};
inline void PushDisabled(bool bDisabled)
{
- vDisabled.push_back(Disabled = bDisabled);
+ DisabledVec.push_back(Disabled = bDisabled);
}
inline void PopDisabled(int count = 1)
{
- int iSize = int(vDisabled.size());
+ int iSize = int(DisabledVec.size());
if (iSize < count)
{
IM_ASSERT_USER_ERROR(0, "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;
+ DisabledVec.pop_back();
+ Disabled = !DisabledVec.empty() ? DisabledVec.back() : false;
}
inline void PushTransparent(bool bTransparent, bool bPushAlpha = false)
{
- vTransparent.push_back(Transparent = bTransparent);
+ TransparentVec.push_back(Transparent = bTransparent);
if (bPushAlpha)
PushStyleVar(ImGuiStyleVar_Alpha, !bTransparent ? 1.f : 0.5f);
}
inline void PopTransparent(int count = 1, int iPopAlpha = false)
{
- int iSize = int(vTransparent.size());
+ int iSize = int(TransparentVec.size());
if (iSize < count)
{
IM_ASSERT_USER_ERROR(0, "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;
+ TransparentVec.pop_back();
+ Transparent = !TransparentVec.empty() ? TransparentVec.back() : false;
if (iPopAlpha)
PopStyleVar(iPopAlpha);
@@ -151,16 +151,36 @@ namespace ImGui
return tColor.Value.x * flRed + tColor.Value.y * flGreen + tColor.Value.z * flBlue < flValue;
}
- inline ImVec4 ColorToVec(Color_t tColor)
+ inline ImU32 ColorByteToInt(Color_t tColor)
+ {
+ return tColor.r << IM_COL32_R_SHIFT | tColor.g << IM_COL32_G_SHIFT | tColor.b << IM_COL32_B_SHIFT | tColor.a << IM_COL32_A_SHIFT;
+ }
+
+ inline Color_t ColorIntToByte(ImU32 tColor)
+ {
+ return { byte(tColor >> IM_COL32_R_SHIFT), byte(tColor >> IM_COL32_G_SHIFT), byte(tColor >> IM_COL32_B_SHIFT), byte(tColor >> IM_COL32_A_SHIFT) };
+ }
+
+ inline ImVec4 ColorByteToVec(Color_t tColor)
{
return { tColor.r / 255.f, tColor.g / 255.f, tColor.b / 255.f, tColor.a / 255.f };
}
- inline Color_t VecToColor(ImVec4 tColor)
+ inline Color_t ColorVecToByte(ImVec4 tColor)
{
return { byte(tColor.x * 255), byte(tColor.y * 255), byte(tColor.z * 255), byte(tColor.w * 255) };
}
+ inline ImColor ColorByteToFloat(Color_t tColor)
+ {
+ return { tColor.r / 255.f, tColor.g / 255.f, tColor.b / 255.f, tColor.a / 255.f };
+ }
+
+ inline Color_t ColorFloatToByte(ImColor tColor)
+ {
+ return { byte(tColor.Value.x * 255), byte(tColor.Value.y * 255), byte(tColor.Value.z * 255), byte(tColor.Value.w * 255) };
+ }
+
inline void DebugDummy(ImVec2 vSize)
{
/*
@@ -232,13 +252,13 @@ namespace ImGui
if (!bHorizontal)
{
- pDrawList->AddRectFilled(vDrawPos, vDrawPos + ImVec2(vSize.x, flSize), uTitle, H::Draw.Scale(4), ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight);
- pDrawList->AddRectFilled(vDrawPos + ImVec2(0, flSize), vDrawPos + vSize, uBackground, H::Draw.Scale(4), ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersBottomRight);
+ pDrawList->AddRectFilled(vDrawPos, vDrawPos + ImVec2(vSize.x, flSize), uTitle, H::Draw.Scale(4), ImDrawFlags_RoundCornersTop);
+ pDrawList->AddRectFilled(vDrawPos + ImVec2(0, flSize), vDrawPos + vSize, uBackground, H::Draw.Scale(4), ImDrawFlags_RoundCornersBottom);
}
else
{
- pDrawList->AddRectFilled(vDrawPos, vDrawPos + ImVec2(flSize, vSize.y), uTitle, H::Draw.Scale(4), ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersBottomLeft);
- pDrawList->AddRectFilled(vDrawPos + ImVec2(flSize, 0), vDrawPos + vSize, uBackground, H::Draw.Scale(4), ImDrawFlags_RoundCornersTopRight | ImDrawFlags_RoundCornersBottomRight);
+ pDrawList->AddRectFilled(vDrawPos, vDrawPos + ImVec2(flSize, vSize.y), uTitle, H::Draw.Scale(4), ImDrawFlags_RoundCornersLeft);
+ pDrawList->AddRectFilled(vDrawPos + ImVec2(flSize, 0), vDrawPos + vSize, uBackground, H::Draw.Scale(4), ImDrawFlags_RoundCornersRight);
}
}
inline void RenderTwoToneBackground(float flSize, ImU32 uTitle, ImU32 uBackground, ImU32 uBorder, float flInset = H::Draw.Scale(), bool bVertical = true, bool bTwoToneBorder = true)
@@ -250,24 +270,24 @@ namespace ImGui
if (bVertical)
{
if (!bTwoToneBorder)
- pDrawList->AddRectFilled(vDrawPos + ImVec2(flInset, flInset), vDrawPos + ImVec2(vSize.x - flInset, flSize), uTitle, H::Draw.Scale(3), ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight);
+ pDrawList->AddRectFilled(vDrawPos + ImVec2(flInset, flInset), vDrawPos + ImVec2(vSize.x - flInset, flSize), uTitle, H::Draw.Scale(3), ImDrawFlags_RoundCornersTop);
else
{
- pDrawList->AddRectFilled(vDrawPos + ImVec2(flInset, flInset), vDrawPos + ImVec2(vSize.x - flInset, flSize - H::Draw.Scale()), uTitle, H::Draw.Scale(3), ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight);
+ pDrawList->AddRectFilled(vDrawPos + ImVec2(flInset, flInset), vDrawPos + ImVec2(vSize.x - flInset, flSize - H::Draw.Scale()), uTitle, H::Draw.Scale(3), ImDrawFlags_RoundCornersTop);
pDrawList->AddRectFilled(vDrawPos + ImVec2(flInset, flSize - H::Draw.Scale()), vDrawPos + ImVec2(vSize.x - flInset, flSize), uBorder);
}
- pDrawList->AddRectFilled(vDrawPos + ImVec2(flInset, flSize), vDrawPos + vSize - ImVec2(flInset, flInset), uBackground, H::Draw.Scale(3), ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersBottomRight);
+ pDrawList->AddRectFilled(vDrawPos + ImVec2(flInset, flSize), vDrawPos + vSize - ImVec2(flInset, flInset), uBackground, H::Draw.Scale(3), ImDrawFlags_RoundCornersBottom);
}
else
{
if (!bTwoToneBorder)
- pDrawList->AddRectFilled(vDrawPos + ImVec2(flInset, flInset), vDrawPos + ImVec2(flSize, vSize.y - flInset), uTitle, H::Draw.Scale(3), ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersBottomLeft);
+ pDrawList->AddRectFilled(vDrawPos + ImVec2(flInset, flInset), vDrawPos + ImVec2(flSize, vSize.y - flInset), uTitle, H::Draw.Scale(3), ImDrawFlags_RoundCornersLeft);
else
{
- pDrawList->AddRectFilled(vDrawPos + ImVec2(flInset, flInset), vDrawPos + ImVec2(flSize - H::Draw.Scale(), vSize.y - flInset), uTitle, H::Draw.Scale(3), ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersBottomLeft);
+ pDrawList->AddRectFilled(vDrawPos + ImVec2(flInset, flInset), vDrawPos + ImVec2(flSize - H::Draw.Scale(), vSize.y - flInset), uTitle, H::Draw.Scale(3), ImDrawFlags_RoundCornersLeft);
pDrawList->AddRectFilled(vDrawPos + ImVec2(flSize - H::Draw.Scale(), flInset), vDrawPos + ImVec2(flSize, vSize.y - flInset), uBorder);
}
- pDrawList->AddRectFilled(vDrawPos + ImVec2(flSize, flInset), vDrawPos + vSize - ImVec2(flInset, flInset), uBackground, H::Draw.Scale(3), ImDrawFlags_RoundCornersTopRight | ImDrawFlags_RoundCornersBottomRight);
+ pDrawList->AddRectFilled(vDrawPos + ImVec2(flSize, flInset), vDrawPos + vSize - ImVec2(flInset, flInset), uBackground, H::Draw.Scale(3), ImDrawFlags_RoundCornersRight);
}
flInset += H::Draw.Scale(0.5f) - 0.5f - H::Draw.Scale();
@@ -1197,7 +1217,7 @@ namespace ImGui
float flOriginal1 = *pVar1, flOriginal2 = pVar2 ? *pVar2 : 0.f;
static std::unordered_map> mStaticVars = {};
- if (!mActiveMap[uHash])
+ if (!ActiveMap[uHash])
mStaticVars[uHash] = { flOriginal1, flOriginal2 };
float& flSVar1 = mStaticVars[uHash].first, &flSVar2 = mStaticVars[uHash].second;
@@ -1251,7 +1271,7 @@ namespace ImGui
auto uHash2 = FNV1A::Hash32Const(std::format("{}## Text", sLabel).c_str());
static std::string sText, sInput;
- if (!mActiveMap[uHash2])
+ if (!ActiveMap[uHash2])
sText = pVar2 ? FormatText(fmt, flSVar1, flSVar2) : FormatText(fmt, flSVar1);
else
{
@@ -1264,7 +1284,7 @@ namespace ImGui
{
try
{
- bool bVar1 = mActiveMap[uHash2] == 1;
+ bool bVar1 = ActiveMap[uHash2] == 1;
float& pVar = bVar1 ? flSVar1 : flSVar2;
pVar = sText.length() ? std::stof(sText) : 0.f;
@@ -1291,7 +1311,7 @@ namespace ImGui
catch (...) {}
}
if (bEnter || IsMouseClicked(ImGuiMouseButton_Left) || U::KeyHandler.Pressed(VK_ESCAPE))
- mActiveMap[uHash2] = false;
+ ActiveMap[uHash2] = false;
}
float flWidth = FCalcTextSize(sText.c_str()).x;
#ifdef ALTERNATE_FULL_SLIDER
@@ -1310,13 +1330,13 @@ namespace ImGui
{
if (!Disabled && IsItemHovered() && IsWindowHovered())
SetMouseCursor(ImGuiMouseCursor_TextInput);
- if (mActiveMap[uHash2])
+ if (ActiveMap[uHash2])
pDrawList->AddRectFilled(vDrawPos + vOriginalPos2 + ImVec2(0, H::Draw.Scale(14)), vDrawPos + vOriginalPos2 + ImVec2(flWidth, H::Draw.Scale(15)), F::Render.Active);
else if (IsItemClicked())
{
float* pVar = !pVar2 || GetMousePos().x - vDrawPos.x - vOriginalPos2.x < flWidth / 2 ? pVar1 : pVar2;
sInput = std::format("{}", *pVar); // would use to_string but i don't like its formatting
- mActiveMap[uHash2] = pVar == pVar1 ? 1 : 2;
+ ActiveMap[uHash2] = pVar == pVar1 ? 1 : 2;
}
}
}
@@ -1353,25 +1373,25 @@ namespace ImGui
if (!Disabled)
{
- if (bWithin && !mActiveMap[uHash])
+ if (bWithin && !ActiveMap[uHash])
{
int iVar = vMouse.x - vDrawPos.x < (flLowerPos + flUpperPos) / 2 ? 1 : 2;
if (IsMouseClicked(ImGuiMouseButton_Left))
- mActiveMap[uHash] = iVar;
+ ActiveMap[uHash] = iVar;
pDrawList->AddCircleFilled(vDrawPos + ImVec2((iVar == 1 ? flLowerPos : flUpperPos), vMins.y + H::Draw.Scale(1)), H::Draw.Scale(12), tTransparent);
}
- else if (mActiveMap[uHash] && IsMouseDown(ImGuiMouseButton_Left))
+ else if (ActiveMap[uHash] && IsMouseDown(ImGuiMouseButton_Left))
{
- bool bVar1 = mActiveMap[uHash] == 1;
+ bool bVar1 = ActiveMap[uHash] == 1;
float& flVar = bVar1 ? flSVar1 : flSVar2;
flVar = flMin + (flMax - flMin) * flMousePerc;
flVar = std::clamp(flVar - fnmodf(flVar, flStep), !bVar1 ? flSVar1 + flStep : flMin, bVar1 ? flSVar2 - flStep : flMax);
pDrawList->AddCircleFilled(vDrawPos + ImVec2((bVar1 ? flLowerPos : flUpperPos), vMins.y + H::Draw.Scale(1)), H::Draw.Scale(16), tTransparent);
}
else
- mActiveMap[uHash] = false;
+ ActiveMap[uHash] = false;
- if (iFlags & FSliderEnum::NoAutoUpdate ? !mActiveMap[uHash] : true)
+ if (iFlags & FSliderEnum::NoAutoUpdate ? !ActiveMap[uHash] : true)
{
*pVar1 = flSVar1;
*pVar2 = flSVar2;
@@ -1389,22 +1409,22 @@ namespace ImGui
if (!Disabled)
{
- if (bWithin && !mActiveMap[uHash])
+ if (bWithin && !ActiveMap[uHash])
{
if (IsMouseClicked(ImGuiMouseButton_Left))
- mActiveMap[uHash] = 1;
+ ActiveMap[uHash] = 1;
pDrawList->AddCircleFilled(vDrawPos + ImVec2(flPos, vMins.y + H::Draw.Scale(1)), H::Draw.Scale(12), tTransparent);
}
- else if (mActiveMap[uHash] && IsMouseDown(ImGuiMouseButton_Left))
+ else if (ActiveMap[uHash] && IsMouseDown(ImGuiMouseButton_Left))
{
flSVar1 = flMin + (flMax - flMin) * flMousePerc;
flSVar1 = std::clamp(flSVar1 - fnmodf(flSVar1, flStep), flMin, flMax);
pDrawList->AddCircleFilled(vDrawPos + ImVec2(flPos, vMins.y + H::Draw.Scale(1)), H::Draw.Scale(16), tTransparent);
}
else
- mActiveMap[uHash] = false;
+ ActiveMap[uHash] = false;
- if (iFlags & FSliderEnum::NoAutoUpdate ? !mActiveMap[uHash] : true)
+ if (iFlags & FSliderEnum::NoAutoUpdate ? !ActiveMap[uHash] : true)
*pVar1 = flSVar1;
}
}
@@ -1715,10 +1735,10 @@ namespace ImGui
static std::string sPreview = "", sInput = "", sTab = "\n";
if (BeginCombo(std::format("##{}", sLabel).c_str(), "", ImGuiComboFlags_CustomPreview | ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_HeightLarge))
{
- if (!mActiveMap[uHash])
+ if (!ActiveMap[uHash])
sPreview = sInput = "";
- mActiveMap[uHash] = true;
+ ActiveMap[uHash] = true;
// this textinput is being used as a temporary measure to prevent the main window drawing over the popup
ImVec2 vOriginalPos2 = GetCursorPos();
@@ -1836,7 +1856,7 @@ namespace ImGui
EndCombo();
}
else
- mActiveMap[uHash] = false;
+ ActiveMap[uHash] = false;
if (!Disabled && IsItemHovered())
SetMouseCursor(ImGuiMouseCursor_TextInput);
if (pHovered)
@@ -1853,37 +1873,37 @@ namespace ImGui
PopFont();
SetCursorPos(vOriginalPos2 + ImVec2(H::Draw.Scale(12), H::Draw.Scale(8)));
- TextUnformatted(TruncateText(mActiveMap[uHash] ? sPreview : *pVar, vSize.x - H::Draw.Scale(vEntries.empty() ? 24 : 45)).c_str());
+ TextUnformatted(TruncateText(ActiveMap[uHash] ? sPreview : *pVar, vSize.x - H::Draw.Scale(vEntries.empty() ? 24 : 45)).c_str());
if (!vEntries.empty())
{
SetCursorPos(vOriginalPos2 + ImVec2(vSize.x - H::Draw.Scale(24), H::Draw.Scale(-1)));
- IconImage(mActiveMap[uHash] ? ICON_MD_KEYBOARD_ARROW_UP : ICON_MD_KEYBOARD_ARROW_DOWN);
+ IconImage(ActiveMap[uHash] ? ICON_MD_KEYBOARD_ARROW_UP : ICON_MD_KEYBOARD_ARROW_DOWN);
}
- if (mActiveMap[uHash] || iFlags & FSDropdownEnum::Custom || vEntries.empty())
+ if (ActiveMap[uHash] || iFlags & FSDropdownEnum::Custom || vEntries.empty())
{
ImVec2 vDrawPos = GetDrawPos() + vOriginalPos2 + ImVec2(H::Draw.Scale(12), H::Draw.Scale(22));
vDrawPos.x = floorf(vDrawPos.x), vDrawPos.y = floorf(vDrawPos.y);
- GetWindowDrawList()->AddRectFilled(vDrawPos, vDrawPos + ImVec2(vSize.x - H::Draw.Scale(vEntries.empty() ? 25 : 45), H::Draw.Scale(2)), mActiveMap[uHash] ? F::Render.Active : F::Render.Inactive);
+ GetWindowDrawList()->AddRectFilled(vDrawPos, vDrawPos + ImVec2(vSize.x - H::Draw.Scale(vEntries.empty() ? 25 : 45), H::Draw.Scale(2)), ActiveMap[uHash] ? F::Render.Active : F::Render.Inactive);
}
}
else
{
SetCursorPos(vOriginalPos2 + ImVec2(H::Draw.Scale(12), 0));
- TextUnformatted(TruncateText(mActiveMap[uHash] ? sPreview : *pVar, vSize.x - H::Draw.Scale(vEntries.empty() ? 24 : 45)).c_str());
+ TextUnformatted(TruncateText(ActiveMap[uHash] ? sPreview : *pVar, vSize.x - H::Draw.Scale(vEntries.empty() ? 24 : 45)).c_str());
if (!vEntries.empty())
{
SetCursorPos(vOriginalPos2 + ImVec2(vSize.x - H::Draw.Scale(24), H::Draw.Scale(-1)));
- IconImage(mActiveMap[uHash] ? ICON_MD_KEYBOARD_ARROW_UP : ICON_MD_KEYBOARD_ARROW_DOWN);
+ IconImage(ActiveMap[uHash] ? ICON_MD_KEYBOARD_ARROW_UP : ICON_MD_KEYBOARD_ARROW_DOWN);
}
- if (mActiveMap[uHash] || iFlags & FSDropdownEnum::Custom || vEntries.empty())
+ if (ActiveMap[uHash] || iFlags & FSDropdownEnum::Custom || vEntries.empty())
{
ImVec2 vDrawPos = GetDrawPos() + vOriginalPos2 + ImVec2(H::Draw.Scale(12), H::Draw.Scale(14));
vDrawPos.x = floorf(vDrawPos.x), vDrawPos.y = floorf(vDrawPos.y);
- GetWindowDrawList()->AddRectFilled(vDrawPos, vDrawPos + ImVec2(vSize.x - H::Draw.Scale(vEntries.empty() ? 25 : 45), H::Draw.Scale(2)), mActiveMap[uHash] ? F::Render.Active : F::Render.Inactive);
+ GetWindowDrawList()->AddRectFilled(vDrawPos, vDrawPos + ImVec2(vSize.x - H::Draw.Scale(vEntries.empty() ? 25 : 45), H::Draw.Scale(2)), ActiveMap[uHash] ? F::Render.Active : F::Render.Inactive);
}
}
@@ -1924,10 +1944,10 @@ namespace ImGui
PushStyleVar(ImGuiStyleVar_PopupBorderSize, H::Draw.Scale());
PushStyleColor(ImGuiCol_PopupBg, F::Render.Background0p5.Value);
- ImVec4 tTempColor = ColorToVec(*pColor);
+ ImVec4 tTempColor = ColorByteToVec(*pColor);
bool bReturn = ColorEdit4(std::format("##{}", sLabel).c_str(), &tTempColor.x, ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_LargeAlphaGrid | ImGuiColorEditFlags_NoRoundRestrict | ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoBorder | ImGuiColorEditFlags_NoTooltip, vSize);
if (bReturn)
- *pColor = VecToColor(tTempColor);
+ *pColor = ColorVecToByte(tTempColor);
if (!Disabled && IsItemHovered())
SetMouseCursor(ImGuiMouseCursor_Hand);
@@ -2318,7 +2338,7 @@ namespace ImGui
return tVar[iParent];
}
- bool bPushedDisabled = false, bPushedTransparent = false;
+ static bool bPushedDisabled = false, bPushedTransparent = false;
template
inline T& FGet(ConfigVar& tVar, bool bDisable = false)
diff --git a/Amalgam/src/Features/ImGui/Menu/Menu.cpp b/Amalgam/src/Features/ImGui/Menu/Menu.cpp
index 2ddb9aa0..8e95f300 100644
--- a/Amalgam/src/Features/ImGui/Menu/Menu.cpp
+++ b/Amalgam/src/Features/ImGui/Menu/Menu.cpp
@@ -1,6 +1,7 @@
#include "Menu.h"
#include "Components.h"
+#include "../Notifications/Notifications.h"
#include "../../Configs/Configs.h"
#include "../../Binds/Binds.h"
#include "../../Visuals/Groups/Groups.h"
@@ -69,11 +70,11 @@ void CMenu::DrawMenu()
PopStyleColor();
}
else
- pDrawList->AddRectFilled(vDrawPos, vDrawPos + ImVec2(flSize - flInset, vWindowSize.y), F::Render.Background0, H::Draw.Scale(3), ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersBottomLeft);
+ pDrawList->AddRectFilled(vDrawPos, vDrawPos + ImVec2(flSize - flInset, vWindowSize.y), F::Render.Background0, H::Draw.Scale(3), ImDrawFlags_RoundCornersLeft);
- PushClipRect({ 0, 0 }, { ImGui::GetIO().DisplaySize.x, ImGui::GetIO().DisplaySize.y }, false);
+ pDrawList->PushClipRect({ 0, 0 }, { GetIO().DisplaySize.x, GetIO().DisplaySize.y }, false);
RenderTwoToneBackground(flSize, {}, F::Render.Background1, F::Render.Background2, 0.f, false);
- PopClipRect();
+ pDrawList->PopClipRect();
static int iTab = 0, iAimbotTab = 0, iVisualsTab = 0, iLogsTab = 0, iSettingsTab = 0;
PushFont(F::Render.FontBold);
@@ -849,7 +850,7 @@ void CMenu::MenuVisuals(int iTab)
// background
float flWidth = GetWindowWidth() / 2 - GetStyle().WindowPadding.x * 1.5f;
float flHeight = H::Draw.Scale(28);
- ImColor tColor = ColorToVec(tGroup.m_tColor.Lerp(Vars::Menu::Theme::Background.Value, 0.5f, LerpEnum::NoAlpha));
+ ImColor tColor = ColorByteToFloat(tGroup.m_tColor.Lerp(Vars::Menu::Theme::Background.Value, 0.5f, LerpEnum::NoAlpha));
ImVec2 vDrawPos = GetDrawPos() + vOriginalPos;
if (iCurrentGroup != iGroup)
GetWindowDrawList()->AddRectFilled(vDrawPos, vDrawPos + ImVec2(flWidth, flHeight), tColor, H::Draw.Scale(4));
@@ -858,7 +859,7 @@ void CMenu::MenuVisuals(int iTab)
ImColor tColor2 = { tColor.Value.x * 1.1f, tColor.Value.y * 1.1f, tColor.Value.z * 1.1f, tColor.Value.w };
GetWindowDrawList()->AddRectFilled(vDrawPos, vDrawPos + ImVec2(flWidth, flHeight), tColor2, H::Draw.Scale(4));
- tColor2 = ColorToVec(tGroup.m_tColor.Lerp(Vars::Menu::Theme::Background.Value, 0.25f, LerpEnum::NoAlpha));
+ tColor2 = ColorByteToFloat(tGroup.m_tColor.Lerp(Vars::Menu::Theme::Background.Value, 0.25f, LerpEnum::NoAlpha));
float flInset = H::Draw.Scale(0.5f) - 0.5f;
GetWindowDrawList()->AddRect(vDrawPos + ImVec2(flInset, flInset), vDrawPos + ImVec2(flWidth - flInset, flHeight - flInset), tColor2, H::Draw.Scale(4), ImDrawFlags_None, H::Draw.Scale());
}
@@ -1483,7 +1484,7 @@ void CMenu::MenuLogs(int iTab)
// background
float flWidth = GetWindowWidth() / 2 - GetStyle().WindowPadding.x * 1.5f;
float flHeight = H::Draw.Scale(28);
- ImColor tColor = ColorToVec(fGetTeamColor(tPlayer.m_iTeam, tPlayer.m_bAlive));
+ ImColor tColor = ColorByteToFloat(fGetTeamColor(tPlayer.m_iTeam, tPlayer.m_bAlive));
ImVec2 vDrawPos = GetDrawPos() + vOriginalPos;
GetWindowDrawList()->AddRectFilled(vDrawPos, vDrawPos + ImVec2(flWidth, flHeight), tColor, H::Draw.Scale(4));
@@ -1532,14 +1533,14 @@ void CMenu::MenuLogs(int iTab)
float flTagOffset = H::Draw.Scale(4);
auto fDrawTag = [&](PriorityLabel_t& tTag, int iID)
{
- ImColor tTagColor = ColorToVec(tTag.m_tColor);
+ ImColor tTagColor = ColorByteToFloat(tTag.m_tColor);
float flTagWidth = FCalcTextSize(tTag.m_sName.c_str()).x + H::Draw.Scale(!iID ? 10 : 25);
float flTagHeight = H::Draw.Scale(20);
ImVec2 vTagPos = { flTagOffset, H::Draw.Scale(4) };
GetWindowDrawList()->AddRectFilled(vDrawPos + vTagPos, vDrawPos + vTagPos + ImVec2(flTagWidth, flTagHeight), tTagColor, H::Draw.Scale(4));
SetCursorPos(vTagPos + ImVec2(H::Draw.Scale(5), H::Draw.Scale(3)));
- TextColored(VecToColor(tColor).Blend(tTag.m_tColor).IsColorBright() ? ImVec4(0, 0, 0, 1) : ImVec4(1, 1, 1, 1), tTag.m_sName.c_str());
+ TextColored(ColorFloatToByte(tColor).Blend(tTag.m_tColor).IsColorBright() ? ImVec4(0, 0, 0, 1) : ImVec4(1, 1, 1, 1), tTag.m_sName.c_str());
if (iID)
{
SetCursorPos(vTagPos + ImVec2(flTagWidth - H::Draw.Scale(22), H::Draw.Scale(-2)));
@@ -1636,10 +1637,10 @@ void CMenu::MenuLogs(int iTab)
if (!tTag.m_bAssignable || F::PlayerUtils.HasTag(tPlayer.m_uAccountID, iID))
continue;
- auto imColor = ColorToVec(tTag.m_tColor);
- PushStyleColor(ImGuiCol_Text, imColor);
- imColor.x /= 3; imColor.y /= 3; imColor.z /= 3;
- if (FSelectable(tTag.m_sName.c_str(), imColor))
+ ImVec4 tColor = ColorByteToVec(tTag.m_tColor);
+ PushStyleColor(ImGuiCol_Text, tColor);
+ tColor.x /= 3; tColor.y /= 3; tColor.z /= 3;
+ if (FSelectable(tTag.m_sName.c_str(), tColor))
F::PlayerUtils.AddTag(tPlayer.m_uAccountID, iID, true, tPlayer.m_sName.c_str());
PopStyleColor();
}
@@ -1910,7 +1911,7 @@ void CMenu::MenuLogs(int iTab)
// background
float flWidth = GetWindowWidth() * (_tTag.m_bLabel ? 1.f / 3 : 2.f / 3) - GetStyle().WindowPadding.x * 1.5f;
float flHeight = H::Draw.Scale(28);
- ImColor tColor = ColorToVec(_tTag.m_tColor.Lerp(Vars::Menu::Theme::Background.Value, 0.5f, LerpEnum::NoAlpha));
+ ImColor tColor = ColorByteToFloat(_tTag.m_tColor.Lerp(Vars::Menu::Theme::Background.Value, 0.5f, LerpEnum::NoAlpha));
ImVec2 vDrawPos = GetDrawPos() + vOriginalPos;
if (iID != _iID)
GetWindowDrawList()->AddRectFilled(vDrawPos, vDrawPos + ImVec2(flWidth, flHeight), tColor, H::Draw.Scale(4));
@@ -1919,7 +1920,7 @@ void CMenu::MenuLogs(int iTab)
ImColor tColor2 = { tColor.Value.x * 1.1f, tColor.Value.y * 1.1f, tColor.Value.z * 1.1f, tColor.Value.w };
GetWindowDrawList()->AddRectFilled(vDrawPos, vDrawPos + ImVec2(flWidth, flHeight), tColor2, H::Draw.Scale(4));
- tColor2 = ColorToVec(_tTag.m_tColor.Lerp(Vars::Menu::Theme::Background.Value, 0.25f, LerpEnum::NoAlpha));
+ tColor2 = ColorByteToFloat(_tTag.m_tColor.Lerp(Vars::Menu::Theme::Background.Value, 0.25f, LerpEnum::NoAlpha));
float flInset = H::Draw.Scale(0.5f) - 0.5f;
GetWindowDrawList()->AddRect(vDrawPos + ImVec2(flInset, flInset), vDrawPos + ImVec2(flWidth - flInset, flHeight - flInset), tColor2, H::Draw.Scale(4), ImDrawFlags_None, H::Draw.Scale());
}
@@ -2132,7 +2133,7 @@ void CMenu::MenuLogs(int iTab)
fStream.close();
SDK::SetClipboard(sString);
- SDK::Output("Amalgam", "Copied playerlist to clipboard", DEFAULT_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Copied playerlist to clipboard", INFO_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_INFO);
}
}
@@ -2233,7 +2234,7 @@ void CMenu::MenuLogs(int iTab)
}
catch (...)
{
- SDK::Output("Amalgam", "Failed to import playerlist", ALTERNATE_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Failed to import playerlist", ERROR_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_CANCEL);
}
}
@@ -2251,7 +2252,7 @@ void CMenu::MenuLogs(int iTab)
auto& iIDTo = mAs[i];
ImVec2 vOriginalPos = GetCursorPos();
- PushStyleColor(ImGuiCol_Text, ColorToVec(vTags[i].m_tColor));
+ PushStyleColor(ImGuiCol_Text, ColorByteToInt(vTags[i].m_tColor));
SetCursorPos(vOriginalPos + ImVec2(H::Draw.Scale(8), H::Draw.Scale(5)));
FText(vTags[i].m_sName.c_str());
PopStyleColor();
@@ -2294,7 +2295,7 @@ void CMenu::MenuLogs(int iTab)
}
F::PlayerUtils.m_bSave = true;
- SDK::Output("Amalgam", "Imported playerlist", DEFAULT_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Imported playerlist", INFO_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_INFO);
CloseCurrentPopup();
}
@@ -2325,11 +2326,11 @@ void CMenu::MenuLogs(int iTab)
F::Configs.m_sCorePath + std::format("Backup{}.json", iBackupCount + 1),
std::filesystem::copy_options::overwrite_existing
);
- SDK::Output("Amalgam", "Saved backup playerlist", DEFAULT_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Saved backup playerlist", INFO_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_INFO);
}
catch (...)
{
- SDK::Output("Amalgam", "Failed to backup playerlist", ALTERNATE_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Failed to backup playerlist", ERROR_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_CANCEL);
}
}
}
@@ -2349,7 +2350,8 @@ void CMenu::MenuLogs(int iTab)
{
FDropdown(Vars::Logging::Logs);
FDropdown(Vars::Logging::NotificationPosition);
- FSlider(Vars::Logging::Lifetime);
+ FSlider(Vars::Logging::NotificationTime);
+ FSlider(Vars::Logging::MaxNotifications);
} EndSection();
if (Section("Cheat Detection"))
{
@@ -2428,6 +2430,8 @@ void CMenu::MenuLogs(int iTab)
{
if (Section("##Output", false, GetWindowHeight() - GetStyle().WindowPadding.y * 2))
{
+ bool bClear = false;
+
for (auto& tOutput : m_vOutput)
{
ImVec2 vOriginalPos = GetCursorPos();
@@ -2441,7 +2445,7 @@ void CMenu::MenuLogs(int iTab)
auto vWrapped = WrapText(tOutput.m_sFunction, flWidth);
if (!vWrapped.empty())
{
- PushStyleColor(ImGuiCol_Text, ColorToVec(tOutput.tAccent));
+ PushStyleColor(ImGuiCol_Text, ColorByteToInt(tOutput.tAccent));
for (auto& sText : vWrapped)
FText(sText.c_str());
@@ -2462,7 +2466,7 @@ void CMenu::MenuLogs(int iTab)
}
else
{
- PushStyleColor(ImGuiCol_Text, ColorToVec(tOutput.tAccent));
+ PushStyleColor(ImGuiCol_Text, ColorByteToInt(tOutput.tAccent));
auto vWrapped = WrapText(tOutput.m_sLog, flWidth);
for (auto& sText : vWrapped)
@@ -2482,11 +2486,16 @@ void CMenu::MenuLogs(int iTab)
if (FSelectable("Copy"))
SDK::SetClipboard(std::format("{}{}{}", tOutput.m_sFunction, tOutput.m_sFunction != "" ? " " : "", tOutput.m_sLog));
+ if (FSelectable("Clear"))
+ bClear = true;
PopStyleVar();
EndPopup();
}
}
+
+ if (bClear)
+ m_vOutput.clear();
} EndSection();
break;
}
@@ -2934,7 +2943,7 @@ void CMenu::MenuSettings(int iTab)
ImColor tColor = F::Render.Background1p5L;
GetWindowDrawList()->AddRectFilled(vDrawPos, vDrawPos + ImVec2(flWidth, flHeight), tColor, H::Draw.Scale(4));
- tColor = ColorToVec((VecToColor(F::Render.Background1p5)).Lerp({ 127, 127, 127 }, 1.f / 9, LerpEnum::NoAlpha));
+ tColor = ColorByteToFloat((ColorFloatToByte(F::Render.Background1p5)).Lerp({ 127, 127, 127 }, 1.f / 9, LerpEnum::NoAlpha));
float flInset = H::Draw.Scale(0.5f) - 0.5f;
GetWindowDrawList()->AddRect(vDrawPos + ImVec2(flInset, flInset), vDrawPos + ImVec2(flWidth - flInset, flHeight - flInset), tColor, H::Draw.Scale(4), ImDrawFlags_None, H::Draw.Scale());
}
@@ -4120,7 +4129,7 @@ void CMenu::Render()
{
using namespace ImGui;
- if (!(ImGui::GetIO().DisplaySize.x > 160.f && ImGui::GetIO().DisplaySize.y > 28.f))
+ if (!(GetIO().DisplaySize.x > 160.f && GetIO().DisplaySize.y > 28.f))
return;
m_bInKeybind = false;
@@ -4154,25 +4163,26 @@ void CMenu::Render()
F::Render.Cursor = GetMouseCursor();
m_bWindowHovered = IsWindowHovered(ImGuiHoveredFlags_AnyWindow | ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem);
- if (!vDisabled.empty())
+ if (!DisabledVec.empty())
{
IM_ASSERT_USER_ERROR(0, "Calling PopDisabled() too little times: stack overflow.");
Disabled = false;
- vDisabled.clear();
+ DisabledVec.clear();
}
- if (!vTransparent.empty())
+ if (!TransparentVec.empty())
{
IM_ASSERT_USER_ERROR(0, "Calling PopTransparent() too little times: stack overflow.");
Transparent = false;
- vTransparent.clear();
+ TransparentVec.clear();
}
}
else
{
- mActiveMap.clear();
+ ActiveMap.clear();
m_bWindowHovered = false;
}
DrawBinds();
+ F::Notifications.Draw();
PopFont();
}
diff --git a/Amalgam/src/Features/ImGui/Notifications/Notifications.cpp b/Amalgam/src/Features/ImGui/Notifications/Notifications.cpp
new file mode 100644
index 00000000..4033af41
--- /dev/null
+++ b/Amalgam/src/Features/ImGui/Notifications/Notifications.cpp
@@ -0,0 +1,142 @@
+#include "Notifications.h"
+
+#include "../Easings/Easings.h"
+#include "../Menu/Components.h"
+#include
+
+#define EASE_IN Ease::OutCubic
+#define EASE_OUT Ease::OutCubic
+#define EASE_Y Ease::InOutCubic
+
+void CNotifications::Add(const std::string& sText, const char* sIcon, Color_t tColor, float flLifeTime, float flPanTime)
+{
+ float flTime = SDK::PlatFloatTime();
+ m_vNotifications.emplace_back(sText, sIcon, flTime, flLifeTime, flPanTime, tColor);
+ if (m_vNotifications.size() > Vars::Logging::MaxNotifications.Value)
+ {
+ for (int i = 0; i < m_vNotifications.size() - Vars::Logging::MaxNotifications.Value; i++)
+ {
+ auto& tNotification = m_vNotifications[i];
+ if (!tNotification.m_flLifeTime)
+ continue;
+
+ tNotification.m_flCreateTime = flTime - tNotification.m_flPanTime;
+ tNotification.m_flLifeTime = 0.f;
+ }
+ //m_vNotifications.pop_front();
+ }
+}
+
+void CNotifications::Add(const std::string& sText, Color_t tColor, float flLifeTime, float flPanTime)
+{
+ Add(sText, nullptr, tColor, flLifeTime, flPanTime);
+}
+
+static inline bool ShouldReverseX()
+{
+ switch (Vars::Logging::NotificationPosition.Value)
+ {
+ case Vars::Logging::NotificationPositionEnum::TopLeft:
+ case Vars::Logging::NotificationPositionEnum::BottomLeft:
+ return false;
+ case Vars::Logging::NotificationPositionEnum::TopRight:
+ case Vars::Logging::NotificationPositionEnum::BottomRight:
+ return true;
+ }
+ return false;
+}
+static inline bool ShouldReverseY()
+{
+ switch (Vars::Logging::NotificationPosition.Value)
+ {
+ case Vars::Logging::NotificationPositionEnum::TopLeft:
+ case Vars::Logging::NotificationPositionEnum::TopRight:
+ return false;
+ case Vars::Logging::NotificationPositionEnum::BottomLeft:
+ case Vars::Logging::NotificationPositionEnum::BottomRight:
+ return true;
+ }
+ return false;
+}
+static inline int X()
+{
+ return ShouldReverseX() ? -1 : 1;
+}
+static inline int Y()
+{
+ return ShouldReverseY() ? -1 : 1;
+}
+
+void CNotifications::Draw()
+{
+ using namespace ImGui;
+
+ for (auto it = m_vNotifications.begin(); it != m_vNotifications.end();)
+ {
+ if (it->m_flCreateTime + it->m_flLifeTime + it->m_flPanTime * 3 < SDK::PlatFloatTime())
+ it = m_vNotifications.erase(it);
+ else
+ ++it;
+ }
+ if (m_vNotifications.empty())
+ return;
+
+ ImDrawList* pDrawList = GetForegroundDrawList();
+
+ float h = H::Draw.Scale(40);
+ float y = ShouldReverseY() ? GetIO().DisplaySize.y - H::Draw.Scale(8) - h : H::Draw.Scale(8);
+ for (auto& tNotification : m_vNotifications)
+ {
+ bool bIcon = tNotification.m_sIcon;
+
+ float w = CalcTextSize(tNotification.m_sText.c_str()).x + H::Draw.Scale(bIcon ? 54 : 30);
+ float x = ShouldReverseX() ? GetIO().DisplaySize.x - H::Draw.Scale(8) - w : H::Draw.Scale(8);
+
+ float flEaseX = 1.f, flEaseY = 1.f;
+ float flTime = SDK::PlatFloatTime();
+ float flCreate = tNotification.m_flCreateTime;
+ float flPan = tNotification.m_flPanTime;
+ float flLife = tNotification.m_flLifeTime + flPan * 2;
+ if (flPan)
+ {
+ if (float flDelta = flTime - flCreate; flDelta < flPan)
+ flEaseX = EASE_IN(Math::RemapVal(flDelta, 0.f, flPan, 0.f, 1.f));
+ else if (float flDelta = flCreate + flLife - flTime; flDelta < flPan)
+ flEaseX = EASE_OUT(Math::RemapVal(flDelta, 0.f, flPan, 0.f, 1.f));
+ if (float flDelta = flCreate + flLife + flPan - flTime; flDelta < flPan)
+ flEaseY = EASE_Y(Math::RemapVal(flDelta, 0.f, flPan, 0.f, 1.f));
+ }
+ flLife = Math::RemapVal(flCreate + flLife - flPan - flTime, 0.f, flLife, 0.f, 1.f);
+
+ x -= (w + H::Draw.Scale(8)) * (1.f - flEaseX) * X();
+
+ ImU32 uBackground = F::Render.Background0;
+ ImU32 uBorder = F::Render.Background2;
+ ImU32 uActive = F::Render.Active;
+ ImU32 uAccentOpaque = ColorByteToInt(tNotification.m_tColor.Alpha(255));
+ ImU32 uAccentTransparent = ColorByteToInt(tNotification.m_tColor.Alpha(50));
+
+ ImVec2 vDrawPos = { x, y };
+ ImVec2 vSize = { w, h };
+ float flInset = H::Draw.Scale();
+
+ pDrawList->AddRectFilled(vDrawPos + ImVec2(flInset, flInset), vDrawPos + vSize - ImVec2(flInset, flInset), uBackground, H::Draw.Scale(3));
+ pDrawList->PushClipRect(vDrawPos + ImVec2(flInset, h - flInset - H::Draw.Scale(2)), vDrawPos + ImVec2(w - flInset, h - flInset), false);
+ pDrawList->AddRectFilled(vDrawPos + ImVec2(flInset, flInset), vDrawPos + vSize - ImVec2(flInset, flInset), uAccentTransparent, H::Draw.Scale(3));
+ pDrawList->PopClipRect();
+ pDrawList->PushClipRect(vDrawPos + ImVec2(flInset, h - flInset - H::Draw.Scale(2)), vDrawPos + ImVec2((w - flInset) * flLife, h - flInset), false);
+ pDrawList->AddRectFilled(vDrawPos + ImVec2(flInset, flInset), vDrawPos + vSize - ImVec2(flInset, flInset), uAccentOpaque, H::Draw.Scale(3));
+ pDrawList->PopClipRect();
+ flInset += H::Draw.Scale(0.5f) - 0.5f - H::Draw.Scale();
+ pDrawList->AddRect(vDrawPos + ImVec2(flInset, flInset), vDrawPos + vSize - ImVec2(flInset, flInset), uBorder, H::Draw.Scale(4), ImDrawFlags_None, H::Draw.Scale());
+ if (!bIcon)
+ pDrawList->AddText(vDrawPos + ImVec2(H::Draw.Scale(15), H::Draw.Scale(13)), uActive, tNotification.m_sText.c_str());
+ else
+ {
+ pDrawList->AddText(vDrawPos + ImVec2(H::Draw.Scale(39), H::Draw.Scale(13)), uActive, tNotification.m_sText.c_str());
+ pDrawList->AddText(F::Render.IconFont, F::Render.IconFont->LegacySize, vDrawPos + ImVec2(H::Draw.Scale(12), H::Draw.Scale(12)), uAccentOpaque, tNotification.m_sIcon);
+ }
+
+ y += (h + H::Draw.Scale(8, Scale_Round)) * (flEaseY) * Y();
+ }
+}
\ No newline at end of file
diff --git a/Amalgam/src/Features/ImGui/Notifications/Notifications.h b/Amalgam/src/Features/ImGui/Notifications/Notifications.h
new file mode 100644
index 00000000..6f38c361
--- /dev/null
+++ b/Amalgam/src/Features/ImGui/Notifications/Notifications.h
@@ -0,0 +1,26 @@
+#pragma once
+#include "../../../SDK/SDK.h"
+
+struct Notification_t
+{
+ std::string m_sText = "";
+ const char* m_sIcon = nullptr;
+ float m_flCreateTime = 0.f;
+ float m_flLifeTime = 0.f;
+ float m_flPanTime = 0.f;
+
+ Color_t m_tColor = {};
+};
+
+class CNotifications
+{
+private:
+ std::deque m_vNotifications;
+
+public:
+ void Add(const std::string& sText, const char* sIcon, Color_t tColor = Vars::Menu::Theme::Accent.Value, float flLifeTime = Vars::Logging::NotificationTime.Value, float flPanTime = 0.2f);
+ void Add(const std::string& sText, Color_t tColor = Vars::Menu::Theme::Accent.Value, float flLifeTime = Vars::Logging::NotificationTime.Value, float flPanTime = 0.2f);
+ void Draw();
+};
+
+ADD_FEATURE(CNotifications, Notifications);
\ No newline at end of file
diff --git a/Amalgam/src/Features/ImGui/Render.cpp b/Amalgam/src/Features/ImGui/Render.cpp
index eebeb106..18b76163 100644
--- a/Amalgam/src/Features/ImGui/Render.cpp
+++ b/Amalgam/src/Features/ImGui/Render.cpp
@@ -8,6 +8,7 @@
#include "Fonts/Roboto/RobotoMedium.h"
#include "Fonts/Roboto/RobotoBlack.h"
#include "Menu/Menu.h"
+#include "Menu/Components.h"
void CRender::Render(IDirect3DDevice9* pDevice)
{
@@ -41,22 +42,19 @@ void CRender::Render(IDirect3DDevice9* pDevice)
void CRender::LoadColors()
{
- auto fColorToVec = [](Color_t tColor) -> ImColor
- {
- return { tColor.r / 255.f, tColor.g / 255.f, tColor.b / 255.f, tColor.a / 255.f };
- };
+ using namespace ImGui;
- Accent = fColorToVec(Vars::Menu::Theme::Accent.Value);
- Background0 = fColorToVec(Vars::Menu::Theme::Background.Value);
- Background0p5 = fColorToVec(Vars::Menu::Theme::Background.Value.Lerp({ 127, 127, 127 }, 0.5f / 9, LerpEnum::NoAlpha));
- Background1 = fColorToVec(Vars::Menu::Theme::Background.Value.Lerp({ 127, 127, 127 }, 1.f / 9, LerpEnum::NoAlpha));
- Background1p5 = fColorToVec(Vars::Menu::Theme::Background.Value.Lerp({ 127, 127, 127 }, 1.5f / 9, LerpEnum::NoAlpha));
+ Accent = ColorByteToFloat(Vars::Menu::Theme::Accent.Value);
+ Background0 = ColorByteToFloat(Vars::Menu::Theme::Background.Value);
+ Background0p5 = ColorByteToFloat(Vars::Menu::Theme::Background.Value.Lerp({ 127, 127, 127 }, 0.5f / 9, LerpEnum::NoAlpha));
+ Background1 = ColorByteToFloat(Vars::Menu::Theme::Background.Value.Lerp({ 127, 127, 127 }, 1.f / 9, LerpEnum::NoAlpha));
+ Background1p5 = ColorByteToFloat(Vars::Menu::Theme::Background.Value.Lerp({ 127, 127, 127 }, 1.5f / 9, LerpEnum::NoAlpha));
Background1p5L = { Background1p5.Value.x * 1.1f, Background1p5.Value.y * 1.1f, Background1p5.Value.z * 1.1f, Background1p5.Value.w };
- Background2 = fColorToVec(Vars::Menu::Theme::Background.Value.Lerp({ 127, 127, 127 }, 2.f / 9, LerpEnum::NoAlpha));
- Inactive = fColorToVec(Vars::Menu::Theme::Inactive.Value);
- Active = fColorToVec(Vars::Menu::Theme::Active.Value);
+ Background2 = ColorByteToFloat(Vars::Menu::Theme::Background.Value.Lerp({ 127, 127, 127 }, 2.f / 9, LerpEnum::NoAlpha));
+ Inactive = ColorByteToFloat(Vars::Menu::Theme::Inactive.Value);
+ Active = ColorByteToFloat(Vars::Menu::Theme::Active.Value);
- ImVec4* colors = ImGui::GetStyle().Colors;
+ ImVec4* colors = GetStyle().Colors;
colors[ImGuiCol_Border] = Background2;
colors[ImGuiCol_Button] = {};
colors[ImGuiCol_ButtonHovered] = {};
@@ -79,7 +77,9 @@ void CRender::LoadColors()
void CRender::LoadFonts()
{
- auto& io = ImGui::GetIO();
+ using namespace ImGui;
+
+ auto& io = GetIO();
if (static bool bLoaded = false; !bLoaded)
bLoaded = true;
@@ -112,7 +112,9 @@ void CRender::LoadFonts()
void CRender::LoadStyle()
{
- auto& style = ImGui::GetStyle();
+ using namespace ImGui;
+
+ auto& style = GetStyle();
style.ButtonTextAlign = { 0.5f, 0.5f };
style.CellPadding = { H::Draw.Scale(4), 0 };
style.ChildBorderSize = 0.f;
diff --git a/Amalgam/src/Features/Output/Output.cpp b/Amalgam/src/Features/Output/Output.cpp
index 57f896fb..88beb52e 100644
--- a/Amalgam/src/Features/Output/Output.cpp
+++ b/Amalgam/src/Features/Output/Output.cpp
@@ -1,25 +1,27 @@
#include "Output.h"
-#include "../Visuals/Notifications/Notifications.h"
+#include "../ImGui/Notifications/Notifications.h"
#include "../Players/PlayerUtils.h"
static std::string s_sRed = Color_t(255, 100, 100).ToHex();
static std::string s_sGreen = Color_t(100, 255, 100).ToHex();
static std::string s_sYellow = Color_t(200, 169, 0).ToHex();
-static inline void OutputInfo(int iFlags, const char* sName, const char* sOutput, const char* sColor)
+static inline void OutputInfo(int iFlags, const char* sName,
+ const char* sOutput, const char* sColor,
+ const char* sIcon = nullptr, Color_t tColor = Vars::Menu::Theme::Accent.Value)
{
- int iTo = (iFlags & Vars::Logging::LogToEnum::Console ? OUTPUT_CONSOLE : 0)
- | (iFlags & Vars::Logging::LogToEnum::Debug ? OUTPUT_DEBUG : 0)
- | (iFlags & Vars::Logging::LogToEnum::Toasts ? OUTPUT_TOAST : 0)
- | (iFlags & Vars::Logging::LogToEnum::Menu ? OUTPUT_MENU : 0)
- | (iFlags & Vars::Logging::LogToEnum::Party ? OUTPUT_PARTY : 0);
- if (iTo)
- SDK::Output(sName, sOutput, Vars::Menu::Theme::Accent.Value, iTo);
+ int iTo;
- iTo = (iFlags & Vars::Logging::LogToEnum::Chat ? OUTPUT_CHAT : 0);
- if (iTo)
- SDK::Output(Vars::Menu::CheatTag.Value.c_str(), sColor, Vars::Menu::Theme::Accent.Value, iTo, -1, "", "");
+ if (iTo = (iFlags & Vars::Logging::LogToEnum::Toasts ? OUTPUT_TOAST : 0)
+ | (iFlags & Vars::Logging::LogToEnum::Party ? OUTPUT_PARTY : 0)
+ | (iFlags & Vars::Logging::LogToEnum::Console ? OUTPUT_CONSOLE : 0)
+ | (iFlags & Vars::Logging::LogToEnum::Menu ? OUTPUT_MENU : 0)
+ | (iFlags & Vars::Logging::LogToEnum::Debug ? OUTPUT_DEBUG : 0))
+ SDK::Output(sName, sOutput, tColor, iTo, sIcon);
+
+ if (iTo = (iFlags & Vars::Logging::LogToEnum::Chat ? OUTPUT_CHAT : 0))
+ SDK::Output(Vars::Menu::CheatTag.Value.c_str(), sColor, tColor, iTo, nullptr, MB_NONE, "", "");
}
// Event info
@@ -55,7 +57,8 @@ void COutput::Event(IGameEvent* pEvent, uint32_t uHash, CTFPlayer* pLocal)
bool bSameTeam = pEntity->As()->m_iTeamNum() == pLocal->m_iTeamNum();
OutputInfo(Vars::Logging::VoteCast::LogTo.Value, "Vote Cast",
std::format("{}{} voted {}", (bSameTeam ? "" : "[Enemy] "), (sName), (bVotedYes ? "Yes" : "No")).c_str(),
- std::format("{}{}{}\x1 voted {}{}", (bSameTeam ? "" : "[Enemy] "), (s_sYellow), (sName), (bVotedYes ? s_sGreen : s_sRed), (bVotedYes ? "Yes" : "No")).c_str()
+ std::format("{}{}{}\x1 voted {}{}", (bSameTeam ? "" : "[Enemy] "), (s_sYellow), (sName), (bVotedYes ? s_sGreen : s_sRed), (bVotedYes ? "Yes" : "No")).c_str(),
+ ICON_MD_HOW_TO_VOTE
);
return;
@@ -78,7 +81,8 @@ void COutput::Event(IGameEvent* pEvent, uint32_t uHash, CTFPlayer* pLocal)
bool bSameTeam = pEntity->As()->m_iTeamNum() == pLocal->m_iTeamNum();
OutputInfo(Vars::Logging::ClassChange::LogTo.Value, "Class Change",
std::format("{}{} changed class to {}", (bSameTeam ? "" : "[Enemy] "), (sName), (SDK::GetClassByIndex(pEvent->GetInt("class")))).c_str(),
- std::format("{}{}{}\x1 changed class to {}{}", (bSameTeam ? "" : "[Enemy] "), (s_sYellow), (sName), (s_sYellow), (SDK::GetClassByIndex(pEvent->GetInt("class")))).c_str()
+ std::format("{}{}{}\x1 changed class to {}{}", (bSameTeam ? "" : "[Enemy] "), (s_sYellow), (sName), (s_sYellow), (SDK::GetClassByIndex(pEvent->GetInt("class")))).c_str(),
+ ICON_MD_INFO
);
return;
@@ -110,7 +114,8 @@ void COutput::Event(IGameEvent* pEvent, uint32_t uHash, CTFPlayer* pLocal)
auto sName = F::PlayerUtils.GetPlayerName(iIndex, pResource->GetName(iIndex));
OutputInfo(Vars::Logging::Damage::LogTo.Value, "Damage",
std::format("Hit {} for {} damage ({} / {}{})", (sName), (nDamage), (nHealth), (iMaxHealth), (bCrit ? ", crit" : bMinicrit ? ", minicrit" : "")).c_str(),
- std::format("Hit {}{}\x1 for {}{} damage{} ({} / {}{})", (s_sYellow), (sName), (s_sRed), (nDamage), (s_sYellow), (nHealth), (iMaxHealth), (bCrit ? ", crit" : bMinicrit ? ", minicrit" : "")).c_str()
+ std::format("Hit {}{}\x1 for {}{} damage{} ({} / {}{})", (s_sYellow), (sName), (s_sRed), (nDamage), (s_sYellow), (nHealth), (iMaxHealth), (bCrit ? ", crit" : bMinicrit ? ", minicrit" : "")).c_str(),
+ ICON_MD_INFO
);
return;
@@ -190,7 +195,8 @@ void COutput::UserMessage(bf_read& msgData)
}
OutputInfo(Vars::Logging::VoteStart::LogTo.Value, "Vote Start",
std::format("{}{} called a vote on {} ({})", (bSameTeam ? "" : "[Enemy] "), (sCallerName), (sTargetName), (sReason)).c_str(),
- std::format("{}{}{}\x1 called a vote on {}{}\x1 ({})", (bSameTeam ? "" : "[Enemy] "), (s_sYellow), (sCallerName), (s_sYellow), (sTargetName), (sReason)).c_str()
+ std::format("{}{}{}\x1 called a vote on {}{}\x1 ({})", (bSameTeam ? "" : "[Enemy] "), (s_sYellow), (sCallerName), (s_sYellow), (sTargetName), (sReason)).c_str(),
+ ICON_MD_BALLOT
);
}
@@ -212,7 +218,8 @@ void COutput::CheatDetection(const char* sName, const char* sAction, const char*
OutputInfo(Vars::Logging::CheatDetection::LogTo.Value, "Cheat Detection",
std::format("{} {} for {}", (sName), (sAction), (sReason)).c_str(),
- std::format("{}{}\x1 {} for {}{}", (s_sYellow), (sName), (sAction), (s_sYellow), (sReason)).c_str()
+ std::format("{}{}\x1 {} for {}{}", (s_sYellow), (sName), (sAction), (s_sYellow), (sReason)).c_str(),
+ ICON_MD_INFO, F::PlayerUtils.m_vTags[F::PlayerUtils.TagToIndex(CHEATER_TAG)].m_tColor
);
}
@@ -300,7 +307,8 @@ void COutput::TagsOnJoin(const char* sName, uint32_t uAccountID)
OutputInfo(Vars::Logging::Tags::LogTo.Value, "Tags",
std::format("{} has the {} {}", (sName), (vColorsTags.size() == 1 ? "tag" : "tags"), (sOutputText)).c_str(),
- std::format("{}{}\x1 has the {} {}", (s_sYellow), (sName), (vColorsTags.size() == 1 ? "tag" : "tags"), (sChatText)).c_str()
+ std::format("{}{}\x1 has the {} {}", (s_sYellow), (sName), (vColorsTags.size() == 1 ? "tag" : "tags"), (sChatText)).c_str(),
+ ICON_MD_INFO, INFO_COLOR
);
}
void COutput::TagsChanged(const char* sName, const char* sAction, const char* sColor, const char* sTag)
@@ -311,7 +319,8 @@ void COutput::TagsChanged(const char* sName, const char* sAction, const char* sC
auto uHash = FNV1A::Hash32(sAction);
OutputInfo(Vars::Logging::Tags::LogTo.Value, "Tags",
std::format("{} tag {} {} {}", (sAction), (sTag), (uHash == FNV1A::Hash32Const("Added") ? "to" : "from"), (sName)).c_str(),
- std::format("{} tag {}{}\x1 {} {}{}", (sAction), (sColor), (sTag), (uHash == FNV1A::Hash32Const("Added") ? "to" : "from"), (s_sYellow), (sName)).c_str()
+ std::format("{} tag {}{}\x1 {} {}{}", (sAction), (sColor), (sTag), (uHash == FNV1A::Hash32Const("Added") ? "to" : "from"), (s_sYellow), (sName)).c_str(),
+ ICON_MD_INFO, INFO_COLOR
);
}
@@ -328,7 +337,8 @@ void COutput::AliasOnJoin(const char* sName, uint32_t uAccountID)
OutputInfo(Vars::Logging::Tags::LogTo.Value, "Aliases",
std::format("{} has the alias \"{}\"", (sName), (sAlias)).c_str(),
- std::format("{}{}\x1 has the alias \"{}{}\x1\"", (s_sYellow), (sName), (s_sYellow), (sAlias)).c_str()
+ std::format("{}{}\x1 has the alias \"{}{}\x1\"", (s_sYellow), (sName), (s_sYellow), (sAlias)).c_str(),
+ ICON_MD_INFO, INFO_COLOR
);
}
void COutput::AliasChanged(const char* sName, const char* sAction, const char* sAlias)
@@ -339,7 +349,8 @@ void COutput::AliasChanged(const char* sName, const char* sAction, const char* s
auto uHash = FNV1A::Hash32(sAction);
OutputInfo(Vars::Logging::Tags::LogTo.Value, "Aliases",
std::format("{} {}'s alias {} \"{}\"", (sAction), (sName), (uHash == FNV1A::Hash32Const("Changed") ? "to" : "of"), (sAlias)).c_str(),
- std::format("{} {}{}\x1's alias {} \"{}{}\x1\"", (sAction), (s_sYellow), (sName), (uHash == FNV1A::Hash32Const("Changed") ? "to" : "of"), (s_sYellow), (sAlias)).c_str()
+ std::format("{} {}{}\x1's alias {} \"{}{}\x1\"", (sAction), (s_sYellow), (sName), (uHash == FNV1A::Hash32Const("Changed") ? "to" : "of"), (s_sYellow), (sAlias)).c_str(),
+ ICON_MD_INFO, INFO_COLOR
);
}
@@ -363,7 +374,8 @@ void COutput::ReportResolver(int iIndex, const char* sAction, const char* sAxis,
auto sName = F::PlayerUtils.GetPlayerName(iIndex, pResource->GetName(iIndex));
OutputInfo(Vars::Logging::Tags::LogTo.Value, "Resolver",
std::format("{} {} of {} to {}", (sAction), (sAxis), (sName), (sValue)).c_str(),
- std::format("{} {}{}\x1 of {}{}\x1 to {}{}\x1", (sAction), (s_sYellow), (sAxis), (s_sYellow), (sName), (s_sYellow), (sValue)).c_str()
+ std::format("{} {}{}\x1 of {}{}\x1 to {}{}\x1", (sAction), (s_sYellow), (sAxis), (s_sYellow), (sName), (s_sYellow), (sValue)).c_str(),
+ ICON_MD_INFO
);
}
void COutput::ReportResolver(const char* sMessage)
@@ -371,5 +383,9 @@ void COutput::ReportResolver(const char* sMessage)
if (!(Vars::Logging::Logs.Value & Vars::Logging::LogsEnum::Resolver))
return;
- OutputInfo(Vars::Logging::Tags::LogTo.Value, "Resolver", sMessage, sMessage);
+ OutputInfo(Vars::Logging::Tags::LogTo.Value, "Resolver",
+ sMessage,
+ sMessage,
+ ICON_MD_INFO
+ );
}
\ No newline at end of file
diff --git a/Amalgam/src/Features/Players/PlayerCore.cpp b/Amalgam/src/Features/Players/PlayerCore.cpp
index 4fc990e3..e1ca5265 100644
--- a/Amalgam/src/Features/Players/PlayerCore.cpp
+++ b/Amalgam/src/Features/Players/PlayerCore.cpp
@@ -74,11 +74,11 @@ void CPlayerlistCore::SavePlayerlist()
write_json(F::Configs.m_sCorePath + "Players.json", tWrite);
- SDK::Output("Amalgam", "Saved playerlist", DEFAULT_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Saved playerlist", INFO_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_INFO);
}
catch (...)
{
- SDK::Output("Amalgam", "Save playerlist failed", ALTERNATE_COLOR, OUTPUT_CONSOLE | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Save playerlist failed", ERROR_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_CANCEL);
}
}
@@ -132,7 +132,7 @@ void CPlayerlistCore::LoadPlayerlist()
}
}
else
- SDK::Output("Amalgam", "Playerlist config not found", ALTERNATE_COLOR, OUTPUT_CONSOLE | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Playerlist config not found", ERROR_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_CANCEL);
if (auto tSub = tRead.get_child_optional("Tags"))
{
@@ -154,7 +154,7 @@ void CPlayerlistCore::LoadPlayerlist()
}
}
else
- SDK::Output("Amalgam", "Playerlist tags not found", ALTERNATE_COLOR, OUTPUT_CONSOLE | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Playerlist tags not found", ERROR_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_CANCEL);
if (auto tSub = tRead.get_child_optional("Aliases"))
{
@@ -168,13 +168,13 @@ void CPlayerlistCore::LoadPlayerlist()
}
}
else
- SDK::Output("Amalgam", "Playerlist aliases not found", ALTERNATE_COLOR, OUTPUT_CONSOLE | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Playerlist aliases not found", ERROR_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_CANCEL);
- SDK::Output("Amalgam", "Loaded playerlist", DEFAULT_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Loaded playerlist", INFO_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_INFO);
}
catch (...)
{
- SDK::Output("Amalgam", "Load playerlist failed", ALTERNATE_COLOR, OUTPUT_CONSOLE | OUTPUT_MENU | OUTPUT_DEBUG);
+ SDK::Output("Amalgam", "Load playerlist failed", ERROR_COLOR, OUTPUT_CONSOLE | OUTPUT_TOAST | OUTPUT_MENU | OUTPUT_DEBUG, ICON_MD_CANCEL);
}
F::PlayerUtils.m_bLoad = false;
diff --git a/Amalgam/src/Features/Visuals/Notifications/Notifications.cpp b/Amalgam/src/Features/Visuals/Notifications/Notifications.cpp
deleted file mode 100644
index 5b9c57b5..00000000
--- a/Amalgam/src/Features/Visuals/Notifications/Notifications.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-#include "Notifications.h"
-
-static inline float EaseInOutCubic(float x)
-{
- return x < 0.5f ? 4 * powf(x, 3) : 1 - powf(-2 * x + 2, 3) / 2;
-}
-
-void CNotifications::Add(const std::string& sText, Color_t tColor, float flLifeTime, float flPanTime)
-{
- m_vNotifications.emplace_back(sText, float(SDK::PlatFloatTime()), flLifeTime, flPanTime, tColor);
- while (m_vNotifications.size() > m_iMaxNotifySize)
- m_vNotifications.pop_front();
-}
-
-static inline bool ShouldReverseX()
-{
- switch (Vars::Logging::NotificationPosition.Value)
- {
- case Vars::Logging::NotificationPositionEnum::TopLeft:
- case Vars::Logging::NotificationPositionEnum::BottomLeft:
- return false;
- case Vars::Logging::NotificationPositionEnum::TopRight:
- case Vars::Logging::NotificationPositionEnum::BottomRight:
- return true;
- }
- return false;
-}
-
-static inline bool ShouldReverseY()
-{
- switch (Vars::Logging::NotificationPosition.Value)
- {
- case Vars::Logging::NotificationPositionEnum::TopLeft:
- case Vars::Logging::NotificationPositionEnum::TopRight:
- return false;
- case Vars::Logging::NotificationPositionEnum::BottomLeft:
- case Vars::Logging::NotificationPositionEnum::BottomRight:
- return true;
- }
- return false;
-}
-
-void CNotifications::Draw()
-{
- for (auto it = m_vNotifications.begin(); it != m_vNotifications.end();)
- {
- if (it->m_flCreateTime + it->m_flLifeTime + it->m_flPanTime < SDK::PlatFloatTime())
- it = m_vNotifications.erase(it);
- else
- ++it;
- }
- if (m_vNotifications.empty())
- return;
-
- const auto& fFont = H::Fonts.GetFont(FONT_INDICATORS);
-
- int h = H::Draw.Scale(40, Scale_Round);
- int y = !ShouldReverseY() ? H::Draw.Scale(8, Scale_Round) : H::Draw.m_nScreenH - H::Draw.Scale(8, Scale_Round) - h;
- for (auto& tNotification : m_vNotifications)
- {
- int w = H::Draw.GetTextSize(tNotification.m_sText.c_str(), fFont).x + H::Draw.Scale(30, Scale_Round);
- int x = !ShouldReverseX() ? H::Draw.Scale(8, Scale_Round) : H::Draw.m_nScreenW - H::Draw.Scale(8, Scale_Round) - w;
-
- float flEaseX = 1.f, flEaseY = 1.f;
- float flTime = SDK::PlatFloatTime();
- float flCreate = tNotification.m_flCreateTime;
- float flLife = tNotification.m_flLifeTime;
- float flPan = tNotification.m_flPanTime;
- if (flPan)
- {
- float flDelta = std::min(flTime - flCreate, flCreate + flLife - flTime);
- if (flDelta < flPan)
- flEaseX = EaseInOutCubic(Math::RemapVal(flDelta, 0.f, flPan, 0.f, 1.f));
-
- flDelta = flCreate + flLife + flPan - flTime;
- if (flDelta < flPan)
- flEaseY = EaseInOutCubic(Math::RemapVal(flDelta, 0.f, flPan, 0.f, 1.f));
- }
- flLife = Math::RemapVal(flCreate + flLife - flPan - flTime, 0.f, flLife, 0.f, 1.f);
-
- x -= (w + H::Draw.Scale(8, Scale_Round)) * (1.f - flEaseX) * (!ShouldReverseX() ? 1 : -1);
-
- Color_t tAccent = tNotification.m_tColor;
- Color_t tBackground = Vars::Menu::Theme::Background.Value;
- Color_t tActive = Vars::Menu::Theme::Active.Value;
-
- H::Draw.FillRoundRect(x + 1, y + 1, w - 2, h - 2, H::Draw.Scale(3, Scale_Round), tBackground, 16);
- H::Draw.StartClipping(x + 1, y + h - 1 - H::Draw.Scale(2, Scale_Round), w - 2, H::Draw.Scale(2, Scale_Round));
- H::Draw.FillRoundRect(x + 1, y + 1, w - 2, h - 2, H::Draw.Scale(3, Scale_Round), tAccent.Alpha(50), 16);
- H::Draw.StartClipping(x + 1, y + h - 1 - H::Draw.Scale(2, Scale_Round), (w - 2) * flLife, H::Draw.Scale(2, Scale_Round));
- H::Draw.FillRoundRect(x + 1, y + 1, w - 2, h - 2, H::Draw.Scale(3, Scale_Round), tAccent.Alpha(255), 16);
- H::Draw.EndClipping();
- H::Draw.LineRoundRect(x, y, w, h, H::Draw.Scale(4, Scale_Round), tBackground.Lerp({ 127, 127, 127 }, 2.f / 9), 16);
- H::Draw.StringOutlined(fFont, x + H::Draw.Scale(15, Scale_Round), y + H::Draw.Scale(13, Scale_Round), tActive.Alpha(255), Vars::Menu::Theme::Background.Value, ALIGN_TOPLEFT, tNotification.m_sText.c_str());
-
- y += (h + H::Draw.Scale(8, Scale_Round)) * (flEaseY) * (!ShouldReverseY() ? 1 : -1);
- }
-}
\ No newline at end of file
diff --git a/Amalgam/src/Features/Visuals/Notifications/Notifications.h b/Amalgam/src/Features/Visuals/Notifications/Notifications.h
deleted file mode 100644
index f20672a0..00000000
--- a/Amalgam/src/Features/Visuals/Notifications/Notifications.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#pragma once
-#include "../../../SDK/SDK.h"
-
-struct Notification_t
-{
- std::string m_sText;
- float m_flCreateTime;
- float m_flLifeTime;
- float m_flPanTime;
-
- Color_t m_tColor;
-};
-
-class CNotifications
-{
-private:
- std::deque m_vNotifications;
- size_t m_iMaxNotifySize = 10;
-
-public:
- void Add(const std::string& sText, Color_t tColor = Vars::Menu::Theme::Accent.Value, float flLifeTime = Vars::Logging::Lifetime.Value, float flPanTime = 0.2f);
- void Draw();
-};
-
-ADD_FEATURE(CNotifications, Notifications);
\ No newline at end of file
diff --git a/Amalgam/src/Hooks/IEngineVGui_Paint.cpp b/Amalgam/src/Hooks/IEngineVGui_Paint.cpp
index e30788ab..dc2f0972 100644
--- a/Amalgam/src/Hooks/IEngineVGui_Paint.cpp
+++ b/Amalgam/src/Hooks/IEngineVGui_Paint.cpp
@@ -1,6 +1,5 @@
#include "../SDK/SDK.h"
-#include "../Features/Visuals/Notifications/Notifications.h"
#include "../Features/Visuals/ESP/ESP.h"
#include "../Features/Visuals/OffscreenArrows/OffscreenArrows.h"
#include "../Features/Visuals/CameraWindow/CameraWindow.h"
@@ -24,7 +23,11 @@ MAKE_HOOK(IEngineVGui_Paint, U::Memory.GetVirtual(I::EngineVGui, 14), void,
if (G::Unload)
return CALL_ORIGINAL(rcx, iMode);
- if (iMode & PAINT_INGAMEPANELS && !SDK::CleanScreenshot())
+ if (iMode & PAINT_UIPANELS)
+ {
+ H::Draw.UpdateKeyStrings();
+ }
+ else if (iMode & PAINT_INGAMEPANELS && !SDK::CleanScreenshot())
{
H::Draw.UpdateScreenSize();
H::Draw.UpdateW2SMatrix();
@@ -59,15 +62,4 @@ MAKE_HOOK(IEngineVGui_Paint, U::Memory.GetVirtual(I::EngineVGui, 14), void,
CALL_ORIGINAL(rcx, iMode);
- if (iMode & PAINT_UIPANELS && !SDK::CleanScreenshot())
- {
- H::Draw.UpdateScreenSize();
- H::Draw.UpdateKeyStrings();
-
- H::Draw.Start();
- {
- F::Notifications.Draw();
- }
- H::Draw.End();
- }
}
\ No newline at end of file
diff --git a/Amalgam/src/SDK/SDK.cpp b/Amalgam/src/SDK/SDK.cpp
index 201077ac..2121076f 100644
--- a/Amalgam/src/SDK/SDK.cpp
+++ b/Amalgam/src/SDK/SDK.cpp
@@ -1,6 +1,6 @@
#include "SDK.h"
-#include "../Features/Visuals/Notifications/Notifications.h"
+#include "../Features/ImGui/Notifications/Notifications.h"
#include "../Features/ImGui/Menu/Menu.h"
#include "../Features/EnginePrediction/EnginePrediction.h"
@@ -33,7 +33,7 @@ static BOOL CALLBACK TeamFortressWindow(HWND hWindow, LPARAM lParam)
void SDK::Output(const char* sFunction, const char* sLog, Color_t tColor,
- int iTo, int iMessageBox,
+ int iTo, const char* sIcon, int iMessageBox,
const char* sLeft, const char* sRight)
{
if (sLog)
@@ -46,7 +46,7 @@ void SDK::Output(const char* sFunction, const char* sLog, Color_t tColor,
if (iTo & OUTPUT_DEBUG)
OutputDebugString(std::format("{}{}{} {}\n", sLeft, sFunction, sRight, sLog).c_str());
if (iTo & OUTPUT_TOAST)
- F::Notifications.Add(sLog, tColor);
+ F::Notifications.Add(sLog, sIcon, tColor);
if (iTo & OUTPUT_MENU)
F::Menu.AddOutput(std::format("{}{}{}", sLeft, sFunction, sRight).c_str(), sLog, tColor);
if (iTo & OUTPUT_CHAT)
@@ -63,7 +63,7 @@ void SDK::Output(const char* sFunction, const char* sLog, Color_t tColor,
if (iTo & OUTPUT_DEBUG)
OutputDebugString(std::format("{}\n", sFunction).c_str());
if (iTo & OUTPUT_TOAST)
- F::Notifications.Add(sFunction, tColor);
+ F::Notifications.Add(sFunction, sIcon, tColor);
if (iTo & OUTPUT_MENU)
F::Menu.AddOutput("", sFunction, tColor);
if (iTo & OUTPUT_CHAT)
diff --git a/Amalgam/src/SDK/SDK.h b/Amalgam/src/SDK/SDK.h
index 3b5870e5..4d7e045e 100644
--- a/Amalgam/src/SDK/SDK.h
+++ b/Amalgam/src/SDK/SDK.h
@@ -19,61 +19,68 @@
#include "../Utils/Math/Math.h"
#include "../Utils/Timer/Timer.h"
#include "../Utils/Macros/Macros.h"
+#include "../Features/ImGui/Fonts/MaterialDesign/IconDefinitions.h"
#include
#include
+#define VK_0 0x30
+#define VK_1 0x31
+#define VK_2 0x32
+#define VK_3 0x33
+#define VK_4 0x34
+#define VK_5 0x35
+#define VK_6 0x36
+#define VK_7 0x37
+#define VK_8 0x38
+#define VK_9 0x39
+#define VK_A 0x41
+#define VK_B 0x42
+#define VK_C 0x43
+#define VK_D 0x44
+#define VK_E 0x45
+#define VK_F 0x46
+#define VK_G 0x47
+#define VK_H 0x48
+#define VK_I 0x49
+#define VK_J 0x4A
+#define VK_K 0x4B
+#define VK_L 0x4C
+#define VK_M 0x4D
+#define VK_N 0x4E
+#define VK_O 0x4F
+#define VK_P 0x50
+#define VK_Q 0x51
+#define VK_R 0x52
+#define VK_S 0x53
+#define VK_T 0x54
+#define VK_U 0x55
+#define VK_V 0x56
+#define VK_W 0x57
+#define VK_X 0x58
+#define VK_Y 0x59
+#define VK_Z 0x5A
+
+#define OUTPUT_NONE 0
+#define OUTPUT_CONSOLE 1 << 0
+#define OUTPUT_DEBUG 1 << 1
+#define OUTPUT_TOAST 1 << 2
+#define OUTPUT_MENU 1 << 3
+#define OUTPUT_CHAT 1 << 4
+#define OUTPUT_PARTY 1 << 5
+
+#define MB_NONE -1
+
#define DEFAULT_COLOR Color_t(175, 150, 255, 255)
#define ALTERNATE_COLOR Color_t(175, 150, 255, 127)
-
-#define VK_0 0x30
-#define VK_1 0x31
-#define VK_2 0x32
-#define VK_3 0x33
-#define VK_4 0x34
-#define VK_5 0x35
-#define VK_6 0x36
-#define VK_7 0x37
-#define VK_8 0x38
-#define VK_9 0x39
-#define VK_A 0x41
-#define VK_B 0x42
-#define VK_C 0x43
-#define VK_D 0x44
-#define VK_E 0x45
-#define VK_F 0x46
-#define VK_G 0x47
-#define VK_H 0x48
-#define VK_I 0x49
-#define VK_J 0x4A
-#define VK_K 0x4B
-#define VK_L 0x4C
-#define VK_M 0x4D
-#define VK_N 0x4E
-#define VK_O 0x4F
-#define VK_P 0x50
-#define VK_Q 0x51
-#define VK_R 0x52
-#define VK_S 0x53
-#define VK_T 0x54
-#define VK_U 0x55
-#define VK_V 0x56
-#define VK_W 0x57
-#define VK_X 0x58
-#define VK_Y 0x59
-#define VK_Z 0x5A
-
-#define OUTPUT_NONE 0
-#define OUTPUT_CONSOLE 1 << 0
-#define OUTPUT_DEBUG 1 << 1
-#define OUTPUT_TOAST 1 << 2
-#define OUTPUT_MENU 1 << 3
-#define OUTPUT_CHAT 1 << 4
-#define OUTPUT_PARTY 1 << 5
+#define SUCCESS_COLOR Color_t(50, 255, 100, 255)
+#define WARNING_COLOR Color_t(255, 200, 0, 255)
+#define ERROR_COLOR Color_t(255, 50, 50, 255)
+#define INFO_COLOR Color_t(50, 150, 255, 255)
namespace SDK
{
void Output(const char* sFunction, const char* sLog = nullptr, Color_t tColor = { 255, 255, 255, 255 },
- int iTo = OUTPUT_CONSOLE, int iMessageBox = -1,
+ int iTo = OUTPUT_CONSOLE, const char* sIcon = nullptr, int iMessageBox = MB_NONE,
const char* sLeft = "[", const char* sRight = "]");
void SetClipboard(const std::string& sString);
diff --git a/Amalgam/src/SDK/Vars.h b/Amalgam/src/SDK/Vars.h
index d43792ca..f4dfcdb8 100644
--- a/Amalgam/src/SDK/Vars.h
+++ b/Amalgam/src/SDK/Vars.h
@@ -833,7 +833,8 @@ NAMESPACE_BEGIN(Vars)
CVarEnum(NotificationPosition, "Notification position", 0, VISUAL, nullptr,
VA_LIST("Top left", "Top right", "Bottom left", "Bottom right"),
TopLeft, TopRight, BottomLeft, BottomRight);
- CVar(Lifetime, "Notification time", 5.f, VISUAL, 0.5f, 5.f, 0.5f);
+ CVar(NotificationTime, "Notification time", 5.f, VISUAL, 0.5f, 5.f, 0.5f);
+ CVar(MaxNotifications, "Max notifications", 10, VISUAL | SLIDER_MIN, 1, 10);
NAMESPACE_BEGIN(VoteStart, Logging)
CVarValues(LogTo, "Vote start log to", 0b000001, DROPDOWN_MULTI, nullptr,
diff --git a/Amalgam/src/Utils/ExceptionHandler/ExceptionHandler.cpp b/Amalgam/src/Utils/ExceptionHandler/ExceptionHandler.cpp
index e6333a29..88bb7aaa 100644
--- a/Amalgam/src/Utils/ExceptionHandler/ExceptionHandler.cpp
+++ b/Amalgam/src/Utils/ExceptionHandler/ExceptionHandler.cpp
@@ -175,7 +175,7 @@ static LONG APIENTRY ExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo)
case STATUS_ACCESS_VIOLATION:
case STATUS_STACK_OVERFLOW:
case STATUS_HEAP_CORRUPTION:
- SDK::Output("Unhandled exception", ssErrorStream.str().c_str(), {}, OUTPUT_DEBUG, MB_OK | MB_ICONERROR);
+ SDK::Output("Unhandled exception", ssErrorStream.str().c_str(), {}, OUTPUT_DEBUG, nullptr, MB_OK | MB_ICONERROR);
}
return EXCEPTION_CONTINUE_SEARCH;