Add fixed core HUD and shared service window for T5 and T6

This commit is contained in:
2026-10-14 15:55:22 -04:00
parent d15bc50b7d
commit 929bf0354b
18 changed files with 1973 additions and 804 deletions
+67 -38
View File
@@ -10,8 +10,8 @@ Platform quirks and deploy commands: [NOTES.md](NOTES.md).
| File | Role |
|---|---|
| [tws_t5_common.gsc](tws_t5_common.gsc) | Shared config, HUD helpers, `.help`, connect/spawn registries, single `connected` listener + dispatcher |
| [tws_t5_hud.gsc](tws_t5_hud.gsc) | Top-left Discord URL, timers, zombie count, health bar |
| [tws_t5_common.gsc](tws_t5_common.gsc) | Shared config, HUD helpers, paginated `.help`, service window, connect/spawn registries, single `connected` listener + dispatcher |
| [tws_t5_hud.gsc](tws_t5_hud.gsc) | Fixed upper-right core: branding, timers, zombie count, current/maximum HP and health bar |
| [tws_t5_afk.gsc](tws_t5_afk.gsc) | `.afk` / `.back` chat toggle + `[AFK]` indicator |
| [tws_t5_join.gsc](tws_t5_join.gsc) | `.join` lets newcomers spawn before the current round ends |
| [tws_t5_lock.gsc](tws_t5_lock.gsc) | Lobby `g_password` lock at a milestone round |
@@ -54,14 +54,24 @@ requests or journal writes, preserving existing strings exactly. Missing or
invalid identities fail privately without changing points. Follow the shared
[identity and deployment checks](../../README.md#bank-identity-validation).
## Persistent Discord text
## Core HUD and service window
The HUD shows `https://discord.tws.lol` in small muted-gray text
at the top-left, including for newcomers waiting in spectator mode. The label
is created once per connection and persists across death and respawn. The
gameplay HUD starts one line lower, keeping timers, help and records clear.
Install HUD `1.1.2` with common `1.1.0` or later, then restart the map; no plugin
update or full server-process restart is required.
The fixed upper-right core shows `TWS ZOMBIES`, `discord.tws.lol`, side-by-side
match/round timers, zombie count, current/maximum HP and a full-width health bar.
HP stays visible at full health. A reserved footer holds the AFK indicator;
there is no co-op name row. The core is created once per connection, including
for spectator newcomers with placeholders until values are available. Creation
does not seed the match clock. It persists across death and respawn.
Clocks, health and zombie-count displays freeze at game over. Health fallbacks
only affect the display and never modify gameplay max health.
Common provides one fixed-height service window beneath the core for help or
records. Services never move or resize the core. They remain private and work
without the HUD module installed. See the [shared layout and validation guide](../../README.md#core-hud-and-service-window-t5-and-t6).
Install HUD `1.2.0`, leaderboard `1.1.0` and AFK `1.0.1` with common `1.2.0+`.
Update the installed scripts together and restart the map; this change requires
no new plugin/backend dependency or full server-process restart.
## Map record announcements
@@ -83,8 +93,10 @@ apply to both games.
Type `.help` or `.commands` in chat to see available player commands and a short description.
The response is visible only to the requesting player and works while spectating,
before the first spawn. Commands are case-insensitive.
Help appears below the health bar for 12 seconds, clear of the timers, zombie
counter and health display. Typing either command again restarts that display time.
Help uses the service window below the core. It shows four commands per page,
advances automatically every 12 seconds and closes after the last page. The
panel retains its height on short pages. Typing either command again returns to
page one with a fresh timer.
| Command | Effect |
|---|---|
@@ -93,12 +105,17 @@ counter and health display. Typing either command again restarts that display ti
| `.back` | Return from AFK |
| `.join` | Join mid-round (newcomers only) |
| `.leaders` | Show the map record again (leaderboard module required) |
| `.b` | Check bank balance (bank module required) |
| `.d <amount\|all>` | Deposit points (bank module required) |
| `.w <amount\|all>` | Withdraw points (bank module required) |
Each module registers its own help entries; removing AFK or join also removes
those entries from `.help` after a map restart.
Each module registers its own help entries. Commands follow the order above,
independent of initialization order; removing a module also removes its entries
from `.help` after a map restart.
The enabled leaderboard module registers `.leaders`, which replays the latest
cached map record privately. Repeating it restarts the record from the first page;
help temporarily hides the record until its own display ends.
help pauses the record's remaining page time and resumes it after the final
help page. `.leaders` during help replaces the pending record replay from page one.
## Dependency graph
@@ -148,16 +165,18 @@ graph BT
## tws_t5_common.gsc
Hub file. Shared config, HUD helpers, spawn-handler registry, and the
Hub file. Shared config, HUD helpers, service window, spawn-handler registry, and the
single `level waittill("connected")` in the fleet. Adding a second
connect listener anywhere else crashes the T5 SP handshake.
**Features**
- Shared HUD constants: `level.hud_x`, `hud_y`, `hud_row_*`, `hud_col_*`,
`hud_font_*`, `hud_bar_*`, `hud_c_*`, `hud_rate`, `hud_health_threshold`
- Shared HUD constants for panel geometry, rows/columns, fonts, health bar,
colors and update rate
- Spawn-handler registry
- Connection-handler registry for optional modules that serve spectator newcomers
- `.help` listener and help registry populated by installed command modules
- `.help` / `.commands` listener and ordered help registry populated by installed modules
- One reusable service window per player, with help/record pagination,
interruption/resume, request replacement and disconnect/game-end cleanup
- Connect listener + per-player dispatch: iterates
`level.tws_spawn_handlers` after `spawned_player` and threads each on
the player
@@ -172,6 +191,9 @@ connect listener anywhere else crashes the T5 SP handshake.
| `register_help_command(command, description)` | Adds a player command to `.help`; call from the owning module's `init()` |
| `make_text_elem(p, x, y, ax, s, c)`| `NewClientHudElem` text element with black-glow outline |
| `make_shader_elem(p, x, y)` | `NewClientHudElem` shader element |
| `make_panel_text(p, x, y, ax, s, c)` | Text positioned relative to the fixed upper-right core origin |
| `make_panel_shader(p, x, y, w, h, c, alpha, sort)` | Background/bar shader positioned relative to the core origin |
| `show_record(snapshot)` | Replace the player's record service request; an undefined snapshot shows unavailable |
| `destroy_on_disconnect(elems)` | Waits on `disconnect`, destroys the array |
| `int_dvar_or(name, fallback)` | Parse an integer dvar with default |
| `format_mmss(elapsed_ms)` | Format milliseconds as `M:SS` |
@@ -180,27 +202,33 @@ connect listener anywhere else crashes the T5 SP handshake.
**Live validation (requires a T5 server)**
1. Type `.help` and `.HELP` while playing and while spectating before the first
spawn. Verify all four descriptions appear below the health bar, only for the
requesting player. Take damage so health numbers are visible and check that
they do not cover the help text.
1. Type `.help`, `.HELP` and `.commands` while playing and spectating before the
first spawn. Verify four commands per page in the service window, private to
the requesting player. Check that full and damaged HP remain visible above it.
2. Remove AFK or join, restart the map, and verify its entries disappear while
`.help` and the remaining commands still work. Restore the scripts afterward.
3. Repeat `.help` before 12 seconds elapse; verify one list stays visible for
12 seconds after the latest request, then hides. Reopen it after expiry,
die/respawn and reconnect; verify no duplicate text or leftover help elements.
3. Verify pages advance every 12 seconds and close after the last page. Repeat
`.help` on a later page and check that it restarts page one. Interrupt a record
with help and verify remaining page time resumes; repeat `.leaders` during
help and verify only the latest replay starts from page one.
4. Reopen after expiry, die/respawn and reconnect; verify no duplicate text or
leftover elements. Repeat without the HUD module. Follow the complete
[HUD validation guide](../../README.md#hud-validation) before rollout.
---
## tws_t5_hud.gsc
Bottom-left cluster. Per-player elements spawn via `::hud_start`.
Fixed upper-right core panel. Per-player elements are created on connection;
gameplay updates start through the existing spawn lifecycle.
**Features**
- Match timer + round timer (round resets each round, both freeze on game over)
- Player-name row (only visible in co-op)
- `TWS ZOMBIES` / `discord.tws.lol` header and reserved AFK footer
- Zombies-remaining counter
- Health bar with green / amber / red ramp; numbers fade in below full HP
- Full-width health bar with green / amber / red ramp; current/maximum HP
remains visible at full health
- Spectator placeholders without starting the match clock on connection
- Round-transition and game-over notify machinery
**Provides**
@@ -214,22 +242,24 @@ Bottom-left cluster. Per-player elements spawn via `::hud_start`.
Spawn handler registered: `::hud_start` — threads `hud_timer_row`,
`hud_zombie_counter`, `hud_health_display`.
Connection handler registered: `::hud_connect` — creates the core with placeholders
without seeding clocks; `hud_start` calls it as a fallback if needed.
**Depends on**
- `scripts\sp\tws_t5_common::` — `ensure_config`, `make_text_elem`,
`make_shader_elem`, `destroy_on_disconnect`, `format_mmss`,
`register_spawn_handler`
- `scripts\sp\tws_t5_common::` — `ensure_config`, `make_panel_text`,
`make_panel_shader`, `destroy_on_disconnect`, `format_mmss`,
`register_spawn_handler`, `register_connect_handler`
- Every `level.hud_*` config value from `tws_t5_common`
- Stock BO1 state: `level.round_number`, `level.zombie_total`,
`level.players`, `self.health`, `self.maxhealth`, `self.name` /
`self.playername`, AI entities' `.animname` and `.ignore_enemy_count`
`level.players`, `self.health`, `self.maxhealth`, AI entities' `.animname`
and `.ignore_enemy_count`
---
## tws_t5_afk.gsc
Self-invoked pause mode. Owns the `[AFK]` indicator element entirely — HUD
module has zero knowledge of AFK.
Self-invoked pause mode. Owns the `[AFK]` indicator element, positioned in the
core's reserved footer through common layout values. It does not require HUD.
**Features**
- Chat commands `.afk` and `.back` (via `level waittill("say")` — not
@@ -247,10 +277,9 @@ module has zero knowledge of AFK.
- Level var: `level.afk_grace_seconds` (default 2)
**Depends on**
- `scripts\sp\tws_t5_common::` — `ensure_config`, `make_text_elem`,
- `scripts\sp\tws_t5_common::` — `ensure_config`, `make_panel_text`,
`destroy_on_disconnect`, `register_spawn_handler`, `register_help_command`
- Shared config: `level.hud_x`, `level.hud_row_match`,
`level.hud_font_small`, `level.hud_c_afk`
- Shared config: core footer position, `level.hud_font_small`, `level.hud_c_afk`
- Stock BO1: `enableInvulnerability`, `disableInvulnerability`,
`freezeControls`, `.ignoreme`, `level waittill("say", message, player)`