mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 02:09:41 +00:00
Port/add throwing subsystem
This commit is contained in:
@@ -422,92 +422,24 @@
|
||||
continue
|
||||
src.throw_impact(A,speed)
|
||||
|
||||
/atom/movable/proc/throw_at(atom/target, range, speed, thrower)
|
||||
if(!target || !src)
|
||||
return 0
|
||||
if(target.z != src.z)
|
||||
return 0
|
||||
//use a modified version of Bresenham's algorithm to get from the atom's current position to that of the target
|
||||
src.throwing = 1
|
||||
src.thrower = thrower
|
||||
src.throw_source = get_turf(src) //store the origin turf
|
||||
src.pixel_z = 0
|
||||
if(usr)
|
||||
if(HULK in usr.mutations)
|
||||
src.throwing = 2 // really strong throw!
|
||||
/atom/movable/proc/throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, datum/callback/callback) //If this returns FALSE then callback will not be called.
|
||||
. = TRUE
|
||||
if (!target || speed <= 0 || QDELETED(src) || (target.z != src.z))
|
||||
return FALSE
|
||||
|
||||
var/dist_travelled = 0
|
||||
var/dist_since_sleep = 0
|
||||
var/area/a = get_area(src.loc)
|
||||
if (pulledby)
|
||||
pulledby.stop_pulling()
|
||||
|
||||
var/dist_x = abs(target.x - src.x)
|
||||
var/dist_y = abs(target.y - src.y)
|
||||
var/datum/thrownthing/TT = new(src, target, range, speed, thrower, callback)
|
||||
throwing = TT
|
||||
|
||||
var/dx
|
||||
if (target.x > src.x)
|
||||
dx = EAST
|
||||
else
|
||||
dx = WEST
|
||||
|
||||
var/dy
|
||||
if (target.y > src.y)
|
||||
dy = NORTH
|
||||
else
|
||||
dy = SOUTH
|
||||
|
||||
var/error
|
||||
var/major_dir
|
||||
var/major_dist
|
||||
var/minor_dir
|
||||
var/minor_dist
|
||||
if(dist_x > dist_y)
|
||||
error = dist_x/2 - dist_y
|
||||
major_dir = dx
|
||||
major_dist = dist_x
|
||||
minor_dir = dy
|
||||
minor_dist = dist_y
|
||||
else
|
||||
error = dist_y/2 - dist_x
|
||||
major_dir = dy
|
||||
major_dist = dist_y
|
||||
minor_dir = dx
|
||||
minor_dist = dist_x
|
||||
|
||||
range = min(dist_x + dist_y, range)
|
||||
|
||||
while(src && target && src.throwing && istype(src.loc, /turf) \
|
||||
&& ((abs(target.x - src.x)+abs(target.y - src.y) > 0 && dist_travelled < range) \
|
||||
|| (a && a.has_gravity == 0) \
|
||||
|| istype(src.loc, /turf/space)))
|
||||
// only stop when we've gone the whole distance (or max throw range) and are on a non-space tile, or hit something, or hit the end of the map, or someone picks it up
|
||||
var/atom/step
|
||||
if(error >= 0)
|
||||
step = get_step(src, major_dir)
|
||||
error -= minor_dist
|
||||
else
|
||||
step = get_step(src, minor_dir)
|
||||
error += major_dist
|
||||
if(!step) // going off the edge of the map makes get_step return null, don't let things go off the edge
|
||||
break
|
||||
src.Move(step)
|
||||
hit_check(speed)
|
||||
dist_travelled++
|
||||
dist_since_sleep++
|
||||
if(dist_since_sleep >= speed)
|
||||
dist_since_sleep = 0
|
||||
sleep(1)
|
||||
a = get_area(src.loc)
|
||||
// and yet it moves
|
||||
if(src.does_spin)
|
||||
src.SpinAnimation(speed = 4, loops = 1)
|
||||
|
||||
//done throwing, either because it hit something or it finished moving
|
||||
if(isobj(src)) src.throw_impact(get_turf(src),speed)
|
||||
src.throwing = 0
|
||||
src.thrower = null
|
||||
src.throw_source = null
|
||||
fall()
|
||||
pixel_z = 0
|
||||
if(spin && does_spin)
|
||||
SpinAnimation(4,1)
|
||||
|
||||
SSthrowing.processing[src] = TT
|
||||
if (SSthrowing.state == SS_PAUSED && length(SSthrowing.currentrun))
|
||||
SSthrowing.currentrun[src] = TT
|
||||
|
||||
//Overlays
|
||||
/atom/movable/overlay
|
||||
|
||||
Reference in New Issue
Block a user