ID:195044
 
/*
Title: Geography
Credit to: Deadron
Modified by: CaptFalcon33035
Contributed by: CaptFalcon33035
Based from: Dearon.Geography

I was just looking over this library trying to determine what
libraries were required to run Deadron's Quest library and I
realized that much of the workings of this library could be
improved to a great deal. So here it is!
*/


#define isturf(n) istype(n, /turf)

atom/proc/dd_area()
if(istype(src, /area)) return src
var/turf/my_loc = locate(src.x, src.y, src.z)
return (my_loc)?(my_loc.loc):(null)


proc/dd_direction_name(var/direction)
. = ""
if(direction & NORTH) . += "NORTH"
else if(direction & SOUTH) . += "SOUTH"
if(direction & EAST) . += "EAST"
else if(direction & WEST) . += "WEST"

proc/dd_get_dist(var/first, var/second)
// Right triangle rule: A squared + B squared = C squared.
var/x = abs(first:x - second:x)
var/y = abs(first:y - second:y)
return round(sqrt((x * x) + (y * y)))

// proc/dd_get_step(var/atom/O, var/direction)
proc/get_steps(var/atom/ref, var/dir, var/dist=1)
if(!ref || !dir || !ref.loc) return 0
var/x_add = 0
var/y_add = 0
if(ref.dir & NORTH) y_add = dist
else if(ref.dir & SOUTH) y_add = -dist
if(ref.dir & EAST) x_add = dist
else if(ref.dir & WEST) x_add = -dist
return locate(ref.x+x_add, ref.y+y_add, ref.z)

proc/dd_get_step_rand(var/atom/O, var/randomness=10, var/considerDensity=1)
ASSERT(istype(O))
var/turf/newLoc
var/direction
var/isTurf = isturf(O)

// Behave random or predictable this time?
if(isTurf || prob(randomness))
// Turfs are always random.
direction = randomDirection()
newLoc = get_steps(O, direction)
if(newLoc && (isTurf || !considerDensity || newLoc.Enter(O)))
return newLoc
else
// Not random; just move in same direction if possible.
direction = O.dir
newLoc = get_steps(O, direction)
if(newLoc && (!considerDensity || newLoc.Enter(O))) return newLoc

// Rotate through every turf in oview() until one is validated.
var/list/my_oview = oview(O, 1)
for(var/turf/t in my_oview)
if(isTurf || !considerDensity || t.Enter(O)) return t
return null

proc/dd_reverse_direction(var/direction)
. = turn(direction, 180)

proc/dd_step_rand(var/atom/movable/M, var/randomness=10)
ASSERT(istype(M))
var/considerDensity=1
var/turf/newLoc = dd_get_step_rand(M, randomness, considerDensity)
if(newLoc) return M.Move(newLoc)
return null

proc/randomDirection()
. = pick(NORTH, SOUTH, EAST, WEST, NORTHEAST,\
NORTHWEST, SOUTHEAST, SOUTHWEST)


Source: hub://Deadron.Geography