diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm
index babb0b64d08..d3b3a10117d 100644
--- a/code/__DEFINES/dcs/signals.dm
+++ b/code/__DEFINES/dcs/signals.dm
@@ -833,6 +833,8 @@
#define COMSIG_SPECIES_GAIN "species_gain"
///from datum/species/on_species_loss(): (datum/species/lost_species)
#define COMSIG_SPECIES_LOSS "species_loss"
+///from /datum/species/proc/spec_hitby()
+#define COMSIG_SPECIES_HITBY "species_hitby"
// /datum/song signals
diff --git a/code/datums/spells/disguise_self.dm b/code/datums/spells/disguise_self.dm
index 4ebd86c5398..f9c5a26a532 100644
--- a/code/datums/spells/disguise_self.dm
+++ b/code/datums/spells/disguise_self.dm
@@ -1,13 +1,13 @@
/datum/spell/disguise_self
name = "Disguise Self"
- desc = "Disguise yourself as a crewmember, based on your current location. Also changes your voice. \
- The disguise will not hold up to being examined directly, and will break if you're damaged."
+ desc = "Disguise yourself as a crewmember, based on your current location. Also changes your voice. Takes two seconds to cast, must stand still. \
+ The illusion isn't strong enough for more thorough examinations, but will fool people at a glance. \
+ You will lose control over the illusion if you're attacked, shoved, or a object is thrown at you, no matter how soft."
school = "illusion"
- base_cooldown = 10 SECONDS
+ base_cooldown = 3 SECONDS
clothes_req = FALSE
- invocation = "Yutake Yutendes"
- invocation_type = "whisper"
+ invocation_type = "none"
level_max = 0 //cannot be improved
action_icon_state = "disguise_self"
sound = null
@@ -19,4 +19,19 @@
if(!ishuman(user))
return FALSE
var/mob/living/carbon/human/H = user
+
+ H.emote("spin")
+ to_chat(H, "You start spinning in place and casting [src]...")
+ if(do_after(H, 2 SECONDS, FALSE, H))
+ finish_disguise(H)
+ return TRUE
+ else
+ H.slip("your own foot", 1 SECONDS, 0, 0, 1, "trip")
+ to_chat(H, "You must stand still to cast [src]!")
+ return FALSE
+
+/datum/spell/disguise_self/proc/finish_disguise(mob/living/carbon/human/H)
H.apply_status_effect(STATUS_EFFECT_MAGIC_DISGUISE)
+ var/datum/effect_system/smoke_spread/smoke = new /datum/effect_system/smoke_spread
+ smoke.set_up(4, FALSE, H.loc)
+ smoke.start()
diff --git a/code/datums/status_effects/magic_disguise.dm b/code/datums/status_effects/magic_disguise.dm
index 4a0ed8dceea..f7bc83343b9 100644
--- a/code/datums/status_effects/magic_disguise.dm
+++ b/code/datums/status_effects/magic_disguise.dm
@@ -31,7 +31,7 @@
to_chat(owner, "Your spell fails to find a disguise!")
return FALSE
- RegisterSignal(owner, COMSIG_MOB_APPLY_DAMAGE, PROC_REF(remove_disguise))
+ RegisterSignal(owner, list(COMSIG_MOB_APPLY_DAMAGE, COMSIG_HUMAN_ATTACKED, COMSIG_SPECIES_HITBY), PROC_REF(remove_disguise))
return TRUE
/datum/status_effect/magic_disguise/on_remove()
@@ -78,7 +78,7 @@
to_chat(H, "You disguise yourself as [disguise.name].")
/datum/status_effect/magic_disguise/proc/remove_disguise()
- SIGNAL_HANDLER // COMSIG_MOB_APPLY_DAMAGE
+ SIGNAL_HANDLER // COMSIG_MOB_APPLY_DAMAGE + COMSIG_HUMAN_ATTACKED + COMSIG_SPECIES_HITBY
if(!ishuman(owner))
return
var/mob/living/carbon/human/H = owner
diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm
index b81dace99f1..731134e710b 100644
--- a/code/modules/mob/living/carbon/human/species/_species.dm
+++ b/code/modules/mob/living/carbon/human/species/_species.dm
@@ -1014,7 +1014,7 @@ It'll return null if the organ doesn't correspond, so include null checks when u
return TRUE
/datum/species/proc/spec_hitby(atom/movable/AM, mob/living/carbon/human/H)
- return
+ SEND_SIGNAL(H, COMSIG_SPECIES_HITBY, AM)
/datum/species/proc/spec_attacked_by(obj/item/I, mob/living/user, obj/item/organ/external/affecting, intent, mob/living/carbon/human/H)
return