From e150104d1300a5f296aa86a010455f507dc4d381 Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Sun, 13 Aug 2023 21:45:54 +0100 Subject: [PATCH] [no gbp] Dump consumed mobs when shapeshift effect ends (#77574) ## About The Pull Request Fixes #77536 When you stop being shapeshifted we delete the mob you were previously transformed into, which obviously also deletes everything in its contents. If that mob can eat other mobs it deletes those mobs too. We have an element "content barfer" which resolves this, I have made it register to the "unshapeshift" signal to trigger dumping the contents too, and added it to some mobs which were missing it. ## Why It's Good For The Game Players were surprised by consuming player corpses after transforming into a gelatinous cube and thus permanently deleting them. ## Changelog :cl: fix: If you shapeshift into a mob which can eat things such as player corpses, those things will fall out when you stop shapeshifting /:cl: --- code/datums/elements/content_barfer.dm | 4 +-- .../hostile/mining_mobs/hivelord.dm | 26 ++++++++++++------- .../mob/living/simple_animal/hostile/ooze.dm | 18 ++++++------- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/code/datums/elements/content_barfer.dm b/code/datums/elements/content_barfer.dm index 782574a2221..e683db3782a 100644 --- a/code/datums/elements/content_barfer.dm +++ b/code/datums/elements/content_barfer.dm @@ -12,10 +12,10 @@ if(!isliving(target)) return ELEMENT_INCOMPATIBLE - RegisterSignals(target, list(COMSIG_LIVING_DEATH, COMSIG_LIVING_ON_WABBAJACKED), PROC_REF(barf_contents)) + RegisterSignals(target, list(COMSIG_LIVING_DEATH, COMSIG_LIVING_ON_WABBAJACKED, COMSIG_LIVING_UNSHAPESHIFTED), PROC_REF(barf_contents)) /datum/element/content_barfer/Detach(datum/target) - UnregisterSignal(target, list(COMSIG_LIVING_DEATH, COMSIG_LIVING_ON_WABBAJACKED)) + UnregisterSignal(target, list(COMSIG_LIVING_DEATH, COMSIG_LIVING_ON_WABBAJACKED, COMSIG_LIVING_UNSHAPESHIFTED)) return ..() /datum/element/content_barfer/proc/barf_contents(mob/living/target) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm index 696f06809c5..ee80422de12 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm @@ -128,6 +128,10 @@ var/dwarf_mob = FALSE var/mob/living/carbon/human/stored_mob +/mob/living/simple_animal/hostile/asteroid/hivelord/legion/Initialize(mapload) + . = ..() + AddElement(/datum/element/content_barfer) + /mob/living/simple_animal/hostile/asteroid/hivelord/legion/random/Initialize(mapload) . = ..() if(prob(5)) @@ -149,18 +153,20 @@ /mob/living/simple_animal/hostile/asteroid/hivelord/legion/death(gibbed) visible_message(span_warning("The skulls on [src] wail in anger as they flee from their dying host!")) - var/turf/T = get_turf(src) - if(T) - if(stored_mob) - stored_mob.forceMove(get_turf(src)) - stored_mob = null - else if(from_spawner) - new /obj/effect/mob_spawn/corpse/human/charredskeleton(T) + if (!isnull(stored_mob)) + stored_mob = null + return ..() + + // We didn't contain a real body so spawn a random one + var/turf/our_turf = get_turf(src) + if(our_turf) + if(from_spawner) + new /obj/effect/mob_spawn/corpse/human/charredskeleton(our_turf) else if(dwarf_mob) - new /obj/effect/mob_spawn/corpse/human/legioninfested/dwarf(T) + new /obj/effect/mob_spawn/corpse/human/legioninfested/dwarf(our_turf) else - new /obj/effect/mob_spawn/corpse/human/legioninfested(T) - ..(gibbed) + new /obj/effect/mob_spawn/corpse/human/legioninfested(our_turf) + return ..() /mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril from_spawner = TRUE diff --git a/code/modules/mob/living/simple_animal/hostile/ooze.dm b/code/modules/mob/living/simple_animal/hostile/ooze.dm index 07451be6b12..d6098a692c9 100644 --- a/code/modules/mob/living/simple_animal/hostile/ooze.dm +++ b/code/modules/mob/living/simple_animal/hostile/ooze.dm @@ -39,6 +39,7 @@ create_reagents(300) add_cell_sample() ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) + AddElement(/datum/element/content_barfer) /mob/living/simple_animal/hostile/ooze/attacked_by(obj/item/I, mob/living/user) if(!eat_atom(I, TRUE)) @@ -202,12 +203,7 @@ ///Register for owner death /datum/action/consume/New(Target) . = ..() - RegisterSignal(owner, COMSIG_LIVING_DEATH, PROC_REF(on_owner_death)) - RegisterSignal(owner, COMSIG_QDELETING, PROC_REF(handle_mob_deletion)) - -/datum/action/consume/proc/handle_mob_deletion() - SIGNAL_HANDLER - stop_consuming() //Shit out the vored mob before u go go + RegisterSignal(owner, COMSIG_LIVING_DEATH, PROC_REF(stop_consuming)) ///Try to consume the pulled mob /datum/action/consume/Trigger(trigger_flags) @@ -235,14 +231,17 @@ /datum/action/consume/proc/start_consuming(mob/living/target) vored_mob = target vored_mob.forceMove(owner) ///AAAAAAAAAAAAAAAAAAAAAAHHH!!! - RegisterSignal(vored_mob, COMSIG_QDELETING, PROC_REF(handle_mob_deletion)) + RegisterSignal(vored_mob, COMSIG_QDELETING, PROC_REF(stop_consuming)) playsound(owner,'sound/items/eatfood.ogg', rand(30,50), TRUE) owner.visible_message(span_warning("[src] devours [target]!"), span_notice("You devour [target].")) START_PROCESSING(SSprocessing, src) ///Stop consuming the mob; dump them on the floor /datum/action/consume/proc/stop_consuming() + SIGNAL_HANDLER STOP_PROCESSING(SSprocessing, src) + if (isnull(vored_mob)) + return vored_mob.forceMove(get_turf(owner)) playsound(get_turf(owner), 'sound/effects/splat.ogg', 50, TRUE) owner.visible_message(span_warning("[owner] pukes out [vored_mob]!"), span_notice("You puke out [vored_mob].")) @@ -260,10 +259,9 @@ if(vored_mob.getBruteLoss() >= 200) stop_consuming() -///On owner death dump the current vored mob -/datum/action/consume/proc/on_owner_death() - SIGNAL_HANDLER +/datum/action/consume/Remove(mob/remove_from) stop_consuming() + return ..() ///* Gelatinious Grapes code below *\\\\