From 4f2588e6bc146eedcfa556365dfbd354b1fffcb6 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Fri, 1 Jan 2021 22:17:15 +0100 Subject: [PATCH] [MIRROR] Refactor on_mob_death, death implants, implant permission (#2432) * Refactor on_mob_death, death implants, implant permission (#55862) * Refactor on_mob_death and death implants There is a proc on `/obj/item` called `on_mob_death` called on all items in the contents of a mob on that mob's death. It is currently used for explosive implant detonation, and the deactivation of the Peaceborg's projectile dampener. Instead of using this old proc, both of them now instad use the COMSIG_LIVING_DEATH signal, already emitted when their owner dies. The activation of an explosive implant will now occur after the rest of the death code has run, since it activates with an async applied function, since some other implants may still want the mob's body intact, and you shouldn't use `sleep()` (which it does in the "slow explosion mode") in signal handlers. In addition, the "can_be_implanted" proc for /mob/living (and overriden for silicons, slimes and simple animals) has been folded into the `/obj/item/implant/proc/can_be_implanted_to` proc. Some future implants may want to be more permissive than the current permissions, but that isn't possible when checking both procs. * Refactor on_mob_death, death implants, implant permission Co-authored-by: coiax --- code/game/objects/items.dm | 2 -- code/game/objects/items/implants/implant.dm | 29 +++++++++---------- .../items/implants/implant_explosive.dm | 16 +++++++--- code/game/objects/items/robot/robot_items.dm | 10 ++++--- code/modules/mob/living/death.dm | 2 -- .../mob/living/simple_animal/slime/slime.dm | 3 -- 6 files changed, 31 insertions(+), 31 deletions(-) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 74834242e05..e3bb252f26b 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -781,8 +781,6 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb if(istype(M) && M.dirty < 100) M.dirty++ -/obj/item/proc/on_mob_death(mob/living/L, gibbed) - /obj/item/proc/grind_requirements(obj/machinery/reagentgrinder/R) //Used to check for extra requirements for grinding an object return TRUE diff --git a/code/game/objects/items/implants/implant.dm b/code/game/objects/items/implants/implant.dm index fd79c112c9b..51c72ad9627 100644 --- a/code/game/objects/items/implants/implant.dm +++ b/code/game/objects/items/implants/implant.dm @@ -14,29 +14,26 @@ /obj/item/implant/proc/trigger(emote, mob/living/carbon/source) return -/obj/item/implant/proc/on_death(emote, mob/living/carbon/source) - return - /obj/item/implant/proc/activate() SEND_SIGNAL(src, COMSIG_IMPLANT_ACTIVATED) /obj/item/implant/ui_action_click() activate("action_button") -/obj/item/implant/proc/can_be_implanted_in(mob/living/target) // for human-only and other special requirements +/obj/item/implant/proc/can_be_implanted_in(mob/living/target) + if(issilicon(target)) + return FALSE + + if(isslime(target)) + return TRUE + + if(isanimal(target)) + var/mob/living/simple_animal/animal = target + // Robots and most non-organics aren't healable. + return animal.healable + return TRUE -/mob/living/proc/can_be_implanted() - return TRUE - -/mob/living/silicon/can_be_implanted() - return FALSE - -/mob/living/simple_animal/can_be_implanted() - return healable //Applies to robots and most non-organics, exceptions can override. - - - //What does the implant do upon injection? //return 1 if the implant injects //return 0 if there is no room for implant / it fails @@ -44,7 +41,7 @@ if(SEND_SIGNAL(src, COMSIG_IMPLANT_IMPLANTING, args) & COMPONENT_STOP_IMPLANTING) return LAZYINITLIST(target.implants) - if(!force && (!target.can_be_implanted() || !can_be_implanted_in(target))) + if(!force && !can_be_implanted_in(target)) return FALSE for(var/X in target.implants) var/obj/item/implant/imp_e = X diff --git a/code/game/objects/items/implants/implant_explosive.dm b/code/game/objects/items/implants/implant_explosive.dm index 3cbdc39f2df..f505dd338d3 100644 --- a/code/game/objects/items/implants/implant_explosive.dm +++ b/code/game/objects/items/implants/implant_explosive.dm @@ -11,8 +11,14 @@ var/popup = FALSE // is the DOUWANNABLOWUP window open? var/active = FALSE -/obj/item/implant/explosive/on_mob_death(mob/living/L, gibbed) - activate("death") +/obj/item/implant/explosive/proc/on_death(datum/source, gibbed) + SIGNAL_HANDLER + + // There may be other signals that want to handle mob's death + // and the process of activating destroys the body, so let the other + // signal handlers at least finish. Also, the "delayed explosion" + // uses sleeps, which is bad for signal handlers to do. + INVOKE_ASYNC(src, .proc/activate, "death") /obj/item/implant/explosive/get_data() var/dat = {"Implant Specifications:
@@ -61,9 +67,11 @@ imp_e.weak += weak imp_e.delay += delay qdel(src) - return 1 + return TRUE - return ..() + . = ..() + if(.) + RegisterSignal(target, COMSIG_LIVING_DEATH, .proc/on_death) /obj/item/implant/explosive/proc/timed_explosion() imp_in.visible_message("[imp_in] starts beeping ominously!") diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index ec4899f4228..ded4639456e 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -610,6 +610,12 @@ icon_state = "shield0" START_PROCESSING(SSfastprocess, src) host = loc + RegisterSignal(host, COMSIG_LIVING_DEATH, .proc/on_death) + +/obj/item/borg/projectile_dampen/proc/on_death(datum/source, gibbed) + SIGNAL_HANDLER + + deactivate_field() /obj/item/borg/projectile_dampen/Destroy() STOP_PROCESSING(SSfastprocess, src) @@ -673,10 +679,6 @@ deactivate_field() . = ..() -/obj/item/borg/projectile_dampen/on_mob_death() - deactivate_field() - . = ..() - /obj/item/borg/projectile_dampen/process(delta_time) process_recharge(delta_time) process_usage(delta_time) diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index 38b278f7891..fecc3c4e771 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -74,8 +74,6 @@ timeofdeath = world.time tod = station_time_timestamp() var/turf/T = get_turf(src) - for(var/obj/item/I in contents) - I.on_mob_death(src, gibbed) if(mind && mind.name && mind.active && !istype(T.loc, /area/ctf)) deadchat_broadcast(" has died at [get_area_name(T)].", "[mind.name]", follow_target = src, turf_target = T, message_type=DEADCHAT_DEATHRATTLE) if(mind) diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm index e344a7bf8de..bf4bca663f9 100644 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -500,9 +500,6 @@ if(..()) return 3 -/mob/living/simple_animal/slime/can_be_implanted() - return TRUE - /mob/living/simple_animal/slime/random/Initialize(mapload, new_colour, new_is_adult) . = ..(mapload, pick(slime_colours), prob(50))