From 28ca6b1b57d61da7d2306cdec85be6aa29cf6dfb Mon Sep 17 00:00:00 2001 From: ccoventry <17183194+ccoventry@users.noreply.github.com> Date: Sun, 11 Oct 2026 00:58:02 -0600 Subject: [PATCH 1/3] feat(goldsrc-hooks): hide the spectator mode label, Press DUCK, centre text and two overview icons (#677) Rows 1, 2, 3, 4 and 6 of #677, all found offline in client.dll (one file, identical in every install) and not yet checked in the game: - dodstudio_hide_spectator_text: the camera mode name (CHudSpectator::SetMode's direct call to MsgFunc_TextMsg becomes add esp, 0xc) and the green "Press DUCK for Spectator Menu" (a ret at the #Spec_Duck helper). Patched while 1, restored at 0. - dodstudio_hud_map_team_marker 2: no camera icon on the overview map (the draw's own no-sprite je becomes a jmp), POV and HLTV. - dodstudio_hud_map_hide_speaker: skips the speaker icon on players' overview blips; the player icons stay. - dodstudio_hide_center_text: drops TextMsg destination 4, from clan_text's existing TextMsg handler; ends the centre line showing when turned on. tools/verify_hide_text_offsets.py re-derives every site from the Rust and a real client.dll. Docs: dodstudio_commands.md, Commands.txt, the vgui2print section of goldsrc_hud_elements.md and hudelement.rs (it also takes all centre text), and hide_asset.rs's wrong voice.rs claim. Part of #677 Co-Authored-By: Claude Opus 5.5 --- docs/dodstudio_commands.md | 5 +- docs/goldsrc_hud_elements.md | 21 +- goldsrc-hooks/src/center_text.rs | 158 +++++++ goldsrc-hooks/src/clan_text.rs | 19 +- goldsrc-hooks/src/commands.rs | 64 +++ goldsrc-hooks/src/hide_asset.rs | 6 +- goldsrc-hooks/src/hudelement.rs | 19 +- goldsrc-hooks/src/lib.rs | 13 +- goldsrc-hooks/src/msglog.rs | 3 +- goldsrc-hooks/src/overview_marker.rs | 132 ++++-- goldsrc-hooks/src/overview_speaker.rs | 235 ++++++++++ goldsrc-hooks/src/spectator_text.rs | 321 ++++++++++++++ .../tools/verify_hide_text_offsets.py | 419 ++++++++++++++++++ goldsrc-hooks/ui/Commands.txt | 10 +- studio/src/console_commands_data.js | 2 +- 15 files changed, 1370 insertions(+), 57 deletions(-) create mode 100644 goldsrc-hooks/src/center_text.rs create mode 100644 goldsrc-hooks/src/overview_speaker.rs create mode 100644 goldsrc-hooks/src/spectator_text.rs create mode 100644 goldsrc-hooks/tools/verify_hide_text_offsets.py diff --git a/docs/dodstudio_commands.md b/docs/dodstudio_commands.md index 72a1cb428..98cff748a 100644 --- a/docs/dodstudio_commands.md +++ b/docs/dodstudio_commands.md @@ -38,13 +38,16 @@ standing "user `.cfg` files are never written" rule (`CLAUDE.md`). | `dodstudio_mute_voice_commands` | `0` | silences "fire in the hole!" and the rest, without touching the game's own `.wav` files; subtitles and speaker icons still show | [`goldsrc_hud_suppression.md`](goldsrc_hud_suppression.md) | | `dodstudio_hide_crosshair` | `0` | hides the crosshair and keeps it hidden, which the stock `crosshair` cvar can't do because `CHud::Redraw` forces the value back every frame | [`goldsrc_crosshair.md`](goldsrc_crosshair.md) | | `dodstudio_hide_spectator_bars` | `0` | hides the spectator panel while spectating, in a demo or live: the two dark bands across the top and bottom of the screen, the score, timer and player name on them, and the menu row DUCK brings up. On screen, with no capture running | [`goldsrc_spectator_bars.md`](goldsrc_spectator_bars.md) | +| `dodstudio_hide_spectator_text` | `0` | hides the two lines the game prints when the view becomes a spectator camera: the camera mode's name in the middle of the screen ("Locked Chase Cam", "Free Chase Cam", "Free Look", "First Person", `#Spec_Mode1`..`4`) and the green "Press DUCK for Spectator Menu" written out below it (`#Spec_Duck`). Both show in a POV demo when the player dies, and in HLTV when the camera mode changes. Every other centre-print and HUD message still shows. A line already on screen when it's turned on stays until it times out (#677) | `goldsrc-hooks/src/spectator_text.rs` | | `dodstudio_spec_lock` | `0` | HLTV demos: the camera stays on the player being watched when he dies. Without it the game moves to the next player four seconds later. The viewer's own keys still change player | [`goldsrc_spectator_camera.md`](goldsrc_spectator_camera.md) | | `dodstudio_hud_map_players` | `0` | which players get an icon on the overview map: `0` the game's own (the team of the player being watched), `1` everyone, `2` only the other team, `3` only the player being watched (the recorder in a POV demo), `4` nobody. A POV demo only holds the enemies the recorder was sent, so in one they come and go; HLTV demos have everybody | `goldsrc-hooks/src/overview_players.rs` | | `dodstudio_run_in_background` | `0` | the game runs at full speed while another window is in front. The engine otherwise waits up to 20 ms for input every frame while it isn't the active app (`CEngine::Frame` calls `SleepUntilInput` when `IsActiveApp` is false), about 45 frames a second, which slows a capture batch's fast-forward between clips 5-8x; this skips that wait. HLAE's recording itself isn't slowed and records right covered or minimised (minimised on the 25th Anniversary build records slowly: cover it instead). A menu left in the background keeps drawing at full speed while it's on | `goldsrc-hooks/src/run_in_background.rs` | -| `dodstudio_hud_map_team_marker` | `0` | HLTV: marks the player being watched on the overview map with his team's camera icon (`allies_camera.spr` / `axis_camera.spr` / `brit_camera.spr`) instead of `spec_camera.spr`. DoD Studio's bordered ones go in `dod_addon/sprites` | `goldsrc-hooks/src/overview_marker.rs` | +| `dodstudio_hud_map_team_marker` | `0` | which camera icon marks the player being watched on the overview map: `0` the game's own, `1` his team's in HLTV too, `2` none. `1` uses `allies_camera.spr` / `axis_camera.spr` / `brit_camera.spr` instead of `spec_camera.spr`; DoD Studio's bordered ones go in `dod_addon/sprites`. `2` works in POV and HLTV, so `spec_camera.spr` needs no blanking, and the player icons stay (#677) | `goldsrc-hooks/src/overview_marker.rs` | +| `dodstudio_hud_map_hide_speaker` | `0` | leaves the speaker icon (`mapsprites/speakerIcon.spr`) off the players' icons on the overview map, so the sprite needs no blanking; the player icons stay, unlike `dodstudio_hud_map_players 4`. What makes the game draw it (a player talking or using a voice command) is a guess (#677) | `goldsrc-hooks/src/overview_speaker.rs` | | `dodstudio_hide_hand_signals` | `0` | replaces any `hs_*` body sequence (the nod, the point, the wave -- players miming their own voice commands) with that player's last ordinary one, for everyone in view | [`goldsrc_hltv_animation_fix.md`](goldsrc_hltv_animation_fix.md) §12 | | `dodstudio_hide_map_text` | `0` | hides the text a map puts on screen itself -- the `dod_anzio` mortar warning, the round result -- by matching each `HudText` message against the `message` strings the loaded map's own entities declare. DoD's own prompts on the same channel (`#Clan_allies_ready` and friends) still show. Reads the map's BSP once per level | `goldsrc-hooks/src/map_text.rs` | | `dodstudio_hide_clan_text` | `0` | hides all of DoD's clan-match text: the warm-up and ready rules, "Warmup Mode" on the left, the countdown to the match and "MATCH IS LIVE!". Drops the `#clan_*` `TextMsg` keys, swallows `ClanTimer` (which draws both the countdown and "MATCH IS LIVE!") and clears `GameRules`' warm-up flag. Turning it off mid-countdown brings the countdown back at once; turning it on mid-countdown removes "Warmup Mode" but not yet a countdown already showing (#618). Leaves everything else alone, round-start text included | `goldsrc-hooks/src/clan_text.rs` | +| `dodstudio_hide_center_text` | `0` | hides the text the server prints in the middle of the screen: every `TextMsg` to `HUD_PRINTCENTER` (destination 4), such as match plugins' `print_center` countdowns and notices. Chat, joins and leaves (destination 3) still show. Turning it on also ends the centre line showing at that moment. Doesn't reach the spectator camera mode's name (`dodstudio_hide_spectator_text`), the clan countdown (`dodstudio_hide_clan_text`) or the engine's own `svc_centerprint` (#677) | `goldsrc-hooks/src/center_text.rs` | | `dodstudio_ex_interp_max` | `100` (the engine's own ceiling) | raises the engine's clamp on `ex_interp` above its stock 100 ms ceiling, for smoother entity motion between snapshots; refuses `<=50` or `>1000`. Mechanism live-proven on pre-Anniversary, no specific value settled on yet. On the 25th Anniversary build (where HLTV demos already get 200 ms) any value but the default sets both paths | [`goldsrc_ex_interp.md`](goldsrc_ex_interp.md) | | `dodstudio_hd_enabled` | `1` if there's a `dodstudio_hd` folder (in `dod_addon`, or `dod` for an install built before #415), else `0`; `GOLDSRC_HOOKS_TEXTURE_HIRES=1`/`0` at launch overrides | HD textures on/off: map textures, model skins, sprites, detail textures and skies from `dodstudio_hd`. A change applies to what loads next -- walls, detail and skies from the next map, models and sprites already loaded after a restart. Turning it on in a session that started off installs the hook then | `goldsrc-hooks/src/texture_hires.rs`, `goldsrc-hooks/tools/hd/README.md` | | `dodstudio_hd_style` | `ultrasharp` | which `dodstudio_hd//