ID:2283831
 
Code:
client
var
list/moveKeys = list("NORTH"=0,"EAST"=0,"SOUTH"=0,"WEST"=0)
moving = 0
verb
northDown()
src.moveKeys["NORTH"] = 1
if(!src.moving)
src.moveLoop()
northUp()
src.moveKeys["NORTH"] = 0
eastDown()
src.moveKeys["EAST"] = 1
if(!src.moving)
src.moveLoop()
eastUp()
src.moveKeys["EAST"] = 0
southDown()
src.moveKeys["SOUTH"] = 1
if(!src.moving)
src.moveLoop()
southUp()
src.moveKeys["SOUTH"] = 0
westDown()
src.moveKeys["WEST"] = 1
if(!src.moving)
src.moveLoop()
westUp()
src.moveKeys["WEST"] = 0
proc
moveLoop()
spawn(0)
src.moving = 1
while(src && src.moving)
var/movement = 0
if(src.moveKeys["NORTH"]) movement |= NORTH
if(src.moveKeys["EAST"]) movement |= EAST
if(src.moveKeys["SOUTH"]) movement |= SOUTH
if(src.moveKeys["WEST"]) movement |= WEST
if(movement)
if(!(step(src.mob,movement)))
if(moveKeys["NORTH"])
movement &= ~NORTH
if(!(step(src.mob,movement)))
movement = NORTH
step(src.mob,movement)
if(moveKeys["SOUTH"])
movement &= ~SOUTH
if(!(step(src.mob,movement)))
movement = SOUTH
step(src.mob,movement)
sleep(world.tick_lag)
else
src.moving = 0
return


Problem description:
Not really a problem. It works as intended. More like a question of whether or not this is the best way to go about it. I will eventually have ways of mobs's movement being hindered through various methods (root, stun, etc), but have not implemented those scenarios yet. Before I get too far into things, I would like to know if there's a more robust way of doing this. I drew inspiration from Nadrew's response here: http://www.byond.com/forum/?post=2143237
That's basically how you do it.

I'm just here to point out that you can store key presses using bit flags instead of that list, just like you're setting the movement variable using bit flags later in the movement loop.

        northDown()
moveKeys |= NORTH
if(!moving)
moveLoop()
northUp()
moveKeys &= ~NORTH

...
if(moveKeys & NORTH) movement |= NORTH
client
var
list/moveKeys = list()
moving = 0
verb
northDown()
src.moveKeys |= NORTH
if(!src.moving)
src.moveLoop()
northUp()
src.moveKeys &= ~NORTH
eastDown()
src.moveKeys |= EAST
if(!src.moving)
src.moveLoop()
eastUp()
src.moveKeys &= ~EAST
southDown()
src.moveKeys |= SOUTH
if(!src.moving)
src.moveLoop()
southUp()
src.moveKeys &= ~SOUTH
westDown()
src.moveKeys |= WEST
if(!src.moving)
src.moveLoop()
westUp()
src.moveKeys &= ~WEST
proc
moveLoop()
spawn(0)
src.moving = 1
while(src && src.moving)
var/movement = 0
if(src.moveKeys & NORTH) movement |= NORTH
if(src.moveKeys & EAST) movement |= EAST
if(src.moveKeys & SOUTH) movement |= SOUTH
if(src.moveKeys & WEST) movement |= WEST
if(movement)
if(!(step(src.mob,movement)))
if(moveKeys & NORTH)
movement &= ~NORTH
if(!(step(src.mob,movement)))
movement = NORTH
step(src.mob,movement)
if(moveKeys & SOUTH)
movement &= ~SOUTH
if(!(step(src.mob,movement)))
movement = SOUTH
step(src.mob,movement)
sleep(world.tick_lag)
else
src.moving = 0
return


Tried doing that, but all I get is NORTHEAST movement that doesn't stop even when all keys are released. It doesn't matter which verb gets called either; it's northeast no matter what.

EDIT
Modified it to this and it works.
client
var
movement = 0
moving = 0
verb
northDown()
src.movement |= NORTH
if(!src.moving)
src.moveLoop()
northUp()
src.movement &= ~NORTH
eastDown()
src.movement |= EAST
if(!src.moving)
src.moveLoop()
eastUp()
src.movement &= ~EAST
southDown()
src.movement |= SOUTH
if(!src.moving)
src.moveLoop()
southUp()
src.movement &= ~SOUTH
westDown()
src.movement |= WEST
if(!src.moving)
src.moveLoop()
westUp()
src.movement &= ~WEST
proc
moveLoop()
spawn(0)
src.moving = 1
while(src && src.moving)
if(movement)
if(!(step(src.mob,movement)))
if(movement & NORTH)
movement &= ~NORTH
if(!(step(src.mob,movement)))
movement = NORTH
step(src.mob,movement)
if(movement & SOUTH)
movement &= ~SOUTH
if(!(step(src.mob,movement)))
movement = SOUTH
step(src.mob,movement)
sleep(world.tick_lag)
else
src.moving = 0
return
Couple of major problems here.

* Your verbs are not set to instant. This is a problem because non-instant verbs will queue up and be sent in sequence, causing apparent input lag.

* Your moveLoop() structure good, but you could lose the spawn(0) with a clever trick (tm). The logic is bad though.

* Your verbs are not set to hidden. This is a smallish problem.

* You could compress a lot of this logic.

client
var
movement_dir = 0
move_loop
verb
moveKeyDown(dir as num|null)
set instant = 1
set hidden = 1
if(!dir) return
movement_dir |= dir
if(!move_loop)
MoveLoop()

moveKeyUp(dir as num|null)
set instant = 1
set hidden = 1
if(!dir) return
movement_dir &= ~dir
if(!move_loop)
MoveLoop()

proc
MoveLoop()
set waitfor = 0
var/tracker = (move_loop = args) //clever trick
var/mdir
while(mob && movement_dir && move_loop==tracker)
mdir = movement_dir&3
if(mdir&&mdir!=3)
step(mob,mdir)
mdir = movement_dir&12
if(mdir&&mdir!=12)
step(mob,mdir)
sleep(world.tick_lag)
if(move_loop==tracker)
move_loop = null

North()
South()
East()
West()
Northeast()
Northwest()
Southeast()
Southwest()
Is there a reason you are overriding the client direction verbs? Would they be called alongside the moveKeyUp/Down verbs whenever the .north, etc verbs are called?

Also, what is the "move_loop = args" line doing? I'm not familiar with it.
I override them because they are verbs exposed to the client, and I don't need their default behavior.

Essentially, your clients would be able to bypass your other restrictions on movement by simply injecting a fraudulent call to them.
In response to Ter13
And the "move_loop = args" line?