From f71f5c32da5506d6f747c4bfd9cd6bea1622d7a8 Mon Sep 17 00:00:00 2001 From: Mothblocks <35135081+Mothblocks@users.noreply.github.com> Date: Sat, 12 Jul 2025 13:15:24 -0700 Subject: [PATCH] You can see inside closets and interact with yourself and others inside them (#92029) ## About The Pull Request https://github.com/user-attachments/assets/65a03f4a-0e44-4bce-b603-a019d5a3a36e I want you to be able to pick up items and stuff in here but it seemed annoying so I'm letting Melbert figure that out Closes #92006 I didn't make it work with client log ins and log outs and all that such and such fyi ## Why It's Good For The Game Doesn't really make sense that you can't heal yourself in closets when you're still able to use items and such in there. You're in the closet. ## Changelog :cl: add: You can now see inside closets you're in, and interact with yourself inside. /:cl: --- .../crates_lockers/closet_see_inside.dm | 106 ++++++++++++++++++ .../structures/crates_lockers/closets.dm | 7 +- icons/effects/closet_see_inside_mask.dmi | Bin 0 -> 1399 bytes tgstation.dme | 1 + 4 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 code/game/objects/structures/crates_lockers/closet_see_inside.dm create mode 100644 icons/effects/closet_see_inside_mask.dmi diff --git a/code/game/objects/structures/crates_lockers/closet_see_inside.dm b/code/game/objects/structures/crates_lockers/closet_see_inside.dm new file mode 100644 index 00000000000..7895d31d519 --- /dev/null +++ b/code/game/objects/structures/crates_lockers/closet_see_inside.dm @@ -0,0 +1,106 @@ +/// Responsible for showing the insides of a closet to those inside it. +/datum/closet_see_inside + var/obj/structure/closet/closet + + var/image/background_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)) + +/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() + + + return ..() + +/datum/closet_see_inside/proc/create_image() + contents_image = new + contents_image.loc = closet + contents_image.appearance_flags |= KEEP_TOGETHER + + background_image = image( + icon = closet.icon, + icon_state = closet.base_icon_state == null ? 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 + + 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, + ) + ) + + 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.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) + SIGNAL_HANDLER + + if (contents_image) + contents_image.vis_contents += arrived + + 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) + 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 diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index d80fd500987..0ac1518a69d 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -101,6 +101,9 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) /// 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 + /datum/armor/structure_closet melee = 20 bullet = 10 @@ -153,6 +156,8 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) if(is_station_level(z) && mapload) add_to_roundstart_list() + closet_see_inside = new(src) + // if closed, any item at the crate's loc is put in the contents if (mapload) is_maploaded = TRUE @@ -203,6 +208,7 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) id_card = null QDEL_NULL(internal_air) QDEL_NULL(door_obj) + QDEL_NULL(closet_see_inside) GLOB.roundstart_station_closets -= src return ..() @@ -978,7 +984,6 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) return container_resist_act(user) - /obj/structure/closet/attack_hand(mob/living/user, list/modifiers) . = ..() if(.) diff --git a/icons/effects/closet_see_inside_mask.dmi b/icons/effects/closet_see_inside_mask.dmi new file mode 100644 index 0000000000000000000000000000000000000000..70d22d84d22e2771bf5bbdfc1b7d28148536ba7b GIT binary patch literal 1399 zcmV--1&I2IP)V=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex6#a*QpwI5Sc+ z(=$pSoZ^zil2jm5DL1h=TZxM^C9|j)$Tj5ROe;#vO@*+P61DIO`Z{+Gzm6YaN?L)>>#;H+&gpC zjD#TikvZp{k!HH9zNzl6UMe=m)$8^2Z^e~CRVc&resNdVbqjT&+(@NTv4^hg5l~UK z=9+fRxtgwLt|ixsYZY3-vu7wXhdMR-OFp#ps*VEM-``iDDc7v4;aY&>P#cQhErFQ< zP~8Tj+7Fl8?uGq>gM;zF1gL`dbvPkVKrCB%lokQFfbz3L;PQ}#uQI@4O-ZOJe0>Yf z*Ihrjwq37XZ(Z+Pd#<0LJv@7hGTW&00ybK(IRzi39c};&ZLd%bL}AUf<@(XJ>v|7> zJ^X%$=eziwzTZXNE!bLw?Hn%ccR5%I)V$p_&v&ku`1)PZ8#vpBL)A9ky^->aVAxuR z?fGGFI!e+=wefY)3_CFT8V?VA);In4Z-?AiHF@l;fxDI2l@P!*z z^p7Yri!Wt6HRb!$uo6*WhCnKDDn6gkHn0i8CrO z?+j$`F)x8rxrZ-xMKI}$KI`I>IkE3k^H?VLw4+bDDS6jHp?9nLT1Z!f-1kCSH{5}cb0Ap6x zbg^iIBU79Fzg#`&#)@b~q&_BK{fLFrbojQQh7}u$NsY_^yL5G2e*x%&fJGF~11w$J z6HeFd{cH@wPlaQ&VoP`K`p52~6;Ow+KU|*yd{vd5P`dHp8fym6b-nahI6_6=ifBbt zKDmxuzXC1>Ks4={>pH+VO44PDZozb4_*giFijk;IcnGkMc=pxq2E{ESMn@Vs0!>*l z189!Zdc%NtzqKMgL=#4{eE<}jF^^W%Q7}45j{umB?`>L#04fkiAUpeKKm^P$&=I25 zLAh>j49ja>FGaeDRVz0Wp;&D)@p37YZe$6>vx{puW2B;AMYH`31>kQ0K0{Qyakimg z!}gP#0E~OAIAi_9RKkfqKbHX14V+v6>cj?9!y)b*iKi$ZAJfahhQR4EIDoi2ivKz@ z=pMi%Qs;2U?0yW8BLE&Fik%cHZ^{vHJRZ