diff options
| author | salmonik <salmonik@tuta.io> | 2026-10-27 21:22:47 +0100 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-10-27 21:22:47 +0100 |
| commit | 9904891162a6749d39110110c0812a64c241a7ea (patch) | |
| tree | 676eea2d0933ccb7675be6cac1481cc8208993ec /src/menu.cpp | |
| parent | Stucklaunch: fix prop detection and add diagnostics (diff) | |
| download | hl2h-9904891162a6749d39110110c0812a64c241a7ea.tar.gz hl2h-9904891162a6749d39110110c0812a64c241a7ea.zip | |
Remove stucklaunch; add valuable-item ESP
- Drop the stucklaunch feature, its settings, diagnostics and
m_hGroundEntity resolution.
- Add a Visuals feature that scans the client entity list for valuable
pickups: health/medkits/chargers, ammo boxes/crates/grenades, batteries,
HEV suit modules/chargers, supply crates and generic items.
- Model-first classification with class fallbacks; category toggles, distance
labels and a max-distance slider.
- Draw colored marker/label tags through walls, independent of the hostile NPC
ESP.
- Persist [items] active/bind/health/ammo/armor/crates/distance/max_dist;
Reset restores defaults; GUI card and CONTEXT updated.
Diffstat (limited to '')
| -rw-r--r-- | src/menu.cpp | 84 |
1 files changed, 44 insertions, 40 deletions
diff --git a/src/menu.cpp b/src/menu.cpp index cc3890a..af8d10d 100644 --- a/src/menu.cpp +++ b/src/menu.cpp | |||
| @@ -44,11 +44,13 @@ FeatureState g_esp{true, 0}; | |||
| 44 | FeatureState g_aimbot{true, 604}; // default Mouse5, rebindable in the GUI | 44 | FeatureState g_aimbot{true, 604}; // default Mouse5, rebindable in the GUI |
| 45 | FeatureState g_triggerbot{true, 603}; // default Mouse4 | 45 | FeatureState g_triggerbot{true, 603}; // default Mouse4 |
| 46 | FeatureState g_silentaim{true, 602}; // default Mouse3 | 46 | FeatureState g_silentaim{true, 602}; // default Mouse3 |
| 47 | FeatureState g_stucklaunch{false, 0}; // opt-in movement assist | 47 | FeatureState g_item_esp{true, 0}; // valuable item tags, always-on by default |
| 48 | bool g_stucklaunch_use_spam = true; | 48 | bool g_item_health = true; |
| 49 | bool g_stucklaunch_gravspam = false; | 49 | bool g_item_ammo = true; |
| 50 | bool g_stucklaunch_autostrafe = true; | 50 | bool g_item_armor = true; |
| 51 | int g_stucklaunch_spam_ticks = 2; | 51 | bool g_item_crates = true; |
| 52 | bool g_item_distance = true; | ||
| 53 | int g_item_max_dist = 2500; | ||
| 52 | 54 | ||
| 53 | // Aimbot bone checklist. Head defaults on (v1 behaviour). | 55 | // Aimbot bone checklist. Head defaults on (v1 behaviour). |
| 54 | bool g_aim_bones[AIM_BONE_COUNT] = {true, false, false, | 56 | bool g_aim_bones[AIM_BONE_COUNT] = {true, false, false, |
| @@ -163,11 +165,6 @@ void config_save() { | |||
| 163 | fprintf(f, "[bhop]\nactive=%d\nbind=%d\nautostrafe=%d\n", g_bhop.active, | 165 | fprintf(f, "[bhop]\nactive=%d\nbind=%d\nautostrafe=%d\n", g_bhop.active, |
| 164 | g_bhop.bind, g_bhop_autostrafe); | 166 | g_bhop.bind, g_bhop_autostrafe); |
| 165 | fprintf(f, "[abh]\nactive=%d\nbind=%d\n", g_abh.active, g_abh.bind); | 167 | fprintf(f, "[abh]\nactive=%d\nbind=%d\n", g_abh.active, g_abh.bind); |
| 166 | fprintf(f, "[stucklaunch]\nactive=%d\nbind=%d\nuse_spam=%d\n" | ||
| 167 | "gravspam=%d\nautostrafe=%d\nspam_ticks=%d\n", | ||
| 168 | g_stucklaunch.active, g_stucklaunch.bind, | ||
| 169 | (int)g_stucklaunch_use_spam, (int)g_stucklaunch_gravspam, | ||
| 170 | (int)g_stucklaunch_autostrafe, g_stucklaunch_spam_ticks); | ||
| 171 | fprintf(f, "[jumpbug]\nactive=%d\nbind=%d\nassist=%d\n", | 168 | fprintf(f, "[jumpbug]\nactive=%d\nbind=%d\nassist=%d\n", |
| 172 | g_jumpbug.active, g_jumpbug.bind, (int)g_jumpbug_assist); | 169 | g_jumpbug.active, g_jumpbug.bind, (int)g_jumpbug_assist); |
| 173 | fprintf(f, "[melee]\nactive=%d\nbind=%d\n", g_melee.active, g_melee.bind); | 170 | fprintf(f, "[melee]\nactive=%d\nbind=%d\n", g_melee.active, g_melee.bind); |
| @@ -186,6 +183,11 @@ void config_save() { | |||
| 186 | g_triggerbot.bind); | 183 | g_triggerbot.bind); |
| 187 | fprintf(f, "[silentaim]\nactive=%d\nbind=%d\nfov=%d\n", g_silentaim.active, | 184 | fprintf(f, "[silentaim]\nactive=%d\nbind=%d\nfov=%d\n", g_silentaim.active, |
| 188 | g_silentaim.bind, g_silent_fov); | 185 | g_silentaim.bind, g_silent_fov); |
| 186 | fprintf(f, "[items]\nactive=%d\nbind=%d\nhealth=%d\nammo=%d\n" | ||
| 187 | "armor=%d\ncrates=%d\ndistance=%d\nmax_dist=%d\n", | ||
| 188 | g_item_esp.active, g_item_esp.bind, (int)g_item_health, | ||
| 189 | (int)g_item_ammo, (int)g_item_armor, (int)g_item_crates, | ||
| 190 | (int)g_item_distance, g_item_max_dist); | ||
| 189 | fprintf(f, "[esp]\nactive=%d\nbind=%d\nneutral=%d\nhealthbar=%d\n" | 191 | fprintf(f, "[esp]\nactive=%d\nbind=%d\nneutral=%d\nhealthbar=%d\n" |
| 190 | "healthnum=%d\nname=%d\nskeleton=%d\nbox=%d\nspeedgraph=%d\n", | 192 | "healthnum=%d\nname=%d\nskeleton=%d\nbox=%d\nspeedgraph=%d\n", |
| 191 | g_esp.active, g_esp.bind, g_esp_opt[ESP_OPT_SHOW_NEUTRAL], | 193 | g_esp.active, g_esp.bind, g_esp_opt[ESP_OPT_SHOW_NEUTRAL], |
| @@ -214,7 +216,7 @@ static bool config_load() { | |||
| 214 | char line[256]; | 216 | char line[256]; |
| 215 | FeatureState *cur = nullptr; | 217 | FeatureState *cur = nullptr; |
| 216 | bool in_esp = false, in_bhop = false, in_aim = false, in_silent = false, | 218 | bool in_esp = false, in_bhop = false, in_aim = false, in_silent = false, |
| 217 | in_jumpbug = false, in_spread = false, in_stucklaunch = false; | 219 | in_jumpbug = false, in_spread = false, in_items = false; |
| 218 | while (fgets(line, sizeof(line), f)) { | 220 | while (fgets(line, sizeof(line), f)) { |
| 219 | line[strcspn(line, "\r\n")] = 0; | 221 | line[strcspn(line, "\r\n")] = 0; |
| 220 | if (line[0] == '[') { | 222 | if (line[0] == '[') { |
| @@ -222,8 +224,6 @@ static bool config_load() { | |||
| 222 | cur = &g_bhop; | 224 | cur = &g_bhop; |
| 223 | else if (strstr(line, "[abh]")) | 225 | else if (strstr(line, "[abh]")) |
| 224 | cur = &g_abh; | 226 | cur = &g_abh; |
| 225 | else if (strstr(line, "[stucklaunch]")) | ||
| 226 | cur = &g_stucklaunch; | ||
| 227 | else if (strstr(line, "[jumpbug]")) | 227 | else if (strstr(line, "[jumpbug]")) |
| 228 | cur = &g_jumpbug; | 228 | cur = &g_jumpbug; |
| 229 | else if (strstr(line, "[melee]")) | 229 | else if (strstr(line, "[melee]")) |
| @@ -232,6 +232,8 @@ static bool config_load() { | |||
| 232 | cur = &g_spread; | 232 | cur = &g_spread; |
| 233 | else if (strstr(line, "[esp]")) | 233 | else if (strstr(line, "[esp]")) |
| 234 | cur = &g_esp; | 234 | cur = &g_esp; |
| 235 | else if (strstr(line, "[items]")) | ||
| 236 | cur = &g_item_esp; | ||
| 235 | else if (strstr(line, "[aimbot]")) | 237 | else if (strstr(line, "[aimbot]")) |
| 236 | cur = &g_aimbot; | 238 | cur = &g_aimbot; |
| 237 | else if (strstr(line, "[triggerbot]")) | 239 | else if (strstr(line, "[triggerbot]")) |
| @@ -246,7 +248,7 @@ static bool config_load() { | |||
| 246 | in_silent = (cur == &g_silentaim); | 248 | in_silent = (cur == &g_silentaim); |
| 247 | in_jumpbug = (cur == &g_jumpbug); | 249 | in_jumpbug = (cur == &g_jumpbug); |
| 248 | in_spread = (cur == &g_spread); | 250 | in_spread = (cur == &g_spread); |
| 249 | in_stucklaunch = (cur == &g_stucklaunch); | 251 | in_items = (cur == &g_item_esp); |
| 250 | } else if (cur) { | 252 | } else if (cur) { |
| 251 | char *eq = strchr(line, '='); | 253 | char *eq = strchr(line, '='); |
| 252 | if (!eq) | 254 | if (!eq) |
| @@ -262,18 +264,22 @@ static bool config_load() { | |||
| 262 | if (in_spread && strcmp(key, "no_spread") == 0) { | 264 | if (in_spread && strcmp(key, "no_spread") == 0) { |
| 263 | g_spread_no_spread = atoi(val) != 0; | 265 | g_spread_no_spread = atoi(val) != 0; |
| 264 | } | 266 | } |
| 265 | if (in_stucklaunch) { | 267 | if (in_items) { |
| 266 | if (strcmp(key, "use_spam") == 0) | 268 | if (strcmp(key, "health") == 0) |
| 267 | g_stucklaunch_use_spam = atoi(val) != 0; | 269 | g_item_health = atoi(val) != 0; |
| 268 | else if (strcmp(key, "gravspam") == 0) | 270 | else if (strcmp(key, "ammo") == 0) |
| 269 | g_stucklaunch_gravspam = atoi(val) != 0; | 271 | g_item_ammo = atoi(val) != 0; |
| 270 | else if (strcmp(key, "autostrafe") == 0) | 272 | else if (strcmp(key, "armor") == 0) |
| 271 | g_stucklaunch_autostrafe = atoi(val) != 0; | 273 | g_item_armor = atoi(val) != 0; |
| 272 | else if (strcmp(key, "spam_ticks") == 0) { | 274 | else if (strcmp(key, "crates") == 0) |
| 275 | g_item_crates = atoi(val) != 0; | ||
| 276 | else if (strcmp(key, "distance") == 0) | ||
| 277 | g_item_distance = atoi(val) != 0; | ||
| 278 | else if (strcmp(key, "max_dist") == 0) { | ||
| 273 | int v = atoi(val); | 279 | int v = atoi(val); |
| 274 | if (v < 1) v = 1; | 280 | if (v < 250) v = 250; |
| 275 | if (v > 16) v = 16; | 281 | if (v > 5000) v = 5000; |
| 276 | g_stucklaunch_spam_ticks = v; | 282 | g_item_max_dist = v; |
| 277 | } | 283 | } |
| 278 | } | 284 | } |
| 279 | if (in_aim) { | 285 | if (in_aim) { |
| @@ -354,11 +360,6 @@ void config_reset_defaults() { | |||
| 354 | g_bhop = {true, 0}; | 360 | g_bhop = {true, 0}; |
| 355 | g_bhop_autostrafe = true; | 361 | g_bhop_autostrafe = true; |
| 356 | g_abh = {true, 0}; | 362 | g_abh = {true, 0}; |
| 357 | g_stucklaunch = {false, 0}; | ||
| 358 | g_stucklaunch_use_spam = true; | ||
| 359 | g_stucklaunch_gravspam = false; | ||
| 360 | g_stucklaunch_autostrafe = true; | ||
| 361 | g_stucklaunch_spam_ticks = 2; | ||
| 362 | g_jumpbug = {true, 0}; | 363 | g_jumpbug = {true, 0}; |
| 363 | g_jumpbug_assist = false; | 364 | g_jumpbug_assist = false; |
| 364 | g_melee = {true, 0}; | 365 | g_melee = {true, 0}; |
| @@ -367,6 +368,13 @@ void config_reset_defaults() { | |||
| 367 | g_esp = {true, 0}; | 368 | g_esp = {true, 0}; |
| 368 | for (int i = 0; i < ESP_OPT_COUNT; i++) | 369 | for (int i = 0; i < ESP_OPT_COUNT; i++) |
| 369 | g_esp_opt[i] = true; | 370 | g_esp_opt[i] = true; |
| 371 | g_item_esp = {true, 0}; | ||
| 372 | g_item_health = true; | ||
| 373 | g_item_ammo = true; | ||
| 374 | g_item_armor = true; | ||
| 375 | g_item_crates = true; | ||
| 376 | g_item_distance = true; | ||
| 377 | g_item_max_dist = 2500; | ||
| 370 | g_aimbot = {true, 604}; | 378 | g_aimbot = {true, 604}; |
| 371 | g_triggerbot = {true, 603}; | 379 | g_triggerbot = {true, 603}; |
| 372 | g_silentaim = {true, 602}; | 380 | g_silentaim = {true, 602}; |
| @@ -476,7 +484,7 @@ static bool key_held(int sc) { | |||
| 476 | static FeatureState *feature_state(int feature) { | 484 | static FeatureState *feature_state(int feature) { |
| 477 | static FeatureState *feats[FEAT_COUNT] = { | 485 | static FeatureState *feats[FEAT_COUNT] = { |
| 478 | &g_bhop, &g_abh, &g_esp, &g_aimbot, &g_triggerbot, | 486 | &g_bhop, &g_abh, &g_esp, &g_aimbot, &g_triggerbot, |
| 479 | &g_silentaim, &g_jumpbug, &g_melee, &g_spread, &g_stucklaunch}; | 487 | &g_silentaim, &g_jumpbug, &g_melee, &g_spread, &g_item_esp}; |
| 480 | if (feature < 0 || feature >= FEAT_COUNT) | 488 | if (feature < 0 || feature >= FEAT_COUNT) |
| 481 | return nullptr; | 489 | return nullptr; |
| 482 | return feats[feature]; | 490 | return feats[feature]; |
| @@ -509,14 +517,6 @@ bool jumpbug_assist_enabled() { return g_jumpbug_assist; } | |||
| 509 | 517 | ||
| 510 | bool spread_no_spread_enabled() { return g_spread_no_spread; } | 518 | bool spread_no_spread_enabled() { return g_spread_no_spread; } |
| 511 | 519 | ||
| 512 | bool stucklaunch_use_spam_enabled() { return g_stucklaunch_use_spam; } | ||
| 513 | |||
| 514 | bool stucklaunch_gravspam_enabled() { return g_stucklaunch_gravspam; } | ||
| 515 | |||
| 516 | bool stucklaunch_autostrafe_enabled() { return g_stucklaunch_autostrafe; } | ||
| 517 | |||
| 518 | int stucklaunch_spam_ticks() { return g_stucklaunch_spam_ticks; } | ||
| 519 | |||
| 520 | unsigned aimbot_bone_mask() { | 520 | unsigned aimbot_bone_mask() { |
| 521 | unsigned m = 0; | 521 | unsigned m = 0; |
| 522 | if (g_aim_bones[AIM_BONE_HEAD]) | 522 | if (g_aim_bones[AIM_BONE_HEAD]) |
| @@ -658,8 +658,10 @@ void outer_draw() { | |||
| 658 | // HL2H_DRAW_TEST=1 draws a probe rect without needing the GUI open | 658 | // HL2H_DRAW_TEST=1 draws a probe rect without needing the GUI open |
| 659 | static bool draw_test = getenv("HL2H_DRAW_TEST") != nullptr; | 659 | static bool draw_test = getenv("HL2H_DRAW_TEST") != nullptr; |
| 660 | bool esp_on = feature_active(FEAT_ESP); | 660 | bool esp_on = feature_active(FEAT_ESP); |
| 661 | bool items_on = feature_active(FEAT_ITEM_ESP); | ||
| 661 | bool toasts = gui_toasts_active(); | 662 | bool toasts = gui_toasts_active(); |
| 662 | if (!g_surface || (!gui_is_open() && !draw_test && !esp_on && !toasts)) | 663 | if (!g_surface || |
| 664 | (!gui_is_open() && !draw_test && !esp_on && !items_on && !toasts)) | ||
| 663 | return; | 665 | return; |
| 664 | 666 | ||
| 665 | // Level/menu -> game transitions can invalidate the VGUI font handle. | 667 | // Level/menu -> game transitions can invalidate the VGUI font handle. |
| @@ -709,6 +711,8 @@ void outer_draw() { | |||
| 709 | surf_push_make_current(panel, false); | 711 | surf_push_make_current(panel, false); |
| 710 | if (esp_on && overlay_font) | 712 | if (esp_on && overlay_font) |
| 711 | esp_draw(); | 713 | esp_draw(); |
| 714 | if (items_on && overlay_font) | ||
| 715 | esp_draw_items(); | ||
| 712 | if (draw_test && overlay_font) { | 716 | if (draw_test && overlay_font) { |
| 713 | surf_draw_set_color(255, 0, 0, 255); | 717 | surf_draw_set_color(255, 0, 0, 255); |
| 714 | surf_draw_filled_rect(20, 20, 180, 60); | 718 | surf_draw_filled_rect(20, 20, 180, 60); |
