From 9eced1ac5b0da035dc83e4f1203e2e0afa5c6723 Mon Sep 17 00:00:00 2001 From: phil235 Date: Sun, 19 Jul 2015 21:29:35 +0200 Subject: [PATCH] Fixes thrown closet opening to not use spawn(). Fixes throw_at() to look nicely for xeno leap by adding the diagonals_first argument. Removes useless gateway/Crossed and gateway/Bumped(). Changes throw_at() to use diagonal directions. I replaced the atom variable "throwpass" with the LETPASSTHROW pass_flags I readded hit_check proc to catch things getting on the thrown thing's tile during its sleep(1) (especially needed for mobs running towards the thing), the only other possibility would've been to add throwing checks in atom/movable/Crossed() (called after every move) and I don't think it'd be worth it. I added the item var "thrownby" to be able to continue to log the thrower of the item when it hits a mob. It removes the need for a thrower argument in throw_impact() and hitby(). --- code/__DEFINES/flags.dm | 11 ++-- code/_onclick/adjacent.dm | 20 ++---- code/game/atoms.dm | 3 +- code/game/atoms_movable.dm | 62 ++++++++++++------- code/game/gamemodes/cult/cult_structures.dm | 6 -- code/game/objects/items.dm | 7 ++- .../structures/crates_lockers/closets.dm | 12 ++-- code/game/objects/structures/morgue.dm | 2 +- code/game/objects/structures/tables_racks.dm | 4 +- code/modules/flufftext/Hallucination.dm | 4 +- .../mob/living/carbon/alien/alien_defense.dm | 4 +- .../carbon/alien/humanoid/caste/hunter.dm | 4 +- .../mob/living/carbon/carbon_defense.dm | 2 +- .../mob/living/carbon/human/human_defense.dm | 2 +- code/modules/mob/living/living.dm | 2 +- code/modules/mob/living/living_defense.dm | 8 +-- code/modules/reagents/reagent_containers.dm | 8 +-- 17 files changed, 79 insertions(+), 82 deletions(-) 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