diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm index 51211f5ad6d..04cc044429e 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm @@ -220,5 +220,8 @@ /// from mob/proc/dropItemToGround() #define COMSIG_MOB_DROPPING_ITEM "mob_dropping_item" +/// from /mob/proc/change_mob_type() : () +#define COMSIG_PRE_MOB_CHANGED_TYPE "mob_changed_type" + #define COMPONENT_BLOCK_MOB_CHANGE (1<<0) /// from /mob/proc/change_mob_type_unchecked() : () #define COMSIG_MOB_CHANGED_TYPE "mob_changed_type" diff --git a/code/modules/mob/mob_transformation_simple.dm b/code/modules/mob/mob_transformation_simple.dm index fe901b3ad9e..6d2a8a9850d 100644 --- a/code/modules/mob/mob_transformation_simple.dm +++ b/code/modules/mob/mob_transformation_simple.dm @@ -22,6 +22,9 @@ to_chat(usr, span_danger("Cannot convert into a new_player mob type.")) return + if (SEND_SIGNAL(src, COMSIG_PRE_MOB_CHANGED_TYPE) & COMPONENT_BLOCK_MOB_CHANGE) + return + return change_mob_type_unchecked(new_type, location, new_name, delete_old_mob) /// Version of [change_mob_type] that does no usr prompting (may send an error message though). Satisfies procs with the SHOULD_NOT_SLEEP restriction @@ -32,7 +35,7 @@ else desired_mob = new new_type(src.loc) - if(!desired_mob || !ismob(desired_mob)) + if(!ismob(desired_mob)) to_chat(usr, "Type path is not a mob (new_type = [new_type]) in change_mob_type(). Contact a coder.") qdel(desired_mob) return diff --git a/code/modules/spells/spell_types/shapeshift/_shape_status.dm b/code/modules/spells/spell_types/shapeshift/_shape_status.dm index ba8269108a8..faa84835255 100644 --- a/code/modules/spells/spell_types/shapeshift/_shape_status.dm +++ b/code/modules/spells/spell_types/shapeshift/_shape_status.dm @@ -35,7 +35,8 @@ ADD_TRAIT(caster_mob, TRAIT_NO_TRANSFORM, REF(src)) caster_mob.apply_status_effect(/datum/status_effect/grouped/stasis, STASIS_SHAPECHANGE_EFFECT) - RegisterSignal(owner, COMSIG_LIVING_PRE_WABBAJACKED, PROC_REF(on_wabbajacked)) + RegisterSignal(owner, COMSIG_LIVING_PRE_WABBAJACKED, PROC_REF(on_pre_wabbajack)) + RegisterSignal(owner, COMSIG_PRE_MOB_CHANGED_TYPE, PROC_REF(on_pre_type_change)) RegisterSignal(owner, COMSIG_LIVING_DEATH, PROC_REF(on_shape_death)) RegisterSignal(caster_mob, COMSIG_LIVING_DEATH, PROC_REF(on_caster_death)) RegisterSignal(caster_mob, COMSIG_QDELETING, PROC_REF(on_caster_deleted)) @@ -53,15 +54,24 @@ // but juuust in case make sure nothing sticks around. caster_mob = null -/// Signal proc for [COMSIG_LIVING_PRE_WABBAJACKED] to prevent us from being Wabbajacked and messed up. -/datum/status_effect/shapechange_mob/proc/on_wabbajacked(mob/living/source, randomized) +/// Called when we're shot by the Wabbajack but before we change into a different mob +/datum/status_effect/shapechange_mob/proc/on_pre_wabbajack(mob/living/source) SIGNAL_HANDLER + on_mob_transformed(source) + return STOP_WABBAJACK + +/// Called when we're turned into a different mob via the change_mob_type proc +/datum/status_effect/shapechange_mob/proc/on_pre_type_change(mob/living/source) + SIGNAL_HANDLER + on_mob_transformed(source) + return COMPONENT_BLOCK_MOB_CHANGE +/// Called when the transformed mob tries to change into a different kind of mob, we wouldn't handle this well so we'll just turn back +/datum/status_effect/shapechange_mob/proc/on_mob_transformed(mob/living/source) var/mob/living/revealed_mob = caster_mob source.visible_message(span_warning("[revealed_mob] gets pulled back to their normal form!")) restore_caster() revealed_mob.Paralyze(10 SECONDS, ignore_canstun = TRUE) - return STOP_WABBAJACK /// Restores the caster back to their human form. /// if kill_caster_after is TRUE, the caster will have death() called on them after restoring.