diff --git a/code/datums/components/squeak.dm b/code/datums/components/squeak.dm
index 2bb7cc66f0d..546e29b14e9 100644
--- a/code/datums/components/squeak.dm
+++ b/code/datums/components/squeak.dm
@@ -25,7 +25,7 @@
return COMPONENT_INCOMPATIBLE
RegisterSignal(parent, list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_BLOB_ACT, COMSIG_ATOM_HULK_ATTACK, COMSIG_PARENT_ATTACKBY), .proc/play_squeak)
if(ismovable(parent))
- RegisterSignal(parent, list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_IMPACT), .proc/play_squeak)
+ RegisterSignal(parent, list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_IMPACT, COMSIG_PROJECTILE_BEFORE_FIRE), .proc/play_squeak)
RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/play_squeak_crossed)
RegisterSignal(parent, COMSIG_ITEM_WEARERCROSSED, .proc/play_squeak_crossed)
RegisterSignal(parent, COMSIG_MOVABLE_DISPOSING, .proc/disposing_react)
@@ -80,16 +80,8 @@
var/obj/item/I = AM
if(I.item_flags & ABSTRACT)
return
- else if(istype(AM, /obj/projectile))
- var/obj/projectile/P = AM
- if(P.original != parent)
- return
- if(istype(AM, /obj/effect/dummy/phased_mob)) //don't squeek if they're in a phased/jaunting container.
+ if(AM.movement_type & (FLYING|FLOATING) || !AM.has_gravity())
return
- if(ismob(AM))
- var/mob/M = AM
- if(M.movement_type & (FLYING|FLOATING))
- return
var/atom/current_parent = parent
if(isturf(current_parent.loc))
play_squeak()
diff --git a/code/game/objects/effects/phased_mob.dm b/code/game/objects/effects/phased_mob.dm
new file mode 100644
index 00000000000..6e6d6e86d7c
--- /dev/null
+++ b/code/game/objects/effects/phased_mob.dm
@@ -0,0 +1,48 @@
+/obj/effect/dummy/phased_mob
+ name = "water"
+ anchored = TRUE
+ flags_1 = PREVENT_CONTENTS_EXPLOSION_1
+ resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
+ invisibility = INVISIBILITY_OBSERVER
+ movement_type = FLOATING
+ var/movedelay = 0
+ var/movespeed = 0
+
+/obj/effect/dummy/phased_mob/spell_jaunt/Destroy()
+ // Eject contents if deleted somehow
+ for(var/a in contents)
+ var/atom/movable/AM = a
+ AM.forceMove(drop_location())
+ return ..()
+
+/obj/effect/dummy/phased_mob/ex_act()
+ return
+
+/obj/effect/dummy/phased_mob/bullet_act(blah)
+ return BULLET_ACT_FORCE_PIERCE
+
+/obj/effect/dummy/phased_mob/relaymove(mob/living/user, direction)
+ var/turf/newloc = phased_check(user, direction)
+ if(!newloc)
+ return
+ setDir(direction)
+ forceMove(newloc)
+
+/// Checks if the conditions are valid to be able to phase. Returns a turf destination if positive.
+/obj/effect/dummy/phased_mob/proc/phased_check(mob/living/user, direction)
+ RETURN_TYPE(/turf)
+ if (movedelay > world.time || !direction)
+ return
+ var/turf/newloc = get_step(src,direction)
+ if(!newloc)
+ return
+ movedelay = world.time + movespeed
+ if(newloc.flags_1 & NOJAUNT_1)
+ to_chat(user, "Some strange aura is blocking the way.")
+ return
+ return newloc
+
+/// React to signals by deleting the effect. Used for bloodcrawl.
+/obj/effect/dummy/phased_mob/proc/deleteself(mob/living/source, obj/effect/decal/cleanable/phase_in_decal)
+ SIGNAL_HANDLER
+ qdel(src)
diff --git a/code/modules/antagonists/_common/antag_spawner.dm b/code/modules/antagonists/_common/antag_spawner.dm
index c9aef9d3775..35773f418e8 100644
--- a/code/modules/antagonists/_common/antag_spawner.dm
+++ b/code/modules/antagonists/_common/antag_spawner.dm
@@ -247,7 +247,7 @@
/obj/item/antag_spawner/slaughter_demon/spawn_antag(client/C, turf/T, kind = "", datum/mind/user)
- var/obj/effect/dummy/phased_mob/slaughter/holder = new /obj/effect/dummy/phased_mob/slaughter(T)
+ var/obj/effect/dummy/phased_mob/holder = new /obj/effect/dummy/phased_mob(T)
var/mob/living/simple_animal/hostile/imp/slaughter/S = new demon_type(holder)
S.key = C.key
S.mind.assigned_role = S.name
diff --git a/code/modules/antagonists/slaughter/slaughter.dm b/code/modules/antagonists/slaughter/slaughter.dm
index a666f21b9b6..9159983e54b 100644
--- a/code/modules/antagonists/slaughter/slaughter.dm
+++ b/code/modules/antagonists/slaughter/slaughter.dm
@@ -99,15 +99,15 @@
/// How much our wound_bonus hitstreak bonus caps at (peak demonry)
var/wound_bonus_hitstreak_max = 12
-/mob/living/simple_animal/hostile/imp/slaughter/Initialize(mapload, obj/effect/dummy/phased_mob/slaughter/bloodpool)//Bloodpool is the blood pool we spawn in
+/mob/living/simple_animal/hostile/imp/slaughter/Initialize(mapload, obj/effect/dummy/phased_mob/bloodpool)//Bloodpool is the blood pool we spawn in
..()
ADD_TRAIT(src, TRAIT_BLOODCRAWL_EAT, "innate")
var/obj/effect/proc_holder/spell/bloodcrawl/bloodspell = new
AddSpell(bloodspell)
- if(istype(loc, /obj/effect/dummy/phased_mob/slaughter))
+ if(istype(loc, /obj/effect/dummy/phased_mob))
bloodspell.phased = TRUE
if(bloodpool)
- bloodpool.RegisterSignal(src, list(COMSIG_LIVING_AFTERPHASEIN,COMSIG_PARENT_QDELETING), /obj/effect/dummy/phased_mob/slaughter/.proc/deleteself)
+ bloodpool.RegisterSignal(src, list(COMSIG_LIVING_AFTERPHASEIN,COMSIG_PARENT_QDELETING), /obj/effect/dummy/phased_mob/.proc/deleteself)
/mob/living/simple_animal/hostile/imp/slaughter/CtrlShiftClickOn(atom/A)
if(!isliving(A))
diff --git a/code/modules/antagonists/slaughter/slaughterevent.dm b/code/modules/antagonists/slaughter/slaughterevent.dm
index 8015b9d6a71..64963abf343 100644
--- a/code/modules/antagonists/slaughter/slaughterevent.dm
+++ b/code/modules/antagonists/slaughter/slaughterevent.dm
@@ -31,7 +31,7 @@
message_admins("No valid spawn locations found, aborting...")
return MAP_ERROR
- var/obj/effect/dummy/phased_mob/slaughter/holder = new /obj/effect/dummy/phased_mob/slaughter((pick(spawn_locs)))
+ var/obj/effect/dummy/phased_mob/holder = new /obj/effect/dummy/phased_mob((pick(spawn_locs)))
var/mob/living/simple_animal/hostile/imp/slaughter/S = new (holder)
player_mind.transfer_to(S)
player_mind.assigned_role = "Slaughter Demon"
diff --git a/code/modules/mob/living/bloodcrawl.dm b/code/modules/mob/living/bloodcrawl.dm
index f7451edba28..8a5bf292c23 100644
--- a/code/modules/mob/living/bloodcrawl.dm
+++ b/code/modules/mob/living/bloodcrawl.dm
@@ -1,30 +1,3 @@
-/obj/effect/dummy/phased_mob/slaughter //Can't use the wizard one, blocked by jaunt/slow
- name = "water"
- icon = 'icons/effects/effects.dmi'
- icon_state = "nothing"
- density = FALSE
- anchored = TRUE
- invisibility = 60
- resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
- var/canmove = TRUE
-
-/obj/effect/dummy/phased_mob/slaughter/relaymove(mob/living/user, direction)
- forceMove(get_step(src,direction))
-
-/obj/effect/dummy/phased_mob/slaughter/ex_act()
- return
-
-/obj/effect/dummy/phased_mob/slaughter/bullet_act()
- return BULLET_ACT_FORCE_PIERCE
-
-/obj/effect/dummy/phased_mob/slaughter/singularity_act()
- return
-
-/obj/effect/dummy/phased_mob/slaughter/proc/deleteself(mob/living/source, obj/effect/decal/cleanable/phase_in_decal)
- SIGNAL_HANDLER
- qdel(src)
-
-
/mob/living/proc/phaseout(obj/effect/decal/cleanable/B)
if(iscarbon(src))
var/mob/living/carbon/C = src
@@ -54,7 +27,7 @@
playsound(get_turf(src), 'sound/magic/enter_blood.ogg', 50, TRUE, -1)
// Extinguish, unbuckle, stop being pulled, set our location into the
// dummy object
- var/obj/effect/dummy/phased_mob/slaughter/holder = new /obj/effect/dummy/phased_mob/slaughter(mobloc)
+ var/obj/effect/dummy/phased_mob/holder = new /obj/effect/dummy/phased_mob(mobloc)
extinguish_mob()
// Keep a reference to whatever we're pulling, because forceMove()
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goldgrub.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goldgrub.dm
index 05a9db5f9a2..836f3b6842a 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goldgrub.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goldgrub.dm
@@ -66,31 +66,9 @@
name = "Burrow"
desc = "Burrow under soft ground, evading predators and increasing your speed."
-/obj/effect/dummy/phased_mob/goldgrub
- name = "water"
- icon = 'icons/effects/effects.dmi'
- icon_state = "nothing"
- density = FALSE
- anchored = TRUE
- invisibility = 60
- resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
- var/canmove = TRUE
-
-/obj/effect/dummy/phased_mob/goldgrub/relaymove(mob/living/user, direction)
- forceMove(get_step(src,direction))
-
-/obj/effect/dummy/phased_mob/goldgrub/ex_act()
- return
-
-/obj/effect/dummy/phased_mob/goldgrub/bullet_act()
- return BULLET_ACT_FORCE_PIERCE
-
-/obj/effect/dummy/phased_mob/goldgrub/singularity_act()
- return
-
/datum/action/innate/goldgrub/burrow/Activate()
var/mob/living/simple_animal/hostile/asteroid/goldgrub/G = owner
- var/obj/effect/dummy/phased_mob/goldgrub/holder = null
+ var/obj/effect/dummy/phased_mob/holder = null
if(G.stat == DEAD)
return
var/turf/T = get_turf(G)
@@ -110,7 +88,7 @@
else
G.visible_message("[G] buries into the ground, vanishing from sight!")
playsound(get_turf(G), 'sound/effects/break_stone.ogg', 50, TRUE, -1)
- holder = new /obj/effect/dummy/phased_mob/goldgrub(T)
+ holder = new /obj/effect/dummy/phased_mob(T)
G.forceMove(holder)
G.is_burrowed = TRUE
diff --git a/code/modules/mob/living/simple_animal/hostile/netherworld.dm b/code/modules/mob/living/simple_animal/hostile/netherworld.dm
index 62a2dfac9b1..ac41afb8ef6 100644
--- a/code/modules/mob/living/simple_animal/hostile/netherworld.dm
+++ b/code/modules/mob/living/simple_animal/hostile/netherworld.dm
@@ -39,31 +39,9 @@
name = "Teleport"
desc = "Teleport to wherever you want, as long as you aren't seen."
-/obj/effect/dummy/phased_mob/creature
- name = "water"
- icon = 'icons/effects/effects.dmi'
- icon_state = "nothing"
- density = FALSE
- anchored = TRUE
- invisibility = 60
- resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
- var/canmove = TRUE
-
-/obj/effect/dummy/phased_mob/creature/relaymove(mob/living/user, direction)
- forceMove(get_step(src,direction))
-
-/obj/effect/dummy/phased_mob/creature/ex_act()
- return
-
-/obj/effect/dummy/phased_mob/creature/bullet_act()
- return BULLET_ACT_FORCE_PIERCE
-
-/obj/effect/dummy/phased_mob/creature/singularity_act()
- return
-
/datum/action/innate/creature/teleport/Activate()
var/mob/living/simple_animal/hostile/netherworld/N = owner
- var/obj/effect/dummy/phased_mob/creature/holder = null
+ var/obj/effect/dummy/phased_mob/holder = null
if(N.stat == DEAD)
return
var/turf/T = get_turf(N)
@@ -81,7 +59,7 @@
playsound(get_turf(N), 'sound/effects/podwoosh.ogg', 50, TRUE, -1)
else
playsound(get_turf(N), 'sound/effects/podwoosh.ogg', 50, TRUE, -1)
- holder = new /obj/effect/dummy/phased_mob/creature(T)
+ holder = new /obj/effect/dummy/phased_mob(T)
N.forceMove(holder)
N.is_phased = TRUE
diff --git a/code/modules/spells/spell_types/ethereal_jaunt.dm b/code/modules/spells/spell_types/ethereal_jaunt.dm
index ac951200b91..ee320a12ada 100644
--- a/code/modules/spells/spell_types/ethereal_jaunt.dm
+++ b/code/modules/spells/spell_types/ethereal_jaunt.dm
@@ -70,42 +70,15 @@
playsound(get_turf(target), 'sound/magic/ethereal_exit.ogg', 50, TRUE, -1)
/obj/effect/dummy/phased_mob/spell_jaunt
- name = "water"
- icon = 'icons/effects/effects.dmi'
- icon_state = "nothing"
+ movespeed = 2 //quite slow.
var/reappearing = FALSE
- var/movedelay = 0
- var/movespeed = 2
- density = FALSE
- anchored = TRUE
- invisibility = 60
- resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
-/obj/effect/dummy/phased_mob/spell_jaunt/Destroy()
- // Eject contents if deleted somehow
- for(var/atom/movable/AM in src)
- AM.forceMove(get_turf(src))
- return ..()
-
-/obj/effect/dummy/phased_mob/spell_jaunt/relaymove(mob/living/user, direction)
- if ((movedelay > world.time) || reappearing || !direction)
+/obj/effect/dummy/phased_mob/spell_jaunt/phased_check(mob/living/user, direction)
+ if(reappearing)
return
- var/turf/newLoc = get_step(src,direction)
- setDir(direction)
-
- movedelay = world.time + movespeed
-
- if(newLoc.flags_1 & NOJAUNT_1)
- to_chat(user, "Some strange aura is blocking the way.")
+ . = ..()
+ if(!.)
return
- if (locate(/obj/effect/blessing, newLoc))
+ if (locate(/obj/effect/blessing, .))
to_chat(user, "Holy energies block your path!")
- return
-
- forceMove(newLoc)
-
-/obj/effect/dummy/phased_mob/spell_jaunt/ex_act(blah)
- return
-
-/obj/effect/dummy/phased_mob/spell_jaunt/bullet_act(blah)
- return BULLET_ACT_FORCE_PIERCE
+ return null
diff --git a/code/modules/spells/spell_types/shadow_walk.dm b/code/modules/spells/spell_types/shadow_walk.dm
index 7cca35db0a8..aa793a5a1de 100644
--- a/code/modules/spells/spell_types/shadow_walk.dm
+++ b/code/modules/spells/spell_types/shadow_walk.dm
@@ -35,23 +35,32 @@
to_chat(user, "It isn't dark enough here!")
/obj/effect/dummy/phased_mob/shadow
- name = "darkness"
- icon = 'icons/effects/effects.dmi'
- icon_state = "nothing"
- var/canmove = TRUE
var/mob/living/jaunter
- density = FALSE
- anchored = TRUE
- invisibility = 60
- resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
+
+/obj/effect/dummy/phased_mob/shadow/Initialize(mapload)
+ . = ..()
+ START_PROCESSING(SSobj, src)
+
+/obj/effect/dummy/phased_mob/shadow/Destroy()
+ STOP_PROCESSING(SSobj, src)
+ . = ..()
+
+/obj/effect/dummy/phased_mob/shadow/process()
+ if(!jaunter || jaunter.loc != src)
+ qdel(src)
+ check_light_level()
/obj/effect/dummy/phased_mob/shadow/relaymove(mob/living/user, direction)
- var/turf/newLoc = get_step(src,direction)
- if(isspaceturf(newLoc))
+ var/turf/oldloc = loc
+ . = ..()
+ if(loc != oldloc)
+ check_light_level()
+
+/obj/effect/dummy/phased_mob/shadow/phased_check(mob/living/user, direction)
+ . = ..()
+ if(. && isspaceturf(.))
to_chat(user, "It really would not be wise to go into space.")
- return
- forceMove(newLoc)
- check_light_level()
+ return FALSE
/obj/effect/dummy/phased_mob/shadow/proc/check_light_level()
var/turf/T = get_turf(src)
@@ -67,32 +76,5 @@
visible_message("[jaunter] is revealed by the light!")
else
visible_message("[jaunter] emerges from the darkness!")
- jaunter.forceMove(get_turf(src))
- playsound(get_turf(jaunter), 'sound/magic/ethereal_exit.ogg', 50, TRUE, -1)
- jaunter = null
+ playsound(loc, 'sound/magic/ethereal_exit.ogg', 50, TRUE, -1)
qdel(src)
-
-/obj/effect/dummy/phased_mob/shadow/Initialize(mapload)
- . = ..()
- START_PROCESSING(SSobj, src)
-
-/obj/effect/dummy/phased_mob/shadow/Destroy()
- STOP_PROCESSING(SSobj, src)
- . = ..()
-
-/obj/effect/dummy/phased_mob/shadow/process()
- if(!jaunter)
- qdel(src)
- if(jaunter.loc != src)
- qdel(src)
- check_light_level()
-
-/obj/effect/dummy/phased_mob/shadow/ex_act()
- return
-
-/obj/effect/dummy/phased_mob/shadow/bullet_act()
- return BULLET_ACT_FORCE_PIERCE
-
-/obj/effect/dummy/phased_mob/shadow/singularity_act()
- return
-
diff --git a/tgstation.dme b/tgstation.dme
index 8e8364330f3..3f4de6aa768 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -927,6 +927,7 @@
#include "code\game\objects\effects\mines.dm"
#include "code\game\objects\effects\misc.dm"
#include "code\game\objects\effects\overlays.dm"
+#include "code\game\objects\effects\phased_mob.dm"
#include "code\game\objects\effects\portals.dm"
#include "code\game\objects\effects\proximity.dm"
#include "code\game\objects\effects\spiders.dm"