From d3dd437437799d1ee8ba361cc1fdcec53ef42f3f Mon Sep 17 00:00:00 2001 From: John Willard <53777086+JohnFulpWillard@users.noreply.github.com> Date: Thu, 2 Oct 2025 14:04:39 -0400 Subject: [PATCH] Lobby TV screen shows an icon of the overflow job (#93023) ## About The Pull Request Hey so remember that TV thing I added, and I wanted it to be useful for overflow jobs so I added it in, but couldn't make it look good with runechat so I made it only appear post-roundstart, rendering it utterly useless? Yeah, I do too, so I've come back to fix it with the help of stealing other people's code (I'm a lazy individual) - Taking Absolucy's work in https://github.com/Monkestation/Monkestation2.0/pull/4589 for this. Now it shows an icon of the job with an active overflow under the TV's effects, and has a tooltip if you hover over in case you don't understand what it's demonstrating. https://github.com/user-attachments/assets/97489f93-f40d-47f9-aea2-6cc32c8fcba3 ## Why It's Good For The Game The TV shows overflow information before the round starts, allowing people to actually see and react to the information rather than only being shown to latejoiners. I prefer it this way as I don't want to have to ensure the different things we may put on the TV's runetext all shows up properly. ## Changelog :cl: Absolucy, JohnFulpWillard image: The Lobby TV now shows an icon of the overflow job. /:cl: --- code/__HELPERS/icons.dm | 23 ++++++++++++++++ code/_onclick/hud/new_player.dm | 37 +++++++++++++++++++++----- code/controllers/subsystem/job.dm | 2 +- code/modules/jobs/job_types/_job.dm | 12 +++++++++ code/modules/jobs/job_types/ai.dm | 3 +++ code/modules/jobs/job_types/cyborg.dm | 3 +++ icons/mob/huds/hud.dmi | Bin 11016 -> 11044 bytes 7 files changed, 73 insertions(+), 7 deletions(-) diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index ba9d701b03a..7f08afd0704 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -1370,3 +1370,26 @@ GLOBAL_LIST_EMPTY(transformation_animation_objects) copy.underlays = underlays_to_keep return copy + +/// Returns the (isolated) security HUD icon for the given job. +/proc/get_job_hud_icon(datum/job/job) as /icon + var/static/alist/icon_cache = alist() + if(isnull(job)) + return + + if(!is_job(job)) + if(ispath(job, /datum/job)) + job = SSjob.get_job_type(job) + else if(istext(job)) + job = SSjob.get_job(job) + if(isnull(job)) + return null + + //add it to the cache if it isn't already + var/job_type = job.type + if(!icon_cache[job_type]) + var/icon/sechud_icon = job.get_lobby_icon() + sechud_icon.Crop(1, 17, 8, 24) + icon_cache[job_type] = sechud_icon + + return icon(icon_cache[job_type]) diff --git a/code/_onclick/hud/new_player.dm b/code/_onclick/hud/new_player.dm index 643a6c167bd..e363240b72e 100644 --- a/code/_onclick/hud/new_player.dm +++ b/code/_onclick/hud/new_player.dm @@ -688,30 +688,58 @@ ///Boolean on whether or not we should have our static overlay, so we 'turn' the TV off when collapsing. var/show_static = TRUE + ///Static mutable appearance of a job icon we're displaying on the TV for overflow job. + var/static/mutable_appearance/job_overlay /atom/movable/screen/lobby/new_player_info/Initialize(mapload, datum/hud/hud_owner) . = ..() START_PROCESSING(SSnewplayer_info, src) update_text() + + //only go if the station trait is selected, otherwise it'll show "Assistant" every round. + var/datum/station_trait/overflow_job_bureaucracy/overflow_job = locate() in SSstation.station_traits + if(overflow_job && isnull(job_overlay)) + var/icon/job_icon = get_job_hud_icon(SSjob.overflow_role) + if(isnull(job_icon)) + stack_trace("[SSjob.overflow_role::title] was selected as the Job Overflow but has no icon!") + else + job_icon.Scale(ICON_SIZE_X / 2, ICON_SIZE_X / 2) + job_overlay = mutable_appearance(job_icon, offset_spokesman = src, alpha = 120, layer = src.layer+0.02) + var/matrix/job_matrix = matrix() + job_matrix.Translate(6, 14) //this is completely arbitruary just what I thought looked good. + job_overlay.transform = job_matrix + 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/MouseEntered(location, control, params) + . = ..() + if(QDELETED(src) || isnull(job_overlay)) + return + openToolTip(usr, src, params, title = "[SSjob.overflow_role::title] overflow", content = "The overflow for the round has been set as [SSjob.overflow_role::title].") + +/atom/movable/screen/lobby/new_player_info/MouseExited() + closeToolTip(usr) + return ..() + /atom/movable/screen/lobby/new_player_info/update_icon_state() . = ..() icon_state = base_icon_state /atom/movable/screen/lobby/new_player_info/update_overlays() . = ..() - . += mutable_appearance(icon, "[base_icon_state]_overlay", layer = src.layer+0.03) + . += mutable_appearance(icon, "[base_icon_state]_overlay", layer = src.layer+0.01) if(!show_static) return . - . += mutable_appearance(icon, "static_base", alpha = 20, layer = src.layer+0.01) + if(job_overlay) + . += job_overlay + . += mutable_appearance(icon, "static_base", alpha = 20, layer = src.layer+0.03) //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) + var/mutable_appearance/scanline = mutable_appearance(generate_icon_alpha_mask('icons/hud/lobby/newplayer_scanline.dmi', "scanline"), alpha = 20, layer = src.layer+0.04) scanline.pixel_y = OVERLAY_X_DIFF scanline.pixel_x = OVERLAY_Y_DIFF . += scanline @@ -751,9 +779,6 @@ new_maptext = "[SSmapping.current_map.map_name]
\ [LAZYLEN(GLOB.clients)] player\s online
\ [ROUND_TIME()] in
" - var/datum/station_trait/overflow_job_bureaucracy/overflow = locate() in SSstation.station_traits - if(overflow) - new_maptext += "[overflow.chosen_job_name] overflow" new_maptext += "
" else var/time_remaining = SSticker.GetTimeLeft() diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index ed286ea66d0..6cb6dd8f760 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -31,7 +31,7 @@ SUBSYSTEM_DEF(job) var/list/prioritized_jobs = list() var/list/latejoin_trackers = list() - var/overflow_role = /datum/job/assistant + var/datum/job/overflow_role = /datum/job/assistant var/list/level_order = list(JP_HIGH, JP_MEDIUM, JP_LOW) diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm index 1dc0d8cef0c..a7e22b570d1 100644 --- a/code/modules/jobs/job_types/_job.dm +++ b/code/modules/jobs/job_types/_job.dm @@ -647,3 +647,15 @@ /// This proc may be called when someone of this job is made into a traitor to create custom objectives related to the job. /datum/job/proc/generate_traitor_objective() return null + +/// Returns a large (due to cropping) icon of this job's sechud icon state. +/datum/job/proc/get_lobby_icon() as /icon + var/datum/outfit/job_outfit = outfit + if(!job_outfit || !job_outfit::id_trim) + CRASH("[src.type] has no job outfit but isn't overwriting get_lobby_icon().") + var/datum/id_trim/job_trim = job_outfit::id_trim + var/icon_state = job_trim::sechud_icon_state + if(!icon_state || icon_state == SECHUD_UNKNOWN) + CRASH("[src.type] has no job icon state.") + + return icon('icons/mob/huds/hud.dmi', icon_state) diff --git a/code/modules/jobs/job_types/ai.dm b/code/modules/jobs/job_types/ai.dm index bd582705507..0a35b5f53ac 100644 --- a/code/modules/jobs/job_types/ai.dm +++ b/code/modules/jobs/job_types/ai.dm @@ -89,3 +89,6 @@ /datum/job/ai/on_respawn(mob/new_character) new_character.AIize() + +/datum/job/ai/get_lobby_icon() + return icon('icons/mob/huds/hud.dmi', "hudai") diff --git a/code/modules/jobs/job_types/cyborg.dm b/code/modules/jobs/job_types/cyborg.dm index 7a70f52ab25..059f12a3f3d 100644 --- a/code/modules/jobs/job_types/cyborg.dm +++ b/code/modules/jobs/job_types/cyborg.dm @@ -38,3 +38,6 @@ /datum/job/cyborg/on_respawn(mob/new_character) new_character.Robotize(TRUE) + +/datum/job/cyborg/get_lobby_icon() + return icon('icons/mob/huds/hud.dmi', "hudcyborg") diff --git a/icons/mob/huds/hud.dmi b/icons/mob/huds/hud.dmi index 53dd33a4544f65d830c1ccc013bc14cf4f49ac77..3927f3f0144af9254d0ae3512598b3b63c1aed87 100644 GIT binary patch delta 8770 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 D&4C4~ delta 8692 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 CD#;1}