From aa536bba3ac19f5749af13a334852dde3a0e8363 Mon Sep 17 00:00:00 2001 From: Christer2222 <25958019+Christer2222@users.noreply.github.com> Date: Wed, 12 Nov 2025 08:22:39 +0100 Subject: [PATCH] Gives ghosts the ability to spook mirrors (#30817) * adds behavior * transparency test * transparency * mask and logic * comments * removed the chance for mirrors to break * linting * autodoc --- code/game/objects/structures/mirror.dm | 35 ++++++++++++++++++++++++- icons/obj/watercloset.dmi | Bin 15320 -> 15338 bytes 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index 1e01adef4b7..49ec8cd590f 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -10,7 +10,13 @@ var/list/ui_users = list() var/broken_icon_state = "mirror_broke" + /// what to show when a ghost Boo!'s this mirror + var/icon/spooked_icon + /// Whether a mirror can be Boo!'d or not. Magic mirrors are animated, so this is used to stop them from looking weird + var/can_be_spooked = TRUE + /obj/structure/mirror/organ + can_be_spooked = FALSE /obj/structure/mirror/Initialize(mapload, newdir = SOUTH, building = FALSE) . = ..() @@ -25,6 +31,7 @@ if(WEST) pixel_x = 32 GLOB.mirrors += src + spooked_icon = update_spooked_icon(icon("icons/mob/human.dmi", "husk_s"), SOUTH, 8, 0) /obj/structure/mirror/Destroy() QDEL_LIST_ASSOC_VAL(ui_users) @@ -86,6 +93,32 @@ if(BURN) playsound(src, 'sound/effects/hit_on_shattered_glass.ogg', 70, TRUE) +/obj/structure/mirror/get_spooked() + if(!can_be_spooked || broken) + return + flicker_ghost(spooked_icon) + return TRUE + +/// This proc sets the icon that will show up in the mirror when spooked +/// * icon_to_show - which icon +/// * offset_dir - you might want to move the icon so it appears in the mirror +/// * offset_pixels - how many pixels you need to move the icon +/// * wrap - if the icon should wrap around +/obj/structure/mirror/proc/update_spooked_icon(icon/icon_to_show, offset_dir, offset_pixels, wrap) + var/icon/our_icon = icon_to_show + our_icon.Shift(offset_dir,offset_pixels,wrap) + var/icon/alpha_mask = new("icons/obj/watercloset.dmi", "mirror_mask") + our_icon.AddAlphaMask(alpha_mask) + var/icon/added_icons = new("icons/obj/watercloset.dmi", "mirror") + added_icons.Blend(our_icon, ICON_OVERLAY) + return added_icons + +/// Shows the icon in the mirror with its mask +/obj/structure/mirror/proc/flicker_ghost(icon/icon_to_show) + icon = icon_to_show + sleep(rand(5,10)) + icon = initial(icon) + return /obj/item/mounted/mirror name = "mirror" @@ -105,6 +138,7 @@ var/options = list("Name", "Body", "Voice") var/organ_warn = FALSE var/actually_magical = TRUE + can_be_spooked = FALSE /obj/structure/mirror/magic/Initialize(mapload, newdir, building) . = ..() @@ -187,4 +221,3 @@ options = list("Body") organ_warn = TRUE actually_magical = FALSE - diff --git a/icons/obj/watercloset.dmi b/icons/obj/watercloset.dmi index 9564291cc8c127da1db3f3c20cd7eb67e0b47618..705ac57153073b7692e5f49261ad9f357ddbcbb2 100644 GIT binary patch delta 954 zcmV;r14aDUcj|YLBmoDJB_)65GEr3=+E+kXyAGY-u|y*|kRVv{O{z0X z{0ohf*49K~Z*H{8HP7h-OSG}-0TPbC1SfSaHm}RirvHMnnQjm*bjM-1i5cYxX`mM0S_Pn zlCwS`u@`@zK?pH4svt>{XmunAh75q=_~f;hW4^{U@uDSv{#WV7h)O6VRl2N_&*atm zhl0|>uv)%W^c`OLwXP8e^a#5g_{8oK0)$2;(NlgNb`85nEa=G(QGShGQLU7(r~FpS zXIpVMw;n_Lk%M?@+sk-r+si@w^|Q??&5$ohesq5gKveO`H9`{w$0v`z5bDV{qWo6M zH=_Jj%ID+pvA`VsakJzLQUhHB@XEeIWeiyznIxR@vwktV=9#y;@XEgEo1$9sS)V_m z@>?XI{Ws(B+0B&?&}M%7k%NjK;QhTH-H7sA zDc^s|`0%Wm-}vm)N{H@<*WIdg3xGfiEnfM8)Iiq>7%@J%j`CX>AKi%ZCv$vwAP|Uy zZ}PVvp?mT(A3>Q3@&&1Zt^rv8i{sKY7iN$fmX(KklnsO?V%I$K^G>{Xd?KbAP*Z+{ zn%{Ey2C+)Mx~6CTfcN))jN0n?icyGHz94@!(Cq@~#wRxtmyEl{)cEKImESV?QDB99 zJ_Pqu+g`@A+jrvXWsC9bb{boeZ=u91UyvGv^#O#$CpW14{544*pWSBpEClz%>u$xo zg;(JHy&o&ld6{uAL%tw22s;lTY<%(vwXtLI*^^j4Kiu+|z)cnT{6rsS1fJc#Q&Ilf>iNp_U^C?lk{4rf0r)1c z(SEqy@!3;AK0nsq+cZ{ch;RB*us-x`H|8yvx5-&WH4AlS&UTFz9(-Kj&Ofg-W0 zrlAeLSSN4TRIijjH-@BK@IS6>C0=*k!|7T;aVgmkguVA> zeRNdSx&OZ>$>cpD2_&;l0rejNhO~i1}yGsZV8ks~-`FYqi>>jb8CqG2_ zHFia{Qof$@TP>e$#ogR`4DCk_;;C&fg2kqC-Hmfv4z99M0H2_h?C)Wr~6dZq_ zJo-YYC*O$jTPfd&@>?mNkH^OXbMVK_k}pUNbPd2O`wEpYWOZbcaLUj6#q64A-s-|D z`=W1(YRPAP{)ozNk$m>wjK^m;S3W?S`RzvzDt>_X_kN6r*WDV@HHcTfAT`i60EXg| zhY3(%ReW?K%5SB7C*#AjW`5(dPb+^Rx*uM5tI{n10xh(7x`4MV<%jFxyD*5V~p7{gb-}^CYtLH05Azt}{)Ihfjpc|juNL+t1?iy3$ zqZ?Fy%j8Fa74rEI+)r(L8P9ItiK~|_#6>60dwgY7o{35E7rTtBV)^`dKbr~2#{Svy z9nbACO}-%cF%%boH7At_s9}GUpY=gwX*NfauNMI~Rpj#%eV7q=cKc36`D?4^E7OC` zlrKnLjKu}uo4`i<;daMoPXYP-SbuZtu^?j*GC|8s`GTY+sUk z`2|2s;n}cYZS{OKw;sd$dp|~*$?^rsi{Z#Xu8z;1Lh=WH9~vM2`{fb9;P3wv3*>ZI kAzzT3gmnh($07*qoM6N<$f@wbFwEzGB