ID:195137
 
//Title: Line Calculation
//Credit to: Jtgibson
//Contributed by: Jtgibson


//This returns a precise list of turfs in a near-perfect
// line from point A to point B. The turfs are presented
// in order of distance, so they can be used to follow a
// path.


proc/get_line(atom/A, atom/B)
var/x_dif = B.x - A.x
var/y_dif = B.y - A.y

if(A.z != B.z) return(list())
if(!A.loc || !B.loc) return(list())

if(!x_dif && !y_dif) return(list(A.loc)) //prevent divide by zero errors

if(abs(x_dif) > abs(y_dif)) //horizontal-tending line
var/y_offset = y_dif/abs(x_dif)

var/list/line = list()

for(var/x_offset = 0, abs(x_offset) <= abs(x_dif),)
var/x_pos = A.x + x_offset
var/y_pos = A.y + (abs(x_offset)*y_offset)

var/turf/T = locate(x_pos, y_pos, A.z)
line += T

if(x_dif < 0) x_offset--
else x_offset++

return(line)

else if(abs(y_dif) > abs(x_dif)) //vertical-tending line
var/x_offset = x_dif/abs(y_dif)

var/list/line = list()

for(var/y_offset = 0, abs(y_offset) <= abs(y_dif),)
var/x_pos = A.x + (abs(y_offset)*x_offset)
var/y_pos = A.y + y_offset

var/turf/T = locate(x_pos, y_pos, A.z)
line += T

if(y_dif < 0) y_offset--
else y_offset++

return(line)

else //diagonal line
var/x_offset
var/y_offset
var/dir = get_dir(A,B)
if(dir&NORTH) y_offset = 1
else y_offset = -1
if(dir&EAST) x_offset = 1
else x_offset = -1

var/list/line = list()

for(var/position = 0, position <= abs(x_dif), position++)
var/x_pos = A.x + (position*x_offset)
var/y_pos = A.y + (position*y_offset)

var/turf/T = locate(x_pos, y_pos, A.z)
line += T

return(line)
A little late but this one will draw a line more accurate that bends properly. I believe it is faster also.
proc
Line(atom/a,atom/b)
var/list/line = new
line+=locate(b.x,b.y,b.z)
line+=locate(a.x,a.y,a.z)

var/x1 = a.x
var/x2 = b.x
var/y1 = a.y
var/y2 = b.y
var/steep = abs(y2 - y1) > abs(x2 - x1)
if(steep)
var/temp = x1
x1 = y1
y1 = temp
temp = x2
x2 = y2
y2 = temp
if(x1 > x2)
var/temp = x1
x1 = x2
x2 = temp
temp = y1
y1 = y2
y2 = temp
var/deltax = x2 - x1
var/deltay = abs(y2 - y1)
var/error = 0
var/ystep
var/y = y1
if(y1 < y2)
ystep = 1
else
ystep = -1
for(var/x = x1, x < x2, x++)
if(steep)
line += locate(y,x,a.z)
else
line += locate(x,y,a.z)
error += deltay
if((2 * error) >= deltax)
y += ystep
error -= deltax
return line