diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm
index 9ddae527eec..0da4f75e1bf 100644
--- a/code/__DEFINES/flags.dm
+++ b/code/__DEFINES/flags.dm
@@ -42,11 +42,12 @@
the atom/checkpass() proc uses them (tables will call movable atom checkpass(PASSTABLE) for example)
*/
//flags for pass_flags
-#define PASSTABLE 1
-#define PASSGLASS 2
-#define PASSGRILLE 4
-#define PASSBLOB 8
-#define PASSMOB 16
+#define PASSTABLE 1
+#define PASSGLASS 2
+#define PASSGRILLE 4
+#define PASSBLOB 8
+#define PASSMOB 16
+#define LETPASSTHROW 32
//flags for species
diff --git a/code/_onclick/adjacent.dm b/code/_onclick/adjacent.dm
index 20aeb967d29..fb06dacb3d0 100644
--- a/code/_onclick/adjacent.dm
+++ b/code/_onclick/adjacent.dm
@@ -23,7 +23,7 @@
* If you are in the same turf, always true
* If you are vertically/horizontally adjacent, ensure there are no border objects
* If you are diagonally adjacent, ensure you can pass through at least one of the mutually adjacent square.
- * Passing through in this case ignores anything with the throwpass flag, such as tables, racks, and morgue trays.
+ * Passing through in this case ignores anything with the LETPASSTHROW pass flag, such as tables, racks, and morgue trays.
*/
/turf/Adjacent(var/atom/neighbor, var/atom/target = null)
var/turf/T0 = get_turf(neighbor)
@@ -80,28 +80,18 @@
/*
This checks if you there is uninterrupted airspace between that turf and this one.
- This is defined as any dense ON_BORDER object, or any dense object without throwpass.
+ This is defined as any dense ON_BORDER object, or any dense object without LETPASSTHROW.
The border_only flag allows you to not objects (for source and destination squares)
*/
/turf/proc/ClickCross(var/target_dir, var/border_only, var/target_atom = null)
for(var/obj/O in src)
- if( !O.density || O == target_atom || O.throwpass) //check if there's a dense object present on the turf
- continue // throwpass is used for anything you can click through (or the firedoor special case, see above)
+ if( !O.density || O == target_atom || (O.pass_flags & 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&ON_BORDER) // windows have throwpass but are on border, check them first
+ if( O.flags&ON_BORDER) // windows are on border, check them first
if( O.dir & target_dir || O.dir & (O.dir-1) ) // full tile windows are just diagonals mechanically
return 0 //O.dir&(O.dir-1) is false for any cardinal direction, but true for diagonal ones
else if( !border_only ) // dense, not on border, cannot pass over
return 0
return 1
-
-/*
- Aside: throwpass does not do what I thought it did originally, and is only used for checking whether or not
- a thrown object should stop after already successfully entering a square. Currently the throw code involved
- only seems to affect hitting mobs, because the checks performed against objects are already performed when
- entering or leaving the square. Since throwpass isn't used on mobs, but only on objects, it is effectively
- useless. Throwpass may later need to be removed and replaced with a passcheck (bitfield on movable atom passflags).
-
- Since I don't want to complicate the click code rework by messing with unrelated systems it won't be changed here.
-*/
\ No newline at end of file
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 95c8c95dabf..a524b655a7f 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -6,7 +6,6 @@
var/list/fingerprintshidden
var/fingerprintslast = null
var/list/blood_DNA
- var/throwpass = 0
///Chemistry.
var/datum/reagents/reagents = null
@@ -260,7 +259,7 @@ its easier to just keep the beam vertical.
/atom/proc/fire_act()
return
-/atom/proc/hitby(atom/movable/AM, mob/thrower, skip, var/hitpush)
+/atom/proc/hitby(atom/movable/AM, skip, var/hitpush)
if(density && !has_gravity(AM)) //thrown stuff bounces off dense stuff in no grav.
spawn(2)
step(AM, turn(AM.dir, 180))
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 8c20fc83801..76e6adc3213 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -93,7 +93,7 @@
/atom/movable/Crossed(atom/movable/AM)
return
-/atom/movable/Bump(var/atom/A as mob|obj|turf|area, yes) //the "yes" arg is to differentiate our Bump proc from byond's, without it every Bump() call would become a double Bump().
+/atom/movable/Bump(atom/A, yes) //the "yes" arg is to differentiate our Bump proc from byond's, without it every Bump() call would become a double Bump().
if((A && yes))
if(throwing)
throwing = 0
@@ -149,20 +149,20 @@
/atom/movable/proc/checkpass(passflag)
return pass_flags&passflag
-/atom/movable/proc/throw_impact(atom/hit_atom, mob/thrower)
- return hit_atom.hitby(src,thrower)
+/atom/movable/proc/throw_impact(atom/hit_atom)
+ return hit_atom.hitby(src)
-/atom/movable/hitby(atom/movable/AM, mob/thrower, skip, var/hitpush = 1)
+/atom/movable/hitby(atom/movable/AM, skip, var/hitpush = 1)
if(!anchored && hitpush)
step(src, AM.dir)
return ..()
-/atom/movable/proc/throw_at(atom/target, range, speed, mob/thrower, spin=1)
+/atom/movable/proc/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0)
if(!target || !src || (flags & NODROP)) return 0
//use a modified version of Bresenham's algorithm to get from the atom's current position to that of the target
throwing = 1
- if(spin) // turns out 1000+ spinning objects being thrown at the singularity creates lag - Iamgoofball
+ if(spin) //if we don't want the /atom/movable to spin.
SpinAnimation(5, 1)
var/dist_travelled = 0
@@ -173,6 +173,10 @@
var/dx = (target.x > src.x) ? EAST : WEST
var/dy = (target.y > src.y) ? NORTH : SOUTH
+ var/pure_diagonal = 0
+ if(dist_x == dist_y)
+ pure_diagonal = 1
+
if(dist_x <= dist_y)
var/olddist_x = dist_x
var/olddx = dx
@@ -182,25 +186,24 @@
dy = olddx
var/error = dist_x/2 - dist_y
-
- var/throw_range = min(range, dist_x + dist_y)
-
+ var/atom/finalturf = get_turf(target)
var/hit = 0
- while(target && (dist_travelled < throw_range || !has_gravity(src)))
- // only stop when we've gone the whole distance (or max throw range) and aren't floating, or hit something, or hit the end of the map, or someone picks it up
- if(!throwing)
- hit = 1
- break
+
+ while(target && ((dist_travelled < range && loc != finalturf) || !has_gravity(src))) //stop if we reached our destination (or max range) and aren't floating
+
if(!istype(loc, /turf))
hit = 1
break
- var/atom/step = get_step(src, (error < 0) ? dy : dx)
- error += (error < 0) ? dist_x : -dist_y
+ var/atom/step = get_step(src, get_dir(src, target))
+ if(!pure_diagonal && !diagonals_first) // not a purely diagonal trajectory and we don't want all diagonal moves to be done first
+ if(error >= 0 && get_dist(src, finalturf) > 1)
+ step = get_step(src, dx)
+ error += (error < 0) ? dist_x/2 : -dist_y
if(!step) // going off the edge of the map makes get_step return null, don't let things go off the edge
break
Move(step, get_dir(loc, step))
- if(!throwing)
+ if(!throwing) // we hit something during our move
hit = 1
break
dist_travelled++
@@ -209,18 +212,29 @@
dist_since_sleep = 0
sleep(1)
+ if(!dist_since_sleep && hitcheck()) //to catch sneaky things moving on our tile during our sleep(1)
+ hit = 1
+ break
+
//done throwing, either because it hit something or it finished moving
throwing = 0
- for(var/atom/A in get_turf(src)) //looking for our target on the turf we land on.
- if(A == target)
- hit = 1
- throw_impact(A, thrower)
-
- if(!hit) // we haven't hit something yet and we still must, let's hit the ground.
- throw_impact(get_turf(src),thrower)
+ if(!hit)
+ for(var/atom/A in get_turf(src)) //looking for our target on the turf we land on.
+ if(A == target)
+ hit = 1
+ throw_impact(A)
+ return 1
+ throw_impact(get_turf(src)) // we haven't hit something yet and we still must, let's hit the ground.
return 1
+/atom/movable/proc/hitcheck()
+ for(var/atom/movable/AM in get_turf(src))
+ if(AM == src)
+ continue
+ if(AM.density && !(AM.pass_flags & LETPASSTHROW) && !(AM.flags & ON_BORDER))
+ throw_impact(AM)
+ return 1
//Overlays
/atom/movable/overlay
diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm
index 60cb2429040..aaac82f87df 100644
--- a/code/game/gamemodes/cult/cult_structures.dm
+++ b/code/game/gamemodes/cult/cult_structures.dm
@@ -33,9 +33,3 @@
density = 1
unacidable = 1
anchored = 1.0
-
-/obj/effect/gateway/Bumped(mob/M as mob|obj)
- return
-
-/obj/effect/gateway/Crossed(AM as mob|obj)
- return
\ No newline at end of file
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 09147da601f..2024cca7d7f 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -55,6 +55,8 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
var/suittoggled = 0
var/hooded = 0
+ var/mob/thrownby = null
+
/obj/item/mouse_drag_pointer = MOUSE_ACTIVE_POINTER //the icon to indicate this object is being dragged
//So items can have custom embedd values
@@ -465,13 +467,14 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
if(!findtext(desc, "it looks slightly melted...")) //it looks slightly melted... it looks slightly melted... it looks slightly melted... etc.
desc += " it looks slightly melted..." //needs a space at the start, formatting
-/obj/item/throw_impact(atom/A, mob/thrower)
+/obj/item/throw_impact(atom/A)
var/itempush = 1
if(w_class < 4)
itempush = 0 //too light to push anything
- return A.hitby(src,thrower, 0, itempush)
+ return A.hitby(src,thrownby, 0, itempush)
/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1)
+ thrownby = thrower
. = ..()
throw_speed = initial(throw_speed) //explosions change this.
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index 697f718d095..1f00d290936 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -79,12 +79,10 @@
return 1
/obj/structure/closet/proc/dump_contents()
-
for(var/obj/O in src)
O.loc = loc
if(throwing) //you keep some momentum when getting out of a thrown closet
- spawn(2) //some time to avoid a collision between the obj and the closet/crate
- step(O, dir)
+ step(O, dir)
for(var/mob/M in src)
M.loc = loc
@@ -92,8 +90,9 @@
M.client.eye = M.client.mob
M.client.perspective = MOB_PERSPECTIVE
if(throwing)
- spawn(2)
- step(M, dir)
+ step(M, dir)
+ if(throwing)
+ throwing = 0
/obj/structure/closet/proc/take_contents()
@@ -106,14 +105,13 @@
return 0
if(!can_open())
return 0
- dump_contents()
-
opened = 1
if(istype(src, /obj/structure/closet/body_bag))
playsound(loc, 'sound/items/zip.ogg', 15, 1, -3)
else
playsound(loc, 'sound/machines/click.ogg', 15, 1, -3)
density = 0
+ dump_contents()
update_icon()
return 1
diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm
index 472f46939f1..87efe8ccffd 100644
--- a/code/game/objects/structures/morgue.dm
+++ b/code/game/objects/structures/morgue.dm
@@ -226,7 +226,7 @@ Crematorium Switch
layer = 2.9
var/obj/structure/bodycontainer/connected = null
anchored = 1.0
- throwpass = 1
+ pass_flags = LETPASSTHROW
/obj/structure/tray/Destroy()
if(connected)
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index 02c24df2966..2a61a56a3d5 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -20,7 +20,7 @@
density = 1
anchored = 1.0
layer = 2.8
- throwpass = 1 //You can throw objects over this, despite it's density.")
+ pass_flags = LETPASSTHROW //You can throw objects over this, despite it's density.")
var/frame = /obj/structure/table_frame
var/framestack = /obj/item/stack/rods
var/buildstack = /obj/item/stack/sheet/metal
@@ -364,7 +364,7 @@
icon_state = "rack"
density = 1
anchored = 1.0
- throwpass = 1 //You can throw objects over this, despite it's density.
+ pass_flags = LETPASSTHROW //You can throw objects over this, despite it's density.
var/health = 5
/obj/structure/rack/ex_act(severity, target)
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index 04c1128c9fb..c1a695be39c 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -191,10 +191,10 @@ Gunshots/explosions/opening doors/less rare audio (done)
xeno = new(pump.loc,target)
sleep(10)
xeno.update_icon("alienh_leap",'icons/mob/alienleap.dmi',-32,-32)
- xeno.throw_at(target,7,1)
+ xeno.throw_at(target,7,1, spin = 0, diagonals_first = 1)
sleep(10)
xeno.update_icon("alienh_leap",'icons/mob/alienleap.dmi',-32,-32)
- xeno.throw_at(pump,7,1)
+ xeno.throw_at(pump,7,1, spin = 0, diagonals_first = 1)
sleep(10)
var/xeno_name = xeno.name
target << "[xeno_name] begins climbing into the ventilation system..."
diff --git a/code/modules/mob/living/carbon/alien/alien_defense.dm b/code/modules/mob/living/carbon/alien/alien_defense.dm
index e217683f129..1684d948211 100644
--- a/code/modules/mob/living/carbon/alien/alien_defense.dm
+++ b/code/modules/mob/living/carbon/alien/alien_defense.dm
@@ -1,5 +1,5 @@
-/mob/living/carbon/alien/hitby(atom/movable/AM, mob/thrower)
- ..(AM, thrower, skip = 1)
+/mob/living/carbon/alien/hitby(atom/movable/AM)
+ ..(AM, skip = 1)
/*Code for aliens attacking aliens. Because aliens act on a hivemind, I don't see them as very aggressive with each other.
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
index e27983fd18d..61544e0f8ee 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
@@ -82,7 +82,7 @@
else //Maybe uses plasma in the future, although that wouldn't make any sense...
leaping = 1
update_icons()
- throw_at(A,MAX_ALIEN_LEAP_DIST,1, spin=0)
+ throw_at(A,MAX_ALIEN_LEAP_DIST,1, spin=0, diagonals_first = 1)
leaping = 0
update_icons()
@@ -113,8 +113,6 @@
update_canmove()
-
-
/mob/living/carbon/alien/humanoid/float(on)
if(leaping)
return
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index 24f9192cca3..0af1f998eb7 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -1,4 +1,4 @@
-/mob/living/carbon/hitby(atom/movable/AM, mob/thrower, skip)
+/mob/living/carbon/hitby(atom/movable/AM, skip)
if(!skip) //ugly, but easy
if(in_throw_mode && !get_active_hand()) //empty active hand and we're in throw mode
if(canmove && !restrained())
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index f1fa58c8509..392d741ae41 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -455,7 +455,7 @@ emp_act
else
..()
-/mob/living/carbon/human/hitby(atom/movable/AM, mob/thrower)
+/mob/living/carbon/human/hitby(atom/movable/AM)
if(throw_speed >= EMBED_THROWSPEED_THRESHOLD)
if(istype(AM, /obj/item))
var/obj/item/I = AM
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 4e47819cd1a..2bdfdb8dba2 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -52,7 +52,7 @@ Sorry Giacom. Please don't be mad :(
//Generic Bump(). Override MobBump() and ObjBump() instead of this.
/mob/living/Bump(atom/A, yes)
- if(..()) //bumped by a thrown /atom/movable
+ if(..()) //we are thrown onto something
return
if (buckled || !yes || now_pushing)
return
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 05711d54ae1..5e219f90060 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -44,13 +44,13 @@
else
return 0
-/mob/living/throw_impact(atom/hit_atom, mob/thrower)
+/mob/living/throw_impact(atom/hit_atom)
. = ..()
if(hit_atom.density)
Weaken(1)
take_organ_damage(10)
-/mob/living/hitby(atom/movable/AM, mob/thrower)
+/mob/living/hitby(atom/movable/AM)
if(istype(AM, /obj/item))
var/obj/item/I = AM
var/zone = ran_zone("chest", 65)//Hits a random part of the body, geared towards the chest
@@ -77,10 +77,10 @@
"[src] has been hit by [I].")
var/armor = run_armor_check(zone, "melee", "Your armor has protected your [parse_zone(zone)].", "Your armor has softened hit to your [parse_zone(zone)].",I.armour_penetration)
apply_damage(I.throwforce, dtype, zone, armor, I)
+ if(I.thrownby)
+ add_logs(I.thrownby, src, "hit", object="[AM]")
else
playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1)
- if(thrower)
- add_logs(thrower, src, "hit", object="[AM]")
return ..()
/mob/living/mech_melee_attack(obj/mecha/M)
diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm
index c4c24929e39..b76994178fe 100644
--- a/code/modules/reagents/reagent_containers.dm
+++ b/code/modules/reagents/reagent_containers.dm
@@ -79,7 +79,7 @@
reagents.handle_reactions()
..()
-/obj/item/weapon/reagent_containers/throw_impact(atom/target,mob/thrower)
+/obj/item/weapon/reagent_containers/throw_impact(atom/target)
. = ..()
if(!reagents.total_volume || !spillable)
@@ -96,11 +96,11 @@
R += A.id + " ("
R += num2text(A.volume) + "),"
- if(thrower)
- add_logs(thrower, M, "splashed", object="[R]")
+ if(thrownby)
+ add_logs(thrownby, M, "splashed", object="[R]")
reagents.reaction(target, TOUCH)
- else if((target.CanPass(src, get_turf(src))) && thrower && thrower.mind && thrower.mind.assigned_role == "Bartender")
+ else if((target.CanPass(src, get_turf(src))) && thrownby && thrownby.mind && thrownby.mind.assigned_role == "Bartender")
visible_message("[src] lands onto the [target.name] without spilling a single drop.")
return