In response to Bravo1
Thank you for the comment. I already have a working Pythagorean function to get true distances. In fact, that's one of the pivotal calculations I use to get the relative angle between two objects. I'm definitely going to be rewriting my projectile code to use datums instead. It might take me a couple hours to get everything working, but I should have something by the end of the day.
Great, I'd love to see the final product!
Just made an update to the code. There was some issues regarding the proc being very laggy after long calls. There was also the issue of a short pause right after the button was pressed for movement before it would start moving at full speed. And an issue where holding down opposite keys wouldn't cause you to move in the other direction when one was released.

To solve this, I made two major changes to the way movement was handled:

First, I did away with the necessity to repeat the movement macro key when calling the verb by simply allowing the movement proc to repeat until no buttons were being held down anymore. Only when the player was at a complete standstill did I allow the verb to call the movement proc. This solves most of the issues, but actually caused the latter one where holding down buttons of opposite directions and releasing one wouldn't force you to move in the other direction.

This issue I solved by creating a makeshift call stack for each plane where the movement proc would simply read the last element in each list. Pressing the key would add that element to the top of the stack, while releasing it would remove that specific element, no matter where in the stack it was present. A very simple fix that completely does away with constantly pinging the server for a movement update each tick.
My latest sub-pixel movement system goes like this:
atom/movable
// position relative to the current pixel, between -0.5 and 0.5
var subpixel = TRUE, __dx, __dy

// sub-pixel movement along a translation vector
proc/Translate(Tx, Ty)
if(!subpixel) return Move(loc, dir, step_x + Tx, step_y + Ty)

// full-pixel movements
var rx = round(__dx + Tx, 1)
var ry = round(__dy + Ty, 1)
__dx += Tx - rx
__dy += Ty - ry

// change step_size only for this movement,
// gotta make it a slide instead of a jump
var s = step_size
step_size = 1 + max(abs(rx), abs(ry))

// move if we can, return success if we tried to move but didn't move a full pixel
. = (Tx || Ty) ? (rx || ry) ? Move(loc, dir, step_x + rx, step_y + ry) : TRUE : FALSE step_size = s

~12 lines of code is the shortest I've gotten it (without making it unreadable, of course).
That looks nice! The subpixel movement was funnily enough the easiest part of the code. Lol. It's all of the auxiliary code for making it move better with the keys that makes mine look kind of ugly.
Here's a demo showing the difference between sub-pixel movement and full-pixel movement that tries to use sub-pixel movements:
In response to Kaiochao
What exactly is the difference in that code?
In response to Kats
With sub-pixel movement on, it uses Translate(velocity.x, velocity.y)

With sub-pixel movement off, it uses
Move(loc, dir, step_x + velocity.x, step_y + velocity.y)
In response to Kaiochao
I see it now. That's very cool.
Page: 1 2 3 4