Refactor atom HUDs to track source of HUD gain/loss. (#32091)

* Refactor atom HUDs to track source of HUD gain/loss.

* Retain shared images from different huds on removal.

* Fix some ghost HUD toggles.

* Add HUD sources to more hud add/remove calls.

* Apply suggestions from CRUNCH review.

Co-authored-by: CRUNCH <143041327+CRUNCH-Borg@users.noreply.github.com>
Signed-off-by: Alan <alfalfascout@users.noreply.github.com>

* Check if a user has a hud before removing it, autodoc.

---------

Signed-off-by: Alan <alfalfascout@users.noreply.github.com>
Co-authored-by: CRUNCH <143041327+CRUNCH-Borg@users.noreply.github.com>
This commit is contained in:
Alan
2026-08-28 23:44:05 +00:00
committed by GitHub
co-authored by CRUNCH
parent e5e3b2c16a
commit 635e4b170e
24 changed files with 98 additions and 87 deletions
+2 -2
View File
@@ -98,13 +98,13 @@
if(zeroth_law_borg)
laws.set_zeroth_law(zeroth_law_borg.law)
var/datum/atom_hud/data/human/malf_ai/H = GLOB.huds[DATA_HUD_MALF_AI]
H.add_hud_to(src)
H.add_hud_to(src, "zeroth law")
else if(zeroth_law)
laws.set_zeroth_law(zeroth_law.law)
else
laws.clear_zeroth_laws()
var/datum/atom_hud/data/human/malf_ai/H = GLOB.huds[DATA_HUD_MALF_AI]
H.remove_hud_from(src)
H.remove_hud_from(src, "zeroth law")
/mob/living/silicon/ai/sync_zeroth(datum/ai_law/zeroth_law, datum/ai_law/zeroth_law_borg)
if(zeroth_law)
+32 -16
View File
@@ -36,9 +36,12 @@ GLOBAL_LIST_INIT(huds, alist(
))
/datum/atom_hud
var/list/atom/hudatoms = list() //list of all atoms which display this hud
var/list/mob/hudusers = list() //list with all mobs who can see the hud
var/list/hud_icons = list() //these will be the indexes for the atom's hud_list
/// All the atoms that display this hud.
var/list/atom/hudatoms = list()
/// All the mobs who can see this hud, and their sources. each_mob = list(source/1, source/2).
var/list/mob/hudusers = list()
/// Indexes for the atom's hud_list.
var/list/hud_icons = list()
/// Do we ignore the invisibility check? Used by anom huds so we can see our stuff.
var/ignore_invisibility_check = FALSE
@@ -54,43 +57,57 @@ GLOBAL_LIST_INIT(huds, alist(
GLOB.all_huds -= src
return ..()
/datum/atom_hud/proc/remove_hud_from(mob/M)
/// Removes `source` from mob's hud sources, and if mob has no hud sources, removes their ability to see this hud
/datum/atom_hud/proc/remove_hud_from(mob/M, atom/source)
if(!M)
return
if(src in M.permanent_huds)
return
for(var/atom/A in hudatoms)
remove_from_single_hud(M, A)
hudusers -= M
if(hudusers[M])
hudusers[M] -= source
if(hudusers[M] && length(hudusers[M]))
return
for(var/atom/A in hudatoms)
remove_hud_images(M, A)
hudusers -= M
M.reload_huds()
/// Removes a single item from being displayed on this hud, for example, removes one mess from janihud.
/datum/atom_hud/proc/remove_from_hud(atom/A)
if(!A)
return
for(var/mob/M in hudusers)
remove_from_single_hud(M, A)
remove_hud_images(M, A)
hudatoms -= A
/datum/atom_hud/proc/remove_from_single_hud(mob/M, atom/A) //unsafe, no sanity apart from client
/// Removes all of the hud pictures that `A` produces from mob `M`'s view.
/datum/atom_hud/proc/remove_hud_images(mob/M, atom/A) // Unsafe, no sanity apart from client.
if(!M || !M.client || !A)
return
for(var/i in hud_icons)
M.client.images -= A.hud_list[i]
/datum/atom_hud/proc/add_hud_to(mob/M)
/// Adds `source` to mob's sources of this hud, and shows them all the pictures on the hud
/datum/atom_hud/proc/add_hud_to(mob/M, atom/source)
if(!M)
return
hudusers |= M
if(!(M in hudusers))
hudusers[M] = list()
hudusers[M] |= source
for(var/atom/A in hudatoms)
add_to_single_hud(M, A)
add_hud_images(M, A)
/// Adds single atom `A` to the list of pictures this hud will display. Shows them to mobs with this hud.
/datum/atom_hud/proc/add_to_hud(atom/A)
if(!A)
return
hudatoms |= A
for(var/mob/M in hudusers)
add_to_single_hud(M, A)
add_hud_images(M, A)
/datum/atom_hud/proc/add_to_single_hud(mob/M, atom/A) //unsafe, no sanity apart from client
/// Adds all hud images that `A` produces to player `M`'s view.
/datum/atom_hud/proc/add_hud_images(mob/M, atom/A) // Unsafe, no sanity apart from client.
if(!M || !M.client || !A)
return
if((A.invisibility > M.see_invisible) && !ignore_invisibility_check) // yee yee ass snowflake check for our yee yee ass snowflake huds
@@ -111,10 +128,9 @@ GLOBAL_LIST_INIT(huds, alist(
for(var/datum/mindslaves/serv in (SSticker.mode.vampires | SSticker.mode.traitors))
serv_huds += serv.thrallhud
for(var/datum/atom_hud/hud in (GLOB.all_huds|serv_huds))//|gang_huds))
if(src in hud.hudusers)
hud.add_hud_to(src)
hud.add_hud_to(src, hud.hudusers[src][1])
/mob/new_player/reload_huds()
return
+2 -2
View File
@@ -337,7 +337,7 @@
//Makes the user passive, it's in their oath not to harm!
ADD_TRAIT(owner, TRAIT_PACIFISM, "hippocraticOath")
var/datum/atom_hud/H = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
H.add_hud_to(owner)
H.add_hud_to(owner, src)
owner.permanent_huds |= H
return ..()
@@ -345,7 +345,7 @@
REMOVE_TRAIT(owner, TRAIT_PACIFISM, "hippocraticOath")
var/datum/atom_hud/H = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
owner.permanent_huds ^= H
H.remove_hud_from(owner)
H.remove_hud_from(owner, src)
/datum/status_effect/hippocratic_oath/tick()
// Death transforms you into a snake after a short grace period