From d1086750d969e542d2cf17f3b8e720fa079e1815 Mon Sep 17 00:00:00 2001
From: John Willard <53777086+JohnFulpWillard@users.noreply.github.com>
Date: Fri, 13 Mar 2026 18:08:56 -0400
Subject: [PATCH] Moves Reboot timer to the game screen (#95357)
## About The Pull Request
Since I'm trying to move away from the stat panel as part of my project
here - https://hackmd.io/443_dE5lRWeEAp9bjGcKYw?view - I thought the
reboot timer should be moved out before the stat panel could be made
optional, due to its importance to post-round players (especially to
know if the round is rebooted).
Once the round is over the whole screen kinda becomes pointless, so we
can take as much screen space as we can.
I put this under the tooltips, using similar behavior to it, like the
layer & outline.
This is inspired by the Goon roundend, which does pretty much 1:1 what
this is.
#### Goon's, for reference:
#### Ours:
https://github.com/user-attachments/assets/b14efae2-e280-47e9-b3db-f57b2060cce7
It's also non-widescreen friendly
## Why It's Good For The Game
Moving things away from the stat panel and to being more player visible
is a positive IMO.
It's also a necessary step to taking away from reliance away from said
stat panel.
## Changelog
:cl:
add: The endround timer telling you when a reboot is happening has been
taken out of the stat panel and is instead text over your screen
(similar to Goon)
/:cl:
---
code/__HELPERS/roundend.dm | 11 +++++++++++
code/controllers/subsystem/statpanel.dm | 8 --------
code/controllers/subsystem/ticker.dm | 13 ++++++++++++-
code/modules/mob/login.dm | 3 +++
4 files changed, 26 insertions(+), 9 deletions(-)
diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm
index 8e21e78b1b2..73125860d58 100644
--- a/code/__HELPERS/roundend.dm
+++ b/code/__HELPERS/roundend.dm
@@ -220,6 +220,8 @@ GLOBAL_LIST_INIT(achievements_unlocked, list())
var/speed_round = (STATION_TIME_PASSED() <= 10 MINUTES)
+ if(isnull(reboot_hud))
+ reboot_hud = new()
for(var/client/C in GLOB.clients)
if(!C?.credits)
C?.RollCredits()
@@ -227,6 +229,7 @@ GLOBAL_LIST_INIT(achievements_unlocked, list())
C?.playtitlemusic(volume_multiplier = 0.5)
if(speed_round && was_forced != ADMIN_FORCE_END_ROUND)
C?.give_award(/datum/award/achievement/misc/speed_round, C?.mob)
+ C?.screen += reboot_hud
HandleRandomHardcoreScore(C)
var/popcount = gather_roundend_feedback()
@@ -752,3 +755,11 @@ GLOBAL_LIST_INIT(achievements_unlocked, list())
var/winner_key
///The name of the area we earned this cheevo in
var/award_location
+
+/atom/movable/screen/reboot_timer
+ screen_loc = "CENTER:-140,TOP:-42"
+ mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ maptext_width = 340
+ maptext_height = 64
+ maptext = ""
+ layer = SCREENTIP_LAYER //This is basically an extra screentip
diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm
index 30615abc0fd..48f1cc1b313 100644
--- a/code/controllers/subsystem/statpanel.dm
+++ b/code/controllers/subsystem/statpanel.dm
@@ -48,14 +48,6 @@ SUBSYSTEM_DEF(statpanels)
if(ETA)
global_data += "[ETA] [SSshuttle.emergency.getTimerStr()]"
- if(SSticker.reboot_timer)
- var/reboot_time = timeleft(SSticker.reboot_timer)
- if(reboot_time)
- global_data += "Reboot: [DisplayTimeText(reboot_time, 1)]"
- // admin must have delayed round end
- else if(SSticker.ready_for_reboot)
- global_data += "Reboot: DELAYED"
-
src.currentrun = GLOB.clients.Copy()
mc_data = null
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index 05f2c5a59a3..92e0390d63e 100644
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -5,7 +5,7 @@ SUBSYSTEM_DEF(ticker)
name = "Ticker"
priority = FIRE_PRIORITY_TICKER
flags = SS_KEEP_TIMING
- runlevels = RUNLEVEL_LOBBY | RUNLEVEL_SETUP | RUNLEVEL_GAME
+ runlevels = RUNLEVEL_LOBBY | RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME
/// state of current round (used by process()) Use the defines GAME_STATE_* !
var/current_state = GAME_STATE_STARTUP
@@ -69,6 +69,8 @@ SUBSYSTEM_DEF(ticker)
/// Why an emergency shuttle was called
var/emergency_reason
+ ///The display of how much time is left before a reboot, given to all clients post-game.
+ var/atom/movable/screen/reboot_timer/reboot_hud
/// ID of round reboot timer, if it exists
var/reboot_timer = null
@@ -204,6 +206,13 @@ SUBSYSTEM_DEF(ticker)
declare_completion(force_ending)
Master.SetRunLevel(RUNLEVEL_POSTGAME)
+ if(GAME_STATE_FINISHED)
+ if(ready_for_reboot)
+ if(isnull(reboot_timer))
+ reboot_hud.maptext = MAPTEXT_PIXELLARI("