Replaces the Space Suit stat panel entry (#95463)

## About The Pull Request

When you put on a space suit, it gives you stat panel entries for
whether the thermal regulator is on, and the charge in the cell.
This replaces it with the already-existing HUD element, and improves
upon it.

1. Re-uses mod's "very low" icon for the HUD, now "max" charge is
100-60%, "mid" is 60-40%, "low" is 40-20% and under that is "very low"
2. The icon now displays "OFF" when the thermal regulator isn't running
3. You can click on the HUD element to turn the thermal regulator on
4. You can hover over the HUD element to see the exact percentage your
space suit is at



https://github.com/user-attachments/assets/3a6cc33d-25d1-479d-99d5-f8160316c230


Maybe in the future we could remove the action button as well if the HUD
element is preferable, as we already seem to have an excess amount of
action buttons. Alternatively we can remove the HUD element entirely and
move the behaviour to the action button, like what we did with the
internals HUD. I'll leave that up to future discussion though I lean
more on it being a HUD element.

## Why It's Good For The Game

Helps me kill the stat panel as part of
https://hackmd.io/443_dE5lRWeEAp9bjGcKYw?view

Space suits is one of the larger parts of this issue as people are
typically expected to wear a space suit, so I think it's pretty
important we get this one done sooner rather than later. Same as my
other recent PRs, this one is also a complement of
https://github.com/tgstation/tgstation/pull/95383

## Changelog

🆑
qol: The stat panel entry for space suits has been replaced with the HUD
element. You can now hover over it to see exact cell percentage, and
click it to turn the regulator on, while it'll also display when it's
off.
/🆑

---------

Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
This commit is contained in:
John Willard
2026-03-28 09:42:49 +01:00
committed by GitHub
co-authored by MrMelbert
parent 96ab2c2cb3
commit d08cd9dbee
9 changed files with 122 additions and 63 deletions
+9
View File
@@ -68,3 +68,12 @@
#define GMESSENGER "Grey Messenger Bag"
/// Backpack type: Leather satchel
#define LSATCHEL "Leather Satchel"
//Defines for space suits. The respective define is also an icon.
#define SPACESUIT_NO_ICON "none"
#define SPACESUIT_CELL_MISSING "missing"
#define SPACESUIT_CELL_EMPTY "empty"
#define SPACESUIT_CELL_HIGH "high"
#define SPACESUIT_CELL_MID "mid"
#define SPACESUIT_CELL_LOW "low"
#define SPACESUIT_CELL_VERY_LOW "very_low"
+2 -2
View File
@@ -93,7 +93,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list(
var/atom/movable/screen/healths
var/atom/movable/screen/stamina
var/atom/movable/screen/healthdoll/healthdoll
var/atom/movable/screen/spacesuit
var/atom/movable/screen/spacesuit/spacesuit_hud
var/atom/movable/screen/hunger/hunger
/// Subtypes can override this to force a specific UI style
@@ -245,7 +245,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list(
healths = null
stamina = null
healthdoll = null
spacesuit = null
spacesuit_hud = null
hunger = null
alien_plasma_display = null
alien_queen_finder = null
+2 -2
View File
@@ -291,8 +291,8 @@
sleep_icon.icon = ui_style
sleep_icon.screen_loc = ui_above_throw
spacesuit = new /atom/movable/screen/spacesuit(null, src)
infodisplay += spacesuit
spacesuit_hud = new /atom/movable/screen/spacesuit(null, src)
infodisplay += spacesuit_hud
healths = new /atom/movable/screen/healths(null, src)
infodisplay += healths
+57
View File
@@ -407,6 +407,63 @@
name = "Space suit cell status"
icon_state = "spacesuit_0"
screen_loc = ui_spacesuit
mouse_over_pointer = MOUSE_HAND_POINTER
///The overlay added on top of the HUD when the thermal regulator is off.
var/static/mutable_appearance/off_overlay = mutable_appearance('icons/hud/screen_gen.dmi', "off")
///Boolean on whether a mouse is being hovered over us right now.
var/hovering = FALSE
///Boolean on whether or not the space suit's thermal mode is on. Start at TRUE so we auto-update when we are first equipped.
var/cached_thermal_on = TRUE
/atom/movable/screen/spacesuit/Click(location, control, params)
if(usr != get_mob())
return
. = ..()
var/mob/living/carbon/human/wearer = hud?.mymob
astype(wearer.wear_suit, /obj/item/clothing/suit/space)?.toggle_spacesuit(wearer, manual_toggle = TRUE)
/atom/movable/screen/spacesuit/MouseEntered(location,control,params)
if(usr != get_mob())
return
. = ..()
hovering = TRUE
var/mob/living/carbon/human/wearer = hud?.mymob
astype(wearer.wear_suit, /obj/item/clothing/suit/space)?.update_hud_icon(usr)
/atom/movable/screen/spacesuit/MouseExited(location, control, params)
if(usr != get_mob())
return
. = ..()
hovering = FALSE
var/mob/living/carbon/human/wearer = hud?.mymob
astype(wearer.wear_suit, /obj/item/clothing/suit/space)?.update_hud_icon(usr)
/atom/movable/screen/spacesuit/proc/update_spacesuit_hud_icon(cell_state, cell_percent, thermal_on = TRUE)
if(cell_state)
switch(cell_state)
if(SPACESUIT_NO_ICON)
icon_state = null
maptext = null
cached_thermal_on = TRUE //for next use
update_appearance(UPDATE_ICON)
return
if(SPACESUIT_CELL_MISSING, SPACESUIT_CELL_EMPTY)
icon_state = "spacesuit_[cell_state]"
maptext = null
else
icon_state = "spacesuit_[cell_state]"
if(cell_percent && hovering)
maptext = MAPTEXT("<div align='right'>[round(cell_percent, 0.1)]%</div>")
else
maptext = null
if(thermal_on != cached_thermal_on)
cached_thermal_on = thermal_on
update_appearance(UPDATE_ICON)
/atom/movable/screen/spacesuit/update_overlays()
. = ..()
if(!cached_thermal_on && icon_state)
. |= off_overlay
/atom/movable/screen/mov_intent
name = "run/walk toggle"
+29 -33
View File
@@ -116,21 +116,14 @@
if(slot & ITEM_SLOT_OCLOTHING) // Check that the slot is valid
START_PROCESSING(SSobj, src)
update_hud_icon(user) // update the hud
RegisterSignal(user, COMSIG_MOB_GET_STATUS_TAB_ITEMS, PROC_REF(get_status_tab_item))
// On removal stop processing, save battery
/obj/item/clothing/suit/space/dropped(mob/living/user)
. = ..()
STOP_PROCESSING(SSobj, src)
UnregisterSignal(user, COMSIG_MOB_GET_STATUS_TAB_ITEMS)
var/mob/living/carbon/carbon_user = user
if(istype(carbon_user))
carbon_user.update_spacesuit_hud_icon("0")
/obj/item/clothing/suit/space/proc/get_status_tab_item(mob/living/source, list/items)
SIGNAL_HANDLER
items += "Thermal Regulator: [thermal_on ? "On" : "Off"]"
items += "Cell Charge: [cell ? "[round(cell.percent(), 0.1)]%" : "No Cell!"]"
var/mob/living/carbon/human/human_user = user
if(istype(human_user) && human_user.hud_used)
human_user.hud_used.spacesuit_hud.update_spacesuit_hud_icon(SPACESUIT_NO_ICON)
// Space Suit temperature regulation and power usage
/obj/item/clothing/suit/space/process(seconds_per_tick)
@@ -165,8 +158,8 @@
if(isatom(cell))
QDEL_NULL(cell)
var/mob/living/carbon/human/human = src.loc
if(istype(human))
human.update_spacesuit_hud_icon("0")
if(istype(human) && human.hud_used)
human.hud_used.spacesuit_hud.update_spacesuit_hud_icon(SPACESUIT_NO_ICON)
STOP_PROCESSING(SSobj, src)
return ..()
@@ -226,6 +219,7 @@
if(user.transferItemToLoc(I, src))
cell = I
to_chat(user, span_notice("You successfully install \the [cell] into [src]."))
update_hud_icon(user)
return
/// Open the cell cover when ALT+Click on the suit
@@ -246,12 +240,14 @@
/// Remove the cell from the suit if the cell cover is open
/obj/item/clothing/suit/space/proc/remove_cell(mob/user)
if(cell_cover_open && cell)
user.visible_message(span_notice("[user] removes \the [cell] from [src]!"), \
span_notice("You remove [cell]."))
cell.add_fingerprint(user)
user.put_in_hands(cell)
cell = null
if(!cell_cover_open || isnull(cell))
return
user.visible_message(span_notice("[user] removes \the [cell] from [src]!"), \
span_notice("You remove [cell]."))
cell.add_fingerprint(user)
user.put_in_hands(cell)
cell = null
update_hud_icon(user)
/// Toggle the space suit's cell cover
/obj/item/clothing/suit/space/proc/toggle_spacesuit_cell(mob/user)
@@ -280,6 +276,8 @@
min_cold_protection_temperature = thermal_on ? SPACE_SUIT_MIN_TEMP_PROTECT : SPACE_SUIT_MIN_TEMP_PROTECT_OFF
update_item_action_buttons()
if(isnull(toggler) && ishuman(loc))
update_hud_icon(loc)
if(!toggler)
return
@@ -305,31 +303,29 @@
// update the HUD icon
/obj/item/clothing/suit/space/proc/update_hud_icon(mob/user)
var/mob/living/carbon/human/human = user
if(!show_hud)
if(!show_hud || human.wear_suit != src || isnull(human.hud_used))
return
if(!cell)
human.update_spacesuit_hud_icon("missing")
human.hud_used.spacesuit_hud.update_spacesuit_hud_icon(SPACESUIT_CELL_MISSING, 0, thermal_on)
return
var/cell_percent = cell.percent()
// Check if there's enough charge to trigger a thermal regulator tick and
// if there is, whethere the cell's capacity indicates high, medium or low
// charge based on it.
if(cell.charge >= THERMAL_REGULATOR_COST)
if(cell_percent > 60)
human.update_spacesuit_hud_icon("high")
return
if(cell_percent > 20)
human.update_spacesuit_hud_icon("mid")
return
human.update_spacesuit_hud_icon("low")
if(cell.charge < THERMAL_REGULATOR_COST)
human.hud_used.spacesuit_hud.update_spacesuit_hud_icon(SPACESUIT_CELL_EMPTY, cell_percent, thermal_on)
return
human.update_spacesuit_hud_icon("empty")
return
switch(cell_percent)
if(0 to 20)
human.hud_used.spacesuit_hud.update_spacesuit_hud_icon(SPACESUIT_CELL_VERY_LOW, cell_percent, thermal_on)
if(21 to 40)
human.hud_used.spacesuit_hud.update_spacesuit_hud_icon(SPACESUIT_CELL_LOW, cell_percent, thermal_on)
if(41 to 60)
human.hud_used.spacesuit_hud.update_spacesuit_hud_icon(SPACESUIT_CELL_MID, cell_percent, thermal_on)
if(61 to 100)
human.hud_used.spacesuit_hud.update_spacesuit_hud_icon(SPACESUIT_CELL_HIGH, cell_percent, thermal_on)
// zap the cell if we get hit with an emp
/obj/item/clothing/suit/space/emp_act(severity)
-3
View File
@@ -669,9 +669,6 @@
else
hud_used.healths.icon_state = "health6"
/mob/living/carbon/proc/update_spacesuit_hud_icon(cell_state = "empty")
hud_used?.spacesuit?.icon_state = "spacesuit_[cell_state]"
/mob/living/carbon/set_health(new_value)
. = ..()
if(. > hardcrit_threshold)
+4 -4
View File
@@ -524,7 +524,7 @@
module.on_unequip()
UnregisterSignal(wearer, list(COMSIG_ATOM_EXITED, COMSIG_SPECIES_GAIN, COMSIG_MOB_CLICKON))
SEND_SIGNAL(src, COMSIG_MOD_WEARER_UNSET, wearer)
wearer.update_spacesuit_hud_icon("0")
wearer.hud_used?.spacesuit_hud.update_spacesuit_hud_icon()
wearer = null
/obj/item/mod/control/proc/get_sealed_slots(list/parts)
@@ -715,17 +715,17 @@
* Updates the wearer's hud according to the current state of the MODsuit
*/
/obj/item/mod/control/proc/update_charge_alert()
if(isnull(wearer))
if(isnull(wearer) || isnull(wearer.client))
return
var/state_to_use
if(!active)
state_to_use = "0"
state_to_use = SPACESUIT_NO_ICON
else if(isnull(core))
state_to_use = "coreless"
else
state_to_use = core.get_charge_icon_state()
wearer.update_spacesuit_hud_icon(state_to_use || "0")
wearer.hud_used.spacesuit_hud.update_spacesuit_hud_icon(state_to_use || SPACESUIT_NO_ICON)
/obj/item/mod/control/proc/update_speed()
var/total_slowdown = 0
+19 -19
View File
@@ -52,7 +52,7 @@
/// Returns what icon state to display on the HUD for the charge level of this core
/obj/item/mod/core/proc/get_charge_icon_state()
return "0"
return SPACESUIT_NO_ICON
/// Gets what the UI should use for the charge bar color.
/obj/item/mod/core/proc/get_chargebar_color()
@@ -90,7 +90,7 @@
return TRUE
/obj/item/mod/core/infinite/get_charge_icon_state()
return "high"
return SPACESUIT_CELL_HIGH
/obj/item/mod/core/infinite/get_chargebar_color()
return "teal"
@@ -171,19 +171,19 @@
/obj/item/mod/core/standard/get_charge_icon_state()
if(isnull(charge_source()))
return "missing"
return SPACESUIT_CELL_MISSING
switch(round(charge_amount() / max_charge_amount(), 0.01))
if(0.75 to INFINITY)
return "high"
return SPACESUIT_CELL_HIGH
if(0.5 to 0.75)
return "mid"
return SPACESUIT_CELL_MID
if(0.25 to 0.5)
return "low"
return SPACESUIT_CELL_LOW
if(0.02 to 0.25)
return "very_low"
return SPACESUIT_CELL_VERY_LOW
return "empty"
return SPACESUIT_CELL_EMPTY
/obj/item/mod/core/standard/get_chargebar_color()
if(isnull(charge_source()))
@@ -335,7 +335,7 @@
return charge_amount() >= amount * charge_modifier
/obj/item/mod/core/ethereal/get_charge_icon_state()
return isnull(charge_source()) ? "missing" : "0"
return isnull(charge_source()) ? SPACESUIT_CELL_MISSING : SPACESUIT_NO_ICON
/obj/item/mod/core/ethereal/get_chargebar_color()
if(isnull(charge_source()))
@@ -405,15 +405,15 @@
/obj/item/mod/core/plasma/get_charge_icon_state()
switch(round(charge_amount() / max_charge_amount(), 0.01))
if(0.75 to INFINITY)
return "high"
return SPACESUIT_CELL_HIGH
if(0.5 to 0.75)
return "mid"
return SPACESUIT_CELL_MID
if(0.25 to 0.5)
return "low"
return SPACESUIT_CELL_LOW
if(0.02 to 0.25)
return "very_low"
return SPACESUIT_CELL_VERY_LOW
return "empty"
return SPACESUIT_CELL_EMPTY
/obj/item/mod/core/plasma/get_chargebar_color()
switch(round(charge_amount() / max_charge_amount(), 0.01))
@@ -648,15 +648,15 @@
/obj/item/mod/core/soul/get_charge_icon_state()
switch(round(charge_amount() / max_charge_amount(), 0.01))
if(0.75 to INFINITY)
return "high"
return SPACESUIT_CELL_HIGH
if(0.5 to 0.75)
return "mid"
return SPACESUIT_CELL_MID
if(0.25 to 0.5)
return "low"
return SPACESUIT_CELL_LOW
if(0.02 to 0.25)
return "very_low"
return SPACESUIT_CELL_VERY_LOW
return "empty"
return SPACESUIT_CELL_EMPTY
/obj/item/mod/core/soul/vv_edit_var(vname, vval)
. = ..()
Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 112 KiB