Files
SyncIt21 d4ac4824f8 Fixes closets not reusing images for clients (#92408)
## About The Pull Request
- Fixes #92214
- Fixes #92407

Whenever a mob with a client attached to it steps into a closet we
create 2 images(background & contents image) to display to that viewer

https://github.com/tgstation/tgstation/blob/4ee0793ecd23876994fa125e4e112a13a6f44455/code/game/objects/structures/crates_lockers/closet_see_inside.dm#L87

We are meant to reuse these images for multiple clients however this
proc does not check if we already made an image before. It just creates
a new one for every client(and we don't keep track of those previously
creates images) so we loose track of all sanity.

But now we make sure we make this image just once to reuse across
multiple clients

## Changelog
🆑
fix: You can no longer see parallel universes when 2 or more people gets
shoved into closets.
code: cleaned up closet see through code. It's documented & slightly
faster performance wise
/🆑

(cherry picked from commit c6dcc304ce)
2025-08-08 15:29:13 -04:00

97 lines
2.7 KiB
Plaintext

/// Responsible for showing the insides of a closet to those inside it.
/datum/closet_see_inside
///Closet grayed out image so players can click on it to get out of closet
var/image/background_image
///Stuff inside closet image
var/image/contents_image
/datum/closet_see_inside/New(obj/structure/closet/closet)
RegisterSignal(closet, COMSIG_CLOSET_PRE_OPEN, PROC_REF(on_closet_pre_open))
RegisterSignal(closet, COMSIG_CLOSET_POST_CLOSE, PROC_REF(on_closet_closed))
/datum/closet_see_inside/Destroy(force)
on_closet_pre_open(src)
return ..()
/**
* Creates the closet background & contents image to display for the client
*
* Arguments
* * obj/structure/closet/closet - the closet whose insides we are taking a snapshot of
*/
/datum/closet_see_inside/proc/create_image(obj/structure/closet/closet)
PRIVATE_PROC(TRUE)
if(contents_image)
return
///closet grayed out image
background_image = image(
icon = closet.icon,
icon_state = isnull(closet.base_icon_state) ? initial(closet.icon_state) : closet.base_icon_state,
loc = closet,
layer = BELOW_OBJ_LAYER,
)
background_image.color = COLOR_GRAY
background_image.opacity = MOUSE_OPACITY_TRANSPARENT
background_image.override = TRUE
//all stuff inside the closet image
contents_image = new
contents_image.loc = closet
contents_image.appearance_flags |= KEEP_TOGETHER
contents_image.add_filter(
"mask",
1,
list(
type = "alpha",
icon = icon('icons/effects/closet_see_inside_mask.dmi', "mask"),
y = -3,
)
)
contents_image.add_filter(
"color",
2,
list(
type = "color",
color = COLOR_GRAY,
)
)
//door & contents to add to image
if (closet.enable_door_overlay)
var/obj/effect/overlay/door = new
door.icon = closet.icon
door.icon_state = "[closet.icon_door || background_image.icon_state]_door"
door.alpha = 85
door.layer = ABOVE_ALL_MOB_LAYER
door.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
contents_image.vis_contents += door
for (var/atom/movable/movable in closet)
contents_image.vis_contents += movable
/datum/closet_see_inside/proc/on_closet_pre_open(obj/structure/closet/source, mob/user)
SIGNAL_HANDLER
if(contents_image)
for(var/atom/movable/movable in source)
if(ismob(movable))
var/client/client = GET_CLIENT(astype(movable, /mob))
if (client)
client.images -= background_image
client.images -= contents_image
contents_image.vis_contents.Cut()
/datum/closet_see_inside/proc/on_closet_closed(obj/structure/closet/source, mob/user)
SIGNAL_HANDLER
for(var/atom/movable/movable in source)
if(ismob(movable))
var/client/client = GET_CLIENT(astype(movable, /mob))
if (client)
create_image(source)
client.images += background_image
client.images += contents_image
if(contents_image)
contents_image.vis_contents += movable