From 853f108c89aa005e2ed1a391a54ed8fd0cb40736 Mon Sep 17 00:00:00 2001 From: Contrabang <91113370+Contrabang@users.noreply.github.com> Date: Mon, 22 Apr 2024 20:50:48 -0400 Subject: [PATCH] [SERIOUS] Improves admin tooling for radiation (#24968) * lets clean some radiation * changes * lgtm --- code/__DEFINES/dcs/signals.dm | 3 + code/controllers/subsystem/SSradiation.dm | 2 + code/datums/components/radioactive.dm | 27 ++++++--- code/defines/procs/admin_keyname_procs.dm | 4 ++ code/modules/admin/verbs/debug.dm | 21 +++++++ code/modules/admin/verbs/toggledebugverbs.dm | 1 + .../buildmode/submodes/antirad_mode.dm | 55 ++++++++++++++++++ icons/misc/buildmode.dmi | Bin 1823 -> 1907 bytes paradise.dme | 1 + 9 files changed, 107 insertions(+), 7 deletions(-) create mode 100644 code/modules/buildmode/submodes/antirad_mode.dm diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 585f6c5365f..f10dc5d3334 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -1058,3 +1058,6 @@ // Sent when a mob spawner is attacked directly or via projectile. #define COMSIG_SPAWNER_SET_TARGET "spawner_set_target" + +/// Used by admin-tooling to remove radiation +#define COMSIG_ADMIN_DECONTAMINATE "admin_decontaminate" diff --git a/code/controllers/subsystem/SSradiation.dm b/code/controllers/subsystem/SSradiation.dm index 540e56ce19a..c30f40a1363 100644 --- a/code/controllers/subsystem/SSradiation.dm +++ b/code/controllers/subsystem/SSradiation.dm @@ -13,6 +13,8 @@ PROCESSING_SUBSYSTEM_DEF(radiation) var/rad_cache_update_interval = 5 SECONDS var/list/turf_rad_cache = list() var/list/prev_rad_cache = list() + /// Lazy list of all radioactive components + var/list/all_radiations /datum/controller/subsystem/processing/radiation/proc/warn(datum/component/radioactive/contamination) diff --git a/code/datums/components/radioactive.dm b/code/datums/components/radioactive.dm index 97d0591c4eb..ba240898e34 100644 --- a/code/datums/components/radioactive.dm +++ b/code/datums/components/radioactive.dm @@ -13,17 +13,17 @@ var/can_contaminate /datum/component/radioactive/Initialize(_strength = 0, _source, _half_life = RAD_HALF_LIFE, _can_contaminate = TRUE) + if(!istype(parent, /atom)) + return COMPONENT_INCOMPATIBLE strength = _strength source = _source hl3_release_date = _half_life can_contaminate = _can_contaminate - if(istype(parent, /atom)) - RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(rad_examine)) - if(isitem(parent)) - RegisterSignal(parent, COMSIG_ITEM_ATTACK, PROC_REF(rad_attack)) - RegisterSignal(parent, COMSIG_ITEM_ATTACK_OBJ, PROC_REF(rad_attack)) - else - return COMPONENT_INCOMPATIBLE + RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(rad_examine)) + RegisterSignal(parent, COMSIG_ADMIN_DECONTAMINATE, PROC_REF(admin_decontaminate)) + if(isitem(parent)) + RegisterSignal(parent, COMSIG_ITEM_ATTACK, PROC_REF(rad_attack)) + RegisterSignal(parent, COMSIG_ITEM_ATTACK_OBJ, PROC_REF(rad_attack)) if(strength > RAD_MINIMUM_CONTAMINATION) SSradiation.warn(src) //Let's make er glow @@ -31,10 +31,12 @@ var/atom/movable/master = parent master.add_filter("rad_glow", 2, list("type" = "outline", "color" = "#39ff1430", "size" = 2)) addtimer(CALLBACK(src, PROC_REF(glow_loop), master), rand(1, 19)) //Things should look uneven + LAZYADD(SSradiation.all_radiations, src) START_PROCESSING(SSradiation, src) /datum/component/radioactive/Destroy() STOP_PROCESSING(SSradiation, src) + LAZYREMOVE(SSradiation.all_radiations, src) var/atom/movable/master = parent master.remove_filter("rad_glow") return ..() @@ -99,6 +101,17 @@ return strength -= strength / hl3_release_date +/datum/component/radioactive/proc/admin_decontaminate() + SIGNAL_HANDLER + . = TRUE + if(ismob(parent)) + var/mob/M = parent + M.radiation = 0 + if(ismob(source)) + var/mob/M = source + M.radiation = 0 + qdel(src) + #undef RAD_AMOUNT_LOW #undef RAD_AMOUNT_MEDIUM #undef RAD_AMOUNT_HIGH diff --git a/code/defines/procs/admin_keyname_procs.dm b/code/defines/procs/admin_keyname_procs.dm index 255b89dd7f8..166540f7b13 100644 --- a/code/defines/procs/admin_keyname_procs.dm +++ b/code/defines/procs/admin_keyname_procs.dm @@ -90,3 +90,7 @@ /proc/log_and_message_admins(message) log_admin("[key_name(usr)] " + message) message_admins("[key_name_admin(usr)] " + message) + +/proc/log_and_message_admins_no_usr(message) + log_admin(message) + message_admins(message) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 6e3753a705c..47529556d96 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -989,3 +989,24 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) vis.set_content(ui_dat.Join("")) vis.open(FALSE) + +/client/proc/cmd_clean_radiation() + set name = "Remove All Radiation" + set desc = "Remove all radiation in the world." + set category = "Debug" + + if(!check_rights(R_DEBUG)) + return + + if(alert(src, "Are you sure you want to remove all radiation in the world? This may lag the server. Alternatively, use the radiation cleaning buildmode.", "Lag warning", "Yes, I'm sure", "No, I want to live") != "Yes, I'm sure") + return + + log_and_message_admins("is decontaminating the world of all radiation. (This may be laggy!)") + + var/counter = 0 + for(var/datum/component/radioactive/rad as anything in SSradiation.all_radiations) + rad.admin_decontaminate() + counter++ + CHECK_TICK + + log_and_message_admins_no_usr("The world has been decontaminated of [counter] radiation components.") diff --git a/code/modules/admin/verbs/toggledebugverbs.dm b/code/modules/admin/verbs/toggledebugverbs.dm index 74d8358640c..120a69b924b 100644 --- a/code/modules/admin/verbs/toggledebugverbs.dm +++ b/code/modules/admin/verbs/toggledebugverbs.dm @@ -16,6 +16,7 @@ GLOBAL_LIST_INIT(admin_verbs_show_debug_verbs, list( /client/proc/forceEvent, /client/proc/admin_redo_space_transitions, /client/proc/make_turf_space_map, + /client/proc/cmd_clean_radiation, )) // Would be nice to make this a permanent admin pref so we don't need to click it each time diff --git a/code/modules/buildmode/submodes/antirad_mode.dm b/code/modules/buildmode/submodes/antirad_mode.dm new file mode 100644 index 00000000000..1ddd9964bb0 --- /dev/null +++ b/code/modules/buildmode/submodes/antirad_mode.dm @@ -0,0 +1,55 @@ +/datum/buildmode_mode/clean_radiation + key = "rad" + +/datum/buildmode_mode/clean_radiation/show_help(mob/user) + var/list/messages = list( + "***********************************************************", + "Left Mouse Button on obj/turf/mob = Remove radiation of selected target.", + "Ctrl-Left Mouse Button on screen = Remove all radiation in your sight.", + "Right Mouse Button on obj/turf/mob = Deep clean: Remove radiation of all recursive contents of turf.", + "Ctrl-Right Mouse Button on screen = Deep clean: Remove radiation of all recursive contents in your sight.", + "***********************************************************" + ) + to_chat(user, messages.Join("
")) + +/datum/buildmode_mode/clean_radiation/handle_click(mob/user, params, atom/target) + var/list/pa = params2list(params) + var/deep_clean = pa.Find("right") + var/clean_screen = pa.Find("ctrl") + + if(!clean_screen) + if(!deep_clean) + if(SEND_SIGNAL(target, COMSIG_ADMIN_DECONTAMINATE)) + to_chat(user, "Decontaminated [target].") + log_admin("Build Mode: [key_name(user)] decontaminated radiation at ([target.x],[target.y],[target.z])") + return + + var/counter = 0 + var/turf/T = get_turf(target) + counter += SEND_SIGNAL(T, COMSIG_ADMIN_DECONTAMINATE) + for(var/atom/movable/cleanable in T) + counter += SEND_SIGNAL(cleanable, COMSIG_ADMIN_DECONTAMINATE) + CHECK_TICK + + if(isliving(cleanable)) + var/mob/living/L = cleanable + for(var/atom/movable/cleanable2 in L.get_contents()) + counter += SEND_SIGNAL(cleanable2, COMSIG_ADMIN_DECONTAMINATE) + CHECK_TICK + to_chat(user, "Decontaminated [counter] atom\s.") + log_admin("Build Mode: [key_name(user)] deep-clean decontaminated radiation at ([target.x],[target.y],[target.z])") + return + + var/counter = 0 + for(var/turf/T in range(user.client.view, user)) + counter += SEND_SIGNAL(T, COMSIG_ADMIN_DECONTAMINATE) + for(var/atom/movable/cleanable in T) + counter += SEND_SIGNAL(cleanable, COMSIG_ADMIN_DECONTAMINATE) + CHECK_TICK + if(deep_clean && isliving(cleanable)) + var/mob/living/L = cleanable + for(var/atom/movable/cleanable2 in L.get_contents()) + counter += SEND_SIGNAL(cleanable2, COMSIG_ADMIN_DECONTAMINATE) + CHECK_TICK + to_chat(user, "Decontaminated [counter] atom\s.") + log_admin("Build Mode: [key_name(user)] [deep_clean ? "deep-clean " : ""]decontaminated their screen of radiation at ([target.x],[target.y],[target.z])") diff --git a/icons/misc/buildmode.dmi b/icons/misc/buildmode.dmi index 0520a9ef005cfae042b0dfbd9ba686e3b57795b3..663d4546caf3283ae775209cd1b29df950182a85 100644 GIT binary patch literal 1907 zcmV-(2aNcMP) zCLii?CdI{r!)E>h*@LY9QL7HhvBq;G8~Yt<(3Wkau*_wfMFxTLK}ygS6glcaV${@{ ztWy|`=jR}$gYt?+zdG-af!E8qeD$+vI`jx#Rs4}$$l3(lQgKVbGiH~72dFS5Zgd<{ zva-+7agv9J))zTeyVLgbv)^nKDEfWfmp}jj1`tU^K~!jg?V3xHhJIB z<@H-~yr0&~>n$(%dOxj~*H5cBet$o$m)9?UZTs=hpYMv+w*7vlHGpNkyndEf{Nr8G z0PXiv4Q5>xkah%{IB*0d?MGC7Kh>IrMLkNO%n1TMcU30{d<@12bU5EmA}~RzIRrYM zZ>JEbD9tP`)5D;|ZiKhI-zC^J4_0;$$TG1u&YB=m7GL3nyq3J5_ z#2~o?&Undth{owz{S~a^Z1X$azCZmRe%1$9>x1a$$MiAtYni>|ett+7GPjobOYY}K zbUcCvUc2~-<_v|_K+eJwNIyTK4+M@buD;Gw82WZUWrD=d59lL-3y_ALz&RrK#}R1% zOiuj#fIbjVcnE=gQXufpgW5qG>h;Ev&;=VjX~;$Qw@9V-^loPn1VJb_4-Ou-RmtZyM>motw=Ld9;05Ak%7NvfEK$i%rdddC# zh%OLR^^*Jf5#5f#fgttsLpmG-UCE_f(e(707<|?TJ@Y%=zMuU-uVBgF|A6(umsEc< z`v;fxXxFi!RrIdmd4X-bJ(Dv(f1$$#L4g%s)%&C+_wyHsAk+`x^Q_HIkhtLs{h@#W zqMq2;4l+UF=dZ+s5wJ=~>Irk1!1-nXGTi>2g9i}LaBc>BS7A=Zz!?9DVioFr6ip;1 zNc=qAQ}@bw0)J0&f?0Qt^QNBAy+{ZMfePv1qqOg5m-B#FRD1^GX#Ejp2@wcF=i^`% z1l%wWRpwz-DzIP9H(qb6b`_u2H`n-9JSEdj7$W&+?FTqP*PNbD4<(3_|3 zJo_T;?x5a%&yj%cIy%lUYtXi7Im=|FPg5xDFL0%gc2XIr#NaSuE&ycjB5@sN-7nxP zeQoKU+AWzy_1=X00N^J?ufmEN&E^C+Aj92;(ax?R_bhuAqRLbUf(^~E`v*pMTOlI| z&M$b`0s-K-F0Q7W#NrO9jNt6*d0d<9=F@r4>@*L~jyTf{KnUWACiCDX0fhP?#?W8j z#C~!^2LMD6c|m(?_5Fhr`tMl7{TsWG1n`WjC~Ni=pY_3v`rx#E&wuc={s!xVFCCqo z|5+albz9KaS^DeZ^Pr`v`>yCAt1k6}ip~(oysEw9rO8t0`u;$su^?*fH(T;q*6zO{ z1)#v7yBsA5&a_(buoaX9dOJe^TS5T#NI<4T%NPKR#~>pxmGf0=Prny~O%PbR<6w*D zKamH(&b$16$b;=p9@q{6r9jI~_hZr~pa~@E0fMocu8!CZ)=ea=DEutqnO`Moz;3?(-<(C5J$h^{!c4{@D-h62L11vRl}5c+_DtY+rMd+92yz0_ zfa#tQY=Z>(2x!E#K#7=uQu{0es!Gjef-(^nZdbeStr6_A3RHbR`6dD9g&tpR&l23y z{|8s`Ss(Pw?{xd#J>l-rMZA51UXX5Ipy%&zU!a$Xw=dAk#QOyN3k1~rEv<$R5b&=| z#J=g{1pF%#y1ZZf1Oa+W^hU+*`%?t6^ZOBFK#$ycv*?fqid+voMv#n{I=h=U5z`1( zZ$+mOP{H$o2+(-aP7@?Cfafw<8Q-p$l?S{O*`j-Xg24D&4l~!HuRs73V?Yy#HYdN* tTJ$i%hj$e{e}DS|)2-ud^E=zV{|Ava6)_@kq^tk{002ovPDHLkV1jZ?q_zM6 literal 1823 zcmV+)2jKXLP)005u_0{{R3dEt5<0000XP)t-s1u_!` zArAvp9R)iU3tc4uP#FM77iP==1u_!_C=LZO6J4Slw*UYD0d!JMQvg8b*k%9#0N;94 zSad{Xb7OL8aCB*JZU6vyoSl=w3c@fDM9;}r1igz@4_>^8MS8HmAZfFj#iU!4*y7(? z^&p5XrnenCY^PKp~E zHQ`L5^POIEc5>3f^G?1fOA3wwP59u+0ItE*eIzqPbzejwJ(i=KQZ=$FL5(tl!ro?s z#-JUwqnuXOXQ=+0^LiWkyprnse-ZBu9mt_6eppUuOayMQx)|xlRl6;e$#Lk78DL6T2&h%fMPJb<1)^DYkZ@yEo<74@9O3C{aPKryzlDe_33w;k3WBVM-5)<_W4Ewq8GiqeyHE!*LT#2TDQ+@jc#2H zvJQl{I_Mp3dB?2V=d}hAp7b7}aVH4n+|?Wq#u&~KLOS0+MCg(-&k#a6-#gdORCi-&k$>$8!qGgG)ybVCJeY@a_~!`a_0JHNn1X$Tkk&zYy<49l zOo&je*d|V_ON47&Z(Lllxr)hZFvO?d;Ts@|O#s!tdSeH{}j-1qdqU`3ubOOM;R z4}bWSKP>)kPIsAuNiVIxo6;MZk}_>+{oRaiR~uRiFzTiCcQd*p4D=gxcSYbx+7oG9nXde>c`!qfAHM1!#Xap%LkqCuc=m2(`Z(YZ`4M zrLHC{G1UHUtVw|keKqRUC~JQ=*4u>DJkxx{~v|@*X27p}Ic!h5C@#?a% z+Ju_s_&1m+UZER(o-kD0@GlTStRY&TC&WY)Ye=KN03m`8RhkT1ta?tzu+d{e=i)0O zAzd8kCysKXEk8m}TNQae@P~7P*NLAXJg5nW1k7qmO(B|iq+J3NuDR+BV#LvevQP04 za0x3DO4RKxVJKlJ21^K00<=rmXNsl5MnCZ#AxOw|xF_VOg>*{00Ddu4nL<&ZX_rPV zJVfJgCx-ne;tN!}0M9>=cTV6rCW$DH^8Q{gya4GHB~t<a()QV8o&KC`-Py00??Q~vM{(dQui>Z{&| zKfG<{Mkk!rpTQsg-01(JKQyJcm8uxscDkG?pJGG9Qst|9S+NfjH2Db6e69ZoS#RS(gi3sn)Pcl3gY*%`3H zqN%lXicoifW1ofxy2KE1K8Avb-j@4x5bu9pt|=6uwIY-osu%0BwfcJvknh#Tc}Y{y zo|%Udv;2-G-K&jvYsHuyxvvdEn>*!9i0O!<&YOblz8Kb*dAdcYx*l%L7fka|JJ{qW z4+w)DExGFlgx*F!xlc$#j5&8rPly!ck~x~t(aj2;teG%%j#95n6Skw;60$~0r`-F( zHKt4I?JL4|RGEkqyoxCr<8lmT4g%(w=y^EG6d@)fp8AI}2iLNi=y^EG6d83i`TI7Q z`h&$&#|zHovdl|>^nIHINQhN8j=#%rDVP5!J=VW+6%)WG{h`#o4}W;YAKtcew=d8h zw?ATc!PXC+^oRWg@A|>+f_MF3cfq?mr=GA|Jw}?h*4%rt*9fU0L9HW`S7^s2#OxAM zL-XMKHlF)9-j}N9dHItXvPGCWS386lTS