diff --git a/data/menu/nullifiedcat/visuals.xml b/data/menu/nullifiedcat/visuals.xml
index 6ba68e3a..0914d77e 100755
--- a/data/menu/nullifiedcat/visuals.xml
+++ b/data/menu/nullifiedcat/visuals.xml
@@ -5,6 +5,7 @@
+
diff --git a/data/menu/nullifiedcat/visuals/chams.xml b/data/menu/nullifiedcat/visuals/chams.xml
index 5fdfd51e..d556819e 100755
--- a/data/menu/nullifiedcat/visuals/chams.xml
+++ b/data/menu/nullifiedcat/visuals/chams.xml
@@ -1,31 +1,77 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/data/menu/nullifiedcat/visuals/chamshaders.xml b/data/menu/nullifiedcat/visuals/chamshaders.xml
new file mode 100644
index 00000000..c1c97cb7
--- /dev/null
+++ b/data/menu/nullifiedcat/visuals/chamshaders.xml
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/data/menu/nullifiedcat/visuals/colors.xml b/data/menu/nullifiedcat/visuals/colors.xml
new file mode 100644
index 00000000..e55b895c
--- /dev/null
+++ b/data/menu/nullifiedcat/visuals/colors.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/data/menu/nullifiedcat/visuals/esp.xml b/data/menu/nullifiedcat/visuals/esp.xml
index f733a3b3..e38b868b 100755
--- a/data/menu/nullifiedcat/visuals/esp.xml
+++ b/data/menu/nullifiedcat/visuals/esp.xml
@@ -77,8 +77,10 @@
diff --git a/data/menu/nullifiedcat/weapons/aimbot.xml b/data/menu/nullifiedcat/weapons/aimbot.xml
index 489963e4..77f89cae 100755
--- a/data/menu/nullifiedcat/weapons/aimbot.xml
+++ b/data/menu/nullifiedcat/weapons/aimbot.xml
@@ -128,10 +128,6 @@
-
-
-
-
-
+
diff --git a/data/menu/nullifiedcat/weapons/nospread.xml b/data/menu/nullifiedcat/weapons/nospread.xml
old mode 100755
new mode 100644
diff --git a/include/hacks/Backtrack.hpp b/include/hacks/Backtrack.hpp
index af1aeee6..50fa0226 100644
--- a/include/hacks/Backtrack.hpp
+++ b/include/hacks/Backtrack.hpp
@@ -50,9 +50,15 @@ extern settings::Float latency;
extern settings::Int bt_slots;
#if ENABLE_VISUALS
extern settings::Boolean chams;
+extern settings::Boolean chams_wireframe;
extern settings::Int chams_ticks;
extern settings::Rgba chams_color;
extern settings::Boolean chams_solid;
+extern settings::Boolean chams_overlay;
+extern settings::Rgba chams_color_overlay;
+extern settings::Float chams_envmap_tint_r;
+extern settings::Float chams_envmap_tint_g;
+extern settings::Float chams_envmap_tint_b;
#endif
// Check if backtrack is enabled
diff --git a/include/visual/EffectChams.hpp b/include/visual/EffectChams.hpp
deleted file mode 100644
index 67c4a433..00000000
--- a/include/visual/EffectChams.hpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * EffectChams.hpp
- *
- * Created on: Apr 16, 2017
- * Author: nullifiedcat
- */
-
-#pragma once
-
-#include "common.hpp"
-#include "sdk/ScreenSpaceEffects.h"
-#include "core/sdk.hpp"
-
-namespace effect_chams
-{
-
-class EffectChams : public IScreenSpaceEffect
-{
-public:
- virtual void Init();
- virtual void Shutdown()
- {
- if (init)
- {
- mat_unlit.Shutdown();
- mat_unlit_z.Shutdown();
- mat_lit.Shutdown();
- mat_lit_z.Shutdown();
- init = false;
- }
- }
-
- inline virtual void SetParameters(KeyValues *params)
- {
- }
-
- virtual void Render(int x, int y, int w, int h);
-
- inline virtual void Enable(bool bEnable)
- {
- enabled = bEnable;
- }
- inline virtual bool IsEnabled()
- {
- return enabled;
- }
-
- void SetEntityColor(CachedEntity *ent, rgba_t color);
- rgba_t ChamsColor(IClientEntity *entity);
- bool ShouldRenderChams(IClientEntity *entity);
- void RenderChams(IClientEntity *entity);
- void BeginRenderChams();
- void EndRenderChams();
- void RenderChamsRecursive(IClientEntity *entity);
-
-public:
- bool init{ false };
- bool drawing{ false };
- bool enabled;
- float orig_modulation[3];
- CMaterialReference mat_unlit;
- CMaterialReference mat_unlit_z;
- CMaterialReference mat_lit;
- CMaterialReference mat_lit_z;
-};
-
-extern EffectChams g_EffectChams;
-extern CScreenSpaceEffectRegistration *g_pEffectChams;
-} // namespace effect_chams
diff --git a/include/visual/colors.hpp b/include/visual/colors.hpp
index a8de9fe1..382b2dc9 100644
--- a/include/visual/colors.hpp
+++ b/include/visual/colors.hpp
@@ -117,10 +117,17 @@ constexpr rgba_t black(0, 0, 0, 1);
constexpr rgba_t pink = FromRGBA8(255, 105, 180, 255);
-constexpr rgba_t red = FromRGBA8(237, 42, 42, 255), blu = FromRGBA8(28, 108, 237, 255);
-constexpr rgba_t red_b = FromRGBA8(64, 32, 32, 178), blu_b = FromRGBA8(32, 32, 64, 178); // Background
-constexpr rgba_t red_v = FromRGBA8(196, 102, 108, 255), blu_v = FromRGBA8(102, 182, 196, 255); // Vaccinator
-constexpr rgba_t red_u = FromRGBA8(216, 34, 186, 255), blu_u = FromRGBA8(167, 75, 252, 255); // Ubercharged
+extern rgba_t red; // RED team user controlled
+extern rgba_t blu; // BLU team user controlled
+extern rgba_t red_b; // Background
+extern rgba_t blu_b; // Background
+extern rgba_t red_v; // Vaccinator
+extern rgba_t blu_v; // Vaccinator
+extern rgba_t red_u; // Ubercharge
+extern rgba_t blu_u; // Ubercharge
+extern rgba_t gui; // GUI color
+extern rgba_t target; // Aimbot target color
+constexpr rgba_t red_s = FromRGBA8(237, 42, 42, 255); // Not user controlled
constexpr rgba_t yellow = FromRGBA8(255, 255, 0, 255);
constexpr rgba_t orange = FromRGBA8(255, 120, 0, 255);
constexpr rgba_t green = FromRGBA8(0, 255, 0, 255);
diff --git a/include/visual/drawing.hpp b/include/visual/drawing.hpp
index 2ba7caf5..95139321 100644
--- a/include/visual/drawing.hpp
+++ b/include/visual/drawing.hpp
@@ -59,11 +59,6 @@ void Update();
extern const std::vector fonts;
} // namespace fonts
-constexpr rgba_t GUIColor()
-{
- return colors::white;
-}
-
void InitStrings();
void ResetStrings();
void AddCenterString(const std::string &string, const rgba_t &color = colors::white);
diff --git a/src/crits.cpp b/src/crits.cpp
index 34efb6ae..1fb1b794 100644
--- a/src/crits.cpp
+++ b/src/crits.cpp
@@ -724,7 +724,7 @@ void DrawCritStrings()
float sx, sy;
fonts::center_screen->stringSize(bar_string, &sx, &sy);
// Center and draw below
- draw::String(x - sx / 2, (y + sy), colors::red, bar_string.c_str(), *fonts::center_screen);
+ draw::String(x - sx / 2, (y + sy), colors::red_s, bar_string.c_str(), *fonts::center_screen);
y += fonts::center_screen->size + 1;
}
@@ -783,22 +783,22 @@ void Draw()
if (shouldCrit())
{
if (can_crit)
- AddCritString("Forcing Crits!", colors::red);
+ AddCritString("Forcing Crits!", colors::red_s);
else
- AddCritString("Weapon can currently not crit!", colors::red);
+ AddCritString("Weapon can currently not crit!", colors::red_s);
}
// Weapon can't randomly crit
if (!re::C_TFWeaponBase::CanFireCriticalShot(RAW_ENT(LOCAL_W), false, nullptr) || !added_per_shot)
{
- AddCritString("Weapon cannot randomly crit.", colors::red);
+ AddCritString("Weapon cannot randomly crit.", colors::red_s);
DrawCritStrings();
return;
}
// We are out of sync. RIP
if (is_out_of_sync)
- AddCritString("Out of sync.", colors::red);
+ AddCritString("Out of sync.", colors::red_s);
// Observed crit chance is not low enough, display how much damage is needed until we can crit again
else if (crit_mult_info.first > crit_mult_info.second && g_pLocalPlayer->weapon_mode != weapon_melee)
AddCritString("Damage Until crit: " + std::to_string(damageUntilToCrit(wep)), colors::orange);
@@ -811,7 +811,7 @@ void Draw()
}
// Mark bucket as ready/not ready
- auto color = colors::red;
+ auto color = colors::red_s;
if (can_crit && (crit_mult_info.first <= crit_mult_info.second || g_pLocalPlayer->weapon_mode != weapon_melee))
color = colors::green;
AddCritString("Crit Bucket: " + std::to_string(bucket), color);
@@ -829,7 +829,7 @@ void Draw()
bucket_color = colors::FromRGBA8(0x34, 0xeb, 0xae, 255);
// Color everything red
if (!can_crit)
- bucket_color = colors::red;
+ bucket_color = colors::red_s;
// Get the percentage the bucket will take up
float bucket_percentage = bucket / getBucketCap();
diff --git a/src/hack.cpp b/src/hack.cpp
index 621ea3d1..bfc33522 100644
--- a/src/hack.cpp
+++ b/src/hack.cpp
@@ -428,7 +428,6 @@ void hack::Shutdown()
EC::run(EC::Shutdown);
#if ENABLE_VISUALS
g_pScreenSpaceEffects->DisableScreenSpaceEffect("_cathook_glow");
- g_pScreenSpaceEffects->DisableScreenSpaceEffect("_cathook_chams");
#if EXTERNAL_DRAWING
xoverlay_destroy();
#endif
diff --git a/src/hacks/Aimbot.cpp b/src/hacks/Aimbot.cpp
index 3d8dad2d..27b12d79 100644
--- a/src/hacks/Aimbot.cpp
+++ b/src/hacks/Aimbot.cpp
@@ -18,12 +18,6 @@
#include "hitrate.hpp"
#include "FollowBot.hpp"
-#if ENABLE_VISUALS
-#ifndef FEATURE_EFFECTS_DISABLED
-#include "EffectChams.hpp"
-#endif
-#endif
-
namespace hacks::shared::aimbot
{
static settings::Boolean normal_enable{ "aimbot.enable", "false" };
@@ -312,8 +306,7 @@ static void CreateMove()
#if ENABLE_VISUALS
if (target_entity->m_Type() == ENTITY_PLAYER)
{
- hacks::shared::esp::SetEntityColor(target_entity, colors::pink);
- effect_chams::g_EffectChams.SetEntityColor(target_entity, colors::pink);
+ hacks::shared::esp::SetEntityColor(target_entity, colors::target);
}
#endif
@@ -1551,7 +1544,7 @@ static void DrawText()
// Dont show ring while player is dead
if (CE_GOOD(LOCAL_E) && LOCAL_E->m_bAlivePlayer())
{
- rgba_t color = GUIColor();
+ rgba_t color = colors::gui;
color.a = float(fovcircle_opacity);
int width, height;
diff --git a/src/hacks/AutoReflect.cpp b/src/hacks/AutoReflect.cpp
index 82d99c24..4d1a2ef0 100644
--- a/src/hacks/AutoReflect.cpp
+++ b/src/hacks/AutoReflect.cpp
@@ -218,7 +218,7 @@ void Draw()
// Dont show ring while player is dead
if (CE_GOOD(LOCAL_E) && LOCAL_E->m_bAlivePlayer())
{
- rgba_t color = GUIColor();
+ rgba_t color = colors::gui;
color.a = float(fovcircle_opacity);
int width, height;
diff --git a/src/hacks/Backtrack.cpp b/src/hacks/Backtrack.cpp
index 7796aa85..53f99517 100644
--- a/src/hacks/Backtrack.cpp
+++ b/src/hacks/Backtrack.cpp
@@ -34,9 +34,14 @@ settings::Float latency{ "backtrack.latency", "0" };
settings::Int bt_slots{ "backtrack.slots", "0" };
#if ENABLE_VISUALS
settings::Boolean chams{ "backtrack.chams", "false" };
+settings::Boolean chams_wireframe{ "backtrack.chams.wireframe", "false" };
settings::Int chams_ticks{ "backtrack.chams.ticks", "1" };
-settings::Rgba chams_color{ "backtrack.chams.color", "646464FF" };
-settings::Boolean chams_solid{ "backtrack.chams.color.solid", "false" };
+settings::Rgba chams_color{ "backtrack.chams.color", "ff00ff10" };
+settings::Boolean chams_overlay{ "backtrack.chams.overlay", "true" };
+settings::Rgba chams_color_overlay{ "backtrack.chams.color.overlay", "000000ff" };
+settings::Float chams_envmap_tint_r{ "backtrack.chams.envmap.tint.r", "1" };
+settings::Float chams_envmap_tint_g{ "backtrack.chams.envmap.tint.g", "0" };
+settings::Float chams_envmap_tint_b{ "backtrack.chams.envmap.tint.b", "1" };
#endif
// Check if backtrack is enabled
@@ -320,7 +325,7 @@ void Draw()
rgba_t draw_color = colors::green;
// Found our target tick
if (bt_ent && tick.tickcount == (*bt_data).tickcount && i == bt_ent->m_IDX)
- draw_color = colors::red;
+ draw_color = colors::red_s;
draw::Rectangle(out.x, out.y, size / 4, size / 4, draw_color);
}
}
diff --git a/src/hacks/ESP.cpp b/src/hacks/ESP.cpp
index a8a433cc..8bef692e 100644
--- a/src/hacks/ESP.cpp
+++ b/src/hacks/ESP.cpp
@@ -926,7 +926,7 @@ void _FASTCALL ProcessEntityPT(CachedEntity *ent)
break;
case 1:
{ // BOTTOM RIGHT
- draw_point = Vector(max_x + 2, max_y - data.at(ent->m_IDX).string_count * 14, 0);
+ draw_point = Vector(max_x + 2, max_y - data.at(ent->m_IDX).string_count * 16, 0);
}
break;
case 2:
@@ -936,13 +936,23 @@ void _FASTCALL ProcessEntityPT(CachedEntity *ent)
break;
case 3:
{ // ABOVE
- draw_point = Vector((min_x + max_x) / 2.0f, min_y - data.at(ent->m_IDX).string_count * 14, 0);
+ draw_point = Vector((min_x + max_x) / 2.0f, min_y - data.at(ent->m_IDX).string_count * 16, 0);
}
break;
case 4:
{ // BELOW
draw_point = Vector((min_x + max_x) / 2.0f, max_y, 0);
}
+ break;
+ case 5:
+ { // ABOVE LEFT
+ draw_point = Vector(min_x + 2, min_y - data.at(ent->m_IDX).string_count * 16, 0);
+ }
+ break;
+ case 6:
+ { // ABOVE RIGHT
+ draw_point = Vector(max_x + 2, min_y - data.at(ent->m_IDX).string_count * 16, 0);
+ }
}
}
}
diff --git a/src/hacks/LightESP.cpp b/src/hacks/LightESP.cpp
index 0fd3daa8..80e25a59 100644
--- a/src/hacks/LightESP.cpp
+++ b/src/hacks/LightESP.cpp
@@ -73,7 +73,7 @@ void draw()
if (size < minsize)
size = minsize;
draw::Rectangle(out.x - fabsf(pout.x - pout2.x) / 4, out.y - fabsf(pout.y - pout2.y) / 4, fabsf(pout.x - pout2.x) / 2, fabsf(pout.y - pout2.y) / 2, hacks::shared::lightesp::LightESPColor(pEntity));
- draw::Rectangle(out.x - size / 8, out.y - size / 8, size / 4, size / 4, colors::red);
+ draw::Rectangle(out.x - size / 8, out.y - size / 8, size / 4, size / 4, colors::red_s);
}
}
}
diff --git a/src/hacks/Misc.cpp b/src/hacks/Misc.cpp
index 3345f797..5bb5defc 100644
--- a/src/hacks/Misc.cpp
+++ b/src/hacks/Misc.cpp
@@ -38,6 +38,7 @@ static settings::Boolean unlimit_bumpercart_movement{ "misc.bumpercarthax.enable
static settings::Boolean ping_reducer{ "misc.ping-reducer.enable", "false" };
static settings::Int force_ping{ "misc.ping-reducer.target", "0" };
static settings::Boolean force_wait{ "misc.force-enable-wait", "true" };
+static settings::Boolean scc{ "misc.scoreboard.match-custom-team-colors", "false" };
#if ENABLE_VISUALS
static settings::Boolean god_mode{ "misc.god-mode", "false" };
@@ -382,7 +383,7 @@ void Draw()
{
case 4:
observermode = "1st Person";
- color = colors::red;
+ color = colors::red_s;
break;
case 5:
observermode = "3rd Person";
@@ -706,13 +707,16 @@ Color &GetPlayerColor(int idx, int team, bool dead = false)
{
static Color returnColor(0, 0, 0, 0);
+ int col_red[] = { scc ? int(colors::red.r * 255) : 255, scc ? int(colors::red.g * 255) : 64, scc ? int(colors::red.b * 255) : 64 };
+ int col_blu[] = { scc ? int(colors::blu.r * 255) : 153, scc ? int(colors::blu.g * 255) : 204, scc ? int(colors::blu.b * 255) : 255 };
+
switch (team)
{
case TEAM_RED:
- returnColor.SetColor(255, 64, 64, 255);
+ returnColor.SetColor(col_red[0], col_red[1], col_red[2], 255);
break;
case TEAM_BLU:
- returnColor.SetColor(153, 204, 255, 255);
+ returnColor.SetColor(col_blu[0], col_blu[1], col_blu[2],255);
break;
default:
returnColor.SetColor(245, 229, 196, 255);
diff --git a/src/hacks/Radar.cpp b/src/hacks/Radar.cpp
index 7a836c4f..a3ad7798 100644
--- a/src/hacks/Radar.cpp
+++ b/src/hacks/Radar.cpp
@@ -223,7 +223,7 @@ void Draw()
int radar_size = *size;
int half_size = radar_size / 2;
- outlineclr = GUIColor();
+ outlineclr = colors::gui;
if (*shape == 0)
{
@@ -273,13 +273,13 @@ void Draw()
DrawEntity(x, y, LOCAL_E);
const auto &wtr = WorldToRadar(g_pLocalPlayer->v_Origin.x, g_pLocalPlayer->v_Origin.y);
if (!use_icons)
- draw::RectangleOutlined(x + wtr.first, y + wtr.second, int(icon_size), int(icon_size), GUIColor(), 0.5f);
+ draw::RectangleOutlined(x + wtr.first, y + wtr.second, int(icon_size), int(icon_size), colors::gui, 0.5f);
}
if (show_cross)
{
- draw::Line(x + half_size, y + half_size / 2, 0, half_size, colors::Transparent(GUIColor(), 0.4f), 0.5f);
- draw::Line(x + half_size / 2, y + half_size, half_size, 0, colors::Transparent(GUIColor(), 0.4f), 0.5f);
+ draw::Line(x + half_size, y + half_size / 2, 0, half_size, colors::Transparent(colors::gui, 0.4f), 0.5f);
+ draw::Line(x + half_size / 2, y + half_size, half_size, 0, colors::Transparent(colors::gui, 0.4f), 0.5f);
}
}
diff --git a/src/hacks/SpyAlert.cpp b/src/hacks/SpyAlert.cpp
index f5b23b51..bfd83a8a 100644
--- a/src/hacks/SpyAlert.cpp
+++ b/src/hacks/SpyAlert.cpp
@@ -80,7 +80,7 @@ void Draw()
}
if (voicemenu && lastVoicemenu.test_and_set(5000))
g_IEngine->ClientCmd_Unrestricted("voicemenu 1 1");
- AddCenterString(format("BACKSTAB WARNING! ", (int) (closest_spy_distance / 64 * 1.22f), "m (", spy_count, ")"), colors::red);
+ AddCenterString(format("BACKSTAB WARNING! ", (int) (closest_spy_distance / 64 * 1.22f), "m (", spy_count, ")"), colors::red_s);
}
else if (closest_spy_distance < (float) distance_warning)
{
diff --git a/src/hacks/Walkbot.cpp b/src/hacks/Walkbot.cpp
index cc5ec9ff..47cf6d3c 100644
--- a/src/hacks/Walkbot.cpp
+++ b/src/hacks/Walkbot.cpp
@@ -1054,7 +1054,7 @@ void DrawNode(index_t node, bool draw_back)
node_size = 6;
}
if (node == state::active_node)
- color = &colors::red;
+ color = &colors::red_s;
draw::Rectangle(wts.x - node_size, wts.y - node_size, 2 * node_size, 2 * node_size, *color);
}
@@ -1112,7 +1112,7 @@ void Draw()
}
if (HasLowHealth())
{
- AddSideString("Walkbot: LOW HEALTH", colors::red);
+ AddSideString("Walkbot: LOW HEALTH", colors::red_s);
}
}
break;
diff --git a/src/hooks/visual/DrawModelExecute.cpp b/src/hooks/visual/DrawModelExecute.cpp
index 70317d6a..2798405e 100644
--- a/src/hooks/visual/DrawModelExecute.cpp
+++ b/src/hooks/visual/DrawModelExecute.cpp
@@ -1,96 +1,623 @@
/*
- Created by Jenny White on 29.04.18.
- Copyright (c) 2018 nullworks. All rights reserved.
+ This file is part of Cathook.
+
+ Cathook is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Cathook is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Cathook. If not, see .
*/
-#include
-#include
-#include "HookedMethods.hpp"
-#include "Backtrack.hpp"
-#include
-#include
-#include "AntiAim.hpp"
+// Codeowners: aUniqueUser
+#include
+#include "common.hpp"
+#include "HookedMethods.hpp"
+#include "MiscTemporary.hpp"
+#include "Backtrack.hpp"
+#include "EffectGlow.hpp"
+#include "Aimbot.hpp"
+
+/* World visual rvars */
static settings::Boolean no_arms{ "remove.arms", "false" };
-static settings::Boolean arms_chams{ "chams.arms", "false" };
static settings::Boolean no_hats{ "remove.hats", "false" };
static settings::Boolean blend_zoom{ "zoom.blend", "false" };
-static settings::Rgba arm_overlaychams_color{ "chams.arms.overlaycolor", "FF6464FF" };
-static settings::Rgba arm_basechams_color{ "chams.arms.basecolor", "006464FF" };
-namespace effect_glow
+static settings::Boolean enable{ "chams.enable", "false" };
+static settings::Boolean render_original{ "chams.original", "false" };
+
+/* Cham target rvars */
+static settings::Boolean health{ "chams.health", "false" };
+static settings::Boolean teammates{ "chams.show.teammates", "false" };
+static settings::Boolean disguised{ "chams.show.disguised", "true" };
+static settings::Boolean players{ "chams.show.players", "true" };
+static settings::Boolean medkits{ "chams.show.medkits", "false" };
+static settings::Boolean ammobox{ "chams.show.ammoboxes", "false" };
+static settings::Boolean buildings{ "chams.show.buildings", "true" };
+static settings::Boolean stickies{ "chams.show.stickies", "true" };
+static settings::Boolean stickies_local{ "chams.show.stickies.local", "true" };
+static settings::Boolean pipes{ "chams.show.pipes", "true" };
+static settings::Boolean pipes_local{ "chams.show.pipes.local", "true" };
+static settings::Boolean teammate_buildings{ "chams.show.teammate-buildings", "false" };
+static settings::Boolean recursive{ "chams.recursive", "true" };
+static settings::Boolean legit{ "chams.legit", "false" };
+static settings::Boolean singlepass{ "chams.single-pass", "false" };
+static settings::Boolean chamsself{ "chams.self", "true" };
+static settings::Boolean weapons{ "chams.weapons", "false" };
+static settings::Rgba weapons_base{ "chams.weapons.basecolor", "ffffffff" };
+static settings::Rgba weapons_overlay{ "chams.weapons.overlaycolor", "ffffffff" };
+static settings::Float cham_alpha{ "chams.alpha", "1" };
+static settings::Boolean overlay_chams{ "chams.overlay", "false" };
+
+/* Lighting rvars */
+static settings::Boolean phong_enable{ "chams.phong", "true" };
+static settings::Boolean halfambert{ "chams.halfambert", "true" };
+static settings::Boolean phong_fresnelrange{ "chams.phonefresnelranges", "true" };
+static settings::Int phong_boost{ "chams.phongboost", "2" };
+static settings::Int additive{ "chams.additive", "1" };
+static settings::Int pearlescent{ "chams.pearlescent", "8" };
+
+static settings::Float phong_exponent{ "chams.phongexponent", "25" };
+static settings::Float phong_fresnelrange_1{ "chams.phongfresnelranges.1", "0" };
+static settings::Float phong_fresnelrange_2{ "chams.phongfresnelranges.2", "3" };
+static settings::Float phong_fresnelrange_3{ "chams.phongfresnelranges.3", "15" };
+
+static settings::Boolean rimlighting{ "chams.rimlighting", "true" };
+static settings::Float rimlighting_boost{ "chams.rimlighting.boost", "1" };
+static settings::Float rimlighting_exponent{ "chams.rimlighting.exponent", "4" };
+
+/* Customization of envmap */
+static settings::Boolean envmap{ "chams.envmap", "true" };
+static settings::Boolean envmap_matt{ "chams.envmap.matt", "false" };
+static settings::Float envmapfresnel{ "chams.envmapfresnel", "1" };
+static settings::Boolean envmap_tint{ "chams.envmap.tint", "true" };
+static settings::Float envmap_tint_red_r{ "chams.envmap.tint.red.r", "4" };
+static settings::Float envmap_tint_red_g{ "chams.envmap.tint.red.g", "0" };
+static settings::Float envmap_tint_red_b{ "chams.envmap.tint.red.b", "2" };
+static settings::Float envmap_tint_blu_r{ "chams.envmap.tint.blu.r", "0" };
+static settings::Float envmap_tint_blu_g{ "chams.envmap.tint.blu.g", "2" };
+static settings::Float envmap_tint_blu_b{ "chams.envmap.tint.blu.b", "4" };
+static settings::Float envmap_tint_weapons_r{ "chams.envmap.tint.weapons.r", "1" };
+static settings::Float envmap_tint_weapons_g{ "chams.envmap.tint.weapons.g", "1" };
+static settings::Float envmap_tint_weapons_b{ "chams.envmap.tint.weapons.b", "1" };
+static settings::Float envmap_tint_local_weapon_r{ "chams.envmap.tint.local-weapon.r", "1" };
+static settings::Float envmap_tint_local_weapon_g{ "chams.envmap.tint.local-weapon.g", "1" };
+static settings::Float envmap_tint_local_weapon_b{ "chams.envmap.tint.local-weapon.b", "1" };
+static settings::Float envmap_tint_arms_r{ "chams.envmap.tint.arms.r", "1" };
+static settings::Float envmap_tint_arms_g{ "chams.envmap.tint.arms.g", "1" };
+static settings::Float envmap_tint_arms_b{ "chams.envmap.tint.arms.b", "1" };
+
+/* Overlay chams team highlight colors */
+static settings::Rgba chams_overlay_color_blu{ "chams.overlay.overlaycolor.blu", "000000ff" };
+static settings::Rgba chams_overlay_color_red{ "chams.overlay.overlaycolor.red", "000000ff" };
+
+/* Seperate cham settings when ignorez */
+static settings::Boolean novis{ "chams.novis", "true" };
+static settings::Rgba novis_team_red{ "chams.novis.red", "ff8800ff" };
+static settings::Rgba novis_team_blu{ "chams.novis.blu", "bc00ffff" };
+
+/* Customization of novis envmap */
+static settings::Float envmap_tint_red_r_novis{ "chams.novis.envmap.tint.red.r", "4" };
+static settings::Float envmap_tint_red_g_novis{ "chams.novis.envmap.tint.red.g", "4" };
+static settings::Float envmap_tint_red_b_novis{ "chams.novis.envmap.tint.red.b", "1" };
+static settings::Float envmap_tint_blu_r_novis{ "chams.novis.envmap.tint.blu.r", "4" };
+static settings::Float envmap_tint_blu_g_novis{ "chams.novis.envmap.tint.blu.g", "1" };
+static settings::Float envmap_tint_blu_b_novis{ "chams.novis.envmap.tint.blu.b", "4" };
+
+/* Overlay chams novis team highlight colors */
+static settings::Rgba chams_overlay_color_blu_novis{ "chams.novis.overlay.overlaycolor.blu", "ff00ffff" };
+static settings::Rgba chams_overlay_color_red_novis{ "chams.novis.overlay.overlaycolor.red", "ff0000ff" };
+
+/* Arm chams */
+static settings::Boolean arms_chams{ "chams.arms", "false" };
+static settings::Boolean arm_chams_original{ "chams.arms.original", "false" };
+static settings::Boolean arms_chams_team_color{ "chams.arms.team-colors", "true" };
+static settings::Boolean arms_chams_wireframe{ "chams.arms.wireframe", "false" };
+static settings::Boolean arm_chams_overlay_chams{ "chams.overlay.arms", "true" };
+static settings::Rgba arm_overlaychams_color{ "chams.arms.overlaycolor", "000000ff" };
+static settings::Rgba arm_basechams_color{ "chams.arms.basecolor", "00000055" };
+
+/* Local weapon chams */
+static settings::Boolean local_weapon_chams{ "chams.local-weapon", "false" };
+static settings::Boolean local_weapon_chams_original{ "chams.local-weapon.original", "false" };
+static settings::Boolean local_weapon_chams_team_color{ "chams.local-weapon.team-colors", "true" };
+static settings::Boolean local_weapon_chams_wireframe{ "chams.local-weapon.wireframe", "false" };
+static settings::Boolean local_weapon_chams_overlay_chams{ "chams.overlay.local-weapon", "true" };
+static settings::Rgba local_weapon_overlaychams_color{ "chams.local-weapon.overlaycolor", "000000ff" };
+static settings::Rgba local_weapon_basechams_color{ "chams.local-weapon.basecolor", "000000ff" };
+
+class Materials
{
-extern settings::Boolean enable;
-} // namespace effect_glow
-namespace effect_chams
+public:
+ CMaterialReference mat_dme_unlit;
+ CMaterialReference mat_dme_lit;
+ CMaterialReference mat_dme_unlit_overlay_base;
+ CMaterialReference mat_dme_lit_overlay;
+
+ // Sadly necessary ):
+ CMaterialReference mat_dme_lit_fp;
+ CMaterialReference mat_dme_unlit_overlay_base_fp;
+ CMaterialReference mat_dme_lit_overlay_fp;
+
+ void Shutdown()
+ {
+ mat_dme_unlit.Shutdown();
+ mat_dme_lit.Shutdown();
+ mat_dme_unlit_overlay_base.Shutdown();
+ mat_dme_lit_overlay.Shutdown();
+
+ mat_dme_lit_fp.Shutdown();
+ mat_dme_unlit_overlay_base_fp.Shutdown();
+ mat_dme_lit_overlay_fp.Shutdown();
+ }
+};
+
+class ChamColors
{
-extern settings::Boolean enable;
-} // namespace effect_chams
+public:
+ float envmap_r, envmap_g, envmap_b;
+ rgba_t rgba;
+
+ rgba_t rgba_overlay = colors::empty;
+
+ ChamColors(rgba_t col = colors::empty, float r = 1.0f, float g = 1.0f, float b = 1.0f)
+ {
+ rgba = col;
+ envmap_r = r;
+ envmap_g = g;
+ envmap_b = b;
+ }
+};
+
namespace hooked_methods
{
-// Global scope so we can deconstruct on shutdown
static bool init_mat = false;
-static CMaterialReference mat_dme_chams;
-static CMaterialReference mat_dme_arm1_chams;
-static CMaterialReference mat_dme_arm_chams;
+static Materials mats;
+
+template void rvarCallback(settings::VariableBase &, T)
+{
+ init_mat = false;
+}
+
+class DrawEntry
+{
+public:
+ int entidx;
+ int parentidx;
+ DrawEntry()
+ {
+ }
+ DrawEntry(int own_idx, int parent_idx)
+ {
+ entidx = own_idx;
+ parentidx = parent_idx;
+ }
+};
+
+std::vector attachment_draw_list;
+
static InitRoutine init_dme([]() {
EC::Register(
EC::LevelShutdown,
[]() {
if (init_mat)
{
- mat_dme_chams.Shutdown();
+ mats.Shutdown();
init_mat = false;
}
+ attachment_draw_list.clear();
},
"dme_lvl_shutdown");
+
+ halfambert.installChangeCallback(rvarCallback);
+ additive.installChangeCallback(rvarCallback);
+ pearlescent.installChangeCallback(rvarCallback);
+
+ phong_enable.installChangeCallback(rvarCallback);
+ phong_boost.installChangeCallback(rvarCallback);
+ phong_exponent.installChangeCallback(rvarCallback);
+ phong_fresnelrange.installChangeCallback(rvarCallback);
+ phong_fresnelrange_1.installChangeCallback(rvarCallback);
+ phong_fresnelrange_2.installChangeCallback(rvarCallback);
+ phong_fresnelrange_3.installChangeCallback(rvarCallback);
+
+ rimlighting.installChangeCallback(rvarCallback);
+ rimlighting_boost.installChangeCallback(rvarCallback);
+ rimlighting_exponent.installChangeCallback(rvarCallback);
+
+ envmap.installChangeCallback(rvarCallback);
+ envmapfresnel.installChangeCallback(rvarCallback);
+ envmap_tint.installChangeCallback(rvarCallback);
+ envmap_matt.installChangeCallback(rvarCallback);
});
-bool aa_draw = false;
+
+// Purpose => Returns true if we should render provided internal entity
+bool ShouldRenderChams(IClientEntity *entity)
+{
+ if (!enable || CE_BAD(LOCAL_E))
+ return false;
+ if (entity->entindex() < 0)
+ return false;
+ CachedEntity *ent = ENTITY(entity->entindex());
+ if (chamsself && ent->m_IDX == LOCAL_E->m_IDX)
+ return true;
+ switch (ent->m_Type())
+ {
+ case ENTITY_BUILDING:
+ if (!buildings)
+ return false;
+ if (!ent->m_bEnemy() && !(teammate_buildings || teammates))
+ return false;
+ if (ent->m_iHealth() == 0 || !ent->m_iHealth())
+ return false;
+ if (CE_BYTE(LOCAL_E, netvar.m_bCarryingObject) && ent->m_IDX == HandleToIDX(CE_INT(LOCAL_E, netvar.m_hCarriedObject)))
+ return false;
+ return true;
+ case ENTITY_PLAYER:
+ if (!players)
+ return false;
+ if (!disguised && IsPlayerDisguised(ent))
+ return false;
+ if (!teammates && !ent->m_bEnemy() && playerlist::IsDefault(ent))
+ return false;
+ if (CE_BYTE(ent, netvar.iLifeState))
+ return false;
+ return true;
+ case ENTITY_PROJECTILE:
+ if (ent->m_iClassID() == CL_CLASS(CTFGrenadePipebombProjectile))
+ if (stickies || pipes)
+ {
+ if (CE_INT(ent, netvar.iPipeType) != 1)
+ {
+ if (pipes)
+ {
+ if (pipes_local && chamsself)
+ if ((CE_INT(ent, netvar.hThrower) & 0xFFF) == g_pLocalPlayer->entity->m_IDX) // Check if the sticky is the players own
+ return true;
+ if (ent->m_bEnemy())
+ return true;
+ }
+ else
+ return false;
+ }
+ if (stickies_local && chamsself)
+ if ((CE_INT(ent, netvar.hThrower) & 0xFFF) == g_pLocalPlayer->entity->m_IDX) // Check if the sticky is the players own
+ return true;
+ if (ent->m_bEnemy())
+ return true;
+ }
+ break;
+ case ENTITY_GENERIC:
+ switch (ent->m_ItemType())
+ {
+ case ITEM_HEALTH_LARGE:
+ case ITEM_HEALTH_MEDIUM:
+ case ITEM_HEALTH_SMALL:
+ return *medkits;
+ case ITEM_AMMO_LARGE:
+ case ITEM_AMMO_MEDIUM:
+ case ITEM_AMMO_SMALL:
+ return *ammobox;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+// Purpose => Get ChamColors struct from internal entity
+static ChamColors GetChamColors(IClientEntity *entity, bool ignorez)
+{
+ CachedEntity *ent = ENTITY(entity->entindex());
+
+ if (CE_BAD(ent))
+ return ChamColors(colors::white);
+ if (ent == hacks::shared::aimbot::CurrentTarget())
+ return ChamColors(colors::target);
+ if (re::C_BaseCombatWeapon::IsBaseCombatWeapon(entity))
+ {
+ IClientEntity *owner = re::C_TFWeaponBase::GetOwnerViaInterface(entity);
+ if (owner)
+ return GetChamColors(owner, ignorez);
+ }
+ switch (ent->m_Type())
+ {
+ case ENTITY_BUILDING:
+ if (!ent->m_bEnemy() && !(teammates || teammate_buildings) && ent != LOCAL_E)
+ return ChamColors();
+ if (health)
+ return ChamColors(colors::Health_dimgreen(ent->m_iHealth(), ent->m_iMaxHealth()));
+ break;
+ case ENTITY_PLAYER:
+ if (!players)
+ return ChamColors();
+ if (health)
+ return ChamColors(colors::Health_dimgreen(ent->m_iHealth(), ent->m_iMaxHealth()));
+ break;
+ default:
+ break;
+ }
+ if (ent->m_Type() == ENTITY_PLAYER || ent->m_Type() == ENTITY_BUILDING || ent->m_Type() == ENTITY_PROJECTILE)
+ {
+ ChamColors result;
+
+ if (ent->m_iTeam() == TEAM_BLU)
+ result = ChamColors(colors::blu, *envmap_tint_blu_r, *envmap_tint_blu_g, *envmap_tint_blu_b);
+ else if (ent->m_iTeam() == TEAM_RED)
+ result = ChamColors(colors::red, *envmap_tint_red_r, *envmap_tint_red_g, *envmap_tint_red_b);
+ if (novis && ignorez)
+ {
+ if (ent->m_iTeam() == TEAM_BLU)
+ result = ChamColors(*novis_team_blu, *envmap_tint_blu_r_novis, *envmap_tint_blu_g_novis, *envmap_tint_blu_b_novis);
+ else if (ent->m_iTeam() == TEAM_RED)
+ result = ChamColors(*novis_team_red, *envmap_tint_red_r_novis, *envmap_tint_red_g_novis, *envmap_tint_red_b_novis);
+ }
+ if (ent->m_Type() == ENTITY_PLAYER)
+ {
+ if (IsPlayerInvulnerable(ent))
+ {
+ if (ent->m_iTeam() == TEAM_BLU)
+ result = ChamColors(colors::blu_u, *envmap_tint_blu_r, *envmap_tint_blu_g, *envmap_tint_blu_b);
+ else if (ent->m_iTeam() == TEAM_RED)
+ result = ChamColors(colors::red_u, *envmap_tint_red_r, *envmap_tint_red_g, *envmap_tint_red_b);
+ }
+ if (HasCondition(ent))
+ {
+ if (ent->m_iTeam() == TEAM_BLU)
+ result = ChamColors(colors::blu_v, *envmap_tint_blu_r, *envmap_tint_blu_g, *envmap_tint_blu_b);
+ else if (ent->m_iTeam() == TEAM_RED)
+ result = ChamColors(colors::red_v, *envmap_tint_red_r, *envmap_tint_red_g, *envmap_tint_red_b);
+ }
+ }
+ auto o = player_tools::forceEspColor(ent);
+ if (o.has_value())
+ result = ChamColors(*o);
+
+ return result;
+ }
+ return ChamColors(colors::EntityF(ent));
+}
+
+// Purpose => Render entity attachments (weapons, hats)
+void RenderAttachment(IClientEntity *entity, IClientEntity *attach, CMaterialReference &mat)
+{
+ if (attach->ShouldDraw())
+ {
+ attachment_draw_list.emplace_back(attach->entindex(), entity->entindex());
+ if (entity->GetClientClass()->m_ClassID == RCC_PLAYER && re::C_BaseCombatWeapon::IsBaseCombatWeapon(attach))
+ {
+ // If separate weapon settings is used, apply them
+ if (weapons)
+ {
+ // Backup original color
+ rgba_t original;
+ g_IVRenderView->GetColorModulation(original.rgba);
+ g_IVRenderView->SetColorModulation(*weapons_base);
+
+ // Setup material
+ g_IVRenderView->SetBlend((*weapons_base).a);
+ if (mat && envmap)
+ mat->FindVar("$envmaptint", nullptr)->SetVecValue(*envmap_tint_weapons_r, *envmap_tint_weapons_g, *envmap_tint_weapons_b);
+
+ // Render
+ attach->DrawModel(1);
+
+ if (overlay_chams)
+ {
+ // Setup material
+ g_IVRenderView->SetColorModulation(*weapons_overlay);
+ g_IVRenderView->SetBlend((*weapons_overlay).a);
+ if (mat && envmap)
+ mat->FindVar("$envmaptint", nullptr)->SetVecValue(*envmap_tint_weapons_r, *envmap_tint_weapons_g, *envmap_tint_weapons_b);
+
+ // Render
+ attach->DrawModel(1);
+ }
+
+ // Reset it!
+ g_IVRenderView->SetColorModulation(original.rgba);
+ }
+ else
+ {
+ attach->DrawModel(1);
+ }
+ }
+ else
+ attach->DrawModel(1);
+ }
+}
+
+// Locked from drawing
+bool chams_attachment_drawing = false;
+
+// Purpose => Render overriden model and and attachments
+void RenderChamsRecursive(IClientEntity *entity, CMaterialReference &mat, IVModelRender *this_, const DrawModelState_t &state, const ModelRenderInfo_t &info, matrix3x4_t *bone)
+{
+#if !ENFORCE_STREAM_SAFETY
+ if (!enable)
+ return;
+ original::DrawModelExecute(this_, state, info, bone);
+
+ if (!*recursive)
+ return;
+
+ IClientEntity *attach;
+ int passes = 0;
+
+ attach = g_IEntityList->GetClientEntity(*(int *) ((uintptr_t) entity + netvar.m_Collision - 24) & 0xFFF);
+ while (attach && passes++ < 32)
+ {
+ chams_attachment_drawing = true;
+ RenderAttachment(entity, attach, mat);
+ chams_attachment_drawing = false;
+ attach = g_IEntityList->GetClientEntity(*(int *) ((uintptr_t) attach + netvar.m_Collision - 20) & 0xFFF);
+ }
+#endif
+}
+
+// Purpose => Apply and render chams according to settings
+void ApplyChams(ChamColors colors, bool recurse, bool render_original, bool overlay, bool ignorez, bool wireframe, bool firstperson, IClientEntity *entity, IVModelRender *this_, const DrawModelState_t &state, const ModelRenderInfo_t &info, matrix3x4_t *bone)
+{
+ static auto &mat = firstperson ? overlay ? mats.mat_dme_unlit_overlay_base_fp : mats.mat_dme_lit_fp : overlay ? mats.mat_dme_unlit_overlay_base : mats.mat_dme_lit;
+ if (render_original)
+ recurse ? RenderChamsRecursive(entity, mat, this_, state, info, bone) : original::DrawModelExecute(this_, state, info, bone);
+
+ // Setup material
+ g_IVRenderView->SetColorModulation(colors.rgba);
+ g_IVRenderView->SetBlend((colors.rgba).a);
+ mat->AlphaModulate((colors.rgba).a);
+ if (envmap && envmap_tint)
+ mat->FindVar("$envmaptint", nullptr)->SetVecValue(colors.envmap_r, colors.envmap_g, colors.envmap_b);
+
+ // Setup wireframe and ignorez using material vars
+ mat->SetMaterialVarFlag(MATERIAL_VAR_IGNOREZ, ignorez);
+ mat->SetMaterialVarFlag(MATERIAL_VAR_WIREFRAME, wireframe);
+
+ // Override
+ g_IVModelRender->ForcedMaterialOverride(mat);
+
+ // Apply our new material
+ recurse ? RenderChamsRecursive(entity, mat, this_, state, info, bone) : original::DrawModelExecute(this_, state, info, bone);
+ if (overlay)
+ {
+ // Use white if no color was supplied
+ if (colors.rgba_overlay == colors::empty && entity && IDX_GOOD(entity->entindex()))
+ {
+ CachedEntity *ent = ENTITY(entity->entindex());
+ if (ent->m_Type() != ENTITY_PLAYER && ent->m_Type() != ENTITY_PROJECTILE && ent->m_Type() != ENTITY_BUILDING)
+ colors.rgba_overlay = colors::white;
+ else
+ colors.rgba_overlay = ent->m_iTeam() == TEAM_RED ? *chams_overlay_color_red : ent->m_iTeam() == TEAM_BLU ? *chams_overlay_color_blu : colors::white;
+ }
+ // Setup material
+ g_IVRenderView->SetColorModulation(colors.rgba_overlay);
+ g_IVRenderView->SetBlend((colors.rgba_overlay).a);
+
+ static auto &mat_overlay = mats.mat_dme_lit_overlay;
+ if (envmap && envmap_tint)
+ mat_overlay->FindVar("$envmaptint", nullptr)->SetVecValue(colors.envmap_r, colors.envmap_g, colors.envmap_b);
+
+ mat_overlay->SetMaterialVarFlag(MATERIAL_VAR_IGNOREZ, ignorez);
+ mat_overlay->AlphaModulate((colors.rgba_overlay).a);
+
+ // Override and apply
+ g_IVModelRender->ForcedMaterialOverride(mat_overlay);
+ recurse ? RenderChamsRecursive(entity, mat, this_, state, info, bone) : original::DrawModelExecute(this_, state, info, bone);
+ }
+}
+
DEFINE_HOOKED_METHOD(DrawModelExecute, void, IVModelRender *this_, const DrawModelState_t &state, const ModelRenderInfo_t &info, matrix3x4_t *bone)
{
- if (!isHackActive())
- return original::DrawModelExecute(this_, state, info, bone);
-
- if (!(hacks::tf2::backtrack::isBacktrackEnabled /*|| (hacks::shared::antiaim::force_fakelag && hacks::shared::antiaim::isEnabled())*/ || blend_zoom || spectator_target || arms_chams || no_arms || no_hats || (*clean_screenshots && g_IEngine->IsTakingScreenshot()) || CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer()))
- {
- return original::DrawModelExecute(this_, state, info, bone);
- }
- if (effect_glow::g_EffectGlow.drawing || effect_chams::g_EffectChams.drawing)
+ if (!isHackActive() || effect_glow::g_EffectGlow.drawing || chams_attachment_drawing || (*clean_screenshots && g_IEngine->IsTakingScreenshot()) || CE_BAD(LOCAL_E) || (!enable && !no_hats && !no_arms && !blend_zoom && !arms_chams && !local_weapon_chams && !(hacks::tf2::backtrack::chams && hacks::tf2::backtrack::isBacktrackEnabled)))
return original::DrawModelExecute(this_, state, info, bone);
PROF_SECTION(DrawModelExecute);
if (!init_mat)
{
+ const char *cubemap_str = *envmap_matt ? "effects/saxxy/saxxy_gold" : "env_cubemap";
{
- KeyValues *kv = new KeyValues("UnlitGeneric");
- kv->SetString("$basetexture", "vgui/white_additive");
- kv->SetInt("$ignorez", 0);
- mat_dme_chams.Init("__cathook_glow_unlit", kv);
+ auto *kv = new KeyValues("UnlitGeneric");
+ kv->SetString("$basetexture", "white");
+ mats.mat_dme_unlit.Init("__cathook_dme_chams_unlit", kv);
}
-
+ KeyValues *kv_vertex_lit = nullptr;
{
- KeyValues *kv = new KeyValues("UnlitGeneric");
- kv->SetString("$basetexture", "vgui/white_additive");
- kv->SetInt("$ignorez", 0);
- kv->SetBool("$flat", true);
- mat_dme_arm1_chams.Init("__cathook_arm_base", kv);
+ auto *kv = new KeyValues("VertexLitGeneric");
+ kv->SetString("$basetexture", "white");
+ kv->SetString("$bumpmap", "water/tfwater001_normal");
+ kv->SetString("$lightwarptexture", "models/player/pyro/pyro_lightwarp");
+ kv->SetBool("$halfambert", *halfambert);
+ kv->SetBool("$phong", *phong_enable);
+ kv->SetFloat("$phongexponent", *phong_exponent);
+ kv->SetFloat("$phongboost", *phong_boost);
+ if (phong_fresnelrange)
+ {
+ char buffer[100];
+ snprintf(buffer, 100, "[%.2f %.2f %.2f]", *phong_fresnelrange_1, *phong_fresnelrange_2, *phong_fresnelrange_3);
+ kv->SetString("$phongfresnelranges", buffer);
+ }
+ if (envmap)
+ {
+ kv->SetString("$envmap", cubemap_str);
+ kv->SetFloat("$envmapfresnel", *envmapfresnel);
+ kv->SetString("$envmapfresnelminmaxexp", "[0.01 1 2]");
+ kv->SetInt("$normalmapalphaenvmapmask", 1);
+ kv->SetInt("$selfillum", 1);
+ if (envmap_tint)
+ kv->SetString("$envmaptint", "[1 1 1]");
+ }
+ kv->SetBool("$rimlight", *rimlighting);
+ kv->SetFloat("$rimlightexponent", *rimlighting_exponent);
+ kv->SetFloat("$rimlightboost", *phong_boost);
+ kv_vertex_lit = kv->MakeCopy();
+ mats.mat_dme_lit.Init("__cathook_dme_chams_lit", kv);
}
-
- { //
- KeyValues *kv = new KeyValues("VertexLitGeneric");
- kv->SetString("$basetexture", "vgui/white_additive");
- kv->SetBool("$phong", true);
- kv->SetInt("$phongboost", 4);
- kv->SetBool("$rimlight", true);
- kv->SetFloat("$rimlightexponent", 2.f);
- kv->SetInt("$additive", 2);
- kv->SetInt("$pearlescent", 8);
+ {
+ auto *kv = new KeyValues("UnlitGeneric");
+ kv->SetString("$basetexture", "white");
+ mats.mat_dme_unlit_overlay_base.Init("__cathook_dme_chams_lit_overlay_base", kv);
+ }
+ {
+ auto *kv = kv_vertex_lit;
+ kv->SetInt("$additive", *additive);
+ kv->SetInt("$pearlescent", *pearlescent);
kv->SetBool("$flat", false);
- kv->SetString("$envmap", "models/effects/cube_white");
- kv->SetFloat("$envmapfresnel", 1.f);
- kv->SetInt("$ignorez", 0);
- mat_dme_arm_chams.Init("__cathook_arm_overlay", kv);
+ mats.mat_dme_lit_overlay.Init("__cathook_dme_chams_lit_overlay", kv);
+ }
+ KeyValues *kv_vertex_lit_fp = nullptr;
+ {
+ auto *kv = new KeyValues("VertexLitGeneric");
+ kv->SetString("$basetexture", "white");
+ kv->SetString("$bumpmap", "water/tfwater001_normal");
+ kv->SetString("$lightwarptexture", "models/player/pyro/pyro_lightwarp");
+ kv->SetBool("$halfambert", *halfambert);
+ kv->SetBool("$phong", *phong_enable);
+ kv->SetFloat("$phongexponent", *phong_exponent);
+ kv->SetFloat("$phongboost", *phong_boost);
+ if (phong_fresnelrange)
+ {
+ char buffer[100];
+ snprintf(buffer, 100, "[%.2f %.2f %.2f]", *phong_fresnelrange_1, *phong_fresnelrange_2, *phong_fresnelrange_3);
+ kv->SetString("$phongfresnelranges", buffer);
+ }
+ if (envmap)
+ {
+ kv->SetString("$envmap", cubemap_str);
+ kv->SetFloat("$envmapfresnel", *envmapfresnel);
+ kv->SetString("$envmapfresnelminmaxexp", "[0.01 1 2]");
+ kv->SetInt("$normalmapalphaenvmapmask", 1);
+ kv->SetInt("$selfillum", 1);
+ if (envmap_tint)
+ kv->SetString("$envmaptint", "[1 1 1]");
+ }
+ kv->SetBool("$rimlight", *rimlighting);
+ kv->SetFloat("$rimlightexponent", *rimlighting_exponent);
+ kv->SetFloat("$rimlightboost", *phong_boost);
+ kv_vertex_lit_fp = kv->MakeCopy();
+ mats.mat_dme_lit_fp.Init("__cathook_dme_chams_lit_fp", kv);
+ }
+ {
+ auto *kv = new KeyValues("UnlitGeneric");
+ kv->SetString("$basetexture", "white");
+ mats.mat_dme_unlit_overlay_base_fp.Init("__cathook_dme_chams_lit_overlay_base_fp", kv);
+ }
+ {
+ auto *kv = kv_vertex_lit_fp;
+ kv->SetInt("$additive", *additive);
+ kv->SetInt("$pearlescent", *pearlescent);
+ kv->SetBool("$flat", false);
+ mats.mat_dme_lit_overlay_fp.Init("__cathook_dme_chams_lit_overlay_fp", kv);
}
init_mat = true;
}
@@ -101,138 +628,168 @@ DEFINE_HOOKED_METHOD(DrawModelExecute, void, IVModelRender *this_, const DrawMod
if (name)
{
std::string sname = name;
- if (sname.find("arms") != std::string::npos || sname.find("c_engineer_gunslinger") != std::string::npos)
+ if ((sname.find("arms") != std::string::npos && sname.find("yeti") == std::string::npos) || sname.find("c_engineer_gunslinger") != std::string::npos)
{
- if (no_arms && sname.find("arms") != std::string::npos)
- {
+ if (no_arms)
return;
- }
if (arms_chams)
{
+ // Backup original colors
rgba_t original_color;
-
g_IVRenderView->GetColorModulation(original_color);
original_color.a = g_IVRenderView->GetBlend();
- g_IVModelRender->ForcedMaterialOverride(mat_dme_arm1_chams);
- g_IVRenderView->SetBlend((*arm_basechams_color).a);
- g_IVRenderView->SetColorModulation(*arm_basechams_color);
- original::DrawModelExecute(this_, state, info, bone);
+ // Setup according to user settings using the ChamColors struct
+ auto colors = GetChamColors(LOCAL_E->InternalEntity(), false);
+ colors.rgba_overlay = LOCAL_E->m_iTeam() == TEAM_RED ? *chams_overlay_color_red : LOCAL_E->m_iTeam() == TEAM_BLU ? *chams_overlay_color_blu : colors::white;
+ if (!arms_chams_team_color)
+ {
+ colors = *arm_basechams_color;
+ colors.rgba_overlay = *arm_overlaychams_color;
+ colors.envmap_r = *envmap_tint_arms_r;
+ colors.envmap_g = *envmap_tint_arms_g;
+ colors.envmap_b = *envmap_tint_arms_b;
+ }
+ colors.rgba.a = (*arm_basechams_color).a;
+ colors.rgba_overlay.a = (*arm_overlaychams_color).a;
- g_IVModelRender->ForcedMaterialOverride(mat_dme_arm_chams);
- g_IVRenderView->SetBlend((*arm_overlaychams_color).a);
- g_IVRenderView->SetColorModulation(*arm_overlaychams_color);
- original::DrawModelExecute(this_, state, info, bone);
+ // Apply arm chams
+ IClientEntity *entity = g_IEntityList->GetClientEntity(info.entity_index);
+ ApplyChams(colors, false, *arm_chams_original, *arm_chams_overlay_chams, false, *arms_chams_wireframe, true, entity, this_, state, info, bone);
+ // Reset it!
g_IVModelRender->ForcedMaterialOverride(nullptr);
g_IVRenderView->SetColorModulation(original_color);
g_IVRenderView->SetBlend(original_color.a);
return;
}
}
+ // Workaround for attachments flickering
+ std::vector tmp_list;
+ bool do_draw = true;
+ for (auto &drawer : attachment_draw_list)
+ {
+ if (drawer.entidx == info.entity_index)
+ {
+ do_draw = false;
+ }
+ else
+ tmp_list.push_back(drawer);
+ }
+ attachment_draw_list = std::move(tmp_list);
+ if (!do_draw)
+ return;
+
+ if (local_weapon_chams && info.entity_index == -1 && sname.find("arms") == std::string::npos && (sname.find("models/weapons") != std::string::npos || sname.find("models/workshop/weapons") != std::string::npos || sname.find("models/workshop_partner/weapons") != std::string::npos))
+ {
+ // Backup original colors
+ rgba_t original_color;
+ g_IVRenderView->GetColorModulation(original_color);
+ original_color.a = g_IVRenderView->GetBlend();
+
+ auto colors = GetChamColors(LOCAL_E->InternalEntity(), false);
+ IClientEntity *entity = g_IEntityList->GetClientEntity(info.entity_index);
+
+ // Setup according to user settings using the ChamColors struct
+ if (local_weapon_chams_team_color)
+ {
+ colors.rgba_overlay = LOCAL_E->m_iTeam() == TEAM_RED ? *chams_overlay_color_red : LOCAL_E->m_iTeam() == TEAM_BLU ? *chams_overlay_color_blu : colors::white;
+ }
+ else
+ {
+ colors = *local_weapon_basechams_color;
+ colors.rgba_overlay = *local_weapon_overlaychams_color;
+ colors.envmap_r = *envmap_tint_local_weapon_r;
+ colors.envmap_g = *envmap_tint_local_weapon_g;
+ colors.envmap_b = *envmap_tint_local_weapon_b;
+ }
+ colors.rgba.a = (*local_weapon_basechams_color).a;
+ colors.rgba_overlay.a = (*local_weapon_overlaychams_color).a;
+
+ // Apply local weapon chams
+ ApplyChams(colors, false, *local_weapon_chams_original, *local_weapon_chams_overlay_chams, false, *local_weapon_chams_wireframe, true, entity, this_, state, info, bone);
+
+ // Reset it!
+ g_IVModelRender->ForcedMaterialOverride(nullptr);
+ g_IVRenderView->SetColorModulation(original_color);
+ g_IVRenderView->SetBlend(original_color.a);
+ return;
+ }
if (no_hats && sname.find("player/items") != std::string::npos)
- {
return;
- }
- /*
- if(g_pLocalPlayer->bZoomed && sname.find("models/weapons") != std::string::npos)
+ // Player, entity and backtrack chams
+ if (IDX_GOOD(info.entity_index))
{
- g_IVModelRender->ForcedMaterialOverride(nullptr);
- g_IVRenderView->SetBlend(0.2f);
- original::DrawModelExecute(this_, state, info, bone);
- return;
- }
- */
- }
- }
-
- // Used for fakes and for backtrack chams/glow
-
- // Maybe one day i'll get this working
- /*if (aa_draw && info.entity_index == g_pLocalPlayer->entity_idx)
- {
- CMatRenderContextPtr ptr(GET_RENDER_CONTEXT);
- rgba_t mod_original;
- // Save color just in case, then set to white
- g_IVRenderView->GetColorModulation(mod_original.rgba);
- g_IVRenderView->SetColorModulation(colors::white);
- // Important for Depth
- ptr->DepthRange(0.0f, 1.0f);
- // Apply our material
- g_IVModelRender->ForcedMaterialOverride(mat_unlit);
- // Run Original
- original::DrawModelExecute(this_, state, info, bone);
- // Revert
- g_IVRenderView->SetColorModulation(mod_original.rgba);
- g_IVModelRender->ForcedMaterialOverride(nullptr);
- return;
- }
- if (hacks::shared::antiaim::force_fakelag && hacks::shared::antiaim::isEnabled() && info.entity_index == g_pLocalPlayer->entity_idx)
- {
- float fake = hacks::shared::antiaim::used_yaw;
- Vector &angles = CE_VECTOR(LOCAL_E, netvar.m_angEyeAngles);
- float backup = angles.y;
- angles.y = fake;
- aa_draw = true;
- RAW_ENT(LOCAL_E)->DrawModel(1);
- aa_draw = false;
- angles.y = backup;
- }*/
- if (hacks::tf2::backtrack::chams && hacks::tf2::backtrack::isBacktrackEnabled)
- {
- const char *name = g_IModelInfo->GetModelName(info.pModel);
- if (name)
- {
- std::string sname = name;
- if (sname.find("models/player") || sname.find("models/weapons") || sname.find("models/workshop/player") || sname.find("models/workshop/weapons"))
- {
- if (IDX_GOOD(info.entity_index) && info.entity_index <= g_IEngine->GetMaxClients() && info.entity_index != g_IEngine->GetLocalPlayer())
+ // Get the internal entity from the index
+ IClientEntity *entity = g_IEntityList->GetClientEntity(info.entity_index);
+ if (ShouldRenderChams(entity))
{
+ // Ensure a valid entity
CachedEntity *ent = ENTITY(info.entity_index);
- if (CE_GOOD(ent) && ent->m_bAlivePlayer())
+ if (CE_GOOD(ent))
{
+ // Get original to restore to later
+ rgba_t original_color;
+ g_IVRenderView->GetColorModulation(original_color);
+ original_color.a = g_IVRenderView->GetBlend();
- // Get Backtrack data for target entity
- auto good_ticks = hacks::tf2::backtrack::getGoodTicks(info.entity_index);
-
- // Check if valid
- if (!good_ticks.empty())
+ // Player and entity chams
+ if (enable)
{
- // Make our own Chamsish Material
- // Render Chams/Glow stuff
- CMatRenderContextPtr ptr(GET_RENDER_CONTEXT);
- // Backup Blend
- float orig_blend = g_IVRenderView->GetBlend();
- // Make Backtrack stuff Use chams alpha
- g_IVRenderView->SetBlend((*hacks::tf2::backtrack::chams_color).a);
-
- rgba_t mod_original;
- // Save color just in case, then set to team color
- g_IVRenderView->GetColorModulation(mod_original.rgba);
- g_IVRenderView->SetColorModulation(*hacks::tf2::backtrack::chams_color);
- // Important for Depth
- ptr->DepthRange(0.0f, 1.0f);
- // Apply our material
- if (hacks::tf2::backtrack::chams_solid)
- g_IVModelRender->ForcedMaterialOverride(mat_dme_chams);
-
- // Draw as many ticks as desired
- for (unsigned i = 0; i <= (unsigned) std::max(*hacks::tf2::backtrack::chams_ticks, 1); i++)
+ // First time has ignorez, 2nd time not
+ for (int i = 1; i >= 0; i--)
{
- // Can't draw more than we have
- if (i >= good_ticks.size())
- break;
- if (!good_ticks[i].bones.empty())
- original::DrawModelExecute(this_, state, info, &good_ticks[i].bones[0]);
+ if (i && legit)
+ continue;
+ if (!i && singlepass)
+ continue;
+
+ // Setup colors
+ auto colors = GetChamColors(entity, i);
+ colors.rgba.a = *cham_alpha;
+
+ // Apply chams according to user settings
+ ApplyChams(colors, *recursive, *render_original, *overlay_chams, i, false, false, entity, this_, state, info, bone);
}
- // Revert
- g_IVRenderView->SetColorModulation(mod_original.rgba);
- g_IVModelRender->ForcedMaterialOverride(nullptr);
- g_IVRenderView->SetBlend(orig_blend);
}
+ // Backtrack chams
+ using namespace hacks::tf2;
+ if (backtrack::chams && backtrack::isBacktrackEnabled)
+ {
+ // TODO: Allow for a fade between the entity's color and a specified color, it would look cool but i'm lazy
+ if (ent->m_bAlivePlayer())
+ {
+ // Get ticks
+ auto good_ticks = backtrack::getGoodTicks(info.entity_index);
+ if (!good_ticks.empty())
+ {
+ // Setup chams according to user settings
+ ChamColors backtrack_colors;
+ backtrack_colors.rgba = *backtrack::chams_color;
+ backtrack_colors.rgba_overlay = *backtrack::chams_color_overlay;
+ backtrack_colors.envmap_r = *backtrack::chams_envmap_tint_r;
+ backtrack_colors.envmap_g = *backtrack::chams_envmap_tint_g;
+ backtrack_colors.envmap_b = *backtrack::chams_envmap_tint_b;
+
+ for (unsigned i = 0; i <= (unsigned) std::max(*backtrack::chams_ticks, 1); i++)
+ {
+ // Can't draw more than we have
+ if (i >= good_ticks.size())
+ break;
+ if (!good_ticks[i].bones.empty())
+ ApplyChams(backtrack_colors, false, false, *backtrack::chams_overlay, false, *backtrack::chams_wireframe, false, entity, this_, state, info, &good_ticks[i].bones[0]);
+ }
+ }
+ }
+ }
+ // Reset it!
+ g_IVModelRender->ForcedMaterialOverride(nullptr);
+ g_IVRenderView->SetColorModulation(original_color);
+ g_IVRenderView->SetBlend(original_color.a);
+ return;
}
}
}
@@ -246,7 +803,6 @@ DEFINE_HOOKED_METHOD(DrawModelExecute, void, IVModelRender *this_, const DrawMod
if (ent->entindex() == spectator_target)
return;
}
-
// Don't do it when we are trying to enforce backtrack chams
if (!hacks::tf2::backtrack::isDrawing)
return original::DrawModelExecute(this_, state, info, bone);
diff --git a/src/hooks/visual/FrameStageNotify.cpp b/src/hooks/visual/FrameStageNotify.cpp
index b7ccab25..2d21df17 100644
--- a/src/hooks/visual/FrameStageNotify.cpp
+++ b/src/hooks/visual/FrameStageNotify.cpp
@@ -18,14 +18,19 @@ static settings::Rgba nightmode_gui_color{ "visual.night-mode.gui-color", "00000
static settings::Rgba nightmode_world_color{ "visual.night-mode.world-color", "000000FF" };
static settings::Rgba nightmode_skybox_color{ "visual.night-mode.skybox-color", "000000FF" };
static settings::Boolean no_shake{ "visual.no-shake", "true" };
+static settings::Boolean override_textures{ "visual.override-textures", "false" };
+static settings::String override_textures_texture{ "visual.override-textures.custom-texture", "dev/dev_measuregeneric01b" };
-// Should we update nightmode?
-static bool update_nightmode = false;
+// Should we update?
+static bool update_nightmode = false;
+static bool update_override_textures = false;
// Which strings trigger this nightmode option
-std::vector world_strings = { "World" };
-std::vector skybox_strings = { "SkyBox" };
-std::vector gui_strings = { "Other", "VGUI" };
+std::vector world_strings = { "World" };
+std::vector skybox_strings = { "SkyBox" };
+std::vector gui_strings = { "Other", "VGUI" };
+std::vector dont_override_strings = { "glass", "door", "water", "tools", "player" };
+std::vector nodraw_strings = { "decal", "overlay", "hay" };
namespace hooked_methods
{
@@ -37,6 +42,52 @@ DEFINE_HOOKED_METHOD(FrameStageNotify, void, void *this_, ClientFrameStage_t sta
PROF_SECTION(FrameStageNotify_TOTAL);
+ if (update_override_textures)
+ {
+ if (override_textures)
+ {
+ for (MaterialHandle_t i = g_IMaterialSystem->FirstMaterial(); i != g_IMaterialSystem->InvalidMaterial(); i = g_IMaterialSystem->NextMaterial(i))
+ {
+ IMaterial *pMaterial = g_IMaterialSystem->GetMaterial(i);
+ if (!pMaterial)
+ continue;
+
+ auto name = std::string(pMaterial->GetTextureGroupName());
+ auto path = std::string(pMaterial->GetName());
+
+ // Ensure world mat
+ if (name.find("World") == std::string::npos)
+ continue;
+ // Don't override this stuff
+ bool good = true;
+ for (auto &entry : dont_override_strings)
+ if (path.find(entry) != path.npos)
+ {
+ good = false;
+ }
+ // Don't draw this stuff
+ for (auto &entry : nodraw_strings)
+ if (path.find(entry) != path.npos)
+ {
+ pMaterial->SetMaterialVarFlag(MATERIAL_VAR_NO_DRAW, true);
+ good = false;
+ }
+ if (!good)
+ continue;
+
+ if (!pMaterial->GetMaterialVarFlag(MATERIAL_VAR_NO_DRAW))
+ {
+ auto *kv = new KeyValues(pMaterial->GetShaderName());
+ kv->SetString("$basetexture", (*override_textures_texture).c_str());
+ kv->SetString("$basetexturetransform", "center .5 .5 scale 6 6 rotate 0 translate 0 0");
+ kv->SetString("$surfaceprop", "concrete");
+ pMaterial->SetShaderAndParams(kv);
+ }
+ }
+ }
+ update_override_textures = false;
+ }
+
if (update_nightmode)
{
static ConVar *r_DrawSpecificStaticProp = g_ICvar->FindVar("r_DrawSpecificStaticProp");
@@ -168,5 +219,9 @@ static InitRoutine init_fsn([]() {
nightmode_gui_color.installChangeCallback(rvarCallback);
nightmode_world_color.installChangeCallback(rvarCallback);
nightmode_skybox_color.installChangeCallback(rvarCallback);
+ override_textures.installChangeCallback([](settings::VariableBase &, bool after) { update_override_textures = true; });
+ override_textures_texture.installChangeCallback([](settings::VariableBase &, std::string after) { update_override_textures = true; });
+ EC::Register(
+ EC::LevelInit, []() { update_nightmode = true; update_override_textures = true; }, "levelinit_fsn");
});
} // namespace hooked_methods
diff --git a/src/nospread.cpp b/src/nospread.cpp
index 38118584..f127d020 100644
--- a/src/nospread.cpp
+++ b/src/nospread.cpp
@@ -914,7 +914,7 @@ static InitRoutine init_bulletnospread([]() {
{
if (bad_mantissa)
{
- draw_color = colors::red;
+ draw_color = colors::red_s;
draw_string = "Server uptime too Low!";
}
else
diff --git a/src/visual/CMakeLists.txt b/src/visual/CMakeLists.txt
index a7bc5a18..5137a908 100755
--- a/src/visual/CMakeLists.txt
+++ b/src/visual/CMakeLists.txt
@@ -2,7 +2,6 @@ set(files "${CMAKE_CURRENT_LIST_DIR}/atlas.cpp"
"${CMAKE_CURRENT_LIST_DIR}/colors.cpp"
"${CMAKE_CURRENT_LIST_DIR}/drawing.cpp"
"${CMAKE_CURRENT_LIST_DIR}/drawmgr.cpp"
- "${CMAKE_CURRENT_LIST_DIR}/EffectChams.cpp"
"${CMAKE_CURRENT_LIST_DIR}/EffectGlow.cpp"
"${CMAKE_CURRENT_LIST_DIR}/EventLogging.cpp"
"${CMAKE_CURRENT_LIST_DIR}/fidgetspinner.cpp"
diff --git a/src/visual/EffectChams.cpp b/src/visual/EffectChams.cpp
deleted file mode 100644
index 46c1334f..00000000
--- a/src/visual/EffectChams.cpp
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * EffectChams.cpp
- *
- * Created on: Apr 16, 2017
- * Author: nullifiedcat
- */
-
-#include
-#include
-#include
-#include "common.hpp"
-#include "Backtrack.hpp"
-
-namespace effect_chams
-{
-static settings::Boolean flat{ "chams.flat", "false" };
-static settings::Boolean health{ "chams.health", "false" };
-static settings::Boolean teammates{ "chams.show.teammates", "false" };
-static settings::Boolean disguised{ "chams.show.disguised", "true" };
-static settings::Boolean players{ "chams.show.players", "true" };
-static settings::Boolean medkits{ "chams.show.medkits", "false" };
-static settings::Boolean ammobox{ "chams.show.ammoboxes", "false" };
-static settings::Boolean buildings{ "chams.show.buildings", "true" };
-static settings::Boolean stickies{ "chams.show.stickies", "true" };
-static settings::Boolean teammate_buildings{ "chams.show.teammate-buildings", "false" };
-static settings::Boolean recursive{ "chams.recursive", "true" };
-static settings::Boolean weapons_white{ "chams.white-weapons", "true" };
-static settings::Boolean legit{ "chams.legit", "false" };
-static settings::Boolean singlepass{ "chams.single-pass", "false" };
-static settings::Boolean chamsself{ "chams.self", "true" };
-static settings::Boolean disco_chams{ "chams.disco", "false" };
-
-settings::Boolean enable{ "chams.enable", "false" };
-CatCommand fix_black_chams("fix_black_chams", "Fix Black Chams", []() {
- effect_chams::g_EffectChams.Shutdown();
- effect_chams::g_EffectChams.Init();
-});
-
-void EffectChams::Init()
-{
-#if !ENFORCE_STREAM_SAFETY
- if (init)
- return;
- logging::Info("Init EffectChams...");
- {
- KeyValues *kv = new KeyValues("UnlitGeneric");
- kv->SetString("$basetexture", "vgui/white_additive");
- kv->SetInt("$ignorez", 0);
- mat_unlit.Init("__cathook_echams_unlit", kv);
- }
- {
- KeyValues *kv = new KeyValues("UnlitGeneric");
- kv->SetString("$basetexture", "vgui/white_additive");
- kv->SetInt("$ignorez", 1);
- mat_unlit_z.Init("__cathook_echams_unlit_z", kv);
- }
- {
- KeyValues *kv = new KeyValues("VertexLitGeneric");
- kv->SetString("$basetexture", "vgui/white_additive");
- kv->SetInt("$ignorez", 0);
- kv->SetInt("$halflambert", 1);
- mat_lit.Init("__cathook_echams_lit", kv);
- }
- {
- KeyValues *kv = new KeyValues("VertexLitGeneric");
- kv->SetString("$basetexture", "vgui/white_additive");
- kv->SetInt("$ignorez", 1);
- kv->SetInt("$halflambert", 1);
- mat_lit_z.Init("__cathook_echams_lit_z", kv);
- }
- logging::Info("Init done!");
- init = true;
-#endif
-}
-
-void EffectChams::BeginRenderChams()
-{
-#if !ENFORCE_STREAM_SAFETY
- drawing = true;
- CMatRenderContextPtr ptr(GET_RENDER_CONTEXT);
- g_IVRenderView->SetBlend(1.0f);
-#endif
-}
-
-void EffectChams::EndRenderChams()
-{
-#if !ENFORCE_STREAM_SAFETY
- drawing = false;
- CMatRenderContextPtr ptr(GET_RENDER_CONTEXT);
- g_IVModelRender->ForcedMaterialOverride(nullptr);
-#endif
-}
-static rgba_t data[PLAYER_ARRAY_SIZE] = { colors::empty };
-void EffectChams::SetEntityColor(CachedEntity *ent, rgba_t color)
-{
- if (ent->m_IDX > MAX_PLAYERS || ent->m_IDX < 0)
- return;
- data[ent->m_IDX] = color;
-}
-static Timer t{};
-static int prevcolor = -1;
-rgba_t EffectChams::ChamsColor(IClientEntity *entity)
-{
- if (!isHackActive() || !*effect_chams::enable)
- return colors::empty;
-
- CachedEntity *ent = ENTITY(entity->entindex());
- if (disco_chams)
- {
- static rgba_t disco{ 0, 0, 0, 0 };
- if (t.test_and_set(200))
- {
- int color = rand() % 20;
- while (color == prevcolor)
- color = rand() % 20;
- prevcolor = color;
- switch (color)
- {
- case 2:
- disco = colors::pink;
- break;
- case 3:
- disco = colors::red;
- break;
- case 4:
- disco = colors::blu;
- break;
- case 5:
- disco = colors::red_b;
- break;
- case 6:
- disco = colors::blu_b;
- break;
- case 7:
- disco = colors::red_v;
- break;
- case 8:
- disco = colors::blu_v;
- break;
- case 9:
- disco = colors::red_u;
- break;
- case 10:
- disco = colors::blu_u;
- break;
- case 0:
- case 1:
- case 11:
- case 12:
- case 13:
- case 14:
- case 15:
- case 16:
- case 17:
- case 18:
- case 19:
- float color1 = rand() % 256;
- float color2 = rand() % 256;
- float color3 = rand() % 256;
- disco = { color1, color2, color3, 255.0f };
- }
- }
- return disco;
- }
- if (ent->m_IDX <= MAX_PLAYERS && ent->m_IDX >= 0)
- {
- if (data[entity->entindex()] != colors::empty)
- {
- auto toret = data[entity->entindex()];
- data[entity->entindex()] = colors::empty;
- return toret;
- }
- }
- if (CE_BAD(ent))
- return colors::white;
- if (re::C_BaseCombatWeapon::IsBaseCombatWeapon(entity))
- {
- IClientEntity *owner = re::C_TFWeaponBase::GetOwnerViaInterface(entity);
- if (owner)
- {
- return ChamsColor(owner);
- }
- }
- switch (ent->m_Type())
- {
- case ENTITY_BUILDING:
- if (!ent->m_bEnemy() && !(teammates || teammate_buildings) && ent != LOCAL_E)
- {
- return colors::empty;
- }
- if (health)
- {
- return colors::Health_dimgreen(ent->m_iHealth(), ent->m_iMaxHealth());
- }
- break;
- case ENTITY_PLAYER:
- if (!players)
- return colors::empty;
- if (health)
- {
- return colors::Health_dimgreen(ent->m_iHealth(), ent->m_iMaxHealth());
- }
- break;
- default:
- break;
- }
- return colors::EntityF(ent);
-}
-
-bool EffectChams::ShouldRenderChams(IClientEntity *entity)
-{
-#if ENFORCE_STREAM_SAFETY
- return false;
-#endif
- if (!isHackActive() || !*effect_chams::enable || CE_BAD(LOCAL_E))
- return false;
- if (entity->entindex() < 0)
- return false;
- CachedEntity *ent = ENTITY(entity->entindex());
- if (!chamsself && ent->m_IDX == LOCAL_E->m_IDX)
- return false;
- switch (ent->m_Type())
- {
- case ENTITY_BUILDING:
- if (!buildings)
- return false;
- if (!ent->m_bEnemy() && !(teammate_buildings || teammates))
- return false;
- if (ent->m_iHealth() == 0 || !ent->m_iHealth())
- return false;
- if (CE_BYTE(LOCAL_E, netvar.m_bCarryingObject) && ent->m_IDX == HandleToIDX(CE_INT(LOCAL_E, netvar.m_hCarriedObject)))
- return false;
- return true;
- case ENTITY_PLAYER:
- if (!players)
- return false;
- if (!disguised && IsPlayerDisguised(ent))
- return false;
- if (!teammates && !ent->m_bEnemy() && playerlist::IsDefault(ent))
- return false;
- if (CE_BYTE(ent, netvar.iLifeState))
- return false;
- return true;
- break;
- case ENTITY_PROJECTILE:
- if (!ent->m_bEnemy())
- return false;
- if (stickies && ent->m_iClassID() == CL_CLASS(CTFGrenadePipebombProjectile))
- {
- return true;
- }
- break;
- case ENTITY_GENERIC:
- switch (ent->m_ItemType())
- {
- case ITEM_HEALTH_LARGE:
- case ITEM_HEALTH_MEDIUM:
- case ITEM_HEALTH_SMALL:
- return *medkits;
- case ITEM_AMMO_LARGE:
- case ITEM_AMMO_MEDIUM:
- case ITEM_AMMO_SMALL:
- return *ammobox;
- default:
- break;
- }
- break;
- default:
- break;
- }
- return false;
-}
-
-void EffectChams::RenderChamsRecursive(IClientEntity *entity)
-{
-#if !ENFORCE_STREAM_SAFETY
- if (!isHackActive() || !*effect_chams::enable)
- return;
- entity->DrawModel(1);
-
- if (!*recursive)
- return;
-
- IClientEntity *attach;
- int passes = 0;
-
- attach = g_IEntityList->GetClientEntity(*(int *) ((uintptr_t) entity + netvar.m_Collision - 24) & 0xFFF);
- while (attach && passes++ < 32)
- {
- if (attach->ShouldDraw())
- {
- if (entity->GetClientClass()->m_ClassID == RCC_PLAYER && re::C_BaseCombatWeapon::IsBaseCombatWeapon(attach))
- {
- if (weapons_white)
- {
- rgba_t mod_original;
- g_IVRenderView->GetColorModulation(mod_original.rgba);
- g_IVRenderView->SetColorModulation(colors::white);
- attach->DrawModel(1);
- g_IVRenderView->SetColorModulation(mod_original.rgba);
- }
- else
- {
- attach->DrawModel(1);
- }
- }
- else
- attach->DrawModel(1);
- }
- attach = g_IEntityList->GetClientEntity(*(int *) ((uintptr_t) attach + netvar.m_Collision - 20) & 0xFFF);
- }
-#endif
-}
-
-void EffectChams::RenderChams(IClientEntity *entity)
-{
-#if !ENFORCE_STREAM_SAFETY
- if (!isHackActive() || !*effect_chams::enable)
- return;
- CMatRenderContextPtr ptr(GET_RENDER_CONTEXT);
- if (ShouldRenderChams(entity))
- {
- rgba_t color = ChamsColor(entity);
- rgba_t color_2 = color * 0.6f;
- if (!legit)
- {
- mat_unlit_z->AlphaModulate(1.0f);
- ptr->DepthRange(0.0f, 0.01f);
- g_IVRenderView->SetColorModulation(color_2);
- g_IVModelRender->ForcedMaterialOverride(flat ? mat_unlit_z : mat_lit_z);
- RenderChamsRecursive(entity);
- }
-
- if (legit || !singlepass)
- {
- mat_unlit->AlphaModulate(1.0f);
- g_IVRenderView->SetColorModulation(color);
- ptr->DepthRange(0.0f, 1.0f);
- g_IVModelRender->ForcedMaterialOverride(flat ? mat_unlit : mat_lit);
- RenderChamsRecursive(entity);
- }
- }
-#endif
-}
-void EffectChams::Render(int x, int y, int w, int h)
-{
-#if !ENFORCE_STREAM_SAFETY
- PROF_SECTION(DRAW_chams);
- if (!isHackActive() || disable_visuals)
- return;
- if (!effect_chams::enable && !(hacks::tf2::backtrack::chams && hacks::tf2::backtrack::isBacktrackEnabled))
- return;
- if (g_Settings.bInvalid)
- return;
- if (!init && effect_chams::enable)
- Init();
- if (!isHackActive() || (g_IEngine->IsTakingScreenshot() && clean_screenshots))
- return;
- if (hacks::tf2::backtrack::chams && hacks::tf2::backtrack::isBacktrackEnabled)
- {
- CMatRenderContextPtr ptr(GET_RENDER_CONTEXT);
- BeginRenderChams();
- // Don't mark as normal chams drawing
- drawing = false;
- for (int i = 1; i <= g_IEngine->GetMaxClients(); i++)
- {
- CachedEntity *ent = ENTITY(i);
- if (CE_BAD(ent) || i == g_IEngine->GetLocalPlayer() || !ent->m_bAlivePlayer() || ent->m_Type() != ENTITY_PLAYER)
- continue;
- // Entity won't draw in some cases so help the chams a bit
- hacks::tf2::backtrack::isDrawing = true;
- RAW_ENT(ent)->DrawModel(1);
- hacks::tf2::backtrack::isDrawing = false;
- }
- EndRenderChams();
- }
- if (!effect_chams::enable)
- return;
- CMatRenderContextPtr ptr(GET_RENDER_CONTEXT);
- BeginRenderChams();
- for (int i = 1; i <= HIGHEST_ENTITY; i++)
- {
- IClientEntity *entity = g_IEntityList->GetClientEntity(i);
- if (!entity || entity->IsDormant() || CE_BAD(ENTITY(i)))
- continue;
- RenderChams(entity);
- }
- EndRenderChams();
-#endif
-}
-EffectChams g_EffectChams;
-CScreenSpaceEffectRegistration *g_pEffectChams = nullptr;
-
-static InitRoutine init([]() {
- EC::Register(
- EC::LevelShutdown, []() { g_EffectChams.Shutdown(); }, "chams");
- if (g_ppScreenSpaceRegistrationHead && g_pScreenSpaceEffects)
- {
- effect_chams::g_pEffectChams = new CScreenSpaceEffectRegistration("_cathook_chams", &effect_chams::g_EffectChams);
- g_pScreenSpaceEffects->EnableScreenSpaceEffect("_cathook_chams");
- }
-});
-} // namespace effect_chams
diff --git a/src/visual/EffectGlow.cpp b/src/visual/EffectGlow.cpp
index ffbb16b1..6fb7bbb2 100644
--- a/src/visual/EffectGlow.cpp
+++ b/src/visual/EffectGlow.cpp
@@ -230,7 +230,7 @@ rgba_t EffectGlow::GlowColor(IClientEntity *entity)
if (CE_BAD(ent))
return colors::white;
if (ent == hacks::shared::aimbot::CurrentTarget())
- return colors::pink;
+ return colors::target;
if (re::C_BaseCombatWeapon::IsBaseCombatWeapon(entity))
{
owner = re::C_TFWeaponBase::GetOwnerViaInterface(entity);
diff --git a/src/visual/colors.cpp b/src/visual/colors.cpp
index e1d2cd03..6ba7d4f9 100644
--- a/src/visual/colors.cpp
+++ b/src/visual/colors.cpp
@@ -8,6 +8,44 @@
#include
#include "common.hpp"
+namespace colors
+{
+settings::Rgba col_red{ "colors.team-red", "ed2a2aff" };
+settings::Rgba col_blu{ "colors.team-blu", "1c6cedff" };
+settings::Rgba col_red_b{ "colors.team-red.background", "402020ff" };
+settings::Rgba col_blu_b{ "colors.team-blu.background", "202040ff" };
+settings::Rgba col_red_v{ "colors.team-red.vaccinator", "c4666cff" };
+settings::Rgba col_blu_v{ "colors.team-blu.vaccinator", "66b6c4ff" };
+settings::Rgba col_red_u{ "colors.team-red.ubercharge", "ff6600ff" };
+settings::Rgba col_blu_u{ "colors.team-blu.ubercharge", "003399ff" };
+settings::Rgba col_guicolor{ "colors.guicolor", "ffffffff" };
+settings::Rgba col_target{ "colors.target", "00ff00ff" };
+
+rgba_t red = *col_red;
+rgba_t blu = *col_blu;
+rgba_t red_b = *col_red_b;
+rgba_t blu_b = *col_blu_b;
+rgba_t red_v = *col_red_v;
+rgba_t blu_v = *col_blu_v;
+rgba_t red_u = *col_red_u;
+rgba_t blu_u = *col_blu_u;
+rgba_t gui = *col_guicolor;
+rgba_t target = *col_target;
+
+static InitRoutine init([]() {
+ col_red.installChangeCallback([](settings::VariableBase &var, rgba_t after) { red = after; });
+ col_blu.installChangeCallback([](settings::VariableBase &var, rgba_t after) { blu = after; });
+ col_red_b.installChangeCallback([](settings::VariableBase &var, rgba_t after) { red_b = after; });
+ col_blu_b.installChangeCallback([](settings::VariableBase &var, rgba_t after) { blu_b = after; });
+ col_red_v.installChangeCallback([](settings::VariableBase &var, rgba_t after) { red_v = after; });
+ col_blu_v.installChangeCallback([](settings::VariableBase &var, rgba_t after) { blu_v = after; });
+ col_red_u.installChangeCallback([](settings::VariableBase &var, rgba_t after) { red_u = after; });
+ col_blu_u.installChangeCallback([](settings::VariableBase &var, rgba_t after) { blu_u = after; });
+ col_guicolor.installChangeCallback([](settings::VariableBase &var, rgba_t after) { gui = after; });
+ col_target.installChangeCallback([](settings::VariableBase &var, rgba_t after) { target = after; });
+});
+}
+
rgba_t colors::EntityF(CachedEntity *ent)
{
rgba_t result, plclr;
diff --git a/src/visual/drawmgr.cpp b/src/visual/drawmgr.cpp
index 01f619b6..28154b62 100644
--- a/src/visual/drawmgr.cpp
+++ b/src/visual/drawmgr.cpp
@@ -85,11 +85,11 @@ void DrawCheatVisuals()
if (!info_text_min)
{
AddSideString(hack::GetVersion(),
- GUIColor()); // github commit and date
- AddSideString(hack::GetType(), GUIColor()); // Compile type
+ colors::gui); // github commit and date
+ AddSideString(hack::GetType(), colors::gui); // Compile type
#if ENABLE_GUI
- AddSideString("Press '" + open_gui_button.toString() + "' key to open/close cheat menu.", GUIColor());
- AddSideString("Use mouse to navigate in menu.", GUIColor());
+ AddSideString("Press '" + open_gui_button.toString() + "' key to open/close cheat menu.", colors::gui);
+ AddSideString("Use mouse to navigate in menu.", colors::gui);
#endif
}
}