Disjointed eyes such as AI eyes, advanced camera consoles, & looking up properly show HUDs (#95526)

## About The Pull Request

Revival of #92846, without which I would have no idea how to do this

Adds a new proc within `/datum/atom_hud` that changes what Z level huds
an atom is seeing without changing what Z level that atom's own hud
exists on, and hooks it into the new `COMSIG_LIVING_LOOK_Z_CHANGE`, sent
by `/mob/living/on_look_z_level_change()`, which is called when a mob
looks up, stops looking up(not when it looks down, it doesn't need to),
or by any z level change done by an `/eye/` that's just the window for
an actual mob(camera consoles, AI eye).

## Why It's Good For The Game

fixes #92370
fixes #92622
fixes the same HUD issue with looking up a floor as any other mob

## Changelog
🆑

fix: HUDs are now visible when looking up a floor, as well as by AIS and
camera consoles on lower floors.

/🆑

---------

Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
This commit is contained in:
Leland Kemble
2026-04-03 15:16:17 +01:00
committed by GitHub
co-authored by Ghom
parent 9b8d29a976
commit 0f95e041e2
5 changed files with 34 additions and 0 deletions
@@ -384,3 +384,6 @@
/// Sent to a mob when its player DNRs
#define COMSIG_LIVING_DNR "living_dnr"
/// From /mob/living/on_looking_z_level_change() : (turf/old_turf, turf/new_turf)
#define COMSIG_LIVING_LOOK_Z_CHANGE "living_look_z_change"
+20
View File
@@ -163,6 +163,7 @@ GLOBAL_LIST_INIT(trait_blockers_to_hud, list(
RegisterSignal(new_viewer, COMSIG_QDELETING, PROC_REF(unregister_atom), override = TRUE) //both hud users and hud atoms use these signals
RegisterSignal(new_viewer, COMSIG_MOVABLE_Z_CHANGED, PROC_REF(on_atom_or_user_z_level_changed), override = TRUE)
RegisterSignal(new_viewer, COMSIG_LIVING_LOOK_Z_CHANGE, PROC_REF(on_look_z_level_changed), override = TRUE)
var/turf/their_turf = get_turf(new_viewer)
if(!their_turf)
@@ -194,6 +195,7 @@ GLOBAL_LIST_INIT(trait_blockers_to_hud, list(
if(!hud_atoms_all_z_levels[former_viewer])//make sure we aren't unregistering changes on a mob that's also a hud atom for this hud
UnregisterSignal(former_viewer, COMSIG_MOVABLE_Z_CHANGED)
UnregisterSignal(former_viewer, COMSIG_QDELETING)
UnregisterSignal(former_viewer, COMSIG_LIVING_LOOK_Z_CHANGE)
hud_users_all_z_levels -= former_viewer
@@ -323,6 +325,24 @@ GLOBAL_LIST_INIT(trait_blockers_to_hud, list(
add_atom_to_all_mob_huds(get_hud_users_for_z_level(new_turf.z), moved_atom)
/// The same operations of on_atom_or_user_z_level_changed(), but without changing the mover's hud.
/// (change the huds the user sees on other people, not the hud other people see on the user)
/// Used for mobs that see through a separate eye mob, and looking up/down.
/datum/atom_hud/proc/on_look_z_level_changed(atom/movable/user, turf/old_turf, turf/new_turf)
SIGNAL_HANDLER
// handle removing hud images from the old z-level
if (old_turf && hud_users_all_z_levels[user]) // old_turf can be null if we tried to look through the ceiling or through the floor
hud_users[old_turf.z] -= user
remove_all_atoms_from_single_hud(user, get_hud_atoms_for_z_level(old_turf.z))
// handle adding hud images from the new z-level
if (hud_users_all_z_levels[user])
hud_users[new_turf.z][user] = TRUE
add_all_atoms_to_single_mob_hud(user, get_hud_atoms_for_z_level(new_turf.z))
/// add just hud_atom's hud images (that are part of this atom_hud) to requesting_mob's client.images list
/datum/atom_hud/proc/add_atom_to_single_mob_hud(mob/requesting_mob, atom/hud_atom) //unsafe, no sanity apart from client
if(!requesting_mob || !requesting_mob.client || !hud_atom)
+4
View File
@@ -158,3 +158,7 @@
/mob/eye/camera/remote/proc/allow_z_transition(datum/space_level/from, datum/space_level/into)
return from == into
/mob/eye/camera/remote/on_changed_z_level(turf/old_turf, turf/new_turf, same_z_layer, notify_contents)
. = ..()
astype(user_ref?.resolve(), /mob/living)?.on_looking_z_level_change(old_turf, new_turf)
+6
View File
@@ -2333,8 +2333,13 @@ GLOBAL_LIST_EMPTY(fire_appearances)
/mob/living/proc/end_look()
reset_perspective()
looking_vertically = NONE
if(!looking_holder)
return
on_looking_z_level_change(looking_holder.loc, get_turf(src))
QDEL_NULL(looking_holder)
/mob/living/proc/on_looking_z_level_change(turf/old_loc, turf/new_loc)
SEND_SIGNAL(src, COMSIG_LIVING_LOOK_Z_CHANGE, old_loc, new_loc)
/**
* look_up Changes the perspective of the mob to any openspace turf above the mob
@@ -2357,6 +2362,7 @@ GLOBAL_LIST_EMPTY(fire_appearances)
looking_vertically = UP
looking_holder = new(above_turf, src, UP)
reset_perspective(looking_holder)
on_looking_z_level_change(get_turf(src), above_turf)
/mob/living/proc/get_looking_turf(direction)
//down needs to check this floor
@@ -127,6 +127,7 @@
if(same_z_layer)
return
update_ai_detect_hud()
ai?.on_looking_z_level_change(old_turf, new_turf)
/*----------------------------------------------------*/