From 2fdb70b2b9f955ee8d5181b2d698fe5a8cabaf87 Mon Sep 17 00:00:00 2001
From: Solaris-Shade <73904284+Solaris-Shade@users.noreply.github.com>
Date: Sun, 6 Mar 2022 15:20:23 -0500
Subject: [PATCH] [DNM][DNM][WIP] Projectile backend code port and update
Ports#54924, #65061, #59804 from /tg.
adds auxiliary code from /tg to make code work.
---
code/__DEFINES/_flags/_flags.dm | 5 +-
code/__DEFINES/projectiles.dm | 11 +
code/_globalvars/bitfields.dm | 2 +-
code/_onclick/adjacent.dm | 2 +-
code/controllers/subsystem/throwing.dm | 2 +-
code/datums/components/mirv.dm | 2 +-
code/datums/components/pellet_cloud.dm | 2 +-
code/game/atoms.dm | 34 +-
code/game/atoms_movable.dm | 14 +-
code/game/machinery/_machinery.dm | 1 +
code/game/machinery/deployable.dm | 25 +-
code/game/machinery/doors/door.dm | 6 +-
code/game/machinery/doors/firedoor.dm | 14 +-
code/game/machinery/doors/windowdoor.dm | 21 +-
code/game/machinery/recycler.dm | 2 +-
code/game/machinery/shieldgen.dm | 5 +-
code/game/machinery/transformer.dm | 10 +-
.../effects/effect_system/effects_foam.dm | 12 +-
.../effects/effect_system/effects_smoke.dm | 10 +-
code/game/objects/effects/spiders.dm | 4 +-
code/game/objects/items/cardboard_cutouts.dm | 4 +-
.../items/devices/forcefieldprojector.dm | 6 +-
code/game/objects/objs.dm | 6 +-
code/game/objects/structures.dm | 4 +-
code/game/objects/structures/aliens.dm | 5 -
.../structures/crates_lockers/closets.dm | 4 +-
.../structures/crates_lockers/crates.dm | 8 +-
code/game/objects/structures/girders.dm | 10 +-
code/game/objects/structures/grille.dm | 13 +-
code/game/objects/structures/holosign.dm | 44 +-
code/game/objects/structures/mineral_doors.dm | 4 +-
code/game/objects/structures/morgue.dm | 20 +-
code/game/objects/structures/plasticflaps.dm | 5 +-
code/game/objects/structures/railings.dm | 2 +-
code/game/objects/structures/tables_racks.dm | 23 +-
.../structures/transit_tubes/transit_tube.dm | 6 +-
.../objects/structures/windoor_assembly.dm | 16 +-
code/game/objects/structures/window.dm | 20 +-
code/game/turfs/closed.dm | 6 +-
code/game/turfs/simulated/chasm.dm | 3 -
code/game/turfs/turf.dm | 23 +-
.../antagonists/blob/blob/blobs/blob_mobs.dm | 6 +-
code/modules/antagonists/blob/blob/theblob.dm | 12 +-
code/modules/antagonists/swarmer/swarmer.dm | 11 +-
code/modules/assembly/infrared.dm | 3 +-
code/modules/awaymissions/away_props.dm | 5 +-
code/modules/awaymissions/capture_the_flag.dm | 8 +-
code/modules/events/spacevine.dm | 2 +-
code/modules/fields/turf_objects.dm | 4 +-
code/modules/flufftext/Hallucination.dm | 4 +-
code/modules/holiday/halloween/halloween.dm | 5 +-
code/modules/hydroponics/grown/towercap.dm | 8 +-
code/modules/mining/minebot.dm | 4 +-
code/modules/mob/dead/observer/observer.dm | 3 -
.../mob/living/carbon/human/human_defense.dm | 4 +-
code/modules/mob/living/living_defense.dm | 4 +-
code/modules/mob/living/living_movement.dm | 12 +-
.../mob/living/silicon/silicon_defense.dm | 4 +-
.../living/simple_animal/animal_defense.dm | 4 +-
.../simple_animal/hostile/jungle/mook.dm | 4 +-
.../hostile/megafauna/bubblegum.dm | 12 +-
.../hostile/megafauna/hierophant.dm | 4 +-
.../simple_animal/hostile/megafauna/legion.dm | 2 +-
.../hostile/mining_mobs/curse_blob.dm | 4 +-
.../hostile/mining_mobs/elites/elite.dm | 5 +-
.../mob/living/simple_animal/slime/slime.dm | 4 +-
code/modules/mob/mob_defines.dm | 2 +-
.../plumbing/plumbers/grinder_chemical.dm | 2 +-
.../power/singularity/containment_field.dm | 4 +-
.../guns/energy/kinetic_accelerator.dm | 4 +-
.../projectiles/guns/misc/beam_rifle.dm | 76 ++--
.../projectiles/guns/misc/blastcannon.dm | 3 +-
code/modules/projectiles/projectile.dm | 396 ++++++++++++------
code/modules/projectiles/projectile/beams.dm | 2 +-
.../projectile/bullets/ferromagnetic.dm | 4 +-
.../projectiles/projectile/bullets/sniper.dm | 3 +-
.../projectiles/projectile/bullets/special.dm | 3 +-
code/modules/projectiles/projectile/magic.dm | 13 +-
.../projectiles/projectile/special/curse.dm | 11 +-
.../ruins/objects_and_mobs/necropolis_gate.dm | 8 +-
.../ruins/objects_and_mobs/sin_ruins.dm | 5 +-
code/modules/shuttle/special.dm | 5 +-
code/modules/spells/spell_types/forcewall.dm | 4 +-
code/modules/vehicles/ridden.dm | 1 +
84 files changed, 597 insertions(+), 503 deletions(-)
diff --git a/code/__DEFINES/_flags/_flags.dm b/code/__DEFINES/_flags/_flags.dm
index 5f591b429b..99c9b293fb 100644
--- a/code/__DEFINES/_flags/_flags.dm
+++ b/code/__DEFINES/_flags/_flags.dm
@@ -104,6 +104,7 @@ GLOBAL_LIST_INIT(bitflags, list(
#define PASSBLOB (1<<3)
#define PASSMOB (1<<4)
#define PASSCLOSEDTURF (1<<5)
+/// Let thrown things past us. **ONLY MEANINGFUL ON pass_flags_self!**
#define LETPASSTHROW (1<<6)
//Movement Types
@@ -111,8 +112,8 @@ GLOBAL_LIST_INIT(bitflags, list(
#define FLYING (1<<1)
#define VENTCRAWLING (1<<2)
#define FLOATING (1<<3)
-///When moving, will Bump()/Cross()/Uncross() everything, but won't be stopped.
-#define UNSTOPPABLE (1<<4)
+///When moving, will Bump()/Cross()/Uncross() everything, but won't stop or Bump() anything.
+#define PHASING (1<<4)
///Applied if you're crawling around on the ground/resting.
#define CRAWLING (1<<5)
diff --git a/code/__DEFINES/projectiles.dm b/code/__DEFINES/projectiles.dm
index 1bd67fbe02..70a2d611ab 100644
--- a/code/__DEFINES/projectiles.dm
+++ b/code/__DEFINES/projectiles.dm
@@ -1,3 +1,14 @@
+
+// check_pierce() return values
+/// Default behavior: hit and delete self
+#define PROJECTILE_PIERCE_NONE 0
+/// Hit the thing but go through without deleting. Causes on_hit to be called with pierced = TRUE
+#define PROJECTILE_PIERCE_HIT 1
+/// Entirely phase through the thing without ever hitting.
+#define PROJECTILE_PIERCE_PHASE 2
+// Delete self without hitting
+#define PROJECTILE_DELETE_WITHOUT_HITTING 3
+
/// This atom should be ricocheted off of from its inherent properties using standard % chance handling.
#define PROJECTILE_RICOCHET_YES 1
/// This atom should not be ricocheted off of from its inherent properties.
diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm
index df3b6e5334..e3675a53f5 100644
--- a/code/_globalvars/bitfields.dm
+++ b/code/_globalvars/bitfields.dm
@@ -130,7 +130,7 @@ GLOBAL_LIST_INIT(bitfields, list(
"FLYING" = FLYING,
"VENTCRAWLING" = VENTCRAWLING,
"FLOATING" = FLOATING,
- "UNSTOPPABLE" = UNSTOPPABLE
+ "PHASING" = PHASING
),
"resistance_flags" = list(
"LAVA_PROOF" = LAVA_PROOF,
diff --git a/code/_onclick/adjacent.dm b/code/_onclick/adjacent.dm
index 3f3eecb676..e629a6eb57 100644
--- a/code/_onclick/adjacent.dm
+++ b/code/_onclick/adjacent.dm
@@ -94,7 +94,7 @@
for(var/obj/O in src)
if((mover && O.CanPass(mover,get_step(src,target_dir))) || (!mover && !O.density))
continue
- if(O == target_atom || O == mover || (O.pass_flags & LETPASSTHROW)) //check if there's a dense object present on the turf
+ if(O == target_atom || O == mover || (O.pass_flags_self & LETPASSTHROW)) //check if there's a dense object present on the turf
continue // LETPASSTHROW is used for anything you can click through (or the firedoor special case, see above)
if( O.flags_1&ON_BORDER_1) // windows are on border, check them first
diff --git a/code/controllers/subsystem/throwing.dm b/code/controllers/subsystem/throwing.dm
index 0fa8035d72..2ff1e284d0 100644
--- a/code/controllers/subsystem/throwing.dm
+++ b/code/controllers/subsystem/throwing.dm
@@ -200,6 +200,6 @@ SUBSYSTEM_DEF(throwing)
var/atom/movable/AM = thing
if (AM == thrownthing || (AM == thrower && !ismob(thrownthing)))
continue
- if (AM.density && !(AM.pass_flags & LETPASSTHROW) && !(AM.flags_1 & ON_BORDER_1))
+ if (AM.density && !(AM.pass_flags_self & LETPASSTHROW) && !(AM.flags_1 & ON_BORDER_1))
finalize(hit=TRUE, target=AM)
return TRUE
diff --git a/code/datums/components/mirv.dm b/code/datums/components/mirv.dm
index 2a1663776c..77c47bcb1d 100644
--- a/code/datums/components/mirv.dm
+++ b/code/datums/components/mirv.dm
@@ -38,5 +38,5 @@
P.range = override_projectile_range
P.preparePixelProjectile(shootat_turf, target)
P.firer = firer // don't hit ourself that would be really annoying
- P.permutated += target // don't hit the target we hit already with the flak
+ P.impacted = list(target = TRUE) // don't hit the target we hit already with the flak
P.fire()
diff --git a/code/datums/components/pellet_cloud.dm b/code/datums/components/pellet_cloud.dm
index dcc806d991..a06242962f 100644
--- a/code/datums/components/pellet_cloud.dm
+++ b/code/datums/components/pellet_cloud.dm
@@ -242,7 +242,7 @@
P.original = target
P.fired_from = parent
P.firer = parent // don't hit ourself that would be really annoying
- P.permutated += parent // don't hit the target we hit already with the flak
+ P.impacted = list(parent = TRUE) // don't hit the target we hit already with the flak
P.suppressed = SUPPRESSED_VERY // set the projectiles to make no message so we can do our own aggregate message
P.preparePixelProjectile(target, parent)
RegisterSignal(P, COMSIG_PROJECTILE_SELF_ON_HIT, .proc/pellet_hit)
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 40162a6c9b..e4b7507560 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -9,6 +9,9 @@
plane = GAME_PLANE
appearance_flags = TILE_BOUND
+ /// pass_flags that we are. If any of this matches a pass_flag on a moving thing, by default, we let them through.
+ var/pass_flags_self = NONE
+
var/level = 2
///If non-null, overrides a/an/some in all cases
var/article
@@ -269,12 +272,27 @@
return FALSE
if((P.flag in list("bullet", "bomb")) && P.ricochet_incidence_leeway)
if((a_incidence_s < 90 && a_incidence_s < 90 - P.ricochet_incidence_leeway) || (a_incidence_s > 270 && a_incidence_s -270 > P.ricochet_incidence_leeway))
- return
+ return FALSE
var/new_angle_s = SIMPLIFY_DEGREES(face_angle + incidence_s)
P.setAngle(new_angle_s)
return TRUE
/atom/proc/CanPass(atom/movable/mover, turf/target)
+ SHOULD_CALL_PARENT(TRUE)
+ if(mover.movement_type & PHASING)
+ return TRUE
+ . = CanAllowThrough(mover, target)
+ // This is cheaper than calling the proc every time since most things dont override CanPassThrough
+ if(!mover.generic_canpass)
+ return mover.CanPassThrough(src, target, .)
+
+/// Returns true or false to allow the mover to move through src
+/atom/proc/CanAllowThrough(atom/movable/mover, turf/target)
+ SHOULD_CALL_PARENT(TRUE)
+ if(mover.pass_flags & pass_flags_self)
+ return TRUE
+ if(mover.throwing && (pass_flags_self & LETPASSTHROW))
+ return TRUE
return !density
/**
@@ -445,9 +463,19 @@
wires.emp_pulse(severity)
return protection // Pass the protection value collected here upwards
-/atom/proc/bullet_act(obj/item/projectile/P, def_zone)
+/**
+ * React to a hit by a projectile object
+ *
+ * Default behaviour is to send the [COMSIG_ATOM_BULLET_ACT] and then call [on_hit][/obj/item/projectile/proc/on_hit] on the projectile
+ *
+ * @params
+ * P - projectile
+ * def_zone - zone hit
+ * piercing_hit - is this hit piercing or normal?
+ */
+/atom/proc/bullet_act(obj/item/projectile/P, def_zone, piercing_hit = FALSE)
SEND_SIGNAL(src, COMSIG_ATOM_BULLET_ACT, P, def_zone)
- . = P.on_hit(src, 0, def_zone)
+ . = P.on_hit(src, 0, def_zone, piercing_hit)
//used on altdisarm() for special interactions between the shoved victim (target) and the src, with user being the one shoving the target on it.
// IMPORTANT: if you wish to add a new own shove_act() to a certain object, remember to add SHOVABLE_ONTO to its obj_flags bitfied var first.
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 5da389fbb8..56c668a24b 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -25,7 +25,10 @@
var/inertia_moving = 0
var/inertia_next_move = 0
var/inertia_move_delay = 5
- var/pass_flags = 0
+ /// Things we can pass through while moving. If any of this matches the thing we're trying to pass's [pass_flags_self], then we can pass through.
+ var/pass_flags = NONE
+ /// If false makes CanPass call CanPassThrough on this type instead of using default behaviour
+ var/generic_canpass = TRUE
var/moving_diagonally = 0 //0: not doing a diagonal move. 1 and 2: doing the first/second step of the diagonal move
var/atom/movable/moving_from_pull //attempt to resume grab after moving instead of before.
var/list/acted_explosions //for explosion dodging
@@ -473,10 +476,15 @@
/atom/movable/proc/move_crushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
return FALSE
-/atom/movable/CanPass(atom/movable/mover, turf/target)
+/atom/movable/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
if(mover in buckled_mobs)
return TRUE
- return ..()
+
+/// Returns true or false to allow src to move through the blocker, mover has final say
+/atom/movable/proc/CanPassThrough(atom/blocker, turf/target, blocker_opinion)
+ SHOULD_CALL_PARENT(TRUE)
+ return blocker_opinion
/// called when this atom is removed from a storage item, which is passed on as S. The loc variable is already set to the new destination before this is called.
/atom/movable/proc/on_exit_storage(datum/component/storage/concrete/S) // rename S to master_storage
diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm
index f40adcd00b..675d54ef22 100644
--- a/code/game/machinery/_machinery.dm
+++ b/code/game/machinery/_machinery.dm
@@ -90,6 +90,7 @@ Class Procs:
verb_say = "beeps"
verb_yell = "blares"
pressure_resistance = 15
+ pass_flags_self = PASSMACHINE
max_integrity = 200
layer = BELOW_OBJ_LAYER //keeps shit coming out of the machine from ending up underneath it.
flags_1 = DEFAULT_RICOCHET_1
diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm
index ca4b392efa..b720a92402 100644
--- a/code/game/machinery/deployable.dm
+++ b/code/game/machinery/deployable.dm
@@ -37,22 +37,19 @@
else
return ..()
-/obj/structure/barricade/CanPass(atom/movable/mover, turf/target)//So bullets will fly over and stuff.
+/obj/structure/barricade/CanAllowThrough(atom/movable/mover, turf/target)//So bullets will fly over and stuff.
+ . = ..()
if(locate(/obj/structure/barricade) in get_turf(mover))
- return 1
+ return TRUE
else if(istype(mover, /obj/item/projectile))
if(!anchored)
- return 1
+ return TRUE
var/obj/item/projectile/proj = mover
if(proj.firer && Adjacent(proj.firer))
- return 1
+ return TRUE
if(prob(proj_pass_rate))
- return 1
- return 0
- else
- return !density
-
-
+ return TRUE
+ return FALSE
/////BARRICADE TYPES///////
@@ -79,7 +76,6 @@
return
return ..()
-
/obj/structure/barricade/wooden/crude
name = "crude plank barricade"
desc = "This space is blocked off by a crude assortment of planks."
@@ -96,7 +92,6 @@
/obj/structure/barricade/wooden/make_debris()
new /obj/item/stack/sheet/mineral/wood(get_turf(src), drop_amount)
-
/obj/structure/barricade/sandbags
name = "sandbags"
desc = "Bags of sand. Self explanatory."
@@ -104,13 +99,12 @@
icon_state = "sandbags"
max_integrity = 280
proj_pass_rate = 20
- pass_flags = LETPASSTHROW
+ pass_flags_self = LETPASSTHROW
bar_material = SAND
climbable = TRUE
smooth = SMOOTH_TRUE
canSmoothWith = list(/obj/structure/barricade/sandbags, /turf/closed/wall, /turf/closed/wall/r_wall, /obj/structure/falsewall, /obj/structure/falsewall/reinforced, /turf/closed/wall/rust, /turf/closed/wall/r_wall/rust, /obj/structure/barricade/security)
-
/obj/structure/barricade/security
name = "security barrier"
desc = "A deployable barrier. Provides good cover in fire fights."
@@ -125,7 +119,6 @@
var/deploy_time = 40
var/deploy_message = TRUE
-
/obj/structure/barricade/security/Initialize()
. = ..()
addtimer(CALLBACK(src, .proc/deploy), deploy_time)
@@ -137,7 +130,6 @@
if(deploy_message)
visible_message("[src] deploys!")
-
/obj/item/grenade/barrier
name = "barrier grenade"
desc = "Instant cover."
@@ -194,7 +186,6 @@
/obj/item/grenade/barrier/ui_action_click(mob/user)
toggle_mode(user)
-
#undef SINGLE
#undef VERTICAL
#undef HORIZONTAL
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index d1781d9477..71df6affb7 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -127,10 +127,12 @@
. = ..()
move_update_air(T)
-/obj/machinery/door/CanPass(atom/movable/mover, turf/target)
+/obj/machinery/door/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
+
+ // Snowflake handling for PASSGLASS.
if(istype(mover) && (mover.pass_flags & PASSGLASS))
return !opacity
- return !density
/obj/machinery/door/proc/bumpopen(mob/user)
if(operating)
diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm
index d84b994b92..62eb08735f 100644
--- a/code/game/machinery/doors/firedoor.dm
+++ b/code/game/machinery/doors/firedoor.dm
@@ -347,21 +347,15 @@
return 0 // not big enough to matter
return start_point.air.return_pressure() < 20 ? -1 : 1
-/obj/machinery/door/firedoor/border_only/CanPass(atom/movable/mover, turf/target)
- if(istype(mover) && (mover.pass_flags & PASSGLASS))
- return TRUE
- if(get_dir(loc, target) == dir) //Make sure looking at appropriate border
- return !density
- else
+/obj/machinery/door/firedoor/border_only/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
+ if(!(get_dir(loc, target) == dir)) //Make sure looking at appropriate border
return TRUE
/obj/machinery/door/firedoor/border_only/CheckExit(atom/movable/mover as mob|obj, turf/target)
- if(istype(mover) && (mover.pass_flags & PASSGLASS))
- return TRUE
if(get_dir(loc, target) == dir)
return !density
- else
- return TRUE
+ return TRUE
/obj/machinery/door/firedoor/border_only/CanAtmosPass(turf/T)
if(get_dir(loc, T) == dir)
diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm
index af7545d3c9..5027e46aa0 100644
--- a/code/game/machinery/doors/windowdoor.dm
+++ b/code/game/machinery/doors/windowdoor.dm
@@ -12,6 +12,7 @@
armor = list("melee" = 20, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 70, "acid" = 100)
visible = FALSE
flags_1 = ON_BORDER_1|DEFAULT_RICOCHET_1
+ pass_flags_self = PASSGLASS
opacity = 0
CanAtmosPass = ATMOS_PASS_PROC
interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_REQUIRES_SILICON | INTERACT_MACHINE_OPEN
@@ -103,11 +104,12 @@
do_animate("deny")
return
-/obj/machinery/door/window/CanPass(atom/movable/mover, turf/target)
- if(istype(mover) && (mover.pass_flags & PASSGLASS))
- return 1
+/obj/machinery/door/window/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
+ if(.)
+ return
if(get_dir(loc, target) == dir) //Make sure looking at appropriate border
- return !density
+ return
if(istype(mover, /obj/structure/window))
var/obj/structure/window/W = mover
if(!valid_window_location(loc, W.ini_dir))
@@ -119,7 +121,7 @@
else if(istype(mover, /obj/machinery/door/window) && !valid_window_location(loc, mover.dir))
return FALSE
else
- return 1
+ return TRUE
/obj/machinery/door/window/CanAtmosPass(turf/T)
if(get_dir(loc, T) == dir)
@@ -131,13 +133,12 @@
/obj/machinery/door/window/CanAStarPass(obj/item/card/id/ID, to_dir)
return !density || (dir != to_dir) || (check_access(ID) && hasPower())
-/obj/machinery/door/window/CheckExit(atom/movable/mover as mob|obj, turf/target)
- if(istype(mover) && (mover.pass_flags & PASSGLASS))
- return 1
+/obj/machinery/door/window/CheckExit(atom/movable/mover, turf/target)
+ if((pass_flags_self & mover.pass_flags)) || ((pass_flags_self & LETPASSTHROW) && mover.throwing))
+ return TRUE
if(get_dir(loc, target) == dir)
return !density
- else
- return 1
+ return TRUE
/obj/machinery/door/window/open(forced=0)
if (src.operating == 1) //doors can still open when emag-disabled
diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm
index 21ef8e2dcf..7129b6fe57 100644
--- a/code/game/machinery/recycler.dm
+++ b/code/game/machinery/recycler.dm
@@ -87,7 +87,7 @@
is_powered = FALSE
icon_state = icon_name + "[is_powered]" + "[(blood ? "bld" : "")]" // add the blood tag at the end
-/obj/machinery/recycler/CanPass(atom/movable/AM)
+/obj/machinery/recycler/CanAllowThrough(atom/movable/AM)
. = ..()
if(!anchored)
return
diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm
index 2ebb137839..51f16c3425 100644
--- a/code/game/machinery/shieldgen.dm
+++ b/code/game/machinery/shieldgen.dm
@@ -454,11 +454,10 @@
if(gen_secondary) //using power may cause us to be destroyed
gen_secondary.use_stored_power(drain_amount*0.5)
-/obj/machinery/shieldwall/CanPass(atom/movable/mover, turf/target)
+/obj/machinery/shieldwall/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
if(istype(mover) && (mover.pass_flags & PASSGLASS))
return prob(20)
else
if(istype(mover, /obj/item/projectile))
return prob(10)
- else
- return !density
diff --git a/code/game/machinery/transformer.dm b/code/game/machinery/transformer.dm
index 8bca58a7de..afaf617cbc 100644
--- a/code/game/machinery/transformer.dm
+++ b/code/game/machinery/transformer.dm
@@ -57,14 +57,14 @@
AM.forceMove(drop_location())
do_transform(AM)
-/obj/machinery/transformer/CanPass(atom/movable/mover, turf/target)
+/obj/machinery/transformer/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
// Allows items to go through,
// to stop them from blocking the conveyor belt.
if(!ishuman(mover))
- var/dir = get_dir(src, mover)
- if(dir == EAST)
- return ..()
- return 0
+ if(get_dir(src, mover) == EAST)
+ return
+ return FALSE
/obj/machinery/transformer/process()
if(cooldown && (cooldown_timer <= world.time))
diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm
index a0f53ceab7..d4a198a5b0 100644
--- a/code/game/objects/effects/effect_system/effects_foam.dm
+++ b/code/game/objects/effects/effect_system/effects_foam.dm
@@ -291,9 +291,6 @@
to_chat(user, "You hit [src] but bounce off it!")
playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1)
-/obj/structure/foamedmetal/CanPass(atom/movable/mover, turf/target)
- return !density
-
/obj/structure/foamedmetal/iron
max_integrity = 50
icon_state = "ironfoam"
@@ -306,6 +303,7 @@
icon_state = "atmos_resin"
alpha = 120
max_integrity = 10
+ pass_flags_self = PASSGLASS
/obj/structure/foamedmetal/resin/Initialize()
. = ..()
@@ -336,14 +334,6 @@
for(var/obj/item/Item in O)
Item.extinguish()
-/obj/structure/foamedmetal/resin/CanPass(atom/movable/mover, turf/target)
- if(istype(mover) && (mover.pass_flags & PASSGLASS))
- return TRUE
- . = ..()
-
-/obj/structure/foamedmetal/resin/BlockThermalConductivity()
- return TRUE
-
#undef ALUMINUM_FOAM
#undef IRON_FOAM
#undef RESIN_FOAM
diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm
index 3e80ade0ce..db1b9d5b2b 100644
--- a/code/game/objects/effects/effect_system/effects_smoke.dm
+++ b/code/game/objects/effects/effect_system/effects_smoke.dm
@@ -133,13 +133,11 @@
M.emote("cough")
return 1
-/obj/effect/particle_effect/smoke/bad/CanPass(atom/movable/mover, turf/target)
- if(istype(mover, /obj/item/projectile/beam))
- var/obj/item/projectile/beam/B = mover
+/obj/effect/particle_effect/smoke/bad/Crossed(atom/movable/AM, oldloc)
+ . = ..()
+ if(istype(AM, /obj/projectile/beam))
+ var/obj/projectile/beam/B = AM
B.damage = (B.damage/2)
- return 1
-
-
/datum/effect_system/smoke_spread/bad
effect_type = /obj/effect/particle_effect/smoke/bad
diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm
index 4b04606401..1c8df008fd 100644
--- a/code/game/objects/effects/spiders.dm
+++ b/code/game/objects/effects/spiders.dm
@@ -36,7 +36,8 @@
icon_state = "stickyweb2"
. = ..()
-/obj/structure/spider/stickyweb/CanPass(atom/movable/mover, turf/target)
+/obj/structure/spider/stickyweb/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
if (genetic)
return
if(istype(mover, /mob/living/simple_animal/hostile/poison/giant_spider))
@@ -49,7 +50,6 @@
return FALSE
else if(istype(mover, /obj/item/projectile))
return prob(30)
- return TRUE
/obj/structure/spider/stickyweb/genetic //for the spider genes in genetics
genetic = TRUE
diff --git a/code/game/objects/items/cardboard_cutouts.dm b/code/game/objects/items/cardboard_cutouts.dm
index a8ff7b9004..4a59118c8a 100644
--- a/code/game/objects/items/cardboard_cutouts.dm
+++ b/code/game/objects/items/cardboard_cutouts.dm
@@ -92,9 +92,9 @@
if(prob(I.force))
push_over()
-/obj/item/cardboard_cutout/bullet_act(obj/item/projectile/P)
+/obj/item/cardboard_cutout/bullet_act(obj/item/projectile/P, def_zone, piercing_hit = FALSE)
if(istype(P, /obj/item/projectile/bullet/reusable))
- P.on_hit(src, 0)
+ P.on_hit(src, 0, piercing_hit)
visible_message("[src] has been hit by [P]!")
playsound(src, 'sound/weapons/slice.ogg', 50, 1)
if(prob(P.damage))
diff --git a/code/game/objects/items/devices/forcefieldprojector.dm b/code/game/objects/items/devices/forcefieldprojector.dm
index 9ef9d73705..71f69a5c93 100644
--- a/code/game/objects/items/devices/forcefieldprojector.dm
+++ b/code/game/objects/items/devices/forcefieldprojector.dm
@@ -84,6 +84,7 @@
layer = ABOVE_ALL_MOB_LAYER
anchored = TRUE
density = TRUE
+ pass_flags_self = PASSGLASS
mouse_opacity = MOUSE_OPACITY_OPAQUE
resistance_flags = INDESTRUCTIBLE
CanAtmosPass = ATMOS_PASS_DENSITY
@@ -101,11 +102,6 @@
generator = null
return ..()
-/obj/structure/projected_forcefield/CanPass(atom/movable/mover, turf/target)
- if(istype(mover) && (mover.pass_flags & PASSGLASS))
- return 1
- return !density
-
/obj/structure/projected_forcefield/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
playsound(loc, 'sound/weapons/egloves.ogg', 80, 1)
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index e263678943..0651891421 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -238,7 +238,11 @@
/obj/get_dumping_location(datum/component/storage/source,mob/user)
return get_turf(src)
-/obj/proc/CanAStarPass()
+/obj/proc/CanAStarPass(ID, dir, caller)
+ if(ismovable(caller))
+ var/atom/movable/AM = caller
+ if(AM.pass_flags & pass_flags_self)
+ return TRUE
. = !density
/obj/proc/check_uplink_validity()
diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm
index 52036427c8..a8f0739bed 100644
--- a/code/game/objects/structures.dm
+++ b/code/game/objects/structures.dm
@@ -10,9 +10,11 @@
var/broken = 0 //similar to machinery's stat BROKEN
layer = BELOW_OBJ_LAYER
//ricochets on structures commented out for now because there's a lot of structures that /shouldnt/ be ricocheting and those need to be reviewed first
+ //With the addition of [pass_flags_self] the ricocheting of structures /shouldnt/ happen by default thus the existing code could be uncommented out - Solaris-Shade
//flags_1 = DEFAULT_RICOCHET_1
//flags_ricochet = RICOCHET_HARD
//ricochet_chance_mod = 0.5
+ pass_flags_self = PASSSTRUCTURE
/obj/structure/Initialize()
if (!armor)
@@ -114,4 +116,4 @@
return "It's falling apart!"
/obj/structure/rust_heretic_act()
- take_damage(500, BRUTE, "melee", 1)
+ take_damage(500, BRUTE, "melee", 1)
diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm
index bc7ce8c36e..bd90db9c12 100644
--- a/code/game/objects/structures/aliens.dm
+++ b/code/game/objects/structures/aliens.dm
@@ -97,11 +97,6 @@
/obj/structure/alien/resin/attack_paw(mob/user)
return attack_hand(user)
-
-/obj/structure/alien/resin/CanPass(atom/movable/mover, turf/target)
- return !density
-
-
/*
* Weeds
*/
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index af4d098157..b511ed7e2d 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -110,10 +110,10 @@
if(HAS_TRAIT(user, TRAIT_SKITTISH))
. += "If you bump into [p_them()] while running, you will jump inside."
-/obj/structure/closet/CanPass(atom/movable/mover, turf/target)
+/obj/structure/closet/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
if(wall_mounted)
return TRUE
- return !density
/obj/structure/closet/proc/can_open(mob/living/user, force = FALSE)
if(force)
diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm
index f6153330e4..ec97dad72c 100644
--- a/code/game/objects/structures/crates_lockers/crates.dm
+++ b/code/game/objects/structures/crates_lockers/crates.dm
@@ -26,15 +26,15 @@
// AddElement(/datum/element/climbable, climb_time = crate_climb_time, climb_stun = 0)
update_icon()
-/obj/structure/closet/crate/CanPass(atom/movable/mover, turf/target)
+/obj/structure/closet/crate/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
if(!istype(mover, /obj/structure/closet))
var/obj/structure/closet/crate/locatedcrate = locate(/obj/structure/closet/crate) in get_turf(mover)
if(locatedcrate) //you can walk on it like tables, if you're not in an open crate trying to move to a closed crate
if(opened) //if we're open, allow entering regardless of located crate openness
- return 1
+ return TRUE
if(!locatedcrate.opened) //otherwise, if the located crate is closed, allow entering
- return 1
- return !density
+ return TRUE
/obj/structure/closet/crate/update_icon_state()
icon_state = "[initial(icon_state)][opened ? "open" : ""]"
diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm
index 50240aabb3..3e6884613e 100644
--- a/code/game/objects/structures/girders.dm
+++ b/code/game/objects/structures/girders.dm
@@ -296,14 +296,10 @@
qdel(src)
return TRUE
-/obj/structure/girder/CanPass(atom/movable/mover, turf/target)
- if(istype(mover) && (mover.pass_flags & PASSGRILLE))
+/obj/structure/girder/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
+ if((mover.pass_flags & PASSGRILLE) || istype(mover, /obj/projectile))
return prob(girderpasschance)
- else
- if(istype(mover, /obj/item/projectile))
- return prob(girderpasschance)
- else
- return 0
/obj/structure/girder/CanAStarPass(ID, dir, caller)
. = !density
diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm
index 2ac85f79dc..54dce18d44 100644
--- a/code/game/objects/structures/grille.dm
+++ b/code/game/objects/structures/grille.dm
@@ -5,6 +5,7 @@
icon_state = "grille"
density = TRUE
anchored = TRUE
+ pass_flags_self = PASSGRILLE
flags_1 = CONDUCT_1
pressure_resistance = 5*ONE_ATMOSPHERE
layer = BELOW_OBJ_LAYER
@@ -124,14 +125,10 @@
if(!shock(user, 70))
take_damage(20, BRUTE, "melee", 1)
-/obj/structure/grille/CanPass(atom/movable/mover, turf/target)
- if(istype(mover) && (mover.pass_flags & PASSGRILLE))
- return TRUE
- else
- if(istype(mover, /obj/item/projectile) && density)
- return prob(30)
- else
- return !density
+/obj/structure/grille/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
+ if(!. && istype(mover, /obj/projectile))
+ return prob(30)
/obj/structure/grille/CanAStarPass(ID, dir, caller)
. = !density
diff --git a/code/game/objects/structures/holosign.dm b/code/game/objects/structures/holosign.dm
index cb9309c4c4..26dedf3b62 100644
--- a/code/game/objects/structures/holosign.dm
+++ b/code/game/objects/structures/holosign.dm
@@ -51,20 +51,19 @@
name = "holo barrier"
desc = "A short holographic barrier which can only be passed by walking."
icon_state = "holosign_sec"
- pass_flags = LETPASSTHROW
+ pass_flags_self = PASSTABLE | PASSGRILLE | PASSGLASS | LETPASSTHROW
density = TRUE
max_integrity = 20
var/allow_walk = 1 //can we pass through it on walk intent
-/obj/structure/holosign/barrier/CanPass(atom/movable/mover, turf/target)
- if(!density)
- return 1
- if(mover.pass_flags & (PASSGLASS|PASSTABLE|PASSGRILLE))
- return 1
+/obj/structure/holosign/barrier/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
+ if(.)
+ return
if(iscarbon(mover))
var/mob/living/carbon/C = mover
if(allow_walk && C.m_intent == MOVE_INTENT_WALK)
- return 1
+ return TRUE
/obj/structure/holosign/barrier/engineering
icon_state = "holosign_engi"
@@ -149,22 +148,27 @@
. = ..()
. += "The biometric scanners are [force_allaccess ? "off" : "on"]."
-/obj/structure/holosign/barrier/medical/CanPass(atom/movable/mover, turf/target)
- icon_state = "holo_medical"
+/obj/structure/holosign/barrier/medical/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
if(force_allaccess)
return TRUE
if(ishuman(mover))
- var/mob/living/carbon/human/sickboi = mover
- var/threat = sickboi.check_virus()
- switch(threat)
- if(DISEASE_SEVERITY_MINOR, DISEASE_SEVERITY_MEDIUM, DISEASE_SEVERITY_HARMFUL, DISEASE_SEVERITY_DANGEROUS, DISEASE_SEVERITY_BIOHAZARD)
- if(buzzcd < world.time)
- playsound(get_turf(src),'sound/machines/buzz-sigh.ogg',65,1,4)
- buzzcd = (world.time + 60)
- icon_state = "holo_medical-deny"
- return FALSE
- else
- return TRUE //nice or benign diseases!
+
+ return CheckHuman(mover)
+
+/obj/structure/holosign/barrier/medical/Bumped(atom/movable/AM)
+ . = ..()
+ icon_state = "holo_medical"
+ if(ishuman(AM) && !CheckHuman(AM))
+ if(buzzcd < world.time)
+ playsound(get_turf(src),'sound/machines/buzz-sigh.ogg',65,TRUE,4)
+ buzzcd = (world.time + 60)
+ icon_state = "holo_medical-deny"
+
+/obj/structure/holosign/barrier/medical/proc/CheckHuman(mob/living/carbon/human/sickboi)
+ var/threat = sickboi.check_virus()
+ if(get_disease_severity_value(threat) > get_disease_severity_value(DISEASE_SEVERITY_MINOR))
+ return FALSE
return TRUE
/obj/structure/holosign/barrier/medical/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm
index b2f1de8750..ecd7c1a03e 100644
--- a/code/game/objects/structures/mineral_doors.dm
+++ b/code/game/objects/structures/mineral_doors.dm
@@ -53,10 +53,10 @@
/obj/structure/mineral_door/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
return TryToSwitchState(user)
-/obj/structure/mineral_door/CanPass(atom/movable/mover, turf/target)
+/obj/structure/mineral_door/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
if(istype(mover, /obj/effect/beam))
return !opacity
- return !density
/obj/structure/mineral_door/proc/TryToSwitchState(atom/user)
if(isSwitchingStates)
diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm
index 73268009ce..f98151e76a 100644
--- a/code/game/objects/structures/morgue.dm
+++ b/code/game/objects/structures/morgue.dm
@@ -306,7 +306,7 @@ GLOBAL_LIST_EMPTY(crematoriums)
layer = TRAY_LAYER
var/obj/structure/bodycontainer/connected = null
anchored = TRUE
- pass_flags = LETPASSTHROW
+ pass_flags_self = LETPASSTHROW
max_integrity = 350
/obj/structure/tray/Destroy()
@@ -362,17 +362,11 @@ GLOBAL_LIST_EMPTY(crematoriums)
name = "morgue tray"
desc = "Apply corpse before closing."
icon_state = "morguet"
+ pass_flags_self = PASSTABLE
-/obj/structure/tray/m_tray/CanPass(atom/movable/mover, turf/target)
- if(istype(mover) && (mover.pass_flags & PASSTABLE))
- return 1
+/obj/structure/tray/m_tray/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
+ if(.)
+ return
if(locate(/obj/structure/table) in get_turf(mover))
- return 1
- else
- return 0
-
-/obj/structure/tray/m_tray/CanAStarPass(ID, dir, caller)
- . = !density
- if(ismovable(caller))
- var/atom/movable/mover = caller
- . = . || (mover.pass_flags & PASSTABLE)
+ return TRUE
diff --git a/code/game/objects/structures/plasticflaps.dm b/code/game/objects/structures/plasticflaps.dm
index ff8287d77b..4e916d57a6 100644
--- a/code/game/objects/structures/plasticflaps.dm
+++ b/code/game/objects/structures/plasticflaps.dm
@@ -69,7 +69,9 @@
return CanAStarPass(ID, to_dir, M.pulling)
return 1 //diseases, stings, etc can pass
-/obj/structure/plasticflaps/CanPass(atom/movable/A, turf/T)
+/obj/structure/plasticflaps/CanAllowThrough(atom/movable/A, turf/T)
+ . = ..()
+
if(istype(A) && (A.pass_flags & PASSGLASS))
return prob(60)
@@ -93,7 +95,6 @@
return 1
if(!M.lying && !(SEND_SIGNAL(M, COMSIG_CHECK_VENTCRAWL)) && M.mob_size != MOB_SIZE_TINY) //If your not laying down, or a ventcrawler or a small creature, no pass.
return 0
- return ..()
/obj/structure/plasticflaps/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
diff --git a/code/game/objects/structures/railings.dm b/code/game/objects/structures/railings.dm
index 21cf97ba70..13bc676239 100644
--- a/code/game/objects/structures/railings.dm
+++ b/code/game/objects/structures/railings.dm
@@ -78,7 +78,7 @@
/obj/structure/railing/CheckExit(atom/movable/mover, turf/target)
..()
if(get_dir(loc, target) & dir)
- var/checking = UNSTOPPABLE | FLYING | FLOATING
+ var/checking = PHASING | FLYING | FLOATING
return !density || mover.throwing || mover.movement_type & checking || mover.move_force >= MOVE_FORCE_EXTREMELY_STRONG
return TRUE
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index 065c0d2f28..2435e9a5f6 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -19,10 +19,10 @@
icon_state = "table"
density = TRUE
anchored = TRUE
+ pass_flags_self = PASSTABLE | LETPASSTHROW
layer = TABLE_LAYER
climbable = TRUE
obj_flags = CAN_BE_HIT|SHOVABLE_ONTO
- pass_flags = LETPASSTHROW //You can throw objects over this, despite it's density.")
attack_hand_speed = CLICK_CD_MELEE
attack_hand_is_action = TRUE
var/frame = /obj/structure/table_frame
@@ -99,15 +99,14 @@
/obj/structure/table/attack_tk()
return FALSE
-/obj/structure/table/CanPass(atom/movable/mover, turf/target)
- if(istype(mover) && (mover.pass_flags & PASSTABLE))
- return 1
+/obj/structure/table/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
+ if(.)
+ return
if(mover.throwing)
- return 1
+ return TRUE
if(locate(/obj/structure/table) in get_turf(mover))
- return 1
- else
- return !density
+ return TRUE
/obj/structure/table/CanAStarPass(ID, dir, caller)
. = !density
@@ -685,7 +684,7 @@
layer = TABLE_LAYER
density = TRUE
anchored = TRUE
- pass_flags = LETPASSTHROW //You can throw objects over this, despite it's density.
+ pass_flags_self = LETPASSTHROW //You can throw objects over this, despite it's density.
max_integrity = 20
attack_hand_speed = CLICK_CD_MELEE
attack_hand_is_action = TRUE
@@ -702,12 +701,6 @@
else
return 0
-/obj/structure/rack/CanAStarPass(ID, dir, caller)
- . = !density
- if(ismovable(caller))
- var/atom/movable/mover = caller
- . = . || (mover.pass_flags & PASSTABLE)
-
/obj/structure/rack/MouseDrop_T(obj/O, mob/user)
. = ..()
if ((!( istype(O, /obj/item) ) || user.get_active_held_item() != O))
diff --git a/code/game/objects/structures/transit_tubes/transit_tube.dm b/code/game/objects/structures/transit_tubes/transit_tube.dm
index 7e3684ad32..c8341c8834 100644
--- a/code/game/objects/structures/transit_tubes/transit_tube.dm
+++ b/code/game/objects/structures/transit_tubes/transit_tube.dm
@@ -8,17 +8,13 @@
layer = LOW_ITEM_LAYER
anchored = TRUE
climbable = 1
+ pass_flags_self = PASSGLASS
var/tube_construction = /obj/structure/c_transit_tube
var/list/tube_dirs //list of directions this tube section can connect to.
var/exit_delay = 1
var/enter_delay = 0
var/const/time_to_unwrench = 2 SECONDS
-/obj/structure/transit_tube/CanPass(atom/movable/mover, turf/target)
- if(istype(mover) && (mover.pass_flags & PASSGLASS))
- return 1
- return !density
-
/obj/structure/transit_tube/New(loc, newdirection)
..(loc)
if(newdirection)
diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm
index ef1ca6720a..4f1de6432a 100644
--- a/code/game/objects/structures/windoor_assembly.dm
+++ b/code/game/objects/structures/windoor_assembly.dm
@@ -50,11 +50,10 @@
/obj/structure/windoor_assembly/update_icon_state()
icon_state = "[facing]_[secure ? "secure_" : ""]windoor_assembly[state]"
-/obj/structure/windoor_assembly/CanPass(atom/movable/mover, turf/target)
- if(istype(mover) && (mover.pass_flags & PASSGLASS))
- return 1
+/obj/structure/windoor_assembly/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
if(get_dir(loc, target) == dir) //Make sure looking at appropriate border
- return !density
+ return
if(istype(mover, /obj/structure/window))
var/obj/structure/window/W = mover
if(!valid_window_location(loc, W.ini_dir))
@@ -65,7 +64,6 @@
return FALSE
else if(istype(mover, /obj/machinery/door/window) && !valid_window_location(loc, mover.dir))
return FALSE
- return 1
/obj/structure/windoor_assembly/CanAtmosPass(turf/T)
if(get_dir(loc, T) == dir)
@@ -73,13 +71,13 @@
else
return 1
-/obj/structure/windoor_assembly/CheckExit(atom/movable/mover as mob|obj, turf/target)
- if(istype(mover) && (mover.pass_flags & PASSGLASS))
- return 1
+/obj/structure/windoor_assembly/CheckExit(atom/movable/mover, turf/target)
+ if(mover.pass_flags & pass_flags_self)
+ return TRUE
if(get_dir(loc, target) == dir)
return !density
else
- return 1
+ return TRUE
/obj/structure/windoor_assembly/attackby(obj/item/W, mob/user, params)
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 4853d553dc..a73de2d367 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -18,6 +18,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
pressure_resistance = 4*ONE_ATMOSPHERE
anchored = TRUE //initially is 0 for tile smoothing
max_integrity = 25
+ pass_flags_self = PASSGLASS
var/ini_dir = null
var/state = WINDOW_OUT_OF_FRAME
var/reinf = FALSE
@@ -90,13 +91,13 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
. = ..()
if(direct)
setDir(direct)
-
+
if(extra_reinforced && anchored)
state = PRWINDOW_SECURE
else if(reinf && anchored)
state = WINDOW_SCREWED_TO_FRAME
-
+
if(mapload && electrochromatic_id && electrochromatic_id[1] == "!")
electrochromatic_id = SSmapping.get_obfuscated_id(electrochromatic_id)
@@ -159,13 +160,15 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
else
..(FULLTILE_WINDOW_DIR)
-/obj/structure/window/CanPass(atom/movable/mover, turf/target)
- if(istype(mover) && (mover.pass_flags & PASSGLASS))
- return 1
+/obj/structure/window/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
+ if(.)
+ return
if(dir == FULLTILE_WINDOW_DIR)
return 0 //full tile window, you can't move into it!
- if(get_dir(loc, target) == dir)
- return !density
+ var/attempted_dir = get_dir(loc, target)
+ if(attempted_dir == dir)
+ return
if(istype(mover, /obj/structure/window))
var/obj/structure/window/W = mover
if(!valid_window_location(loc, W.ini_dir))
@@ -176,7 +179,8 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
return FALSE
else if(istype(mover, /obj/machinery/door/window) && !valid_window_location(loc, mover.dir))
return FALSE
- return 1
+ else if(attempted_dir != dir)
+ return TRUE
/obj/structure/window/CheckExit(atom/movable/O, turf/target)
if(istype(O) && (O.pass_flags & PASSGLASS))
diff --git a/code/game/turfs/closed.dm b/code/game/turfs/closed.dm
index ccfb5dc238..3c2f38e872 100644
--- a/code/game/turfs/closed.dm
+++ b/code/game/turfs/closed.dm
@@ -6,6 +6,7 @@
blocks_air = 1
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
rad_insulation = RAD_MEDIUM_INSULATION
+ pass_flags_self = PASSCLOSEDTURF
wave_explosion_block = 10
wave_explosion_multiply = 0.75
/// How much we block yelling
@@ -23,11 +24,6 @@
/turf/closed/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
return FALSE
-/turf/closed/CanPass(atom/movable/mover, turf/target)
- if(istype(mover) && (mover.pass_flags & PASSCLOSEDTURF))
- return TRUE
- return ..()
-
/turf/closed/indestructible
name = "wall"
icon = 'icons/turf/walls.dmi'
diff --git a/code/game/turfs/simulated/chasm.dm b/code/game/turfs/simulated/chasm.dm
index 9490d728fe..40b96dbcc8 100644
--- a/code/game/turfs/simulated/chasm.dm
+++ b/code/game/turfs/simulated/chasm.dm
@@ -77,9 +77,6 @@
else
to_chat(user, "The plating is going to need some support! Place metal rods first.")
-/turf/open/chasm/CanPass(atom/movable/mover, turf/target)
- return 1
-
// Chasms for Lavaland, with planetary atmos and lava glow
/turf/open/chasm/lavaland
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 85de964463..c87d386b5f 100755
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -225,16 +225,6 @@ GLOBAL_LIST_EMPTY(station_turfs)
return FALSE
-/turf/CanPass(atom/movable/mover, turf/target)
- if(!target)
- return FALSE
-
- if(istype(mover)) // turf/Enter(...) will perform more advanced checks
- return !density
-
- stack_trace("Non movable passed to turf CanPass : [mover]")
- return FALSE
-
//There's a lot of QDELETED() calls here if someone can figure out how to optimize this but not runtime when something gets deleted by a Bump/CanPass/Cross call, lemme know or go ahead and fix this mess - kevinz000
/turf/Enter(atom/movable/mover, atom/oldloc)
// Do not call ..()
@@ -243,7 +233,7 @@ GLOBAL_LIST_EMPTY(station_turfs)
// Here's hoping it doesn't stay like this for years before we finish conversion to step_
var/atom/firstbump
var/canPassSelf = CanPass(mover, src)
- if(canPassSelf || (mover.movement_type & UNSTOPPABLE))
+ if(canPassSelf || (mover.movement_type & PHASING))
for(var/i in contents)
if(QDELETED(mover))
return FALSE //We were deleted, do not attempt to proceed with movement.
@@ -253,7 +243,7 @@ GLOBAL_LIST_EMPTY(station_turfs)
if(!thing.Cross(mover))
if(QDELETED(mover)) //Mover deleted from Cross/CanPass, do not proceed.
return FALSE
- if((mover.movement_type & UNSTOPPABLE))
+ if((mover.movement_type & PHASING))
mover.Bump(thing)
continue
else
@@ -265,7 +255,7 @@ GLOBAL_LIST_EMPTY(station_turfs)
firstbump = src
if(firstbump)
mover.Bump(firstbump)
- return (mover.movement_type & UNSTOPPABLE)
+ return (mover.movement_type & PHASING)
return TRUE
/turf/Exit(atom/movable/mover, atom/newloc)
@@ -279,7 +269,7 @@ GLOBAL_LIST_EMPTY(station_turfs)
if(!thing.Uncross(mover, newloc))
if(thing.flags_1 & ON_BORDER_1)
mover.Bump(thing)
- if(!(mover.movement_type & UNSTOPPABLE))
+ if(!(mover.movement_type & PHASING))
return FALSE
if(QDELETED(mover))
return FALSE //We were deleted.
@@ -621,11 +611,6 @@ GLOBAL_LIST_EMPTY(station_turfs)
/turf/proc/Melt()
return ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
-/turf/bullet_act(obj/item/projectile/P)
- . = ..()
- if(. != BULLET_ACT_FORCE_PIERCE)
- . = BULLET_ACT_TURF
-
/turf/proc/get_yelling_resistance(power)
. = 0
// don't bother checking fulltile, we don't need accuracy
diff --git a/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm b/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm
index f9763b92fd..3caaff4a53 100644
--- a/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm
+++ b/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm
@@ -46,10 +46,10 @@
else
adjustFireLoss(5)
-/mob/living/simple_animal/hostile/blob/CanPass(atom/movable/mover, turf/target)
+/mob/living/simple_animal/hostile/blob/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
if(istype(mover, /obj/structure/blob))
- return 1
- return ..()
+ return TRUE
/mob/living/simple_animal/hostile/blob/Process_Spacemove(movement_dir = 0)
for(var/obj/structure/blob/B in range(1, src))
diff --git a/code/modules/antagonists/blob/blob/theblob.dm b/code/modules/antagonists/blob/blob/theblob.dm
index a95f73f90d..7651093ea1 100644
--- a/code/modules/antagonists/blob/blob/theblob.dm
+++ b/code/modules/antagonists/blob/blob/theblob.dm
@@ -8,6 +8,7 @@
opacity = 0
anchored = TRUE
layer = BELOW_MOB_LAYER
+ pass_flags_self = PASSBLOB
CanAtmosPass = ATMOS_PASS_PROC
var/point_return = 0 //How many points the blob gets back when it removes a blob of that type. If less than 0, blob cannot be removed.
max_integrity = 30
@@ -67,20 +68,9 @@
/obj/structure/blob/BlockThermalConductivity()
return atmosblock
-/obj/structure/blob/CanPass(atom/movable/mover, turf/target)
- if(istype(mover) && (mover.pass_flags & PASSBLOB))
- return 1
- return 0
-
/obj/structure/blob/CanAtmosPass(turf/T)
return !atmosblock
-/obj/structure/blob/CanAStarPass(ID, dir, caller)
- . = 0
- if(ismovable(caller))
- var/atom/movable/mover = caller
- . = . || (mover.pass_flags & PASSBLOB)
-
/obj/structure/blob/update_icon() //Updates color based on overmind color if we have an overmind.
if(overmind)
add_atom_colour(overmind.blobstrain.color, FIXED_COLOUR_PRIORITY)
diff --git a/code/modules/antagonists/swarmer/swarmer.dm b/code/modules/antagonists/swarmer/swarmer.dm
index 2d4ac88656..a572238877 100644
--- a/code/modules/antagonists/swarmer/swarmer.dm
+++ b/code/modules/antagonists/swarmer/swarmer.dm
@@ -139,12 +139,12 @@
else
death()
-/mob/living/simple_animal/hostile/swarmer/CanPass(atom/movable/O)
+/mob/living/simple_animal/hostile/swarmer/CanAllowThrough(atom/movable/O)
+ . = ..()
if(istype(O, /obj/item/projectile/beam/disabler))//Allows for swarmers to fight as a group without wasting their shots hitting each other
return 1
if(isswarmer(O))
return 1
- ..()
////CTRL CLICK FOR SWARMERS AND SWARMER_ACT()'S////
/mob/living/simple_animal/hostile/swarmer/AttackingTarget()
@@ -698,11 +698,12 @@
light_range = MINIMUM_USEFUL_LIGHT_RANGE
max_integrity = 50
-/obj/structure/swarmer/blockade/CanPass(atom/movable/O)
+/obj/structure/swarmer/blockade/CanAllowThrough(atom/movable/O)
+ . = ..()
if(isswarmer(O))
- return 1
+ return TRUE
if(istype(O, /obj/item/projectile/beam/disabler))
- return 1
+ return TRUE
/mob/living/simple_animal/hostile/swarmer/proc/CreateSwarmer()
set name = "Replicate"
diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm
index d0ed0f2436..94f7409cc9 100644
--- a/code/modules/assembly/infrared.dm
+++ b/code/modules/assembly/infrared.dm
@@ -220,7 +220,8 @@
icon_state = "ibeam"
anchored = TRUE
density = FALSE
- pass_flags = PASSTABLE|PASSGLASS|PASSGRILLE|LETPASSTHROW
+ pass_flags = PASSTABLE|PASSGLASS|PASSGRILLE
+ pass_flags_self = LETPASSTHROW
var/obj/item/assembly/infra/master
/obj/effect/beam/i_beam/Crossed(atom/movable/AM as mob|obj)
diff --git a/code/modules/awaymissions/away_props.dm b/code/modules/awaymissions/away_props.dm
index 36ed9b6ba3..d5d94b2a92 100644
--- a/code/modules/awaymissions/away_props.dm
+++ b/code/modules/awaymissions/away_props.dm
@@ -6,10 +6,11 @@
invisibility = INVISIBILITY_MAXIMUM
anchored = TRUE
-/obj/effect/oneway/CanPass(atom/movable/mover, turf/target)
+/obj/effect/oneway/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
var/turf/T = get_turf(src)
var/turf/MT = get_turf(mover)
- return ..() && (T == MT || get_dir(MT,T) == dir)
+ return . && (T == MT || get_dir(MT,T) == dir)
/obj/effect/wind
diff --git a/code/modules/awaymissions/capture_the_flag.dm b/code/modules/awaymissions/capture_the_flag.dm
index d32905e007..c6cd2e4d77 100644
--- a/code/modules/awaymissions/capture_the_flag.dm
+++ b/code/modules/awaymissions/capture_the_flag.dm
@@ -405,10 +405,10 @@
/obj/item/projectile/bullet/ctf
damage = 0
-/obj/item/projectile/bullet/ctf/prehit(atom/target)
+/obj/item/projectile/bullet/ctf/prehit_pierce(atom/target)
if(is_ctf_target(target))
damage = 60
- return //PROJECTILE_PIERCE_NONE /// hey uhh don't hit anyone behind them
+ return PROJECTILE_PIERCE_NONE /// hey uhh don't hit anyone behind them
. = ..()
/obj/item/gun/ballistic/automatic/laser/ctf
@@ -442,10 +442,10 @@
damage = 0
icon_state = "omnilaser"
-/obj/item/projectile/beam/ctf/prehit(atom/target)
+/obj/item/projectile/beam/ctf/prehit_pierce(atom/target)
if(is_ctf_target(target))
damage = 150
- return //PROJECTILE_PIERCE_NONE /// hey uhhh don't hit anyone behind them
+ return PROJECTILE_PIERCE_NONE /// hey uhhh don't hit anyone behind them
. = ..()
/proc/is_ctf_target(atom/target)
diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm
index ed6a087cd9..8cbe7f50e1 100644
--- a/code/modules/events/spacevine.dm
+++ b/code/modules/events/spacevine.dm
@@ -523,7 +523,7 @@
if(!override)
qdel(src)
-/obj/structure/spacevine/CanPass(atom/movable/mover, turf/target)
+/obj/structure/spacevine/CanAllowThrough(atom/movable/mover, turf/target)
. = ..()
if(isvineimmune(mover))
return TRUE
diff --git a/code/modules/fields/turf_objects.dm b/code/modules/fields/turf_objects.dm
index 1af924294a..f8d139a45d 100644
--- a/code/modules/fields/turf_objects.dm
+++ b/code/modules/fields/turf_objects.dm
@@ -23,7 +23,7 @@
name = "energy field"
desc = "Get off my turf!"
-/obj/effect/abstract/proximity_checker/advanced/field_turf/CanPass(atom/movable/AM, turf/target)
+/obj/effect/abstract/proximity_checker/advanced/field_turf/CanAllowThrough(atom/movable/AM, turf/target)
. = ..()
if(parent)
return parent.field_turf_canpass(AM, src, target)
@@ -48,7 +48,7 @@
name = "energy field edge"
desc = "Edgy description here."
-/obj/effect/abstract/proximity_checker/advanced/field_edge/CanPass(atom/movable/AM, turf/target)
+/obj/effect/abstract/proximity_checker/advanced/field_edge/CanAllowThrough(atom/movable/AM, turf/target)
. = ..()
if(parent)
return parent.field_edge_canpass(AM, src, target)
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index 5d84901e7f..a43bb0cff5 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -647,10 +647,10 @@ GLOBAL_LIST_INIT(hallucination_list, list(
target.playsound_local(get_turf(airlock), 'sound/machines/boltsup.ogg',30,0,3)
qdel(src)
-/obj/effect/hallucination/fake_door_lock/CanPass(atom/movable/mover, turf/_target)
+/obj/effect/hallucination/fake_door_lock/CanAllowThrough(atom/movable/mover, turf/_target)
+ . = ..()
if(mover == target && airlock.density)
return FALSE
- return TRUE
/datum/hallucination/chat
diff --git a/code/modules/holiday/halloween/halloween.dm b/code/modules/holiday/halloween/halloween.dm
index 0c9987fc00..1e5f4b4502 100644
--- a/code/modules/holiday/halloween/halloween.dm
+++ b/code/modules/holiday/halloween/halloween.dm
@@ -175,9 +175,6 @@
step(I,direction)
return
-/mob/living/simple_animal/hostile/construct/shade/howling_ghost/CanPass(atom/movable/mover, turf/target)
- return 1
-
///////////////////////////
//Spookoween Insane Clown//
///////////////////////////
@@ -233,7 +230,7 @@
return
/mob/living/simple_animal/hostile/retaliate/clown/insane/adjustHealth()
- . = ..()
+ . = ..()
if(prob(5))
playsound(loc, 'sound/spookoween/insane_low_laugh.ogg', 300, 1)
diff --git a/code/modules/hydroponics/grown/towercap.dm b/code/modules/hydroponics/grown/towercap.dm
index 38e4fcc6ff..a314210570 100644
--- a/code/modules/hydroponics/grown/towercap.dm
+++ b/code/modules/hydroponics/grown/towercap.dm
@@ -151,6 +151,7 @@
density = FALSE
anchored = TRUE
buckle_lying = 0
+ pass_flags_self = PASSTABLE | LETPASSTHROW
var/burning = 0
var/burn_icon = "bonfire_on_fire" //for a softer more burning embers icon, use "bonfire_warm"
var/grill = FALSE
@@ -163,13 +164,6 @@
. = ..()
StartBurning()
-/obj/structure/bonfire/CanPass(atom/movable/mover, turf/target)
- if(istype(mover) && (mover.pass_flags & PASSTABLE))
- return TRUE
- if(mover.throwing)
- return TRUE
- return ..()
-
/obj/structure/bonfire/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/stack/rods) && !can_buckle && !grill)
var/obj/item/stack/rods/R = W
diff --git a/code/modules/mining/minebot.dm b/code/modules/mining/minebot.dm
index 8037a22a52..50c91378ec 100644
--- a/code/modules/mining/minebot.dm
+++ b/code/modules/mining/minebot.dm
@@ -131,7 +131,8 @@
to_chat(M, "[src] has been set to attack hostile wildlife.")
return
-/mob/living/simple_animal/hostile/mining_drone/CanPass(atom/movable/O)
+/mob/living/simple_animal/hostile/mining_drone/CanAllowThrough(atom/movable/O)
+ . = ..()
if(istype(O, /obj/item/projectile/kinetic))
var/obj/item/projectile/kinetic/K = O
if(K.kinetic_gun)
@@ -141,7 +142,6 @@
return TRUE
if(istype(O, /obj/item/projectile/destabilizer))
return TRUE
- return ..()
/mob/living/simple_animal/hostile/mining_drone/proc/SetCollectBehavior()
mode = MINEDRONE_COLLECT
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 624db8caf5..4b228e1eb3 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -166,9 +166,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
QDEL_NULL(spawners_menu)
return ..()
-/mob/dead/CanPass(atom/movable/mover, turf/target)
- return 1
-
/*
* This proc will update the icon of the ghost itself, with hair overlays, as well as the ghost image.
* Please call update_icon(icon_state) from now on when you want to update the icon_state of the ghost,
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 71573abc90..b65155f086 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -53,7 +53,7 @@
dna.species.on_hit(P, src)
-/mob/living/carbon/human/bullet_act(obj/item/projectile/P, def_zone)
+/mob/living/carbon/human/bullet_act(obj/item/projectile/P, def_zone, piercing_hit = FALSE)
if(dna && dna.species)
var/spec_return = dna.species.bullet_act(P, src)
if(spec_return)
@@ -61,7 +61,7 @@
if(mind) //martial art stuff
if(mind.martial_art && mind.martial_art.can_use(src)) //Some martial arts users can deflect projectiles!
- var/martial_art_result = mind.martial_art.on_projectile_hit(src, P, def_zone)
+ var/martial_art_result = mind.martial_art.on_projectile_hit(src, P, def_zone, piercing_hit)
if(!(martial_art_result == BULLET_ACT_HIT))
return martial_art_result
return ..()
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 5ce80c5575..2aaedb22a5 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -68,7 +68,7 @@
else
CRASH("Invalid rediretion mode [redirection_mode]")
-/mob/living/bullet_act(obj/item/projectile/P, def_zone)
+/mob/living/bullet_act(obj/item/projectile/P, def_zone, piercing_hit = FALSE)
var/totaldamage = P.damage
var/final_percent = 0
if(P.original != src || P.firer != src) //try to block or reflect the bullet, can't do so when shooting oneself
@@ -81,7 +81,7 @@
if(returned & BLOCK_REDIRECTED)
return BULLET_ACT_FORCE_PIERCE
if(returned & BLOCK_SUCCESS)
- P.on_hit(src, final_percent, def_zone)
+ P.on_hit(src, final_percent, def_zone, piercing_hit)
return BULLET_ACT_BLOCK
totaldamage = block_calculate_resultant_damage(totaldamage, returnlist)
var/armor = run_armor_check(def_zone, P.flag, null, null, P.armour_penetration, null)
diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm
index a35558884b..fcab9344d9 100644
--- a/code/modules/mob/living/living_movement.dm
+++ b/code/modules/mob/living/living_movement.dm
@@ -20,12 +20,10 @@
/mob/living/proc/update_density()
density = !lying && !HAS_TRAIT(src, TRAIT_LIVING_NO_DENSITY)
-/mob/living/CanPass(atom/movable/mover, turf/target)
- if((mover.pass_flags & PASSMOB))
- return TRUE
- if(istype(mover, /obj/item/projectile))
- var/obj/item/projectile/P = mover
- return !P.can_hit_target(src, P.permutated, src == P.original, TRUE)
+/mob/living/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
+ if(.)
+ return
if(mover.throwing)
return (!density || lying)
if(buckled == mover)
@@ -41,7 +39,7 @@
var/mob/living/L = mover //typecast first, check isliving and only check this if living using short circuit
if(isliving(L) && lying && L.lying) //if we're both lying down and aren't already being thrown/shipped around, don't pass
return FALSE
- return (!density || (isliving(mover)? L.can_move_under_living(src) : !mover.density))
+ return (isliving(mover)? L.can_move_under_living(src) : !mover.density)
/mob/living/toggle_move_intent()
. = ..()
diff --git a/code/modules/mob/living/silicon/silicon_defense.dm b/code/modules/mob/living/silicon/silicon_defense.dm
index 55d0336671..a87c0a81ab 100644
--- a/code/modules/mob/living/silicon/silicon_defense.dm
+++ b/code/modules/mob/living/silicon/silicon_defense.dm
@@ -120,7 +120,7 @@
"You are thrown off of [src]!")
flash_act(affect_silicon = 1)
-/mob/living/silicon/bullet_act(obj/item/projectile/P, def_zone)
+/mob/living/silicon/bullet_act(obj/item/projectile/P, def_zone, piercing_hit = FALSE)
var/totaldamage = P.damage
if(P.original != src || P.firer != src) //try to block or reflect the bullet, can't do so when shooting oneself
var/list/returnlist = list()
@@ -141,7 +141,7 @@
"You are knocked off of [src] by the [P]!")
unbuckle_mob(M)
M.DefaultCombatKnockdown(40)
- P.on_hit(src, 0, def_zone)
+ P.on_hit(src, 0, def_zone, 0, piercing_hit)
return BULLET_ACT_HIT
/mob/living/silicon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /atom/movable/screen/fullscreen/tiled/flash/static)
diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm
index b003e066ef..df8ef44845 100644
--- a/code/modules/mob/living/simple_animal/animal_defense.dm
+++ b/code/modules/mob/living/simple_animal/animal_defense.dm
@@ -124,10 +124,10 @@
apply_damage(damage, damagetype, null, getarmor(null, armorcheck))
return TRUE
-/mob/living/simple_animal/bullet_act(obj/item/projectile/Proj)
+/mob/living/simple_animal/bullet_act(obj/item/projectile/Proj, def_zone, piercing_hit = FALSE)
if(!Proj)
return
- apply_damage(Proj.damage, Proj.damage_type)
+ apply_damage(Proj.damage, Proj.damage_type, 0, piercing_hit)
Proj.on_hit(src)
return BULLET_ACT_HIT
diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm b/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm
index 2d964f5721..baa0fe4649 100644
--- a/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm
+++ b/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm
@@ -33,12 +33,12 @@
footstep_type = FOOTSTEP_MOB_BAREFOOT
-/mob/living/simple_animal/hostile/jungle/mook/CanPass(atom/movable/O)
+/mob/living/simple_animal/hostile/jungle/mook/CanAllowThrough(atom/movable/O)
+ . = ..()
if(istype(O, /mob/living/simple_animal/hostile/jungle/mook))
var/mob/living/simple_animal/hostile/jungle/mook/M = O
if(M.attack_state == MOOK_ATTACK_ACTIVE && M.throwing)
return TRUE
- return ..()
/mob/living/simple_animal/hostile/jungle/mook/death()
desc = "A deceased primitive. Upon closer inspection, it was suffering from severe cellular degeneration and its garments are machine made..."//Can you guess the twist
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
index 9bcc21efa6..ab6c9fa301 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
@@ -160,10 +160,10 @@ Difficulty: Hard
severity = EXPLODE_LIGHT // puny mortals
return ..()
-/mob/living/simple_animal/hostile/megafauna/bubblegum/CanPass(atom/movable/mover, turf/target)
+/mob/living/simple_animal/hostile/megafauna/bubblegum/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
if(istype(mover, /mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination))
- return 1
- return ..()
+ return TRUE
/mob/living/simple_animal/hostile/megafauna/bubblegum/Goto(target, delay, minimum_distance)
if(!charging)
@@ -466,10 +466,10 @@ Difficulty: Hard
new /obj/effect/decal/cleanable/blood(get_turf(src))
. = ..()
-/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/CanPass(atom/movable/mover, turf/target)
+/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
if(istype(mover, /mob/living/simple_animal/hostile/megafauna/bubblegum)) // hallucinations should not be stopping bubblegum or eachother
- return 1
- return ..()
+ return TRUE
/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/Life()
return
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
index c1aea8db9d..a4620cd781 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
@@ -490,7 +490,8 @@ Difficulty: Normal
queue_smooth_neighbors(src)
return ..()
-/obj/effect/temp_visual/hierophant/wall/CanPass(atom/movable/mover, turf/target)
+/obj/effect/temp_visual/hierophant/wall/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
if(QDELETED(caster))
return FALSE
if(mover == caster.pulledby)
@@ -501,7 +502,6 @@ Difficulty: Normal
return TRUE
if(mover == caster)
return TRUE
- return FALSE
/obj/effect/temp_visual/hierophant/chaser //a hierophant's chaser. follows target around, moving and producing a blast every speed deciseconds.
duration = 98
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
index 15bfe2b7f7..f0f978c03f 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
@@ -394,7 +394,7 @@ SHITCODE AHEAD. BE ADVISED. Also comment extravaganza
muzzle_type = /obj/effect/projectile/tracer/legion
impact_type = /obj/effect/projectile/tracer/legion
hitscan = TRUE
- movement_type = UNSTOPPABLE
+ projectile_piercing = ALL
///Used for the legion turret tracer.
/obj/effect/projectile/tracer/legion/tracer
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm
index ed056c2ad9..04b003b315 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm
@@ -72,14 +72,14 @@
return
//if it's not our target, we ignore it
-/mob/living/simple_animal/hostile/asteroid/curseblob/CanPass(atom/movable/mover, turf/target)
+/mob/living/simple_animal/hostile/asteroid/curseblob/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
if(mover == set_target)
return FALSE
if(istype(mover, /obj/item/projectile))
var/obj/item/projectile/P = mover
if(P.firer == set_target)
return FALSE
- return TRUE
#define IGNORE_PROC_IF_NOT_TARGET(X) /mob/living/simple_animal/hostile/asteroid/curseblob/##X(AM) { if (AM == set_target) return ..(); }
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm
index be596b0292..b92f429c8c 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm
@@ -383,8 +383,7 @@ While using this makes the system rely on OnFire, it still gives options for tim
ourelite = null
return ..()
-/obj/effect/temp_visual/elite_tumor_wall/CanPass(atom/movable/mover, turf/target)
+/obj/effect/temp_visual/elite_tumor_wall/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
if(mover == ourelite || mover == activator)
return FALSE
- else
- return TRUE
diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm
index 38149494bc..9812307300 100644
--- a/code/modules/mob/living/simple_animal/slime/slime.dm
+++ b/code/modules/mob/living/simple_animal/slime/slime.dm
@@ -231,11 +231,11 @@
amount = -abs(amount)
return ..() //Heals them
-/mob/living/simple_animal/slime/bullet_act(obj/item/projectile/Proj)
+/mob/living/simple_animal/slime/bullet_act(obj/item/projectile/Proj, def_zone, piercing_hit = FALSE)
attacked += 10
if((Proj.damage_type == BURN))
adjustBruteLoss(-abs(Proj.damage)) //fire projectiles heals slimes.
- Proj.on_hit(src)
+ Proj.on_hit(src, 0, piercing_hit)
return BULLET_ACT_BLOCK
return ..()
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 527b0c0917..138a3b9662 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -9,7 +9,7 @@
mouse_drag_pointer = MOUSE_ACTIVE_POINTER
throwforce = 10
blocks_emissive = EMISSIVE_BLOCK_GENERIC
-
+ pass_flags_self = PASSMOB
vis_flags = VIS_INHERIT_PLANE //when this be added to vis_contents of something it inherit something.plane, important for visualisation of mob in openspace.
attack_hand_is_action = TRUE
diff --git a/code/modules/plumbing/plumbers/grinder_chemical.dm b/code/modules/plumbing/plumbers/grinder_chemical.dm
index f39c79f906..1d216046e4 100644
--- a/code/modules/plumbing/plumbers/grinder_chemical.dm
+++ b/code/modules/plumbing/plumbers/grinder_chemical.dm
@@ -31,7 +31,7 @@
eat_dir = WEST
return TRUE
-/obj/machinery/plumbing/grinder_chemical/CanPass(atom/movable/AM)
+/obj/machinery/plumbing/grinder_chemical/CanAllowThrough(atom/movable/AM)
. = ..()
if(!anchored)
return
diff --git a/code/modules/power/singularity/containment_field.dm b/code/modules/power/singularity/containment_field.dm
index ff6cf99411..7c6b1cc922 100644
--- a/code/modules/power/singularity/containment_field.dm
+++ b/code/modules/power/singularity/containment_field.dm
@@ -100,10 +100,10 @@
return
-/obj/machinery/field/CanPass(atom/movable/mover, turf/target)
+/obj/machinery/field/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
if(hasShocked || isliving(mover) || ismachinery(mover) || isstructure(mover) || ismecha(mover))
return FALSE
- return ..()
/obj/machinery/field/proc/shock(mob/living/user)
var/shock_damage = min(rand(30,40),rand(30,40))
diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
index 4d394401c4..7516092149 100644
--- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
+++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
@@ -232,14 +232,14 @@
kinetic_gun = null
return ..()
-/obj/item/projectile/kinetic/prehit(atom/target)
+/obj/item/projectile/kinetic/prehit_pierce(atom/target)
. = ..()
if(.)
if(kinetic_gun)
var/list/mods = kinetic_gun.get_modkits()
for(var/obj/item/borg/upgrade/modkit/M in mods)
M.projectile_prehit(src, target, kinetic_gun)
- if(!lavaland_equipment_pressure_check(get_turf(target)))
+ if(!pressure_decrease_active && !lavaland_equipment_pressure_check(get_turf(target)))
name = "weakened [name]"
damage = damage * pressure_decrease
pressure_decrease_active = TRUE
diff --git a/code/modules/projectiles/guns/misc/beam_rifle.dm b/code/modules/projectiles/guns/misc/beam_rifle.dm
index 2ef974a450..ebc388a965 100644
--- a/code/modules/projectiles/guns/misc/beam_rifle.dm
+++ b/code/modules/projectiles/guns/misc/beam_rifle.dm
@@ -427,11 +427,9 @@
var/aoe_mob_damage = 30
var/impact_structure_damage = 0
var/impact_direct_damage = 0
- var/turf/cached
var/list/pierced = list()
/obj/item/projectile/beam/beam_rifle/proc/AOE(turf/epicenter)
- set waitfor = FALSE
if(!epicenter)
return
new /obj/effect/temp_visual/explosion/fast(epicenter)
@@ -447,31 +445,22 @@
continue
O.take_damage(aoe_structure_damage * get_damage_coeff(O), BURN, "laser", FALSE)
-/obj/item/projectile/beam/beam_rifle/proc/check_pierce(atom/target)
- if(!do_pierce)
- return FALSE
- if(pierced[target]) //we already pierced them go away
- return TRUE
- if(isclosedturf(target))
- if(wall_pierce++ < wall_pierce_amount)
- if(prob(wall_devastate))
- if(iswallturf(target))
- var/turf/closed/wall/W = target
- W.dismantle_wall(TRUE, TRUE)
- else
- target.ex_act(EXPLODE_HEAVY)
- return TRUE
- if(ismovable(target))
- var/atom/movable/AM = target
- if(AM.density && !AM.CanPass(src, get_turf(target)) && !ismob(AM))
- if(structure_pierce < structure_pierce_amount)
- if(isobj(AM))
- var/obj/O = AM
- O.take_damage((impact_structure_damage + aoe_structure_damage) * structure_bleed_coeff * get_damage_coeff(AM), BURN, "energy", FALSE)
- pierced[AM] = TRUE
- structure_pierce++
- return TRUE
- return FALSE
+/obj/item/projectile/beam/beam_rifle/proc/check_pierce(atom/A)
+ if(isclosedturf(A) && (wall_pierce < wall_pierce_amount))
+ if(prob(wall_devastate))
+ if(iswallturf(A))
+ var/turf/closed/wall/W = A
+ W.dismantle_wall(TRUE, TRUE)
+ else
+ target.ex_act(EXPLODE_HEAVY)
+ ++wall_pierce
+ return PROJECTILE_PIERCE_PHASE // yeah this gun is a snowflakey piece of garbage - Silly-Cons
+ if(isobj(A) && (structure_pierce < structure_pierce_amount))
+ ++structure_pierce
+ var/obj/O = A
+ O.take_damage((impact_structure_damage + aoe_structure_damage) * structure_bleed_coeff * get_damage_coeff(A), BURN, ENERGY, FALSE)
+ return PROJECTILE_PIERCE_PHASE // ditto and this could be refactored to on_hit honestly - Silly-Cons
+ return ..()
/obj/item/projectile/beam/beam_rifle/proc/get_damage_coeff(atom/target)
if(istype(target, /obj/machinery/door))
@@ -491,32 +480,18 @@
L.adjustFireLoss(impact_direct_damage)
L.emote("scream")
-/obj/item/projectile/beam/beam_rifle/proc/handle_hit(atom/target)
+/obj/item/projectile/beam/beam_rifle/proc/handle_hit(atom/target, piercing_hit = FALSE)
set waitfor = FALSE
- if(!cached && !QDELETED(target))
- cached = get_turf(target)
if(nodamage)
return FALSE
- playsound(cached, 'sound/effects/explosion3.ogg', 100, 1)
- AOE(cached)
+ playsound(src, 'sound/effects/explosion3.ogg', 100, TRUE)
+ if(!piercing_hit)
+ AOE(get_turf(target) || get_turf(src))
if(!QDELETED(target))
handle_impact(target)
-/obj/item/projectile/beam/beam_rifle/Bump(atom/target)
- if(check_pierce(target))
- permutated += target
- trajectory_ignore_forcemove = TRUE
- forceMove(target.loc)
- trajectory_ignore_forcemove = FALSE
- return FALSE
- if(!QDELETED(target))
- cached = get_turf(target)
- . = ..()
-
-/obj/item/projectile/beam/beam_rifle/on_hit(atom/target, blocked = FALSE)
- if(!QDELETED(target))
- cached = get_turf(target)
- handle_hit(target)
+/obj/projectile/beam/beam_rifle/on_hit(atom/target, blocked = FALSE, piercing_hit = FALSE)
+ handle_hit(target, piercing_hit)
. = ..()
/obj/item/projectile/beam/beam_rifle/hitscan
@@ -547,6 +522,9 @@
hitscan_light_intensity = 0
hitscan_light_color_override = "#99ff99"
-/obj/item/projectile/beam/beam_rifle/hitscan/aiming_beam/prehit(atom/target)
+/obj/projectile/beam/beam_rifle/hitscan/aiming_beam/prehit_pierce(atom/target)
+ return PROJECTILE_DELETE_WITHOUT_HITTING
+
+/obj/projectile/beam/beam_rifle/hitscan/aiming_beam/on_hit()
qdel(src)
- return FALSE
+ return BULLET_ACT_BLOCK
diff --git a/code/modules/projectiles/guns/misc/blastcannon.dm b/code/modules/projectiles/guns/misc/blastcannon.dm
index 64cffe52e7..b28c06a2c2 100644
--- a/code/modules/projectiles/guns/misc/blastcannon.dm
+++ b/code/modules/projectiles/guns/misc/blastcannon.dm
@@ -114,7 +114,8 @@
icon_state = "blastwave"
damage = 0
nodamage = FALSE
- movement_type = FLYING | UNSTOPPABLE
+ movement_type = FLYING
+ projectile_phasing = ALL // just blows up the turfs lmao - Silly-Cons
var/heavyr = 0
var/mediumr = 0
var/lightr = 0
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index ca07bde239..3fd1bce1ca 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -13,9 +13,9 @@
density = FALSE
anchored = TRUE
item_flags = ABSTRACT
- pass_flags = PASSTABLE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
movement_type = FLYING
+ generic_canpass = FALSE
animate_movement = NO_STEPS
hitsound = 'sound/weapons/pierce.ogg'
appearance_flags = PIXEL_SCALE
@@ -40,6 +40,35 @@
var/time_offset = 0
var/datum/point/vector/trajectory
var/trajectory_ignore_forcemove = FALSE //instructs forceMove to NOT reset our trajectory to the new location!
+ /// We already impacted these things, do not impact them again. Used to make sure we can pierce things we want to pierce. Lazylist, typecache style (object = TRUE) for performance.
+ var/list/impacted
+ /// If TRUE, we can hit our firer.
+ var/ignore_source_check = FALSE
+ /// We are flagged PHASING temporarily to not stop moving when we Bump something but want to keep going anyways.
+ var/temporary_unstoppable_movement = FALSE
+
+ /** PROJECTILE PIERCING
+ * WARNING:
+ * Projectile piercing MUST be done using these variables.
+ * Ordinary passflags will be **IGNORED**.
+ * The two flag variables below both use pass flags.
+ * In the context of LETPASStHROW, it means the projectile will ignore things that are currently "in the air" from a throw.
+ *
+ * Also, projectiles sense hits using Bump(), and then pierce them if necessary.
+ * They simply do not follow conventional movement rules.
+ * NEVER flag a projectile as PHASING movement type.
+ * If you so badly need to make one go through *everything*, override check_pierce() for your projectile to always return PROJECTILE_PIERCE_PHASE/HIT.
+ */
+ /// The "usual" flags of pass_flags is used in that can_hit_target ignores these unless they're specifically targeted/clicked on. This behavior entirely bypasses process_hit if triggered, rather than phasing which uses prehit_pierce() to check.
+ pass_flags = PASSTABLE
+ /// If FALSE, allow us to hit something directly targeted/clicked/whatnot even if we're able to phase through it
+ var/phasing_ignore_direct_target = FALSE
+ /// Bitflag for things the projectile should just phase through entirely - No hitting unless direct target and [phasing_ignore_direct_target] is FALSE. Uses pass_flags flags.
+ var/projectile_phasing = NONE
+ /// Bitflag for things the projectile should hit, but pierce through without deleting itself. Defers to projectile_phasing. Uses pass_flags flags.
+ var/projectile_piercing = NONE
+ /// number of times we've pierced something. Incremented BEFORE bullet_act and on_hit proc!
+ var/pierces = 0
/// "leftover" pixels for Range() calculation as pixel_move() was moved to simulated semi-pixel movement and Range() is in tiles.
var/pixels_range_leftover = 0
/// "leftover" tick pixels and stuff yeah, so we don't round off things and introducing tracing inaccuracy.
@@ -117,8 +146,6 @@
/// How many deciseconds are each hitscan movement considered. Used for homing and other things that use seconds for timing rather than ticks.
var/hitscan_movement_decisecond_equivalency = 0.1
- var/ignore_source_check = FALSE
-
var/damage = 10
var/damage_type = BRUTE //BRUTE, BURN, TOX, OXY, CLONE are the only things that should be in here
var/nodamage = 0 //Determines if the projectile will skip any damage inflictions
@@ -150,8 +177,6 @@
var/impact_effect_type //what type of impact effect to show when hitting something
var/log_override = FALSE //is this type spammed enough to not log? (KAs)
- var/temporary_unstoppable_movement = FALSE
-
///If defined, on hit we create an item of this type then call hitby() on the hit target with this, mainly used for embedding items (bullets) in targets
var/shrapnel_type
///If TRUE, hit mobs even if they're on the floor and not our target
@@ -167,7 +192,6 @@
/obj/item/projectile/Initialize()
. = ..()
- permutated = list()
decayedRange = range
if(embedding)
updateEmbedding()
@@ -201,10 +225,7 @@
else //when a limb is missing the damage is actually passed to the chest
return BODY_ZONE_CHEST
-/obj/item/projectile/proc/prehit(atom/target)
- return TRUE
-
-/obj/item/projectile/proc/on_hit(atom/target, blocked = FALSE)
+/obj/item/projectile/proc/on_hit(atom/target, blocked = FALSE, pierce_hit)
if(fired_from)
SEND_SIGNAL(fired_from, COMSIG_PROJECTILE_ON_HIT, firer, target, Angle)
@@ -238,6 +259,11 @@
if(!isliving(target))
if(impact_effect_type && !hitscan)
new impact_effect_type(target_loca, hitx, hity)
+ if(isturf(target) && hitsound_wall)
+ var/volume = clamp(vol_by_damage() + 20, 0, 100)
+ if(suppressed)
+ volume = 5
+ playsound(loc, hitsound_wall, volume, TRUE, -1)
return BULLET_ACT_HIT
var/mob/living/L = target
@@ -278,7 +304,7 @@
else
if(hitsound)
var/volume = vol_by_damage()
- playsound(loc, hitsound, volume, 1, -1)
+ playsound(src, hitsound, volume, 1, -1)
L.visible_message("[L] is hit by \a [src][organ_hit_text]!", \
"[L] is hit by \a [src][organ_hit_text]!", null, COMBAT_MESSAGE_RANGE)
if(candink && def_zone == BODY_ZONE_HEAD)
@@ -298,7 +324,7 @@
/obj/item/projectile/proc/vol_by_damage()
if(src.damage)
- return clamp((src.damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then CLAMP the value between 30 and 100
+ return clamp((src.damage) * 0.67, 30, 100) // Multiply projectile damage by 0.67, then CLAMP the value between 30 and 100
else
return 50 //if the projectile doesn't do damage, play its hitsound at 50% volume
@@ -327,95 +353,267 @@
beam_segments[beam_index] = null
/obj/item/projectile/Bump(atom/A)
- if(!trajectory)
+ SEND_SIGNAL(src, COMSIG_MOVABLE_BUMP, A)
+ if(!can_hit_target(A, A == original, TRUE))
return
+ Impact(A)
+
+/**
+ * Called when the projectile hits something
+ * This can either be from it bumping something,
+ * or it passing over a turf/being crossed and scanning that there is infact
+ * a valid target it needs to hit.
+ * This target isn't however necessarily WHAT it hits
+ * that is determined by process_hit and select_target.
+ *
+ * Furthermore, this proc shouldn't check can_hit_target - this should only be called if can hit target is already checked.
+ * Also, we select_target to find what to process_hit first.
+ */
+/obj/projectile/proc/Impact(atom/A)
+ if(!trajectory)
+ qdel(src)
+ return FALSE
+ if(impacted[A]) // NEVER doublehit - Silly-Cons
+ return FALSE
+ var/datum/point/pcache = trajectory.copy_to()
var/turf/T = get_turf(A)
if(check_ricochet_flag(A) && check_ricochet(A)) //if you can ricochet, attempt to ricochet off the object
ricochets++
if(A.handle_ricochet(src))
on_ricochet(A) //if allowed, use autoaim to ricochet into someone, otherwise default to ricocheting off the object from above
- var/datum/point/pcache = trajectory.copy_to()
- if(hitscan)
- store_hitscan_collision(pcache)
+ impacted = list() // Shoot a x-ray laser at a pair of mirrors I dare you
+ ignore_source_check = TRUE // Firer is no longer immune
decayedRange = max(0, decayedRange - reflect_range_decrease)
ricochet_chance *= ricochet_decay_chance
damage *= ricochet_decay_damage
range = decayedRange
+ if(hitscan)
+ store_hitscan_collision(pcache)
return TRUE
var/distance = get_dist(T, starting) // Get the distance between the turf shot from and the mob we hit and use that for the calculations.
if(def_zone && check_zone(def_zone) != BODY_ZONE_CHEST)
def_zone = ran_zone(def_zone, max(100-(7*distance), 5) * zone_accuracy_factor) //Lower accurancy/longer range tradeoff. 7 is a balanced number to use.
- if(isturf(A) && hitsound_wall)
- var/volume = clamp(vol_by_damage() + 20, 0, 100)
- if(suppressed)
- volume = 5
- playsound(loc, hitsound_wall, volume, 1, -1)
+ return process_hit(T, select_target(T, A)) // SELECT TARGET FIRST!
- return process_hit(T, select_target(T, A))
-
-#define QDEL_SELF 1 //Delete if we're not UNSTOPPABLE flagged non-temporarily
-#define DO_NOT_QDEL 2 //Pass through.
-#define FORCE_QDEL 3 //Force deletion.
-
-/obj/item/projectile/proc/process_hit(turf/T, atom/target, qdel_self, hit_something = FALSE) //probably needs to be reworked entirely when pixel movement is done.
- if(QDELETED(src) || !T || !target) //We're done, nothing's left.
- if((qdel_self == FORCE_QDEL) || ((qdel_self == QDEL_SELF) && !temporary_unstoppable_movement && !(movement_type & UNSTOPPABLE)))
- qdel(src)
+/**
+ * The primary workhorse proc of projectile impacts.
+ * This is a RECURSIVE call - process_hit is called on the first selected target, and then repeatedly called if the projectile still hasn't been deleted.
+ *
+ * Order of operations:
+ * 1. Checks if we are deleted, or if we're somehow trying to hit a null, in which case, bail out
+ * 2. Adds the thing we're hitting to impacted so we can make sure we don't doublehit
+ * 3. Checks piercing - stores this.
+ * Afterwards:
+ * Hit and delete, hit without deleting and pass through, pass through without hitting, or delete without hitting depending on result
+ * If we're going through without hitting, find something else to hit if possible and recurse, set unstoppable movement to true
+ * If we're deleting without hitting, delete and return
+ * Otherwise, send signal of COMSIG_PROJECTILE_PREHIT to target
+ * Then, hit, deleting ourselves if necessary.
+ * @params
+ * T - Turf we're on/supposedly hitting
+ * target - target we're hitting
+ * hit_something - only should be set by recursive calling by this proc - tracks if we hit something already
+ *
+ * Returns if we hit something.
+ * - Silly-Cons
+ */
+/obj/item/projectile/proc/process_hit(turf/T, atom/target, hit_something = FALSE)
+ // 1.
+ if(QDELETED(src) || !T || !target)
+ return
+ // 2.
+ impacted[target] = TRUE //hash lookup > in for performance in hit-checking
+ // 3.
+ var/mode = prehit_pierce(target)
+ if(mode == PROJECTILE_DELETE_WITHOUT_HITTING)
+ qdel(src)
return hit_something
- permutated |= target //Make sure we're never hitting it again. If we ever run into weirdness with piercing projectiles needing to hit something multiple times.. well.. that's a to-do.
- if(!prehit(target))
- return process_hit(T, select_target(T), qdel_self, hit_something) //Hit whatever else we can since that didn't work.
- var/result = target.bullet_act(src, def_zone)
- if(result == BULLET_ACT_FORCE_PIERCE)
- if(!(movement_type & UNSTOPPABLE))
+ else if(mode == PROJECTILE_PIERCE_PHASE)
+ if(!(movement_type & PHASING))
temporary_unstoppable_movement = TRUE
- movement_type |= UNSTOPPABLE
- return process_hit(T, select_target(T), qdel_self, TRUE) //Hit whatever else we can since we're piercing through but we're still on the same tile.
- else if(result == BULLET_ACT_TURF) //We hit the turf but instead we're going to also hit something else on it.
- return process_hit(T, select_target(T), QDEL_SELF, TRUE)
- else //Whether it hit or blocked, we're done!
- qdel_self = QDEL_SELF
- hit_something = TRUE
- if((qdel_self == FORCE_QDEL) || ((qdel_self == QDEL_SELF) && !temporary_unstoppable_movement && !(movement_type & UNSTOPPABLE)))
+ movement_type |= PHASING
+ return process_hit(T, select_target(T, target), hit_something) // try to hit something else
+ // at this point we are going to hit the thing
+ // in which case send signal to it
+ SEND_SIGNAL(target, COMSIG_PROJECTILE_PREHIT, args)
+ if(mode == PROJECTILE_PIERCE_HIT)
+ ++pierces
+ hit_something = TRUE
+ var/result = target.bullet_act(src, def_zone, mode == PROJECTILE_PIERCE_HIT)
+ if((result == BULLET_ACT_FORCE_PIERCE) || (mode == PROJECTILE_PIERCE_HIT))
+ if(!(movement_type & PHASING))
+ temporary_unstoppable_movement = TRUE
+ movement_type |= PHASING
+ return process_hit(T, select_target(T, target), TRUE)
qdel(src)
return hit_something
-#undef QDEL_SELF
-#undef DO_NOT_QDEL
-#undef FORCE_QDEL
-
-/obj/item/projectile/proc/select_target(turf/T, atom/target) //Select a target from a turf.
- if((original in T) && can_hit_target(original, permutated, TRUE, TRUE))
+/**
+ * Selects a target to hit from a turf
+ *
+ * @params
+ * T - The turf
+ * target - The "preferred" atom to hit, usually what we Bumped() first.
+ *
+ * Priority:
+ * 0. Anything that is already in impacted is ignored no matter what. Furthermore, in any bracket, if the target atom parameter is in it, that's hit first.
+ * Furthermore, can_hit_target is always checked. This (entire proc) is PERFORMANCE OVERHEAD!! But, it shouldn't be ""too"" bad and I frankly don't have a better *generic non snowflakey* way that I can think of right now at 3 AM.
+ * FURTHERMORE, mobs/objs have a density check from can_hit_target - to hit non dense objects over a turf, you must click on them, same for mobs that usually wouldn't get hit.
+ * 1. The thing originally aimed at/clicked on
+ * 2. Mobs - picks lowest buckled mob to prevent scarp piggybacking memes
+ * 3. Objs
+ * 4. Turf
+ * 5. Nothing
+ */
+/obj/projectile/proc/select_target(turf/T, atom/target)
+ // 1. original
+ if(can_hit_target(original, TRUE, FALSE))
return original
- if(target && can_hit_target(target, permutated, target == original, TRUE))
- return target
- var/list/mob/living/possible_mobs = typecache_filter_list(T, GLOB.typecache_mob)
- var/list/mob/mobs = list()
- for(var/mob/living/M in possible_mobs)
- if(!can_hit_target(M, permutated, M == original, TRUE))
+ var/list/atom/possible = list() // let's define these ONCE
+ var/list/atom/considering = list()
+ // 2. mobs
+ possible = typecache_filter_list(T, GLOB.typecache_living) // living only
+ for(var/i in possible)
+ if(!can_hit_target(i, i == original, TRUE))
continue
- mobs += M
- var/mob/M = safepick(mobs)
- if(M)
+ considering += i
+ if(considering.len)
+ var/mob/living/M = pick(considering)
return M.lowest_buckled_mob()
- var/list/obj/possible_objs = typecache_filter_list(T, GLOB.typecache_machine_or_structure)
- var/list/obj/objs = list()
- for(var/obj/O in possible_objs)
- if(!can_hit_target(O, permutated, O == original, TRUE))
+ considering.len = 0
+ // 3. objs
+ possible = typecache_filter_list(T, GLOB.typecache_machine_or_structure) // because why are items ever dense?
+ for(var/i in possible)
+ if(!can_hit_target(i, i == original, TRUE))
continue
- objs += O
- var/obj/O = safepick(objs)
- if(O)
- if(length(O.buckled_mobs))
- return pick(O.buckled_mobs)
- return O
- //Nothing else is here that we can hit, hit the turf if we haven't.
- if(!(T in permutated) && can_hit_target(T, permutated, T == original, TRUE))
+ considering += i
+ if(considering.len)
+ return pick(considering)
+ // 4. turf
+ if(can_hit_target(T, T == original, TRUE))
return T
- //Returns null if nothing at all was found.
+ // 5. nothing
+ // (returns null)
+//Returns true if the target atom is on our current turf and above the right layer
+//If direct target is true it's the originally clicked target.
+/obj/projectile/proc/can_hit_target(atom/target, direct_target = FALSE, ignore_loc = FALSE)
+ if(QDELETED(target) || impacted[target])
+ return FALSE
+ if(!ignore_loc && (loc != target.loc))
+ return FALSE
+ // if pass_flags match, pass through entirely
+ if(target.pass_flags_self & pass_flags) // phasing
+ return FALSE
+ if(!ignore_source_check && firer)
+ var/mob/M = firer
+ if((target == firer) || ((target == firer.loc) && ismecha(firer.loc)) || (target in firer.buckled_mobs) || (istype(M) && (M.buckled == target)))
+ return FALSE
+ if(target.density) //This thing blocks projectiles, hit it regardless of layer/mob stuns/etc.
+ return TRUE
+ if(!isliving(target))
+ if(isturf(target)) // non dense turfs
+ return FALSE
+ if(target.layer < PROJECTILE_HIT_THRESHHOLD_LAYER)
+ return FALSE
+ else if(!direct_target) // non dense objects do not get hit unless specifically clicked
+ return FALSE
+ else
+ var/mob/living/L = target
+ if(direct_target)
+ return TRUE
+ // If target not able to use items, move and stand - or if they're just dead, pass over.
+ if(L.stat == DEAD || (!hit_stunned_targets && HAS_TRAIT(L, TRAIT_IMMOBILIZED) && HAS_TRAIT(L, TRAIT_FLOORED) && HAS_TRAIT(L, TRAIT_HANDS_BLOCKED)))
+ return FALSE
+ return TRUE
+
+/**
+ * Scan if we should hit something and hit it if we need to
+ * The difference between this and handling in Impact is
+ * In this we strictly check if we need to Impact() something in specific
+ * If we do, we do
+ * We don't even check if it got hit already - Impact() does that
+ * In impact there's more code for selecting WHAT to hit
+ * So this proc is more of checking if we should hit something at all BY having an atom cross us.
+ */
+/obj/projectile/proc/scan_crossed_hit(atom/movable/A)
+ if(can_hit_target(A, direct_target = (A == original)))
+ Impact(A)
+
+/**
+ * Scans if we should hit something on the turf we just moved to if we haven't already
+ *
+ * This proc is a little high in overhead but allows us to not snowflake CanPass in living and other things.
+ */
+/obj/projectile/proc/scan_moved_turf()
+ // Optimally, we scan: mobs --> objs --> turf for impact
+ // but, overhead is a thing and 2 for loops every time it moves is a no-go.
+ // realistically, since we already do select_target in impact, we can not do that
+ // and hope projectiles get refactored again in the future to have a less stupid impact detection system
+ // that hopefully won't also involve a ton of overhead
+ if(can_hit_target(original, TRUE, FALSE))
+ Impact(original) // try to hit thing clicked on
+ // else, try to hit mobs
+ else // because if we impacted original and pierced we'll already have select target'd and hit everything else we should be hitting
+ for(var/mob/M in loc) // so I guess we're STILL doing a for loop of mobs because living movement would otherwise have snowflake code for projectile CanPass
+ // so the snowflake vs performance is pretty arguable here
+ if(can_hit_target(M, M == original, TRUE))
+ Impact(M)
+ break
+
+/**
+ * Projectile crossed: When something enters a projectile's tile, make sure the projectile hits it if it should be hitting it.
+ */
+/obj/projectile/Crossed(atom/movable/AM)
+ . = ..()
+ scan_crossed_hit(AM)
+
+/**
+ * Projectile can pass through
+ * Used to not even attempt to Bump() or fail to Cross() anything we already hit.
+ */
+/obj/projectile/CanPassThrough(atom/blocker, turf/target, blocker_opinion)
+ return impacted[blocker]? TRUE : ..()
+
+/**
+ * Projectile moved:
+ *
+ * If not fired yet, do not do anything. Else,
+ *
+ * If temporary unstoppable movement used for piercing through things we already hit (impacted list) is set, unset it.
+ * Scan turf we're now in for anything we can/should hit. This is useful for hitting non dense objects the user
+ * directly clicks on, as well as for PHASING projectiles to be able to hit things at all as they don't ever Bump().
+ */
+/obj/projectile/Moved(atom/OldLoc, Dir)
+ . = ..()
+ if(!fired)
+ return
+ if(temporary_unstoppable_movement)
+ temporary_unstoppable_movement = FALSE
+ movement_type &= ~PHASING
+ scan_moved_turf() //mostly used for making sure we can hit a non-dense object the user directly clicked on, and for penetrating projectiles that don't bump
+
+/**
+ * Checks if we should pierce something.
+ *
+ * NOT meant to be a pure proc, since this replaces prehit() which was used to do things.
+ * Return PROJECTILE_DELETE_WITHOUT_HITTING to delete projectile without hitting at all!
+ */
+/obj/projectile/proc/prehit_pierce(atom/A)
+ if(projectile_phasing & A.pass_flags_self)
+ return PROJECTILE_PIERCE_PHASE
+ if(projectile_piercing & A.pass_flags_self)
+ return PROJECTILE_PIERCE_HIT
+ if(ismovable(A))
+ var/atom/movable/AM = A
+ if(AM.throwing)
+ return (projectile_phasing & LETPASSTHROW)? PROJECTILE_PIERCE_PHASE : ((projectile_piercing & LETPASSTHROW)? PROJECTILE_PIERCE_HIT : PROJECTILE_PIERCE_NONE)
+ return PROJECTILE_PIERCE_NONE
+
+/**INeedAnAdult I am unsure what the fuck is going on in here and I'll have to get clairification on this shit.
+ */
/obj/item/projectile/proc/check_ricochet(atom/A)
if(ricochets > ricochets_max) //safety thing, we don't care about what the other thing says about this.
return FALSE
@@ -484,11 +682,10 @@
AddElement(/datum/element/embed, projectile_payload = shrapnel_type)
if(!log_override && firer && original)
log_combat(firer, original, "fired at", src, "from [get_area_name(src, TRUE)]")
- if(direct_target)
- if(prehit(direct_target))
- direct_target.bullet_act(src, def_zone)
- qdel(src)
- return
+ if(direct_target && (get_dist(direct_target, get_turf(src)) <= 1)) // point blank shots
+ process_hit(get_turf(direct_target), direct_target)
+ if(QDELETED(src))
+ return
if(isnum(angle))
setAngle(angle)
if(spread)
@@ -506,6 +703,7 @@
var/matrix/M = new
M.Turn(Angle)
transform = M
+ LAZYINITLIST(impacted)
trajectory_ignore_forcemove = TRUE
forceMove(starting)
set_light(fired_light_range, fired_light_intensity, fired_light_color)
@@ -544,6 +742,8 @@
if(zc)
before_z_change(old, target)
. = ..()
+ if(QDELETED(src)) // we coulda bumped something
+ return
if(trajectory && !trajectory_ignore_forcemove && isturf(target))
if(hitscan)
finalize_hitscan_and_generate_tracers(FALSE)
@@ -678,30 +878,6 @@
if(prob(50))
homing_offset_y = -homing_offset_y
-//Returns true if the target atom is on our current turf and above the right layer
-//If direct target is true it's the originally clicked target.
-/obj/item/projectile/proc/can_hit_target(atom/target, list/passthrough, direct_target = FALSE, ignore_loc = FALSE)
- if(QDELETED(target))
- return FALSE
- if(!ignore_source_check && firer)
- var/mob/M = firer
- if((target == firer) || ((target == firer.loc) && ismecha(firer.loc)) || (target in firer.buckled_mobs) || (istype(M) && (M.buckled == target)))
- if(!ricochets) //if it has ricocheted, it can hit the firer.
- return FALSE
- if(!ignore_loc && (loc != target.loc))
- return FALSE
- if(target in passthrough)
- return FALSE
- if(target.density) //This thing blocks projectiles, hit it regardless of layer/mob stuns/etc.
- return TRUE
- if(!isliving(target))
- if(target.layer < PROJECTILE_HIT_THRESHHOLD_LAYER)
- return FALSE
- else
- var/mob/living/L = target
- if(!direct_target && !L.density)
- return FALSE
- return TRUE
//Spread is FORCED!
/obj/item/projectile/proc/preparePixelProjectile(atom/target, atom/source, params, spread = 0)
@@ -762,22 +938,6 @@
angle = arctan(y - oy, x - ox)
return list(angle, p_x, p_y)
-/obj/item/projectile/Crossed(atom/movable/AM) //A mob moving on a tile with a projectile is hit by it.
- . = ..()
- if(isliving(AM) && !(pass_flags & PASSMOB))
- var/mob/living/L = AM
- if(can_hit_target(L, permutated, (AM == original)))
- Bump(AM)
-
-/obj/item/projectile/Move(atom/newloc, dir = NONE)
- . = ..()
- if(.)
- if(temporary_unstoppable_movement)
- temporary_unstoppable_movement = FALSE
- movement_type &= ~(UNSTOPPABLE)
- if(fired && can_hit_target(original, permutated, TRUE))
- Bump(original)
-
/obj/item/projectile/Destroy()
STOP_PROCESSING(SSprojectiles, src)
if(hitscan)
diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm
index 79e9ab8b4b..a74a71d141 100644
--- a/code/modules/projectiles/projectile/beams.dm
+++ b/code/modules/projectiles/projectile/beams.dm
@@ -166,7 +166,7 @@
/obj/item/projectile/beam/lasertag/mag //the projectile, compatible with regular laser tag armor
icon_state = "magjectile-toy"
name = "lasertag magbolt"
- movement_type = FLYING | UNSTOPPABLE //for penetration memes
+ movement_type = FLYING | PHASING //for penetration memes
range = 5 //so it isn't super annoying
light_range = 2
light_color = LIGHT_COLOR_YELLOW
diff --git a/code/modules/projectiles/projectile/bullets/ferromagnetic.dm b/code/modules/projectiles/projectile/bullets/ferromagnetic.dm
index 03482e2a9d..1ba6ba7b79 100644
--- a/code/modules/projectiles/projectile/bullets/ferromagnetic.dm
+++ b/code/modules/projectiles/projectile/bullets/ferromagnetic.dm
@@ -28,7 +28,7 @@
damage = 10
armour_penetration = 20
stamina = 10
- movement_type = FLYING | UNSTOPPABLE
+ movement_type = FLYING | PHASING
range = 6
fired_light_range = 1
fired_light_color = LIGHT_COLOR_RED
@@ -37,7 +37,7 @@
icon_state = "magjectile-large"
damage = 10
armour_penetration = 20
- movement_type = FLYING | UNSTOPPABLE
+ movement_type = FLYING | PHASING
range = 20
pixels_per_second = TILES_TO_PIXELS(12.5)
fired_light_range = 4
diff --git a/code/modules/projectiles/projectile/bullets/sniper.dm b/code/modules/projectiles/projectile/bullets/sniper.dm
index f69b62a149..80edd716b5 100644
--- a/code/modules/projectiles/projectile/bullets/sniper.dm
+++ b/code/modules/projectiles/projectile/bullets/sniper.dm
@@ -35,7 +35,8 @@
icon_state = "gauss"
name = "penetrator round"
damage = 60
- movement_type = FLYING | UNSTOPPABLE
+ projectile_piercing = PASSMOB
+ projectile_phasing = (ALL & (~PASSMOB))
dismemberment = 0 //It goes through you cleanly.
knockdown = 0
breakthings = FALSE
diff --git a/code/modules/projectiles/projectile/bullets/special.dm b/code/modules/projectiles/projectile/bullets/special.dm
index a0414d8a9c..76ba76fbfe 100644
--- a/code/modules/projectiles/projectile/bullets/special.dm
+++ b/code/modules/projectiles/projectile/bullets/special.dm
@@ -3,7 +3,8 @@
/obj/item/projectile/bullet/honker
damage = 0
knockdown = 60
- movement_type = FLYING | UNSTOPPABLE
+ movement_type = FLYING
+ projectile_piercing = ALL
nodamage = TRUE
candink = FALSE
hitsound = 'sound/items/bikehorn.ogg'
diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm
index 76cd1a6bc5..21af43478a 100644
--- a/code/modules/projectiles/projectile/magic.dm
+++ b/code/modules/projectiles/projectile/magic.dm
@@ -344,18 +344,17 @@
var/created = FALSE //prevents creation of more then one locker if it has multiple hits
var/locker_suck = TRUE
-/obj/item/projectile/magic/locker/prehit(atom/A)
+/obj/item/projectile/magic/locker/prehit_pierce(atom/A)
+ . = ..()
if(ismob(A) && locker_suck)
var/mob/M = A
- if(M.anti_magic_check())
+ if(M.anti_magic_check()) // no this doesn't check if ..() returned to phase through do I care no it's magic ain't gotta explain shit - Silly-Cons
M.visible_message("[src] vanishes on contact with [A]!")
- qdel(src)
- return
+ return PROJECTILE_DELETE_WITHOUT_HITTING
if(M.anchored)
- return ..()
+ return
M.forceMove(src)
- return FALSE
- return ..()
+ return PROJECTILE_PIERCE_PHASE
/obj/item/projectile/magic/locker/on_hit(target)
if(created)
diff --git a/code/modules/projectiles/projectile/special/curse.dm b/code/modules/projectiles/projectile/special/curse.dm
index 6c682763ae..36c27ac0e1 100644
--- a/code/modules/projectiles/projectile/special/curse.dm
+++ b/code/modules/projectiles/projectile/special/curse.dm
@@ -12,7 +12,6 @@
knockdown = 20
pixels_per_second = TILES_TO_PIXELS(5)
range = 16
- movement_type = FLYING | UNSTOPPABLE
var/datum/beam/arm
var/handedness = 0
@@ -29,18 +28,14 @@
arm = starting.Beam(src, icon_state = "curse[handedness]", time = INFINITY, maxdistance = INFINITY, beam_type=/obj/effect/ebeam/curse_arm)
..()
-/obj/item/projectile/curse_hand/prehit(atom/target)
- if(target == original)
- movement_type &= ~(UNSTOPPABLE)
- else if(!isturf(target))
- return FALSE
- return ..()
+/obj/projectile/curse_hand/prehit_pierce(atom/target)
+ return (target == original)? PROJECTILE_PIERCE_NONE : PROJECTILE_PIERCE_PHASE
/obj/item/projectile/curse_hand/Destroy()
if(arm)
arm.End()
arm = null
- if((movement_type & UNSTOPPABLE))
+ if((movement_type & PHASING))
playsound(src, 'sound/effects/curse3.ogg', 25, 1, -1)
var/turf/T = get_step(src, dir)
var/obj/effect/temp_visual/dir_setting/curse/hand/leftover = new(T, dir)
diff --git a/code/modules/ruins/objects_and_mobs/necropolis_gate.dm b/code/modules/ruins/objects_and_mobs/necropolis_gate.dm
index d62b3c2611..54e07d24e5 100644
--- a/code/modules/ruins/objects_and_mobs/necropolis_gate.dm
+++ b/code/modules/ruins/objects_and_mobs/necropolis_gate.dm
@@ -59,10 +59,10 @@
/obj/structure/necropolis_gate/singularity_pull()
return 0
-/obj/structure/necropolis_gate/CanPass(atom/movable/mover, turf/target)
- if(get_dir(loc, target) == dir)
- return !density
- return 1
+/obj/structure/necropolis_gate/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
+ if(!(get_dir(loc, target) == dir))
+ return TRUE
/obj/structure/necropolis_gate/CheckExit(atom/movable/O, target)
if(get_dir(O.loc, target) == dir)
diff --git a/code/modules/ruins/objects_and_mobs/sin_ruins.dm b/code/modules/ruins/objects_and_mobs/sin_ruins.dm
index 5e2fc3d7e4..da6179197c 100644
--- a/code/modules/ruins/objects_and_mobs/sin_ruins.dm
+++ b/code/modules/ruins/objects_and_mobs/sin_ruins.dm
@@ -80,7 +80,8 @@
icon = 'icons/mob/blob.dmi'
color = rgb(145, 150, 0)
-/obj/effect/gluttony/CanPass(atom/movable/mover, turf/target)//So bullets will fly over and stuff.
+/obj/effect/gluttony/CanAllowThrough(atom/movable/mover, turf/target)//So bullets will fly over and stuff.
+ . = ..()
if(ishuman(mover))
var/mob/living/carbon/human/H = mover
if(H.nutrition >= NUTRITION_LEVEL_FAT)
@@ -90,8 +91,6 @@
to_chat(H, "You're repulsed by even looking at [src]. Only a pig could force themselves to go through it.")
if(istype(mover, /mob/living/simple_animal/hostile/morph))
return TRUE
- else
- return FALSE
/obj/structure/mirror/magic/pride //Pride's mirror: Used in the Pride ruin.
name = "pride's mirror"
diff --git a/code/modules/shuttle/special.dm b/code/modules/shuttle/special.dm
index 05450fd7c2..274efcda5a 100644
--- a/code/modules/shuttle/special.dm
+++ b/code/modules/shuttle/special.dm
@@ -212,15 +212,14 @@
var/static/list/check_times = list()
-/obj/effect/forcefield/luxury_shuttle/CanPass(atom/movable/mover, turf/target)
+/obj/effect/forcefield/luxury_shuttle/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
if(mover in approved_passengers)
return TRUE
if(!isliving(mover)) //No stowaways
return FALSE
- return FALSE
-
#define LUXURY_MESSAGE_COOLDOWN 100
/obj/effect/forcefield/luxury_shuttle/Bumped(atom/movable/AM)
diff --git a/code/modules/spells/spell_types/forcewall.dm b/code/modules/spells/spell_types/forcewall.dm
index e0c21066cf..be7bb4cbd3 100644
--- a/code/modules/spells/spell_types/forcewall.dm
+++ b/code/modules/spells/spell_types/forcewall.dm
@@ -30,11 +30,11 @@
. = ..()
wizard = summoner
-/obj/effect/forcefield/wizard/CanPass(atom/movable/mover, turf/target)
+/obj/effect/forcefield/wizard/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
if(mover == wizard)
return TRUE
if(ismob(mover))
var/mob/M = mover
if(M.anti_magic_check(chargecost = 0))
return TRUE
- return FALSE
diff --git a/code/modules/vehicles/ridden.dm b/code/modules/vehicles/ridden.dm
index f71d9367d3..28b79a1599 100644
--- a/code/modules/vehicles/ridden.dm
+++ b/code/modules/vehicles/ridden.dm
@@ -4,6 +4,7 @@
max_buckled_mobs = 1
buckle_lying = FALSE
default_driver_move = FALSE
+ pass_flags_self = PASSTABLE
var/legs_required = 1
var/arms_required = 0 //why not?