That's what problem I faced with s_missile. Al, much to my delight, helped me out with what was then SPL Missile, telling me a variety of mathematical formulae, even offering some code.
The worst part was, the code worked... but only in two directions. Not wanting to bother Al again (hey, he only gets a little snippet of online time every little while anyway...), I've decided to try a few things a little more unique and a lot more exciting.
Essentially, SPL Missile had four procs; spl_missile1(), spl_missile2(), spl_missile3(), and spl_missile4(). Talk about obfuscated... now people had to remember which number did what! Respectively, those functions were to fire an icon, to fire an icon and icon_state, to fire an object of a specified prototype, and to fire an actual mob or obj that exists.
Now, thanks to isicon(), I've merged all of these procs into one convenient source; s_missile(). The usages thereof are as follows:
s_missile(icon,trg,lag=1,homing=0)
s_missile(icon,icon_state,trg,lag=1,homing=0)
s_missile(type,trg,lag=1,homing=0)
s_missile(ref,trg,lag=1,homing=0)
s_missile(icon,icon_state,trg,lag=1,homing=0)
s_missile(type,trg,lag=1,homing=0)
s_missile(ref,trg,lag=1,homing=0)
The main problem that balked me, however, was how to get the linear movement in walk_line() to work. Originally, the plan was to determine the tangent from the source to the destination, convert that to degrees, then move the missile in that direction.
But I've found a much more apt solution; I simply use a variation on Guy's principle of rise over run; I constantly add the rise/run to a variable called _process, and then I subtract the rounded value thereof from the variable. The rounded value, then, is compared, and if 0, it moves horizontally, if 1 it moves diagonally, and if 2 it moves diagonally and tells itself to move vertically next turn (and so on for the other numbers above two, with vertical moves divided between before and after the diagonal move). This is continually applied until the missile reaches its destination.
Here's hoping that I can pull it off!
You don't need to reinvent the wheel: In the 60:s a matematician named Bresenham wrote a line drawing algorithm, and it's perfectly applicable in this case. I found some code in a book, and rewrote it to Byond:
The only problem occurs when the missile has to travel many steps on one axis, but only one step in the other. I'm sure you can optimize it.
/Andreas