From d4ac4824f853d2bbf06391ffcdd69ea0462a67bf Mon Sep 17 00:00:00 2001 From: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Date: Tue, 5 Aug 2025 08:57:00 +0530 Subject: [PATCH] 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 :cl: 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 /:cl: (cherry picked from commit c6dcc304ce649cffb3e20471d6dcaa164d279f8e) --- .../crates_lockers/closet_see_inside.dm | 96 +++++++++---------- .../structures/crates_lockers/closets.dm | 5 +- 2 files changed, 45 insertions(+), 56 deletions(-) diff --git a/code/game/objects/structures/crates_lockers/closet_see_inside.dm b/code/game/objects/structures/crates_lockers/closet_see_inside.dm index 7895d31d519..efd7b338e40 100644 --- a/code/game/objects/structures/crates_lockers/closet_see_inside.dm +++ b/code/game/objects/structures/crates_lockers/closet_see_inside.dm @@ -1,41 +1,34 @@ /// Responsible for showing the insides of a closet to those inside it. /datum/closet_see_inside - var/obj/structure/closet/closet - + ///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 - var/list/client/clients_looking_at_image = list() - - var/door_alpha = 85 - /datum/closet_see_inside/New(obj/structure/closet/closet) - src.closet = closet - - RegisterSignal(closet, COMSIG_ATOM_ENTERED, PROC_REF(on_atom_entered)) - RegisterSignal(closet, COMSIG_ATOM_EXITED, PROC_REF(on_atom_exited)) + 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) - if (contents_image) - for (var/client/looking_at_image as anything in clients_looking_at_image) - looking_at_image.images -= background_image - looking_at_image.images -= contents_image - - contents_image.vis_contents.Cut() - - clients_looking_at_image.Cut() - - + on_closet_pre_open(src) return ..() -/datum/closet_see_inside/proc/create_image() - contents_image = new - contents_image.loc = closet - contents_image.appearance_flags |= KEEP_TOGETHER +/** + * 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 = closet.base_icon_state == null ? initial(closet.icon_state) : closet.base_icon_state, + icon_state = isnull(closet.base_icon_state) ? initial(closet.icon_state) : closet.base_icon_state, loc = closet, layer = BELOW_OBJ_LAYER, ) @@ -43,6 +36,10 @@ 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, @@ -52,7 +49,6 @@ y = -3, ) ) - contents_image.add_filter( "color", 2, @@ -62,45 +58,39 @@ ) ) + //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 = door_alpha + 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_atom_entered(obj/structure/closet/source, atom/movable/arrived) +/datum/closet_see_inside/proc/on_closet_pre_open(obj/structure/closet/source, mob/user) SIGNAL_HANDLER - if (contents_image) - contents_image.vis_contents += arrived + 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() - if (ismob(arrived)) - var/mob/arrived_mob = arrived - var/client/client = GET_CLIENT(arrived_mob) - if (client) - create_image() - clients_looking_at_image += client - client.images += background_image - client.images += contents_image - -/datum/closet_see_inside/proc/on_atom_exited(obj/structure/closet/source, atom/movable/exited) +/datum/closet_see_inside/proc/on_closet_closed(obj/structure/closet/source, mob/user) SIGNAL_HANDLER - if (!contents_image) - return - - contents_image.vis_contents -= exited - - if (ismob(exited)) - var/mob/exited_mob = exited - var/client/client = GET_CLIENT(exited_mob) - if (client) - clients_looking_at_image -= client - client.images -= background_image - client.images -= contents_image + 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 diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index c511562d769..8a35511c6f4 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -100,9 +100,8 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) var/x_shake_pixel_shift = 2 /// how many pixels the closet can shift on the y axes when shaking var/y_shake_pixel_shift = 1 - - VAR_PRIVATE - datum/closet_see_inside/closet_see_inside + ///Creates see through image for clients to see while inside closet + VAR_PRIVATE/datum/closet_see_inside/closet_see_inside /datum/armor/structure_closet melee = 20