Center zombie counters and use ASCII HUD separators
This commit is contained in:
@@ -4,6 +4,60 @@ Changes are listed newest first, with an independent version for every individua
|
||||
T5/T6 script and each native plugin. Current versions are recorded in
|
||||
[versions.json](versions.json); see the [version policy](README.md#versioning).
|
||||
|
||||
## 2026-10-17
|
||||
|
||||
### Center the complete zombie count above the health bar
|
||||
|
||||
| Component | Version | Affected source |
|
||||
| --- | --- | --- |
|
||||
| `tws_t5_hud.gsc` | `1.4.2` | `t5/scripts/tws_t5_hud.gsc` |
|
||||
| `tws_t6_hud.gsc` | `1.4.2` | `t6/scripts/tws_t6_hud.gsc` |
|
||||
|
||||
- Replace the separately positioned number and label with one center-aligned
|
||||
`N ZOMBIES` readout at the health track's midpoint in both engines. Use a
|
||||
uniform font scale of `1.25` and the existing count color; digit changes and
|
||||
the initial `-- ZOMBIES` placeholder share the same center.
|
||||
- Update text only when the count changes using `SetTextUnlimited`, avoiding
|
||||
a new config string for each distinct count. Keep counting, `.hud` visibility,
|
||||
game-over termination and disconnect cleanup behavior. Core HUD allocation
|
||||
decreases from 11 to 10 archived elements; AFK still adds one.
|
||||
- Compatibility: HUD `1.4.2` requires matching common `1.4.0+` and
|
||||
[Plutonium r5334+](https://plutonium.pw/docs/changelog/#r5334), which provides
|
||||
`SetTextUnlimited` for T5 and T6. No new plugin or backend requirement.
|
||||
Common and AFK need no source change for this fix; both HUD scripts change.
|
||||
- Validation: 73 HUD checks passed, including digit transitions, a non-default
|
||||
track midpoint, unchanged-count polling, hidden updates and service cleanup.
|
||||
Leaderboard (143), bank (42), join (17) and telemetry (23) portable checks
|
||||
passed. These use engine shims; actual EC integration and live Plutonium
|
||||
validation were not run. GSC compilation was unavailable because gsc-tool
|
||||
and PowerShell are not installed. Verify rendering on Windows/Plutonium.
|
||||
- Deployment: copy each updated HUD script and restart the map on r5334+.
|
||||
Older installations must first update Plutonium on clients and servers and
|
||||
fully restart those processes. No full server-process restart is required
|
||||
for the script update alone. No deployment performed.
|
||||
|
||||
### Use ASCII separators in HUD branding and map records
|
||||
|
||||
| Component | Version | Affected source |
|
||||
| --- | --- | --- |
|
||||
| `tws_t5_common.gsc` | `1.4.1` | `t5/scripts/tws_t5_common.gsc` |
|
||||
| `tws_t6_common.gsc` | `1.4.1` | `t6/scripts/tws_t6_common.gsc` |
|
||||
| `tws_t5_hud.gsc` | `1.4.1` | `t5/scripts/tws_t5_hud.gsc` |
|
||||
| `tws_t6_hud.gsc` | `1.4.1` | `t6/scripts/tws_t6_hud.gsc` |
|
||||
|
||||
- Replace the middle dot with an ASCII vertical bar in the top-center branding
|
||||
and map-record heading after the separator displayed as two dots on T5.
|
||||
Apply the same text change to T6 for a consistent appearance. Keep existing
|
||||
spacing, positioning and HUD/service behavior.
|
||||
- Compatibility: no new dependency requirement. No native-plugin, backend or
|
||||
other script changes are required.
|
||||
- Validation: 71 HUD, 143 leaderboard, 42 bank, 17 join and 23 telemetry portable
|
||||
checks passed. These use engine shims; actual EC bank integration, GSC
|
||||
compilation and live Windows/Plutonium validation were not performed.
|
||||
- Deployment: copy the updated common and HUD scripts for each installed game,
|
||||
then restart the map. No full server-process restart is required. No deployment
|
||||
performed; live Windows/Plutonium rendering validation remains outstanding.
|
||||
|
||||
## 2026-10-15 — Player moderation runtime
|
||||
|
||||
- **tws_t5_moderation.gsc 1.0.0 / tws_t6_moderation.gsc 1.0.0**: new optional
|
||||
|
||||
@@ -362,11 +362,14 @@ settles legacy and public journals without duplicate ledger entries or lost poin
|
||||
## Core HUD and service window (T5 and T6)
|
||||
|
||||
The core uses a light, unboxed layout: match time above round time at the upper
|
||||
left, `TWS ZOMBIES · discord.tws.lol` centered along the top, and the zombie
|
||||
count centered near the bottom above a slim health bar. Current/maximum HP
|
||||
appears to the right of the bar only while injured, then disappears at full
|
||||
health. The AFK indicator sits above the zombie count. Text uses an outline for
|
||||
contrast; there are no panel backgrounds or timer labels.
|
||||
left, `TWS ZOMBIES | discord.tws.lol` centered along the top, and the zombie
|
||||
count centered near the bottom above a slim health bar. The complete
|
||||
`N ZOMBIES` text uses one centered element at the health track's midpoint,
|
||||
keeping the group centered as the count gains or loses digits. It uses a
|
||||
uniform font scale of `1.25` and shows `-- ZOMBIES` before data is available.
|
||||
Current/maximum HP appears to the right of the bar only while injured, then
|
||||
disappears at full health. The AFK indicator sits above the zombie count. Text
|
||||
uses an outline for contrast; there are no panel backgrounds or timer labels.
|
||||
|
||||
Fullscreen X/Y anchors bypass safe-area insets. Overlay positions and shader
|
||||
widths use the normalized `640 × 480` viewport directly. Text uses a minimum
|
||||
@@ -401,7 +404,7 @@ count appears only when more than one page is needed. Each page lasts
|
||||
command restarts page one. Both engines position rows explicitly, avoiding
|
||||
T5's newline-rendering problem.
|
||||
|
||||
Records use the same service area, right aligned: `Map record · Round N`
|
||||
Records use the same service area, right aligned: `Map record | Round N`
|
||||
followed by up to three bounded holder lines. Single-page records have no
|
||||
counter or footer; ties spanning multiple pages retain a page count and
|
||||
12 seconds per page. Help pauses a visible record and resumes its remaining
|
||||
@@ -411,19 +414,24 @@ remain private and work when the HUD module is omitted.
|
||||
|
||||
Both games allocate only the active service view and release it when idle or
|
||||
before switching between help and records. Pages reuse the active view's
|
||||
elements. The core uses 11 archived elements, plus one for AFK. The standard
|
||||
elements. The core uses 10 archived elements, plus one for AFK. The standard
|
||||
nine-command help view uses 19 nonarchived elements, or 20 with a multi-page
|
||||
counter; records use four, or five with a multi-page counter. Hidden elements
|
||||
still occupy slots. The controller and pending requests are separate from
|
||||
display lifetime, so an idle service holds no HUD elements.
|
||||
|
||||
HUD `1.4.0` and AFK `1.2.0` require matching common `1.4.0+` on both games.
|
||||
Update common, HUD and AFK together where installed, then restart the map.
|
||||
Leaderboard `1.1.0` remains compatible. There is no new Plutonium, native-plugin
|
||||
or backend requirement, and this change does not require a full server-process
|
||||
restart. Existing leaderboard plugin requirements still apply. Common retains
|
||||
its older panel helpers for unchanged consumers; the new layout uses fullscreen
|
||||
overlay helpers with the same integer shader-width handling.
|
||||
HUD `1.4.2` requires matching common `1.4.0+` and
|
||||
[Plutonium r5334+](https://plutonium.pw/docs/changelog/#r5334) on both games.
|
||||
The centered counter uses `SetTextUnlimited` only when the count changes,
|
||||
avoiding dynamic counter strings in the text config-string pool. Numeric HP
|
||||
still uses `SetValue`. On r5334+, deploy the updated HUD script and restart
|
||||
the map; no full server-process restart is required. On older Plutonium
|
||||
revisions, update clients and server and fully restart them before deploying.
|
||||
AFK `1.2.0` and leaderboard `1.1.0` remain compatible; AFK still requires
|
||||
common `1.4.0+`. There is no new native-plugin or backend requirement. Existing
|
||||
leaderboard plugin requirements still apply. Common retains its older panel
|
||||
helpers for unchanged consumers; the new layout uses fullscreen overlay helpers
|
||||
with the same integer shader-width handling.
|
||||
|
||||
### HUD validation
|
||||
|
||||
@@ -445,7 +453,9 @@ Before rollout, validate both engines in Plutonium:
|
||||
legible without panel backgrounds; services must clear the Plutonium tag.
|
||||
Verify the health-bar fill stays within its track and damage-only HP clears
|
||||
stock scores/ammo. Check text fit at other aspect ratios because horizontal
|
||||
geometry scales with viewport width.
|
||||
geometry scales with viewport width. Check `0`, `6`, `9`, `10`, `99` and
|
||||
`100 ZOMBIES`: the entire text must stay centered over the health track,
|
||||
including after `.hud` hides/shows it and after game over freezes the count.
|
||||
2. Join before spawning, join mid-match, die/respawn and reconnect. Verify one
|
||||
core per player, spectator placeholders, no early match-clock start, correct
|
||||
health/Juggernog changes, and frozen timers at game over. HP numbers must
|
||||
@@ -509,7 +519,7 @@ when changing variants; restart the map after changing these settings.
|
||||
|
||||
The announcement starts five seconds after player readiness and waits for the
|
||||
initial record fetch if necessary. It appears as right-aligned text in the
|
||||
common-owned upper-right service area: `Map record · Round N`, followed by up
|
||||
common-owned upper-right service area: `Map record | Round N`, followed by up
|
||||
to three holder lines. There is no background or replay footer, and a page
|
||||
count appears only for multi-page records. Each page lasts 12 seconds. Opening `.help` pauses the record's remaining
|
||||
page time until help closes. A `.leaders` request during help replaces any
|
||||
|
||||
+24
-13
@@ -32,12 +32,15 @@ before copying the renamed scripts.
|
||||
- **`SetTimerUp(N)` only ticks when `N == 0`** on T5 SP. Non-zero seeds
|
||||
render "0:00" but don't advance. Late joiners see 0, not real elapsed;
|
||||
authoritative elapsed lives in `level.match_start_time`.
|
||||
- **Dynamic numbers use `SetValue`.** Repeatedly generating unique strings
|
||||
risks exhausting the text config-string pool; identical strings can be reused
|
||||
by the engine's [string lookup](https://github.com/MisaDev4/bo1-zombies-decompiled/blob/102f6992be332610aff587e681e3180b15f395bb/src/game_mp/g_utils_mp.cpp#L46).
|
||||
Composite HP uses numeric elements around a static slash and `HP` suffix;
|
||||
the group appears only while injured. Help reuses up to nine explicitly
|
||||
positioned command/description pairs, and record rows skip unchanged text.
|
||||
- **Dynamic counter text uses `SetTextUnlimited`; HP uses `SetValue`.**
|
||||
Repeatedly generating unique strings through `SetText` risks exhausting the
|
||||
text config-string pool; identical strings can be reused by the engine's
|
||||
[string lookup](https://github.com/MisaDev4/bo1-zombies-decompiled/blob/102f6992be332610aff587e681e3180b15f395bb/src/game_mp/g_utils_mp.cpp#L46).
|
||||
The centered `N ZOMBIES` element uses Plutonium r5334+'s `SetTextUnlimited`
|
||||
only when the count changes. Composite HP retains numeric elements around a
|
||||
static slash and `HP` suffix; the group appears only while injured. Help
|
||||
reuses up to nine explicitly positioned command/description pairs, and
|
||||
record rows skip unchanged text.
|
||||
- **`NewClientHudElem(player)`, not `NewHudElem()`.** `NewHudElem` is
|
||||
globally owned; in co-op every player's HUD draws on top of every other
|
||||
player's. Fall back to `NewHudElem` only if elements don't render at all
|
||||
@@ -77,7 +80,7 @@ before copying the renamed scripts.
|
||||
from page one. Keep both services independent of the HUD module. Services
|
||||
never reposition the core, and AFK remains centered above the zombie count.
|
||||
- **Bound HUD element counts, including hidden elements.** Core + AFK use
|
||||
11 + 1 archived elements. Common allocates only the active service view:
|
||||
10 + 1 archived elements. Common allocates only the active service view:
|
||||
19 nonarchived elements for nine-command help (20 with a multi-page counter),
|
||||
or four for records (five with a multi-page counter), and none while idle.
|
||||
Switching help/record views destroys the previous view first; pages reuse
|
||||
@@ -99,12 +102,16 @@ before copying the renamed scripts.
|
||||
polling `self.health` misses the zero-crossing (health is rewritten during
|
||||
the game-over sequence).
|
||||
|
||||
HUD `1.4.0` and AFK `1.2.0` require matching common `1.4.0+`. Update all three
|
||||
where installed and restart the map. Leaderboard `1.1.0` remains compatible.
|
||||
HUD `1.4.2` requires matching common `1.4.0+` and
|
||||
[Plutonium r5334+](https://plutonium.pw/docs/changelog/#r5334) for
|
||||
`SetTextUnlimited`. On r5334+, update the HUD script and restart the map;
|
||||
older Plutonium clients and servers need updates and full restarts first.
|
||||
AFK `1.2.0` and leaderboard `1.1.0` remain compatible; AFK still requires
|
||||
common `1.4.0+`.
|
||||
The full help order is `.help`, `.hud`, `.afk`, `.back`, `.join`, `.leaders`,
|
||||
`.b`, `.d`, `.w`: one page of nine commands, with full `<amount|all>` bank
|
||||
syntax. `.hud` is absent when HUD is omitted. Records use right-aligned
|
||||
`Map record · Round N` and up to three bounded holder lines, with no footer
|
||||
`Map record | Round N` and up to three bounded holder lines, with no footer
|
||||
and no single-page counter. Both views retain 12-second page timing.
|
||||
Fullscreen X/Y overlay anchors use direct normalized `640 × 480` coordinates.
|
||||
Dynamic health fills use `make_overlay_width()` like their tracks. Apply
|
||||
@@ -112,10 +119,14 @@ Dynamic health fills use `make_overlay_width()` like their tracks. Apply
|
||||
`SetShader` requires an integer width. Legacy panel helpers and their `0.75`
|
||||
horizontal conversion remain available for existing consumers. Font scale is
|
||||
at least `1.0`. Numeric HP appears only while injured; the core and services
|
||||
have no panel backgrounds. There is no new Plutonium/native-plugin/backend
|
||||
dependency or full server-process restart requirement.
|
||||
have no panel backgrounds. The counter is one `N ZOMBIES` element centered
|
||||
at the health track's midpoint with uniform scale `1.25`, starting as
|
||||
`-- ZOMBIES`. There is no new native-plugin/backend dependency or full
|
||||
server-process restart requirement when already using Plutonium r5334+.
|
||||
Run the [shared HUD checks](../../README.md#hud-validation); portable fixtures
|
||||
do not replace T5 live loading, layout and lifecycle validation.
|
||||
do not replace T5 live loading, layout and lifecycle validation. Check the
|
||||
counter's centering at `0`, `6`, `9`, `10`, `99` and `100`, after `.hud`
|
||||
hides/shows it, and after game over freezes the count.
|
||||
|
||||
## Module map
|
||||
|
||||
|
||||
+22
-12
@@ -60,10 +60,13 @@ invalid identities fail privately without changing points. Follow the shared
|
||||
## Core HUD and service window
|
||||
|
||||
The unboxed core puts match time above round time at the upper left,
|
||||
`TWS ZOMBIES · discord.tws.lol` at the top center, and zombies remaining above a
|
||||
slim health bar at the bottom center. Current/maximum HP appears to the right
|
||||
of the bar only while injured; it disappears at full health. The AFK indicator
|
||||
sits above the zombie count. There are no panel backgrounds or timer labels.
|
||||
`TWS ZOMBIES | discord.tws.lol` at the top center, and zombies remaining above a
|
||||
slim health bar at the bottom center. `N ZOMBIES` is one centered element at
|
||||
the health track's midpoint, using uniform font scale `1.25` so the whole group
|
||||
stays centered as the digit count changes. Its initial placeholder is
|
||||
`-- ZOMBIES`. Current/maximum HP appears to the right of the bar only while
|
||||
injured; it disappears at full health. The AFK indicator sits above the zombie
|
||||
count. There are no panel backgrounds or timer labels.
|
||||
Fullscreen X/Y anchors use the normalized `640 × 480` viewport directly and
|
||||
bypass safe-area insets. Font scale is at least `1.0`; verify text fit, stock
|
||||
HUD overlap and Plutonium tag clearance at each aspect ratio in-game.
|
||||
@@ -81,7 +84,7 @@ continue updating while hidden; game-over values remain frozen. Help, records
|
||||
and the stock HUD are unaffected. `.hud` requires the HUD module.
|
||||
|
||||
Common provides one unboxed upper-right service area below the Plutonium tag.
|
||||
Records are right aligned, with `Map record · Round N` followed by up to three
|
||||
Records are right aligned, with `Map record | Round N` followed by up to three
|
||||
holder lines; there is no replay footer or single-page counter. Help displays
|
||||
the full nine-command list in aligned rows. Services remain private, leave the
|
||||
core in place and work without the HUD module installed. See the
|
||||
@@ -90,12 +93,15 @@ Only the active service view holds HUD elements: 19 for nine-command help
|
||||
(20 with a multi-page counter), or four for records (five with a multi-page
|
||||
counter). Pages reuse elements; switching views or closing the service releases
|
||||
them. Idle services hold no HUD elements, while the controller retains pending
|
||||
requests and interruption/resume behavior. Core + AFK use 11 + 1 elements.
|
||||
requests and interruption/resume behavior. Core + AFK use 10 + 1 elements.
|
||||
|
||||
HUD `1.4.0` and AFK `1.2.0` require common `1.4.0+`. Update common, HUD and AFK
|
||||
together where installed, then restart the map. Leaderboard `1.1.0` remains
|
||||
compatible. This change requires no new Plutonium/plugin/backend dependency or
|
||||
full server-process restart.
|
||||
HUD `1.4.2` requires common `1.4.0+` and
|
||||
[Plutonium r5334+](https://plutonium.pw/docs/changelog/#r5334) for its
|
||||
`SetTextUnlimited` counter, updated only when the count changes. Deploy the
|
||||
updated HUD script and restart the map on r5334+; no full server-process
|
||||
restart is required. Older Plutonium revisions need client/server updates and
|
||||
full restarts first. AFK `1.2.0` and leaderboard `1.1.0` remain compatible;
|
||||
AFK still requires common `1.4.0+`. No new native-plugin or backend requirement.
|
||||
|
||||
## Map record announcements
|
||||
|
||||
@@ -263,6 +269,9 @@ connect listener anywhere else crashes the T5 SP handshake.
|
||||
Check that branding, the health bar, damage-only HP, zombie count and timers
|
||||
remain correct during each view and after it closes.
|
||||
Include other installed HUD mods; the live T5 SP element limit is unverified.
|
||||
6. Check `0`, `6`, `9`, `10`, `99` and `100 ZOMBIES` at different resolutions:
|
||||
the complete text must stay centered above the health track. Repeat after
|
||||
toggling `.hud` and after game over freezes the count.
|
||||
|
||||
---
|
||||
|
||||
@@ -274,8 +283,8 @@ gameplay updates start through the existing spawn lifecycle.
|
||||
**Features**
|
||||
- Upper-left match timer above round timer (round resets each round, both freeze on game over)
|
||||
- `.hud` toggles this player's core and AFK indicator; data updates continue while hidden
|
||||
- Top-center `TWS ZOMBIES · discord.tws.lol` branding
|
||||
- Bottom-center zombies-remaining counter, with the AFK indicator above it
|
||||
- Top-center `TWS ZOMBIES | discord.tws.lol` branding
|
||||
- One `N ZOMBIES` element centered above the health track, with the AFK indicator above it
|
||||
- Slim health bar with green / amber / red ramp; current/maximum HP appears
|
||||
beside it only while injured
|
||||
- Spectator placeholders without starting the match clock on connection
|
||||
@@ -301,6 +310,7 @@ without seeding clocks; `hud_start` calls it as a fallback if needed.
|
||||
`destroy_on_disconnect`, `format_mmss`, `register_help_command`,
|
||||
`register_spawn_handler`, `register_connect_handler`
|
||||
- Every `level.hud_*` config value from `tws_t5_common`
|
||||
- Plutonium r5334+ for the count's `SetTextUnlimited` updates
|
||||
- Stock BO1 state: `level.round_number`, `level.zombie_total`,
|
||||
`level.players`, `self.health`, `self.maxhealth`, AI entities' `.animname`
|
||||
and `.ignore_enemy_count`
|
||||
|
||||
@@ -457,7 +457,7 @@ service_render(state)
|
||||
{
|
||||
header = "No recorded high round yet";
|
||||
if (snapshot.round > 0)
|
||||
header = "Map record · Round " + snapshot.round;
|
||||
header = "Map record | Round " + snapshot.round;
|
||||
}
|
||||
if (!isDefined(state.record_header_text) || state.record_header_text != header)
|
||||
{
|
||||
|
||||
@@ -52,12 +52,12 @@ hud_connect()
|
||||
self.tws_hud_round = self hud_text(level.hud_overlay_timer_x,
|
||||
level.hud_overlay_round_y, "left", 1.25, level.hud_c_dim, "--:--");
|
||||
self hud_text(level.hud_overlay_brand_x, level.hud_overlay_brand_y,
|
||||
"center", 1.1, level.hud_c_dim, "TWS ZOMBIES · discord.tws.lol");
|
||||
"center", 1.1, level.hud_c_dim, "TWS ZOMBIES | discord.tws.lol");
|
||||
|
||||
self.tws_hud_count = self hud_text(level.hud_overlay_count_x,
|
||||
level.hud_overlay_count_y, "right", 1.5, level.hud_c_count, "--");
|
||||
self hud_text(level.hud_overlay_count_label_x, level.hud_overlay_count_label_y,
|
||||
"left", 1.05, level.hud_c_dim, "ZOMBIES");
|
||||
// Center the entire readout on the track, regardless of the digit count.
|
||||
count_x = level.hud_overlay_bar_x + level.hud_overlay_bar_width / 2.0;
|
||||
self.tws_hud_count = self hud_text(count_x,
|
||||
level.hud_overlay_count_y, "center", 1.25, level.hud_c_count, "-- ZOMBIES");
|
||||
|
||||
// Independent numeric elements avoid a new config string on every tick.
|
||||
// The readout appears only after a valid damaged-health sample.
|
||||
@@ -233,7 +233,8 @@ hud_zombie_counter()
|
||||
|
||||
if (remaining != last)
|
||||
{
|
||||
count SetValue(remaining);
|
||||
// Plutonium r5334+: reuse text storage as the count changes.
|
||||
count SetTextUnlimited(int(remaining) + " ZOMBIES");
|
||||
last = remaining;
|
||||
}
|
||||
|
||||
|
||||
+15
-7
@@ -43,7 +43,7 @@ view: 19 nonarchived elements for nine-command help (20 with a multi-page
|
||||
counter), or four for records (five with a multi-page counter). Closing the
|
||||
service or switching kinds destroys the view; idle holds no elements. Pages
|
||||
reuse the active elements, separately from controller and pending-request state.
|
||||
Core + AFK use 11 + 1 archived elements. Hidden elements still occupy slots.
|
||||
Core + AFK use 10 + 1 archived elements. Hidden elements still occupy slots.
|
||||
The [T6 player HUD structure](https://github.com/skiff/t6-gsc-helper/blob/50ff6cb7397c9376894a195f48118d1743812d1d/src/game/structs.hpp#L184)
|
||||
has 31 slots in each bucket; it does not establish current Plutonium stock HUD
|
||||
usage. Keep the live overlap/element-budget checks alongside the portable checks.
|
||||
@@ -54,18 +54,24 @@ creation must not seed the match clock. The unboxed layout has timers at the
|
||||
upper left, branding at top center and zombies/health at bottom center. HP
|
||||
numbers appear to the right of the bar only while injured; AFK sits above the
|
||||
zombie count. Services never reposition the core. Records are right aligned,
|
||||
with `Map record · Round N` followed by up to three bounded holder lines, no
|
||||
with `Map record | Round N` followed by up to three bounded holder lines, no
|
||||
footer and no single-page counter. Their 12-second page timing is unchanged.
|
||||
|
||||
HUD `1.4.0` and AFK `1.2.0` require matching common `1.4.0+`; update all three
|
||||
where installed and restart the map. Leaderboard `1.1.0` remains compatible.
|
||||
HUD `1.4.2` requires matching common `1.4.0+` and
|
||||
[Plutonium r5334+](https://plutonium.pw/docs/changelog/#r5334) for
|
||||
`SetTextUnlimited`. The `N ZOMBIES` counter is one element centered at the
|
||||
health track's midpoint with uniform scale `1.25`, starting as `-- ZOMBIES`.
|
||||
Only changed counts update its text; numeric HP retains `SetValue`. On r5334+,
|
||||
update the HUD script and restart the map. Older Plutonium clients and servers
|
||||
need updates and full restarts first. AFK `1.2.0` and leaderboard `1.1.0` remain
|
||||
compatible; AFK still requires common `1.4.0+`.
|
||||
Overlay helpers use direct normalized `640 × 480` coordinates. Dynamic health
|
||||
fills use `make_overlay_width()` like their tracks. Apply `int()` after `max()`
|
||||
in that helper: native `max()` returns a float, but `SetShader` requires an
|
||||
integer width. Legacy panel helpers retain their `0.75` horizontal conversion
|
||||
for existing consumers. Font scale is at least `1.0`. This introduces no
|
||||
Plutonium/native-plugin/backend dependency or full server-process restart
|
||||
requirement.
|
||||
for existing consumers. Font scale is at least `1.0`. There is no new
|
||||
native-plugin/backend dependency or full server-process restart requirement
|
||||
when already using Plutonium r5334+.
|
||||
|
||||
HUD owns the exact, case-insensitive `.hud` chat command and registers it in
|
||||
help only while installed. Common's core wrappers preserve each element's
|
||||
@@ -195,6 +201,8 @@ Live checks after deploying:
|
||||
spectator placeholders without an early clock start. Check damage-only HP,
|
||||
health/Juggernog changes, AFK placement and timers frozen at game over.
|
||||
Test safe-area settings and different resolutions against stock HUD elements.
|
||||
Check `0`, `6`, `9`, `10`, `99` and `100 ZOMBIES` remain centered above the
|
||||
health track, including after `.hud` toggles and game over freezes the count.
|
||||
2. `.afk` blocks movement, shooting and grenades; `.back` restores them. Try rapid
|
||||
toggles, a round transition, death/respawn and game over.
|
||||
3. Lock fires at the threshold and clears on game over/restart. HUD must be installed.
|
||||
|
||||
+17
-11
@@ -8,7 +8,7 @@ private server token.
|
||||
| File | Role | Dependencies |
|
||||
| --- | --- | --- |
|
||||
| `tws_t6_common.gsc` | Shared HUD values, helpers, paginated `.help`, service window, connection and first-spawn dispatchers | Stock T6 |
|
||||
| `tws_t6_hud.gsc` | Unboxed timers, branding, zombies/health and per-player `.hud` visibility toggle | Common 1.4.0+ |
|
||||
| `tws_t6_hud.gsc` | Unboxed timers, branding, zombies/health and per-player `.hud` visibility toggle | Common 1.4.0+, Plutonium r5334+ |
|
||||
| `tws_t6_afk.gsc` | `.afk` / `.back`, protection, movement and weapon blocking | Common 1.4.0+ |
|
||||
| `tws_t6_lock.gsc` | Lock at round 20; clear password on game over | Common, HUD |
|
||||
| `tws_t6_telemetry.gsc` | Async queued game reports (game_start/heartbeat/round_change/game_end) | tws-t6-gsc-utils |
|
||||
@@ -73,10 +73,13 @@ populates that field before the `connected` notification. Follow the shared
|
||||
## Core HUD and service window
|
||||
|
||||
The unboxed core puts match time above round time at the upper left,
|
||||
`TWS ZOMBIES · discord.tws.lol` at the top center, and zombies remaining above a
|
||||
slim health bar at the bottom center. Current/maximum HP appears to the right
|
||||
of the bar only while injured; it disappears at full health. The AFK indicator
|
||||
sits above the zombie count. There are no panel backgrounds or timer labels.
|
||||
`TWS ZOMBIES | discord.tws.lol` at the top center, and zombies remaining above a
|
||||
slim health bar at the bottom center. `N ZOMBIES` is one centered element at
|
||||
the health track's midpoint, using uniform font scale `1.25` so the whole group
|
||||
stays centered as the digit count changes. Its initial placeholder is
|
||||
`-- ZOMBIES`. Current/maximum HP appears to the right of the bar only while
|
||||
injured; it disappears at full health. The AFK indicator sits above the zombie
|
||||
count. There are no panel backgrounds or timer labels.
|
||||
Fullscreen X/Y anchors use the normalized `640 × 480` viewport directly and
|
||||
bypass safe-area insets. Font scale is at least `1.0`; verify text fit, stock
|
||||
HUD overlap and Plutonium tag clearance at each aspect ratio in-game.
|
||||
@@ -94,7 +97,7 @@ continue updating while hidden; game-over values remain frozen. Help, records
|
||||
and the stock HUD are unaffected. `.hud` requires the HUD module.
|
||||
|
||||
Common provides one unboxed upper-right service area below the Plutonium tag.
|
||||
Records are right aligned, with `Map record · Round N` followed by up to three
|
||||
Records are right aligned, with `Map record | Round N` followed by up to three
|
||||
holder lines; there is no replay footer or single-page counter. Help displays
|
||||
the full nine-command list in aligned rows. Services remain private, leave the
|
||||
core in place and work without the HUD module installed. See the
|
||||
@@ -103,12 +106,15 @@ Only the active service view holds HUD elements: 19 for nine-command help
|
||||
(20 with a multi-page counter), or four for records (five with a multi-page
|
||||
counter). Pages reuse elements; switching views or closing the service releases
|
||||
them. Idle services hold no HUD elements, while the controller retains pending
|
||||
requests and interruption/resume behavior. Core + AFK use 11 + 1 elements.
|
||||
requests and interruption/resume behavior. Core + AFK use 10 + 1 elements.
|
||||
|
||||
HUD `1.4.0` and AFK `1.2.0` require common `1.4.0+`. Update common, HUD and AFK
|
||||
together where installed, then restart the map. Leaderboard `1.1.0` remains
|
||||
compatible. This change requires no new Plutonium/plugin/backend dependency or
|
||||
full server-process restart.
|
||||
HUD `1.4.2` requires common `1.4.0+` and
|
||||
[Plutonium r5334+](https://plutonium.pw/docs/changelog/#r5334) for its
|
||||
`SetTextUnlimited` counter, updated only when the count changes. Deploy the
|
||||
updated HUD script and restart the map on r5334+; no full server-process
|
||||
restart is required. Older Plutonium revisions need client/server updates and
|
||||
full restarts first. AFK `1.2.0` and leaderboard `1.1.0` remain compatible;
|
||||
AFK still requires common `1.4.0+`. No new native-plugin or backend requirement.
|
||||
|
||||
## Map record announcements
|
||||
|
||||
|
||||
@@ -453,7 +453,7 @@ service_render(state)
|
||||
{
|
||||
header = "No recorded high round yet";
|
||||
if (snapshot.round > 0)
|
||||
header = "Map record · Round " + snapshot.round;
|
||||
header = "Map record | Round " + snapshot.round;
|
||||
}
|
||||
if (!isDefined(state.record_header_text) || state.record_header_text != header)
|
||||
{
|
||||
|
||||
@@ -54,12 +54,12 @@ hud_connect()
|
||||
self.tws_hud_round = self hud_text(level.hud_overlay_timer_x,
|
||||
level.hud_overlay_round_y, "left", 1.25, level.hud_c_dim, "--:--");
|
||||
self hud_text(level.hud_overlay_brand_x, level.hud_overlay_brand_y,
|
||||
"center", 1.1, level.hud_c_dim, "TWS ZOMBIES · discord.tws.lol");
|
||||
"center", 1.1, level.hud_c_dim, "TWS ZOMBIES | discord.tws.lol");
|
||||
|
||||
self.tws_hud_count = self hud_text(level.hud_overlay_count_x,
|
||||
level.hud_overlay_count_y, "right", 1.5, level.hud_c_count, "--");
|
||||
self hud_text(level.hud_overlay_count_label_x, level.hud_overlay_count_label_y,
|
||||
"left", 1.05, level.hud_c_dim, "ZOMBIES");
|
||||
// Center the entire readout on the track, regardless of the digit count.
|
||||
count_x = level.hud_overlay_bar_x + level.hud_overlay_bar_width / 2.0;
|
||||
self.tws_hud_count = self hud_text(count_x,
|
||||
level.hud_overlay_count_y, "center", 1.25, level.hud_c_count, "-- ZOMBIES");
|
||||
|
||||
// Independent numeric elements avoid a new config string on every tick.
|
||||
// The readout appears only after a valid damaged-health sample.
|
||||
@@ -239,7 +239,8 @@ hud_zombie_counter()
|
||||
|
||||
if (remaining != last)
|
||||
{
|
||||
count SetValue(remaining);
|
||||
// Plutonium r5334+: reuse text storage as the count changes.
|
||||
count SetTextUnlimited(int(remaining) + " ZOMBIES");
|
||||
last = remaining;
|
||||
}
|
||||
|
||||
|
||||
+47
-15
@@ -26,11 +26,12 @@ function install(context, source, names) {
|
||||
const locals = [...new Set([...code.matchAll(/(?<![\w.])(\w+)\s*(?:=(?!=)|\+\+|--)/g)].map(match => match[1]))];
|
||||
code = code.replace(/(?:self|level) endon\([^;]+;/g, '')
|
||||
.replace(/scripts\\(?:sp|zm)\\tws_t[56]_common::/g, 'common.')
|
||||
.replace(/maps\\mp\\zombies\\_zm_utility::get_current_zombie_count/g, 'get_enemy_count')
|
||||
.replace(/self thread ([\w.]+)\(([^;]*)\);/g, (_, fn, values) => `queued.push(['${fn}', ${values}]);`)
|
||||
.replace(/self common\.toggle_core_hud\(\)/g, 'common.toggle_core_hud()')
|
||||
.replace(/self ((?:hud_|afk_)\w+)\(/g, '$1(')
|
||||
.replace(/self (\w+)\(/g, 'self.$1(')
|
||||
.replace(/(\w+) (SetText|SetValue|SetTimerUp|SetShader)\(([^;]*)\);/g, '$1.$2($3);')
|
||||
.replace(/(\w+) (SetText|SetTextUnlimited|SetValue|SetTimerUp|SetShader)\(([^;]*)\);/g, '$1.$2($3);')
|
||||
.replace(/level notify\(([^;]*)\);/g, 'level.notify($1);')
|
||||
.replace(/level waittill\(([^;]*)\);/g, 'yield { event: $1 };')
|
||||
.replace(/\.size\b/g, '.length')
|
||||
@@ -51,6 +52,7 @@ function engine(game, source, afk, hidden = false) {
|
||||
function element(args, alpha = 1) {
|
||||
const result = { args, alpha, writes: [],
|
||||
SetText(value) { this.text = value; this.writes.push(['text', value]); },
|
||||
SetTextUnlimited(value) { this.text = value; this.writes.push(['unlimitedText', value]); },
|
||||
SetValue(value) { this.value = value; this.writes.push(['value', value]); },
|
||||
SetShader(...args) { this.shader = args; },
|
||||
SetTimerUp(value) { this.timer = value; this.writes.push(['timer', value]); },
|
||||
@@ -79,7 +81,7 @@ function engine(game, source, afk, hidden = false) {
|
||||
player_active: player => player.active,
|
||||
format_mmss: ms => `${Math.floor(ms / 60000)}:${String(Math.floor(ms / 1000) % 60).padStart(2, '0')}`,
|
||||
};
|
||||
const level = { round_number: 1, hud_rate: .1, afk_grace_seconds: 2,
|
||||
const level = { round_number: 1, hud_rate: .1, afk_grace_seconds: 2, zombie_team: 'axis',
|
||||
hud_overlay_timer_x: 6, hud_overlay_match_y: 8, hud_overlay_round_y: 30,
|
||||
hud_overlay_brand_x: 320, hud_overlay_brand_y: 8,
|
||||
hud_overlay_count_x: 300, hud_overlay_count_y: 440,
|
||||
@@ -92,10 +94,11 @@ function engine(game, source, afk, hidden = false) {
|
||||
hud_c_count: 'white', hud_c_dim: 'dim', hud_c_afk: 'yellow',
|
||||
hud_c_high: 'green', hud_c_mid: 'yellow', hud_c_low: 'red', notify() {} };
|
||||
const context = vm.createContext({ self, level, common, queued, getTime: () => now,
|
||||
get_enemy_count: () => level.fixture_enemies ?? 0,
|
||||
isDefined: value => value !== undefined && value !== null, is_true: value => !!value,
|
||||
int: Math.trunc, max: Math.max });
|
||||
install(context, source, ['hud_connect', 'hud_text', 'hud_start', 'hud_toggle', 'hud_timer_row',
|
||||
'hud_health_display', 'freeze_timers_on_game_over']);
|
||||
'hud_health_display', 'hud_zombie_counter', 'freeze_timers_on_game_over']);
|
||||
install(context, afk, ['afk_spawn', 'afk_enter', 'afk_exit',
|
||||
...(game === 't6' ? ['afk_release', 'afk_lock_controls', 'afk_restore_controls'] : [])]);
|
||||
return { context, self, level, queued, elems, actions, common,
|
||||
@@ -118,7 +121,7 @@ for (const game of ['t5', 't6']) {
|
||||
assert(chat.includes('player thread hud_toggle()'), 'disconnect scope stays in the player worker');
|
||||
assert(!body(source, 'hud_connect')[1].includes('getTime()'));
|
||||
assert(!source.includes('tws_hud_hidden ='), 'spawn/construction must not reset the preference');
|
||||
for (const name of ['round_watcher', 'reset_timer_each_round', 'match_timer_bind'])
|
||||
for (const name of ['round_watcher', 'reset_timer_each_round', 'match_timer_bind', 'hud_zombie_counter'])
|
||||
assert(body(source, name)[1].includes('level endon("hud_game_over")'));
|
||||
const bind = body(source, 'match_timer_bind')[1];
|
||||
if (game === 't5') assert(bind.includes('elem SetTimerUp(0)'));
|
||||
@@ -127,13 +130,13 @@ for (const game of ['t5', 't6']) {
|
||||
assert(afk.includes('level.hud_overlay_afk_y'));
|
||||
assert(!/\.alpha\s*=/.test(afk), 'AFK visibility must use the common mask');
|
||||
});
|
||||
check(`${game}: connection places 11 box-free core elements at the screen edges without seeding clocks`, () => {
|
||||
check(`${game}: connection places 10 box-free core elements at the screen edges without seeding clocks`, () => {
|
||||
const e = make(); e.context.hud_connect();
|
||||
assert.equal(e.level.match_start_time, undefined); assert.equal(e.level.round_start_time, undefined);
|
||||
assert.equal(e.self.tws_hud_match.text, '--:--'); assert.equal(e.self.tws_hud_health.text, '--');
|
||||
assert.equal(e.elems.length, 11);
|
||||
assert.equal(e.self.tws_core_hud_elems.length, 11);
|
||||
e.context.hud_connect(); assert.equal(e.elems.length, 11);
|
||||
assert.equal(e.elems.length, 10);
|
||||
assert.equal(e.self.tws_core_hud_elems.length, 10);
|
||||
e.context.hud_connect(); assert.equal(e.elems.length, 10);
|
||||
assert.equal(e.queued.length, 1); assert.equal(e.queued[0][0], 'common.destroy_on_disconnect');
|
||||
assert.equal(e.queued[0][1].length, e.elems.length);
|
||||
const textAt = (text, x, y, align, scale, colour) => {
|
||||
@@ -142,9 +145,9 @@ for (const game of ['t5', 't6']) {
|
||||
};
|
||||
assert.deepEqual(e.self.tws_hud_match.args.slice(1), [6, 8, 'left', 1.4, 'white']);
|
||||
assert.deepEqual(e.self.tws_hud_round.args.slice(1), [6, 30, 'left', 1.25, 'dim']);
|
||||
textAt('TWS ZOMBIES · discord.tws.lol', 320, 8, 'center', 1.1, 'dim');
|
||||
assert.deepEqual(e.self.tws_hud_count.args.slice(1), [300, 440, 'right', 1.5, 'white']);
|
||||
textAt('ZOMBIES', 306, 446, 'left', 1.05, 'dim');
|
||||
textAt('TWS ZOMBIES | discord.tws.lol', 320, 8, 'center', 1.1, 'dim');
|
||||
textAt('-- ZOMBIES', 320, 440, 'center', 1.25, 'white');
|
||||
assert(!e.elems.some(elem => elem.text === 'ZOMBIES'), 'count and label share one alignment');
|
||||
textAt('HP', 449, 460, 'left', 1, 'white');
|
||||
for (const [key, x, align] of [['health', 414, 'right'], ['slash', 418, 'left'], ['maxhealth', 445, 'right']]) {
|
||||
const elem = e.self[`tws_hud_${key}`];
|
||||
@@ -165,13 +168,42 @@ for (const game of ['t5', 't6']) {
|
||||
assert.equal(e.level.match_start_time, undefined); assert.equal(e.level.round_start_time, undefined);
|
||||
assert.equal(e.queued.length, 1, 'toggle only queues disconnect cleanup');
|
||||
e.context.hud_start(); e.context.hud_start();
|
||||
assert.equal(e.elems.length, 11); assert.equal(e.self.tws_hud_hidden, true);
|
||||
assert.equal(e.elems.length, 10); assert.equal(e.self.tws_hud_hidden, true);
|
||||
assert.deepEqual(e.queued.slice(1).map(item => item[0]), ['hud_timer_row', 'hud_zombie_counter', 'hud_health_display']);
|
||||
e.context.hud_timer_row();
|
||||
assert.equal(e.level.match_start_time, 123456); assert.equal(e.level.round_start_time, 123456);
|
||||
const threads = e.queued.length;
|
||||
e.context.hud_toggle(); e.context.hud_toggle(); e.context.hud_start();
|
||||
assert.equal(e.queued.length, threads); assert.equal(e.elems.length, 11);
|
||||
assert.equal(e.queued.length, threads); assert.equal(e.elems.length, 10);
|
||||
});
|
||||
check(`${game}: complete zombie text stays centered through digit changes and hidden updates without config-string churn`, () => {
|
||||
const e = make();
|
||||
// Center on the configured track, including non-default and fractional midpoints.
|
||||
e.level.hud_overlay_bar_x = 210;
|
||||
e.level.hud_overlay_bar_width = 155;
|
||||
e.context.hud_connect();
|
||||
const count = e.self.tws_hud_count;
|
||||
assert.deepEqual(count.args.slice(1, 4), [287.5, 440, 'center']);
|
||||
const run = e.context.hud_zombie_counter();
|
||||
for (const value of [0, 6, 9, 10, 99, 100, 999, 1000, 6]) {
|
||||
e.level.fixture_enemies = value;
|
||||
run.next();
|
||||
assert.equal(count.text, `${value} ZOMBIES`);
|
||||
assert.deepEqual(count.args.slice(1, 4), [287.5, 440, 'center']);
|
||||
const writes = count.writes.length;
|
||||
run.next(); assert.equal(count.writes.length, writes, 'unchanged counts do not rewrite text');
|
||||
}
|
||||
e.level.zombie_total = 94; run.next();
|
||||
assert.equal(count.text, '100 ZOMBIES', 'remaining spawn count remains included');
|
||||
e.context.hud_toggle();
|
||||
e.level.zombie_total = -4; run.next();
|
||||
assert.equal(count.text, '6 ZOMBIES'); assert.equal(count.alpha, 0);
|
||||
e.context.hud_toggle();
|
||||
assert.equal(count.text, '6 ZOMBIES'); assert.equal(count.alpha, 1);
|
||||
assert.equal(count.writes.filter(([kind]) => kind === 'text').length, 1,
|
||||
'only the fixed placeholder uses a normal config string');
|
||||
assert(count.writes.slice(1).every(([kind]) => kind === 'unlimitedText'));
|
||||
assert.equal(e.elems.length, 10, 'updates and toggles never allocate replacement elements');
|
||||
});
|
||||
check(`${game}: health numbers appear only while damaged, follow the bar colour, and avoid config-string churn`, () => {
|
||||
const e = make(); e.context.hud_connect(); const { self } = e;
|
||||
@@ -216,7 +248,7 @@ for (const game of ['t5', 't6']) {
|
||||
e.context.hud_toggle();
|
||||
assert.equal(e.self.tws_hud_bar.alpha, 1); assert.equal(e.self.tws_hud_health.value, 50);
|
||||
assert.equal(other.self.tws_hud_hidden, undefined); assert.equal(other.self.tws_hud_health.alpha, 0);
|
||||
assert.equal(e.elems.length, 11); assert.equal(e.queued.length, 1);
|
||||
assert.equal(e.elems.length, 10); assert.equal(e.queued.length, 1);
|
||||
e.context.hud_toggle(); e.self.health = 100; run.next(); e.context.hud_toggle();
|
||||
assert.equal(e.self.tws_hud_health.alpha, 0, 'healing while hidden conceals the readout when shown');
|
||||
assert.equal(e.self.tws_hud_hp.alpha, 0); assert.equal(e.self.tws_hud_bar.alpha, 1);
|
||||
@@ -254,7 +286,7 @@ for (const game of ['t5', 't6']) {
|
||||
e.context.hud_toggle(); assert.equal(indicator.alpha, 0);
|
||||
exit.next(); assert.equal(e.self.ignoreme, false);
|
||||
assert(e.actions.some(([name]) => name === 'disableInvulnerability'));
|
||||
assert.equal(e.elems.length, 12);
|
||||
assert.equal(e.elems.length, 11);
|
||||
});
|
||||
if (game === 't6') check('t6: AFK release while hidden respects stock protection ownership', () => {
|
||||
const e = make(); e.context.hud_connect(); const watcher = e.spawnAfk();
|
||||
|
||||
+13
-12
@@ -45,7 +45,7 @@ function translate(source) {
|
||||
.replace(/(self|level) notify\(([^;]+)\);/g, 'emit($1, $2);')
|
||||
.replace(/self (\w+)\(/g, '$1(')
|
||||
.replace(/\bwait ([\d.]+);/g, 'yield { milliseconds: $1 * 1000 };')
|
||||
.replace(/([\w.]+(?:\[[^\]\n]+\])?)\s+(SetText|SetValue|SetShader|Destroy)\(/g, '$1.$2(')
|
||||
.replace(/([\w.]+(?:\[[^\]\n]+\])?)\s+(SetText|SetTextUnlimited|SetValue|SetShader|Destroy)\(/g, '$1.$2(')
|
||||
.replace(/__literal_(\d+)__/g, (_, i) => literals[Number(i)]);
|
||||
result.push(`function${coroutineNames.has(name) ? '*' : ''} ${name}(${match[2]}) { var ${[...locals].join(', ') || 'unused'}; ${body} }`);
|
||||
}
|
||||
@@ -99,6 +99,7 @@ function engine(game, count = 8, withHud = false) {
|
||||
owner,
|
||||
alpha: 1, textCalls: 0, valueCalls: 0, destroyCalls: 0,
|
||||
SetText(text) { assert(!this.destroyCalls); this.text = text; this.textCalls++; },
|
||||
SetTextUnlimited(text) { assert(!this.destroyCalls); this.text = text; this.textCalls++; },
|
||||
SetValue(value) { assert(!this.destroyCalls); this.value = value; this.valueCalls++; },
|
||||
SetShader(shader, width, height) {
|
||||
assert(!this.destroyCalls);
|
||||
@@ -335,7 +336,7 @@ for (const game of ['t5', 't6']) {
|
||||
assertCounter(e, 1, 1);
|
||||
e.record(snapshot(['A', 'B', 'C', 'D']));
|
||||
assert(first.every(elem => elem.destroyCalls === 1), 'pagedness changes release the old view first');
|
||||
assert.equal(e.state.record_title.text, 'Map record · Round 82');
|
||||
assert.equal(e.state.record_title.text, 'Map record | Round 82');
|
||||
assert.equal(e.live.length, 5);
|
||||
const paged = [...e.live];
|
||||
assertCounter(e, 1, 2);
|
||||
@@ -380,7 +381,7 @@ for (const game of ['t5', 't6']) {
|
||||
e.advance(11000);
|
||||
assert.equal(e.textCalls, calls);
|
||||
assert.equal(e.elements.length, count);
|
||||
assert.equal(e.state.record_title.text, 'Map record · Round 82');
|
||||
assert.equal(e.state.record_title.text, 'Map record | Round 82');
|
||||
assert.equal(e.state.commands[3].command, '.join');
|
||||
assert.match(e.c.help_description(e.state.commands[3]), /newcomer/);
|
||||
assert.equal(e.c.help_command_label(e.state.commands[6].command), '.d <amount|all>');
|
||||
@@ -522,9 +523,9 @@ check('T5 service transitions preserve actual core element identities, styles, d
|
||||
const e = engine('t5', 8, true);
|
||||
e.createCore();
|
||||
const core = Array.from(e.self.tws_core_hud_elems);
|
||||
assert.equal(core.length, 12, 'eleven core elements plus one optional AFK indicator');
|
||||
assert.equal(e.live.length, 12);
|
||||
e.self.tws_hud_count.SetValue(6);
|
||||
assert.equal(core.length, 11, 'ten core elements plus one optional AFK indicator');
|
||||
assert.equal(e.live.length, 11);
|
||||
e.self.tws_hud_count.SetTextUnlimited('6 ZOMBIES');
|
||||
e.self.tws_hud_health.SetValue(100);
|
||||
e.self.tws_hud_maxhealth.SetValue(100);
|
||||
e.c.set_core_alpha(e.self, e.self.tws_hud_bar, 1);
|
||||
@@ -536,17 +537,17 @@ check('T5 service transitions preserve actual core element identities, styles, d
|
||||
e.advance(3000);
|
||||
e.record(snapshot(['Jeff', 'Lokester', 'Moniialx']));
|
||||
const controller = e.state, tasks = e.tasks.length;
|
||||
assert.equal(e.live.length, 16);
|
||||
assert.equal(e.live.length, 15);
|
||||
assert.deepEqual(state(), initial);
|
||||
e.advance(12000);
|
||||
assert.equal(e.state, controller);
|
||||
assert.equal(e.state.closed, false, 'idle releases the view, not its controller');
|
||||
assert.equal(e.state.elems.length, 0);
|
||||
assert.equal(e.live.length, 12);
|
||||
assert.equal(e.live.length, 11);
|
||||
assert.deepEqual(state(), initial);
|
||||
for (let i = 0; i < 4; i++) {
|
||||
e.record(snapshot(['One', 'Two', 'Three', 'Four'])); e.advance(15000); e.help();
|
||||
assert.equal(e.live.length, 31, '12 core/AFK plus 19 help elements; this is not an engine pool-limit assertion');
|
||||
assert.equal(e.live.length, 30, '11 core/AFK plus 19 help elements; this is not an engine pool-limit assertion');
|
||||
assert.equal(e.live.filter(elem => elem.archived === false).length, 19);
|
||||
e.c.toggle_core_hud();
|
||||
assert(core.every(elem => elem.alpha === 0));
|
||||
@@ -556,17 +557,17 @@ check('T5 service transitions preserve actual core element identities, styles, d
|
||||
e.advance(12000);
|
||||
assert.equal(e.state.rows[0].text, 'Latest');
|
||||
assert.equal(e.state.record.remaining, 12000);
|
||||
assert.equal(e.live.length, 16);
|
||||
assert.equal(e.live.length, 15);
|
||||
assert(core.every(elem => elem.alpha === 0 && elem.destroyCalls === 0));
|
||||
e.c.toggle_core_hud();
|
||||
assert.deepEqual(state(), initial);
|
||||
e.advance(12000);
|
||||
assert.equal(e.live.length, 12);
|
||||
assert.equal(e.live.length, 11);
|
||||
assert.equal(e.state.elems.length, 0);
|
||||
assert.equal(e.tasks.length, tasks, 'reopening reuses the controller and cleanup watchers');
|
||||
assert.deepEqual(state(), initial);
|
||||
}
|
||||
assert.equal(e.peakLive, 31);
|
||||
assert.equal(e.peakLive, 30);
|
||||
assert.deepEqual(Array.from(e.self.tws_core_hud_elems), core);
|
||||
e.event('disconnect');
|
||||
assert.equal(e.live.length, 0);
|
||||
|
||||
+4
-4
@@ -1,16 +1,16 @@
|
||||
{
|
||||
"tws_t5_afk.gsc": "1.2.0",
|
||||
"tws_t5_bank.gsc": "2.0.3",
|
||||
"tws_t5_common.gsc": "1.4.0",
|
||||
"tws_t5_hud.gsc": "1.4.0",
|
||||
"tws_t5_common.gsc": "1.4.1",
|
||||
"tws_t5_hud.gsc": "1.4.2",
|
||||
"tws_t5_join.gsc": "1.0.0",
|
||||
"tws_t5_leaderboard.gsc": "1.1.0",
|
||||
"tws_t5_lock.gsc": "1.0.0",
|
||||
"tws_t5_telemetry.gsc": "1.0.0",
|
||||
"tws_t6_afk.gsc": "1.2.0",
|
||||
"tws_t6_bank.gsc": "2.0.3",
|
||||
"tws_t6_common.gsc": "1.4.0",
|
||||
"tws_t6_hud.gsc": "1.4.0",
|
||||
"tws_t6_common.gsc": "1.4.1",
|
||||
"tws_t6_hud.gsc": "1.4.2",
|
||||
"tws_t6_join.gsc": "1.0.1",
|
||||
"tws_t6_leaderboard.gsc": "1.1.0",
|
||||
"tws_t6_lock.gsc": "1.0.0",
|
||||
|
||||
Reference in New Issue
Block a user