From 6ff440bbc278ecf9f935dc67504bb0fb21bc7caa Mon Sep 17 00:00:00 2001
From: John Willard <53777086+JohnFulpWillard@users.noreply.github.com>
Date: Sun, 13 Apr 2025 16:18:37 -0400
Subject: [PATCH] Lobby info is now part of the hud instead of stat panel
(#90572)
## About The Pull Request
Removes ``/mob/dead/get_status_tab_items()``, replaces it with a lobby
hud icon showing the same information
TV sprite made by Kryson, scanline and static taken from ``effects.dmi``
which I then blew up to fit the size.
https://github.com/user-attachments/assets/99733ae6-c596-42b1-bcae-d1a8d8f094c3
## Why It's Good For The Game
I want to try to remove as much reliance from the stat panel as possible
so we can hopefully remove it, as it takes up 1/3 of the screen for
nothing.
## Changelog
:cl: Kryson, JohnFulpWillard
qol: Lobby info is now on the title screen rather than being hidden in
the stat panel.
/:cl:
---
code/_onclick/hud/new_player.dm | 121 ++++++++++++++++++
.../subsystem/processing/newplayer.dm | 5 +
code/modules/mob/dead/dead.dm | 17 ---
icons/hud/lobby/newplayer.dmi | Bin 0 -> 5478 bytes
icons/hud/lobby/newplayer_scanline.dmi | Bin 0 -> 427 bytes
tgstation.dme | 1 +
6 files changed, 127 insertions(+), 17 deletions(-)
create mode 100644 code/controllers/subsystem/processing/newplayer.dm
create mode 100644 icons/hud/lobby/newplayer.dmi
create mode 100644 icons/hud/lobby/newplayer_scanline.dmi
diff --git a/code/_onclick/hud/new_player.dm b/code/_onclick/hud/new_player.dm
index 31d0ad332f1..8e526e2a1c3 100644
--- a/code/_onclick/hud/new_player.dm
+++ b/code/_onclick/hud/new_player.dm
@@ -637,6 +637,127 @@
if(SSticker.current_state == GAME_STATE_STARTUP)
to_chat(usr, span_admin("The server is still setting up, but the round will be started as soon as possible."))
+#define OVERLAY_X_DIFF 12
+#define OVERLAY_Y_DIFF 5
+
+///Lobby screen that appears before the game has started showing how many players there are and who is ready.
+/atom/movable/screen/lobby/new_player_info
+ name = "New Player Info"
+ screen_loc = "TOP:-20,CENTER:192"
+ icon = 'icons/hud/lobby/newplayer.dmi'
+ icon_state = null //we only show up when we get update appearance called, cause we need our overlay to not look bad.
+ base_icon_state = "newplayer"
+ maptext_height = 70
+ maptext_width = 80
+ maptext_x = OVERLAY_X_DIFF
+ maptext_y = OVERLAY_Y_DIFF
+
+ var/show_static = TRUE
+
+/atom/movable/screen/lobby/new_player_info/Initialize(mapload, datum/hud/hud_owner)
+ . = ..()
+ switch(SSticker.current_state)
+ if(GAME_STATE_PREGAME, GAME_STATE_STARTUP)
+ RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, PROC_REF(hide_info))
+ if(GAME_STATE_SETTING_UP)
+ RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, PROC_REF(show_info))
+
+ START_PROCESSING(SSnewplayer_info, src)
+ update_text()
+ update_appearance(UPDATE_ICON)
+
+/atom/movable/screen/lobby/new_player_info/Destroy()
+ STOP_PROCESSING(SSnewplayer_info, src)
+ return ..()
+
+/atom/movable/screen/lobby/new_player_info/update_overlays()
+ . = ..()
+ if(!always_available)
+ return .
+ . += mutable_appearance(icon, "[base_icon_state]_overlay", layer = src.layer+0.03)
+ if(show_static)
+ . += mutable_appearance(icon, "static_base", alpha = 20, layer = src.layer+0.01)
+ //we have this in a separate file because `generate_icon_alpha_mask` puts lighting even on non-existent pixels,
+ //giving the icon a weird background color.
+ var/mutable_appearance/scanline = mutable_appearance(generate_icon_alpha_mask('icons/hud/lobby/newplayer_scanline.dmi', "scanline"), alpha = 20, layer = src.layer+0.02)
+ scanline.pixel_y = OVERLAY_X_DIFF
+ scanline.pixel_x = OVERLAY_Y_DIFF
+ . += scanline
+
+/atom/movable/screen/lobby/new_player_info/update_icon_state()
+ . = ..()
+ if(!always_available)
+ icon_state = "[base_icon_state]_disabled"
+ else
+ icon_state = base_icon_state
+
+/atom/movable/screen/lobby/new_player_info/process(seconds_per_tick)
+ update_text()
+
+/atom/movable/screen/lobby/new_player_info/collapse_button()
+ show_static = FALSE
+ update_text()
+ //to be in sync with parent, we'll turn the TV off in this time instead.
+ animate(src, appearance = update_appearance(UPDATE_ICON), time = SHUTTER_MOVEMENT_DURATION + SHUTTER_WAIT_DURATION)
+ //we go to the right, not up
+ animate(transform = transform.Translate(x = 146, y = 0), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_IN)
+
+/atom/movable/screen/lobby/new_player_info/expand_button()
+ . = ..()
+ show_static = TRUE
+ update_appearance(UPDATE_ICON)
+ update_text()
+
+/atom/movable/screen/lobby/new_player_info/proc/hide_info()
+ SIGNAL_HANDLER
+
+ STOP_PROCESSING(SSnewplayer_info, src)
+ UnregisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP)
+ RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, PROC_REF(show_info))
+ always_available = FALSE
+ update_appearance(UPDATE_ICON)
+ update_text()
+
+/atom/movable/screen/lobby/new_player_info/proc/show_info()
+ SIGNAL_HANDLER
+
+ always_available = TRUE
+ update_appearance(UPDATE_ICON)
+ update_text()
+ START_PROCESSING(SSnewplayer_info, src)
+ UnregisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP)
+ RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, PROC_REF(hide_info))
+
+/atom/movable/screen/lobby/new_player_info/proc/update_text()
+ if(!always_available || !hud || !show_static)
+ maptext = null
+ return
+ var/new_maptext
+ if(!MC_RUNNING())
+ new_maptext = "Loading..."
+ else
+ var/time_remaining = SSticker.GetTimeLeft()
+ if(time_remaining > 0)
+ time_remaining = "[round(time_remaining/10)]s"
+ else if(time_remaining == -10)
+ time_remaining = "DELAYED"
+ else
+ time_remaining = "SOON"
+
+ if(hud.mymob.client.holder)
+ new_maptext = "Starting in [time_remaining]
\
+ [LAZYLEN(GLOB.clients)] player\s
\
+ [SSticker.totalPlayersReady] players ready
\
+ [SSticker.total_admins_ready] / [length(GLOB.admins)] admins ready"
+ else
+ new_maptext = "[time_remaining]
\
+ [LAZYLEN(GLOB.clients)] player\s"
+
+ maptext = MAPTEXT(new_maptext)
+
+#undef OVERLAY_X_DIFF
+#undef OVERLAY_Y_DIFF
+
#undef SHUTTER_MOVEMENT_DURATION
#undef SHUTTER_WAIT_DURATION
#undef MAX_STATION_TRAIT_BUTTONS_VERTICAL
diff --git a/code/controllers/subsystem/processing/newplayer.dm b/code/controllers/subsystem/processing/newplayer.dm
new file mode 100644
index 00000000000..796f7405ef8
--- /dev/null
+++ b/code/controllers/subsystem/processing/newplayer.dm
@@ -0,0 +1,5 @@
+PROCESSING_SUBSYSTEM_DEF(newplayer_info)
+ name = "New Player Info"
+ flags = SS_NO_INIT | SS_BACKGROUND
+ wait = 1 SECONDS
+ runlevels = RUNLEVEL_LOBBY|RUNLEVEL_SETUP
diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm
index aec19662d3a..eccf8807a76 100644
--- a/code/modules/mob/dead/dead.dm
+++ b/code/modules/mob/dead/dead.dm
@@ -29,23 +29,6 @@ INITIALIZE_IMMEDIATE(/mob/dead)
/mob/dead/canUseStorage()
return FALSE
-/mob/dead/get_status_tab_items()
- . = ..()
- if(SSticker.HasRoundStarted())
- return
- var/time_remaining = SSticker.GetTimeLeft()
- if(time_remaining > 0)
- . += "Time To Start: [round(time_remaining/10)]s"
- else if(time_remaining == -10)
- . += "Time To Start: DELAYED"
- else
- . += "Time To Start: SOON"
-
- . += "Players: [LAZYLEN(GLOB.clients)]"
- if(client.holder)
- . += "Players Ready: [SSticker.totalPlayersReady]"
- . += "Admins Ready: [SSticker.total_admins_ready] / [length(GLOB.admins)]"
-
#define SERVER_HOPPER_TRAIT "server_hopper"
/mob/dead/proc/server_hop()
diff --git a/icons/hud/lobby/newplayer.dmi b/icons/hud/lobby/newplayer.dmi
new file mode 100644
index 0000000000000000000000000000000000000000..b94a2937a1b726031a1dd9d38f545a69f6dbe43c
GIT binary patch
literal 5478
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