proc/bounds_align(atom/movable/ref, atom/movable/trg, dir = SOUTH, offset = 0)
if(!ref || !trg) return
// save this incase the movement jump fails.
var turf/old_loc = ref.loc
// if the movement is successful, we want to let
// the atoms in ref's old location know.
var list/old_bounds = bounds(ref)
// Move() performs a jump if the distance traveled is
// greater than ref's step_size or world.icon_size (whichever's larger),
// and the target location is on the same z plane.
// For the best results, forcing a jump is necessary.
ref.loc = locate(1, 1, 1)
var move_x = (dir & (EAST | WEST)) ? (dir & EAST) ? (trg.step_x + ref.bound_width + offset) : (trg.step_x - ref.bound_width - offset) : (trg.step_x)
var move_y = (dir & (NORTH | SOUTH)) ? (dir & NORTH) ? (trg.step_y + ref.bound_height + offset) : (trg.step_y - ref.bound_height - offset) : (trg.step_y)
. = ref.Move(trg.loc, ref.dir, move_x, move_y)
if(.)
var atom/movable/a
for(a in old_bounds)
a.Uncrossed(ref)
old_loc.Exited(ref)
if(old_loc.loc)
old_loc.loc.Exited(ref)
else
ref.loc = old_loc
Here's numbers from Dream Daemon's Profiler for those interested:
Edit (05.17.16): Fixed an oversight in the offset calculation that could cause incorrect results at times. Also modified the proc to take a single 'offset' value as opposed to an offset for x and y.