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: image #### 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("
Server reboot \n\ DELAYED
") + else + reboot_hud.maptext = MAPTEXT_PIXELLARI("
Server rebooting in:\n\ [DisplayTimeText(timeleft(SSticker.reboot_timer), 1)]
") + /// Checks if the round should be ending, called every ticker tick /datum/controller/subsystem/ticker/proc/check_finished() if(!setup_done) @@ -833,6 +842,8 @@ SUBSYSTEM_DEF(ticker) var/start_wait = world.time UNTIL(round_end_sound_sent || (world.time - start_wait) > (delay * 2)) //don't wait forever + if(!isnull(reboot_timer)) //Override existing reboot timers. + deltimer(reboot_timer) reboot_timer = addtimer(CALLBACK(src, PROC_REF(reboot_callback), reason, end_string), delay - (world.time - start_wait), TIMER_STOPPABLE) diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index 691a36a8b65..1f0069e203c 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -134,6 +134,9 @@ SEND_GLOBAL_SIGNAL(COMSIG_GLOB_MOB_LOGGED_IN, src) + if(SSticker.IsPostgame()) + client.screen += SSticker.reboot_hud + return TRUE