diff options
| author | salmonik <salmonik@tuta.io> | 2026-11-03 23:32:16 +0100 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-11-03 23:32:16 +0100 |
| commit | edba65625dd5823705619a2e682a99d6ad91ae8b (patch) | |
| tree | cae03d46267469d1076937ad22c7b2aec63b068e /src/menu.cpp | |
| parent | GUI: add inline colour picker control (diff) | |
| download | hl2h-edba65625dd5823705619a2e682a99d6ad91ae8b.tar.gz hl2h-edba65625dd5823705619a2e682a99d6ad91ae8b.zip | |
World: add prop tint and fog override
- World tint now also colours prop materials (models/props*) with their own
colour, covering static props and prop_physics while leaving NPC, player and
weapon materials untouched.
- New Fog card: fog_override colour/start/end via ClientCmd, optional skybox
fog, and a Remove fog mode. Restores the map fog (fog_override 0) when
disabled and re-applies after level changes.
- Config sections [worldtint] prop/colour keys and [fog].
Diffstat (limited to 'src/menu.cpp')
| -rw-r--r-- | src/menu.cpp | 72 |
1 files changed, 66 insertions, 6 deletions
diff --git a/src/menu.cpp b/src/menu.cpp index 6a7ffe5..237502b 100644 --- a/src/menu.cpp +++ b/src/menu.cpp | |||
| @@ -49,8 +49,16 @@ FeatureState g_fullbright{false, 0}; // mat_fullbright world lighting | |||
| 49 | FeatureState g_world_tint{false, 0}; // material colour modulation | 49 | FeatureState g_world_tint{false, 0}; // material colour modulation |
| 50 | bool g_tint_world_on = true; | 50 | bool g_tint_world_on = true; |
| 51 | bool g_tint_sky_on = true; | 51 | bool g_tint_sky_on = true; |
| 52 | bool g_tint_prop_on = true; | ||
| 52 | int g_tint_world_rgb[3] = {255, 255, 255}; | 53 | int g_tint_world_rgb[3] = {255, 255, 255}; |
| 53 | int g_tint_sky_rgb[3] = {255, 255, 255}; | 54 | int g_tint_sky_rgb[3] = {255, 255, 255}; |
| 55 | int g_tint_prop_rgb[3] = {255, 255, 255}; | ||
| 56 | FeatureState g_fog{false, 0}; // fog_override colour/distance | ||
| 57 | bool g_fog_skybox = true; | ||
| 58 | bool g_fog_disable = false; | ||
| 59 | int g_fog_rgb[3] = {160, 170, 190}; | ||
| 60 | int g_fog_start = 200; | ||
| 61 | int g_fog_end = 3000; | ||
| 54 | bool g_item_health = true; | 62 | bool g_item_health = true; |
| 55 | bool g_item_ammo = true; | 63 | bool g_item_ammo = true; |
| 56 | bool g_item_armor = true; | 64 | bool g_item_armor = true; |
| @@ -193,11 +201,17 @@ void config_save() { | |||
| 193 | fprintf(f, "[fullbright]\nactive=%d\nbind=%d\n", g_fullbright.active, | 201 | fprintf(f, "[fullbright]\nactive=%d\nbind=%d\n", g_fullbright.active, |
| 194 | g_fullbright.bind); | 202 | g_fullbright.bind); |
| 195 | fprintf(f, "[worldtint]\nactive=%d\nbind=%d\nworld=%d\nsky=%d\n" | 203 | fprintf(f, "[worldtint]\nactive=%d\nbind=%d\nworld=%d\nsky=%d\n" |
| 196 | "wr=%d\nwg=%d\nwb=%d\nsr=%d\nsg=%d\nsb=%d\n", | 204 | "prop=%d\nwr=%d\nwg=%d\nwb=%d\nsr=%d\nsg=%d\nsb=%d\n" |
| 205 | "pr=%d\npg=%d\npb=%d\n", | ||
| 197 | g_world_tint.active, g_world_tint.bind, (int)g_tint_world_on, | 206 | g_world_tint.active, g_world_tint.bind, (int)g_tint_world_on, |
| 198 | (int)g_tint_sky_on, g_tint_world_rgb[0], g_tint_world_rgb[1], | 207 | (int)g_tint_sky_on, (int)g_tint_prop_on, g_tint_world_rgb[0], |
| 199 | g_tint_world_rgb[2], g_tint_sky_rgb[0], g_tint_sky_rgb[1], | 208 | g_tint_world_rgb[1], g_tint_world_rgb[2], g_tint_sky_rgb[0], |
| 200 | g_tint_sky_rgb[2]); | 209 | g_tint_sky_rgb[1], g_tint_sky_rgb[2], g_tint_prop_rgb[0], |
| 210 | g_tint_prop_rgb[1], g_tint_prop_rgb[2]); | ||
| 211 | fprintf(f, "[fog]\nactive=%d\nbind=%d\nr=%d\ng=%d\nb=%d\n" | ||
| 212 | "start=%d\nend=%d\nskybox=%d\ndisable=%d\n", | ||
| 213 | g_fog.active, g_fog.bind, g_fog_rgb[0], g_fog_rgb[1], g_fog_rgb[2], | ||
| 214 | g_fog_start, g_fog_end, (int)g_fog_skybox, (int)g_fog_disable); | ||
| 201 | fprintf(f, "[items]\nactive=%d\nbind=%d\nhealth=%d\nammo=%d\n" | 215 | fprintf(f, "[items]\nactive=%d\nbind=%d\nhealth=%d\nammo=%d\n" |
| 202 | "armor=%d\nweapons=%d\ncrates=%d\ndistance=%d\nmax_dist=%d\n", | 216 | "armor=%d\nweapons=%d\ncrates=%d\ndistance=%d\nmax_dist=%d\n", |
| 203 | g_item_esp.active, g_item_esp.bind, (int)g_item_health, | 217 | g_item_esp.active, g_item_esp.bind, (int)g_item_health, |
| @@ -232,7 +246,7 @@ static bool config_load() { | |||
| 232 | FeatureState *cur = nullptr; | 246 | FeatureState *cur = nullptr; |
| 233 | bool in_esp = false, in_bhop = false, in_aim = false, in_silent = false, | 247 | bool in_esp = false, in_bhop = false, in_aim = false, in_silent = false, |
| 234 | in_jumpbug = false, in_spread = false, in_items = false, | 248 | in_jumpbug = false, in_spread = false, in_items = false, |
| 235 | in_tint = false; | 249 | in_tint = false, in_fog = false; |
| 236 | while (fgets(line, sizeof(line), f)) { | 250 | while (fgets(line, sizeof(line), f)) { |
| 237 | line[strcspn(line, "\r\n")] = 0; | 251 | line[strcspn(line, "\r\n")] = 0; |
| 238 | if (line[0] == '[') { | 252 | if (line[0] == '[') { |
| @@ -254,6 +268,8 @@ static bool config_load() { | |||
| 254 | cur = &g_fullbright; | 268 | cur = &g_fullbright; |
| 255 | else if (strstr(line, "[worldtint]")) | 269 | else if (strstr(line, "[worldtint]")) |
| 256 | cur = &g_world_tint; | 270 | cur = &g_world_tint; |
| 271 | else if (strstr(line, "[fog]")) | ||
| 272 | cur = &g_fog; | ||
| 257 | else if (strstr(line, "[aimbot]")) | 273 | else if (strstr(line, "[aimbot]")) |
| 258 | cur = &g_aimbot; | 274 | cur = &g_aimbot; |
| 259 | else if (strstr(line, "[triggerbot]")) | 275 | else if (strstr(line, "[triggerbot]")) |
| @@ -270,6 +286,7 @@ static bool config_load() { | |||
| 270 | in_spread = (cur == &g_spread); | 286 | in_spread = (cur == &g_spread); |
| 271 | in_items = (cur == &g_item_esp); | 287 | in_items = (cur == &g_item_esp); |
| 272 | in_tint = (cur == &g_world_tint); | 288 | in_tint = (cur == &g_world_tint); |
| 289 | in_fog = (cur == &g_fog); | ||
| 273 | } else if (cur) { | 290 | } else if (cur) { |
| 274 | char *eq = strchr(line, '='); | 291 | char *eq = strchr(line, '='); |
| 275 | if (!eq) | 292 | if (!eq) |
| @@ -345,6 +362,8 @@ static bool config_load() { | |||
| 345 | g_tint_world_on = atoi(val) != 0; | 362 | g_tint_world_on = atoi(val) != 0; |
| 346 | else if (strcmp(key, "sky") == 0) | 363 | else if (strcmp(key, "sky") == 0) |
| 347 | g_tint_sky_on = atoi(val) != 0; | 364 | g_tint_sky_on = atoi(val) != 0; |
| 365 | else if (strcmp(key, "prop") == 0) | ||
| 366 | g_tint_prop_on = atoi(val) != 0; | ||
| 348 | else if (strcmp(key, "wr") == 0 || strcmp(key, "wg") == 0 || | 367 | else if (strcmp(key, "wr") == 0 || strcmp(key, "wg") == 0 || |
| 349 | strcmp(key, "wb") == 0) { | 368 | strcmp(key, "wb") == 0) { |
| 350 | int v = atoi(val); | 369 | int v = atoi(val); |
| @@ -357,6 +376,35 @@ static bool config_load() { | |||
| 357 | if (v < 0) v = 0; | 376 | if (v < 0) v = 0; |
| 358 | if (v > 255) v = 255; | 377 | if (v > 255) v = 255; |
| 359 | g_tint_sky_rgb[key[1] == 'r' ? 0 : key[1] == 'g' ? 1 : 2] = v; | 378 | g_tint_sky_rgb[key[1] == 'r' ? 0 : key[1] == 'g' ? 1 : 2] = v; |
| 379 | } else if (strcmp(key, "pr") == 0 || strcmp(key, "pg") == 0 || | ||
| 380 | strcmp(key, "pb") == 0) { | ||
| 381 | int v = atoi(val); | ||
| 382 | if (v < 0) v = 0; | ||
| 383 | if (v > 255) v = 255; | ||
| 384 | g_tint_prop_rgb[key[1] == 'r' ? 0 : key[1] == 'g' ? 1 : 2] = v; | ||
| 385 | } | ||
| 386 | } | ||
| 387 | if (in_fog) { | ||
| 388 | if (strcmp(key, "r") == 0 || strcmp(key, "g") == 0 || | ||
| 389 | strcmp(key, "b") == 0) { | ||
| 390 | int v = atoi(val); | ||
| 391 | if (v < 0) v = 0; | ||
| 392 | if (v > 255) v = 255; | ||
| 393 | g_fog_rgb[key[0] == 'r' ? 0 : key[0] == 'g' ? 1 : 2] = v; | ||
| 394 | } else if (strcmp(key, "start") == 0) { | ||
| 395 | int v = atoi(val); | ||
| 396 | if (v < 0) v = 0; | ||
| 397 | if (v > 8000) v = 8000; | ||
| 398 | g_fog_start = v; | ||
| 399 | } else if (strcmp(key, "end") == 0) { | ||
| 400 | int v = atoi(val); | ||
| 401 | if (v < 0) v = 0; | ||
| 402 | if (v > 20000) v = 20000; | ||
| 403 | g_fog_end = v; | ||
| 404 | } else if (strcmp(key, "skybox") == 0) { | ||
| 405 | g_fog_skybox = atoi(val) != 0; | ||
| 406 | } else if (strcmp(key, "disable") == 0) { | ||
| 407 | g_fog_disable = atoi(val) != 0; | ||
| 360 | } | 408 | } |
| 361 | } | 409 | } |
| 362 | if (in_esp) { | 410 | if (in_esp) { |
| @@ -415,8 +463,18 @@ void config_reset_defaults() { | |||
| 415 | g_world_tint = {false, 0}; | 463 | g_world_tint = {false, 0}; |
| 416 | g_tint_world_on = true; | 464 | g_tint_world_on = true; |
| 417 | g_tint_sky_on = true; | 465 | g_tint_sky_on = true; |
| 466 | g_tint_prop_on = true; | ||
| 418 | g_tint_world_rgb[0] = g_tint_world_rgb[1] = g_tint_world_rgb[2] = 255; | 467 | g_tint_world_rgb[0] = g_tint_world_rgb[1] = g_tint_world_rgb[2] = 255; |
| 419 | g_tint_sky_rgb[0] = g_tint_sky_rgb[1] = g_tint_sky_rgb[2] = 255; | 468 | g_tint_sky_rgb[0] = g_tint_sky_rgb[1] = g_tint_sky_rgb[2] = 255; |
| 469 | g_tint_prop_rgb[0] = g_tint_prop_rgb[1] = g_tint_prop_rgb[2] = 255; | ||
| 470 | g_fog = {false, 0}; | ||
| 471 | g_fog_skybox = true; | ||
| 472 | g_fog_disable = false; | ||
| 473 | g_fog_rgb[0] = 160; | ||
| 474 | g_fog_rgb[1] = 170; | ||
| 475 | g_fog_rgb[2] = 190; | ||
| 476 | g_fog_start = 200; | ||
| 477 | g_fog_end = 3000; | ||
| 420 | g_item_health = true; | 478 | g_item_health = true; |
| 421 | g_item_ammo = true; | 479 | g_item_ammo = true; |
| 422 | g_item_armor = true; | 480 | g_item_armor = true; |
| @@ -534,7 +592,7 @@ static FeatureState *feature_state(int feature) { | |||
| 534 | static FeatureState *feats[FEAT_COUNT] = { | 592 | static FeatureState *feats[FEAT_COUNT] = { |
| 535 | &g_bhop, &g_abh, &g_esp, &g_aimbot, &g_triggerbot, | 593 | &g_bhop, &g_abh, &g_esp, &g_aimbot, &g_triggerbot, |
| 536 | &g_silentaim, &g_jumpbug, &g_melee, &g_spread, &g_item_esp, | 594 | &g_silentaim, &g_jumpbug, &g_melee, &g_spread, &g_item_esp, |
| 537 | &g_fullbright, &g_world_tint}; | 595 | &g_fullbright, &g_world_tint, &g_fog}; |
| 538 | if (feature < 0 || feature >= FEAT_COUNT) | 596 | if (feature < 0 || feature >= FEAT_COUNT) |
| 539 | return nullptr; | 597 | return nullptr; |
| 540 | return feats[feature]; | 598 | return feats[feature]; |
| @@ -741,6 +799,7 @@ void outer_draw() { | |||
| 741 | poll_keyboard(); | 799 | poll_keyboard(); |
| 742 | fullbright_update(); | 800 | fullbright_update(); |
| 743 | world_tint_update(); | 801 | world_tint_update(); |
| 802 | fog_update(); | ||
| 744 | gui_handle_input(); | 803 | gui_handle_input(); |
| 745 | // HL2H_DRAW_TEST=1 draws a probe rect without needing the GUI open | 804 | // HL2H_DRAW_TEST=1 draws a probe rect without needing the GUI open |
| 746 | static bool draw_test = getenv("HL2H_DRAW_TEST") != nullptr; | 805 | static bool draw_test = getenv("HL2H_DRAW_TEST") != nullptr; |
| @@ -762,6 +821,7 @@ void outer_draw() { | |||
| 762 | last_local = le; | 821 | last_local = le; |
| 763 | font_reset = true; | 822 | font_reset = true; |
| 764 | world_tint_invalidate(); | 823 | world_tint_invalidate(); |
| 824 | fog_invalidate(); | ||
| 765 | } | 825 | } |
| 766 | } | 826 | } |
| 767 | if (font_reset && g_font) { | 827 | if (font_reset && g_font) { |
