Add .leaders command to replay map records in T5 and T6

This commit is contained in:
2026-10-07 22:49:55 -04:00
parent dec51a7032
commit 58399d2191
6 changed files with 156 additions and 11 deletions
+4
View File
@@ -72,11 +72,15 @@ counter and health display. Typing either command again restarts that display ti
| `.afk` | Pause with protection |
| `.back` | Return from AFK |
| `.join` | Join mid-round (newcomers only) |
| `.leaders` | Show the map record again (leaderboard module required) |
AFK and Join register their commands during `init()` through
`tws_t6_common::register_help_command(command, description)`. If a module is
omitted, its commands are omitted from `.help`. Register new commands alongside
their module's initialization so the list stays current.
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.
## Defaults, matching T5
+62 -5
View File
@@ -1,4 +1,4 @@
/* tws_t6_leaderboard.gsc - private map record announcement, once per connection. */
/* tws_t6_leaderboard.gsc - private map record announcements and .leaders replay. */
#include maps\mp\_utility;
#include common_scripts\utility;
@@ -26,7 +26,9 @@ init()
level.tws_lb_pending = undefined;
level.tws_lb_cache = undefined;
level.tws_lb_attempt = 0;
scripts\zm\tws_t6_common::register_help_command(".leaders", "Show the map record again");
scripts\zm\tws_t6_common::register_connect_handler(::lb_welcome);
level thread lb_chat_listener();
level thread lb_worker();
}
@@ -67,6 +69,7 @@ lb_worker()
lb_welcome()
{
self endon("disconnect");
self endon("tws_lb_requested");
level endon("end_game");
level endon("game_ended");
level endon("intermission");
@@ -87,18 +90,62 @@ lb_welcome()
while (!isDefined(level.tws_lb_cache) && level.tws_lb_attempt == 0)
wait 0.25;
self lb_request(false);
}
lb_chat_listener()
{
level endon("end_game");
level endon("game_ended");
level endon("intermission");
for (;;)
{
level waittill("say", message, player);
if (!isDefined(player) || !isDefined(message))
continue;
if (toLower(message) == ".leaders")
player thread lb_request(true);
}
}
lb_cached_record()
{
if (!isDefined(level.tws_lb_cache))
return;
return undefined;
snapshot = level.tws_lb_cache;
// Do not advertise an indefinitely stale record during an outage.
if (getTime() - snapshot.saved_at > 900000)
return;
return undefined;
return snapshot;
}
lb_request(manual)
{
self endon("disconnect");
level endon("end_game");
level endon("game_ended");
level endon("intermission");
snapshot = lb_cached_record();
if (!isDefined(snapshot))
{
if (manual)
self iPrintLnBold("^3Map record unavailable; try .leaders again shortly");
return;
}
// A manual replay replaces any welcome announcement still waiting to run.
if (manual)
self notify("tws_lb_requested");
self lb_show_hud(snapshot);
}
lb_show_hud(snapshot)
{
// Stop the previous display and its cleanup threads before replacing it.
self notify("tws_lb_hud_done");
if (isDefined(self.tws_lb_elems))
lb_hud_destroy(self.tws_lb_elems);
self endon("disconnect");
self endon("tws_lb_hud_done");
@@ -124,8 +171,9 @@ lb_show_hud(snapshot)
elems[elems.size] = row;
}
// Cleanup runs independently of the welcome thread's endon handlers.
self thread scripts\zm\tws_t6_common::destroy_on_disconnect(elems);
// Cleanup runs independently of the display and ends when it is replaced.
self.tws_lb_elems = elems;
self thread lb_hud_disconnect(elems);
self thread lb_hud_end_game(elems, "end_game");
self thread lb_hud_end_game(elems, "game_ended");
self thread lb_hud_end_game(elems, "intermission");
@@ -159,6 +207,7 @@ lb_show_hud(snapshot)
break;
}
lb_hud_destroy(elems);
self.tws_lb_elems = undefined;
self notify("tws_lb_hud_done");
}
@@ -168,12 +217,20 @@ lb_hud_help_visible()
isDefined(self.tws_help_elems[0]) && self.tws_help_elems[0].alpha > 0;
}
lb_hud_disconnect(elems)
{
self endon("tws_lb_hud_done");
self waittill("disconnect");
lb_hud_destroy(elems);
}
lb_hud_end_game(elems, event)
{
self endon("disconnect");
self endon("tws_lb_hud_done");
level waittill(event);
lb_hud_destroy(elems);
self.tws_lb_elems = undefined;
self notify("tws_lb_hud_done");
}