diff --git a/code/__defines/_planes+layers.dm b/code/__defines/_planes+layers.dm index faaa475894..60557d1dd7 100644 --- a/code/__defines/_planes+layers.dm +++ b/code/__defines/_planes+layers.dm @@ -71,6 +71,7 @@ What is the naming convention for planes or layers? #define HIDING_LAYER 2.6 // Layer at which mobs hide to be under things like tables #define DOOR_OPEN_LAYER 2.7 // Under all objects if opened. 2.7 due to tables being at 2.6 #define TABLE_LAYER 2.8 // Just under stuff that wants to be slightly below common objects. + #define PROJECTILE_HIT_THRESHOLD_LAYER 2.8 #define UNDER_JUNK_LAYER 2.9 // Things that want to be slightly below common objects // Turf/Obj layer boundary #define ABOVE_JUNK_LAYER 3.1 // Things that want to be slightly above common objects diff --git a/code/__defines/flags.dm b/code/__defines/flags.dm index 5b6152e6d2..8af1d98622 100644 --- a/code/__defines/flags.dm +++ b/code/__defines/flags.dm @@ -43,3 +43,4 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204 #define PASSGLASS (1<<1) #define PASSGRILLE (1<<2) #define PASSBLOB (1<<3) +#define PASSMOB (1<<4) diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm new file mode 100644 index 0000000000..3143c914a0 --- /dev/null +++ b/code/modules/mob/living/living_movement.dm @@ -0,0 +1,31 @@ +/mob/CanPass(atom/movable/mover, turf/target, height, air_group) + if(air_group || (height == 0)) + return TRUE + + if(ismob(mover)) + var/mob/moving_mob = mover + if ((other_mobs && moving_mob.other_mobs)) + 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) + return (!mover.density || !density || lying) + +/* +/mob/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) + if(air_group || (height==0)) return 1 + + if((mover.pass_flags & PASSMOB)) + return TRUE + if(istype(mover, /obj/item/projectile) || mover.throwing) + return (!density || !(mobility_flags & MOBILITY_STAND)) + if(buckled == mover) + return TRUE + if(ismob(mover)) + var/mob/moving_mob = mover + if ((other_mobs && moving_mob.other_mobs)) + return TRUE + if (mover in buckled_mobs) + return TRUE + return (!mover.density || !density || !(mobility_flags & MOBILITY_STAND)) +*/ diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 60afcdf558..b6f7121455 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -1,34 +1,3 @@ -/mob/CanPass(atom/movable/mover, turf/target, height, air_group) - if(air_group || !height) - return TRUE - - if(ismob(mover)) - var/mob/moving_mob = mover - if ((other_mobs && moving_mob.other_mobs)) - return 1 - return (!mover.density || !density || lying) - else - return (!mover.density || !density || lying) - -/* -/mob/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0)) return 1 - - if((mover.pass_flags & PASSMOB)) - return TRUE - if(istype(mover, /obj/item/projectile) || mover.throwing) - return (!density || !(mobility_flags & MOBILITY_STAND)) - if(buckled == mover) - return TRUE - if(ismob(mover)) - var/mob/moving_mob = mover - if ((other_mobs && moving_mob.other_mobs)) - return TRUE - if (mover in buckled_mobs) - return TRUE - return (!mover.density || !density || !(mobility_flags & MOBILITY_STAND)) -*/ - /mob/proc/setMoveCooldown(var/timeout) move_delay = max(world.time + timeout, move_delay) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index ed4d0a639f..39aba2a710 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -24,6 +24,7 @@ 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! + var/ignore_source_check = FALSE var/speed = 0.8 //Amount of deciseconds it takes for projectile to travel var/Angle = 0 @@ -114,6 +115,8 @@ var/vacuum_traversal = TRUE //Determines if the projectile can exist in vacuum, if false, the projectile will be deleted if it enters vacuum. + var/temporary_unstoppable_movement = FALSE + /obj/item/projectile/proc/Range() range-- if(range <= 0 && loc) @@ -206,8 +209,10 @@ /obj/item/projectile/Crossed(atom/movable/AM) //A mob moving on a tile with a projectile is hit by it. ..() - if(isliving(AM) && (AM.density || AM == original)) - Bump(AM) + if(isliving(AM) && !(pass_flags & PASSMOB)) + var/mob/living/L = AM + if(can_hit_target(L, permutated, (AM == original))) + Bump(AM) /obj/item/projectile/proc/process_homing() //may need speeding up in the future performance wise. if(!homing_target) @@ -312,6 +317,15 @@ START_PROCESSING(SSprojectiles, src) pixel_move(1, FALSE) //move it now! +/obj/item/projectile/Move(atom/newloc, dir = NONE) + . = ..() + if(.) + if(temporary_unstoppable_movement) + temporary_unstoppable_movement = FALSE + DISABLE_BITFIELD(movement_type, UNSTOPPABLE) + if(fired && can_hit_target(original, permutated, TRUE)) + Bump(original) + /obj/item/projectile/proc/after_z_change(atom/olcloc, atom/newloc) /obj/item/projectile/proc/before_z_change(atom/oldloc, atom/newloc) @@ -452,11 +466,35 @@ cleanup_beam_segments() //Returns true if the target atom is on our current turf and above the right layer -/obj/item/projectile/proc/can_hit_target(atom/target, var/list/passthrough) - return (target && ((target.layer >= TABLE_LAYER) || ismob(target)) && (loc == get_turf(target)) && (!(target in passthrough))) +//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) && istype(firer.loc, /obj/mecha)) || (target in firer.buckled_mobs) || (istype(M) && (M.buckled == target))) + 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) + if(!L.density) + return FALSE + return TRUE /obj/item/projectile/Bump(atom/A) if(A in permutated) + trajectory_ignore_forcemove = TRUE + forceMove(get_turf(A)) + trajectory_ignore_forcemove = FALSE return FALSE if(firer && !reflected) if(A == firer || (A == firer.loc && istype(A, /obj/mecha))) //cannot shoot yourself or your mech diff --git a/polaris.dme b/polaris.dme index 39da324e1c..9893c3279e 100644 --- a/polaris.dme +++ b/polaris.dme @@ -1853,6 +1853,7 @@ #include "code\modules\mob\living\living.dm" #include "code\modules\mob\living\living_defense.dm" #include "code\modules\mob\living\living_defines.dm" +#include "code\modules\mob\living\living_movement.dm" #include "code\modules\mob\living\living_powers.dm" #include "code\modules\mob\living\login.dm" #include "code\modules\mob\living\logout.dm"