mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-27 23:27:34 +01:00
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().
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
+1
-2
@@ -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))
|
||||
|
||||
+38
-24
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 << "<span class='notice'>[xeno_name] begins climbing into the ventilation system...</span>"
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 @@
|
||||
"<span class='userdanger'>[src] has been hit by [I].</span>")
|
||||
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)
|
||||
|
||||
@@ -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("<span class='notice'>[src] lands onto the [target.name] without spilling a single drop.</span>")
|
||||
return
|
||||
|
||||
|
||||
Reference in New Issue
Block a user