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 0520a9ef005..663d4546caf 100644 Binary files a/icons/misc/buildmode.dmi and b/icons/misc/buildmode.dmi differ diff --git a/paradise.dme b/paradise.dme index 912489efe04..bdac76b5105 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1598,6 +1598,7 @@ #include "code\modules\buildmode\buildmode_hud.dm" #include "code\modules\buildmode\effects\line.dm" #include "code\modules\buildmode\submodes\advanced.dm" +#include "code\modules\buildmode\submodes\antirad_mode.dm" #include "code\modules\buildmode\submodes\area_edit.dm" #include "code\modules\buildmode\submodes\atmos.dm" #include "code\modules\buildmode\submodes\basic.dm"