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