ID:195143
 
//Title: Table-Lookup Distance Proc
//Credit to: Jtgibson
//Contributed by: Jtgibson
//Dependency of: Linear Distance Procs (Jtgibson)


/*
(Note well that you'll need the Linear Distance Procs included in your project
before this will work! The procs should be available from the same location you
got this.)


A distance table helps take the load off of the CPU by "caching" calculations
you've made. Whenever you make a calculation, it compares the distance between
the target and you, and then looks up that distance on the table. If that
distance has already been computed, then it simply returns that distance, saving
some CPU time. In the event of Euclid distance, this is MUCH faster than calcu-
lating the distance a second time... in the case of the other distance func-
tions, it's actually faster to just calculate the distances over and over again,
because the CPU takes more time to find the data within your computer's RAM.

You should note that a distance table doesn't mean your computer doesn't have to
work as hard. That data still has to go somewhere -- the difference is that
instead of calculating it time and again, the data is stored in your computer's
memory. In other words, for every byte of data that the CPU doesn't have to
calculate, your computer's RAM has to remember. It's a perversion of the Law of
Conservation of Energy. =)


Serious Programmers: I'm not sure how BYOND's architecture handles its equiva-
lent of a function pointer. It may in fact have to do a table lookup just to
find the function to use for the table lookup! I've left a couple commented-out
lines in there which you can use to replace the function pointers and just stick
to Euclidean distance (which is really the only reason why you'd want to use a
distance table in the first place). If you really want to use the table for
other distance types, replace the #define below with the appropriate proc.
*/


//#define HARDCODE_DISTANCE(X,Y) euclid_dist((X),(Y))


dist_table
var/table[world.maxx][world.maxy][world.maxz] //don't touch this!

var/function = "euclid_dist" //comment out if you disable function pointers
//Acceptable values:
//"euclid_dist"
//"compare_dist"
//"manhattan_dist"
//"chebyshev_dist"
//"get_dist"
//"shift_dist"
//See the Linear Distance Procs for more information on each of those functions.

proc/get_distance(atom/src, atom/trg)
var/x_offset = abs(src.x-trg.x)
var/y_offset = abs(src.y-trg.y)
var/z_offset = abs(src.z-trg.z)
var/val = table[x_offset+1][y_offset+1][z_offset+1]
if(val == null)
val = call(function)(src,trg) //comment out to disable function pointers
//val = HARDCODE_DISTANCE(src,trg) //uncomment to use hard-coded distance
table[x_offset+1][y_offset+1][z_offset+1] = val
return val



///*
//Testing code/sample implementation

var/dist_table/DISTANCETABLE = new

atom/verb/find_distance()
set src in oview()
usr << DISTANCETABLE.get_distance(usr,src)
//*/