From 49df428d95a7c443d418d5b7e2a93af599b54f76 Mon Sep 17 00:00:00 2001 From: salmonik Date: Wed, 4 Nov 2026 17:51:20 +0100 Subject: Add chams - Hook IVModelRender::DrawModelExecute (VEngineModel016 slot 19) and force models/debug/debugwhite for NPC models, identified by ModelRenderInfo_t::entity_index. - Two passes: MATERIAL_VAR_IGNOREZ through walls, then normal depth, with IMaterial::ColorModulate for the configured colour; restore the shared material's flag/colour afterwards. - Material lookup via the IMaterialSystem list, FindMaterial fallback. - New Chams feature/card with Through walls and colour; [chams] config. - Remove the temporary ammo/projectile/fuse diagnostics. --- src/menu.cpp | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'src/menu.cpp') diff --git a/src/menu.cpp b/src/menu.cpp index 521bf43..77eb35f 100644 --- a/src/menu.cpp +++ b/src/menu.cpp @@ -63,6 +63,9 @@ FeatureState g_skybox{false, 0}; // skybox.png image override FeatureState g_projectiles{true, 0}; // grenade / rocket ESP bool g_proj_fuse = true; bool g_proj_radius = true; +FeatureState g_chams{false, 0}; // flat model material, optional through walls +bool g_chams_walls = true; +int g_chams_rgb[3] = {255, 60, 60}; bool g_item_health = true; bool g_item_ammo = true; bool g_item_armor = true; @@ -234,6 +237,9 @@ void config_save() { fprintf(f, "[projectiles]\nactive=%d\nbind=%d\nfuse=%d\nradius=%d\n", g_projectiles.active, g_projectiles.bind, (int)g_proj_fuse, (int)g_proj_radius); + fprintf(f, "[chams]\nactive=%d\nbind=%d\nwalls=%d\nr=%d\ng=%d\nb=%d\n", + g_chams.active, g_chams.bind, (int)g_chams_walls, g_chams_rgb[0], + g_chams_rgb[1], g_chams_rgb[2]); fprintf(f, "[items]\nactive=%d\nbind=%d\nhealth=%d\nammo=%d\n" "armor=%d\nweapons=%d\ncrates=%d\ndistance=%d\nmax_dist=%d\n" "usable=%d\n", @@ -284,7 +290,7 @@ static bool config_load() { bool in_esp = false, in_bhop = false, in_aim = false, in_jumpbug = false, in_spread = false, in_items = false, in_tint = false, in_fog = false, in_view = false, in_movement = false, - in_proj = false; + in_proj = false, in_chams = false; while (fgets(line, sizeof(line), f)) { line[strcspn(line, "\r\n")] = 0; if (line[0] == '[') { @@ -312,6 +318,8 @@ static bool config_load() { cur = &g_skybox; else if (strstr(line, "[projectiles]")) cur = &g_projectiles; + else if (strstr(line, "[chams]")) + cur = &g_chams; else if (strstr(line, "[aimbot]")) cur = &g_aimbot; else if (strstr(line, "[triggerbot]")) @@ -335,6 +343,7 @@ static bool config_load() { in_view = strstr(line, "[view]") != nullptr; in_movement = strstr(line, "[movement]") != nullptr; in_proj = (cur == &g_projectiles); + in_chams = (cur == &g_chams); } else if (cur || in_view || in_movement) { char *eq = strchr(line, '='); if (!eq) @@ -381,6 +390,17 @@ static bool config_load() { else if (strcmp(key, "radius") == 0) g_proj_radius = atoi(val) != 0; } + if (in_chams) { + if (strcmp(key, "walls") == 0) + g_chams_walls = atoi(val) != 0; + else if (strcmp(key, "r") == 0 || strcmp(key, "g") == 0 || + strcmp(key, "b") == 0) { + int v = atoi(val); + if (v < 0) v = 0; + if (v > 255) v = 255; + g_chams_rgb[key[0] == 'r' ? 0 : key[0] == 'g' ? 1 : 2] = v; + } + } if (in_aim) { if (strcmp(key, "smooth") == 0) { int v = atoi(val); @@ -605,6 +625,11 @@ void config_reset_defaults() { g_projectiles = {true, 0}; g_proj_fuse = true; g_proj_radius = true; + g_chams = {false, 0}; + g_chams_walls = true; + g_chams_rgb[0] = 255; + g_chams_rgb[1] = 60; + g_chams_rgb[2] = 60; g_item_health = true; g_item_ammo = true; g_item_armor = true; @@ -738,7 +763,8 @@ static FeatureState *feature_state(int feature) { static FeatureState *feats[FEAT_COUNT] = { &g_bhop, &g_abh, &g_esp, &g_aimbot, &g_triggerbot, &g_silentaim, &g_jumpbug, &g_melee, &g_spread, &g_item_esp, - &g_fullbright, &g_world_tint, &g_fog, &g_skybox, &g_projectiles}; + &g_fullbright, &g_world_tint, &g_fog, &g_skybox, &g_projectiles, + &g_chams}; if (feature < 0 || feature >= FEAT_COUNT) return nullptr; return feats[feature]; -- cgit v1.2.3