ID:2374850
 
(See the best response by FKI.)
Code:
mob
verb
movekeypress(key as num|null)
set hidden = 1, instant = 1
if(lockkey||stun)return
client.keys_pressed++
switch(key)
if(1)client.Keys_Pressed["NORTH"] = 1
if(2)client.Keys_Pressed["SOUTH"] = 1
if(4)client.Keys_Pressed["EAST"] = 1
if(8)client.Keys_Pressed["WEST"] = 1
client.move_dir = key

movekeyrelease(key as num|null)
set hidden = 1, instant = 1
client.keys_pressed--
switch(key)
if(1)client.Keys_Pressed["NORTH"] = 0
if(2)client.Keys_Pressed["SOUTH"] = 0
if(4)client.Keys_Pressed["EAST"] = 0
if(8)client.Keys_Pressed["WEST"] = 0
client.move_dir = Get_Direction()

client
var
move_dir = 0
tmp
keys_pressed = 0
list/Keys_Pressed = new
proc
MoveLoop()
while(src)
if(move_dir)
Move(mob.loc,move_dir)
sleep(world.tick_lag)
New()
. = ..()
MoveLoop()

client
North()
world << "NORTH"
..()


Problem description:
Good afternoon. I'm trying to be able to use client.North() in my pixel movement system but I'm not understanding how it works very well. Any idea on how I could use client.North() with this system?

In order to steer you more accurately, may I have more context on what you are trying to do exactly?
Well, for example, I want to make it so I can create an object, set it in motion, and then make it turn when I press on the movement keys. Something along those lines
Actually, a better way to describe it is simply: when I move north, I want the object or mob I’m controlling to move North with me, if that makes any sense. Let’s say I have a mob in mind control, and when I move North, the person I’m controlling also moves north. I think the easiest way to accomplish that is in client.North, but it isn’t being called when I move north
In response to Vincent916
Best response
I am not sure that would work [efficiently] for what you want, and I feel I have a simpler alternative.

Based on your example, this is essentially what I would do:

client
var/tmp/movement_listeners[]

New()
. = ..()
if(.)
moveloop()


Move(loc, dir)
. = ..(loc, dir)

if(movement_listeners)
for(var/atom/movable/m in movement_listeners)
m.on_move(loc, dir, .)

proc/add_move_listener(atom/movable/m)
if(!movement_listeners)
movement_listeners = list()
movement_listeners += m

proc/remove_move_listener(atom/movable/m)
if(!movement_listeners) return
movement_listeners -= m
if(!movement_listeners.len)
movement_listeners = null


proc/moveloop()
set waitfor = 0
while(src)
if(move_dir)
Move(mob.loc, move_dir)
sleep(world.tick_lag)

atom/movable
proc/on_move(loc, dir, parent_success)

obj/example
on_move(loc, dir, parent_success)
if(parent_success)
Move(loc, dir)


With this, you don't have to change your control scheme.

Something to know: Your original example does not spawn() MoveLoop() or use the waitfor setting to allow client/New() to finish. I believe this is hazardous (or simply bad practice) but someone can correct me if not.
Thank you for the help, when I’m off work this evening I’ll give it a shot. Thanks so much for your time and patience
Alright, I got home from work and was able to play with this a little, and I'm still having a little trouble. Here's the code:

client
var
move_dir = 0
tmp
keys_pressed = 0
list/Keys_Pressed = new
movement_listeners[]

New()
. = ..()
moveloop()

proc
moveloop()
set waitfor = 0
while(src)
if(move_dir)
Move(mob.loc, move_dir)
sleep(world.tick_lag)

add_move_listener(atom/movable/m)
if(!movement_listeners)
movement_listeners = list()
movement_listeners += m

remove_move_listener(atom/movable/m)
if(!movement_listeners) return
movement_listeners -= m
if(!movement_listeners.len)
movement_listeners = null

Move(loc, dir)
. = ..(loc, dir)

if(movement_listeners)
for(var/atom/movable/m in movement_listeners)
m.on_move(loc, dir)

atom/movable
proc/on_move(loc, dir)

obj/example
icon = 'pixel projectile test.dmi'
on_move(loc, dir)
Move(loc, dir)
mob/verb
Test()
var/obj/example/K = new/obj/example(loc)
K.step_size = step_size
K.loc = locate(x+3,y,z)
client.add_move_listener(K)


So, first off, a couple things were causing it not to work at all, they are:

if(.)moveloop() Removing if(.) made it work

if(parent_success) Removing it made it work


The main issue is I want the object to simply move in the direction I'm moving in from it's own location. currently, it's moving the object to my location. Below is a visual (I'm really bad at explaining this): https://gyazo.com/226da077a3da9ab0f2b97364b022fbb8


I've noticed something else as well, and I think I understand what is happening here. It would appear that the object only moves as I move from one tile to the next. So if I move 8 pixels and don't enter a new tile, the object doesn't move at all either
In response to Vincent916
if(parent_success) Removing it made it work

Your version doesn't pass the dot(.) var to parent_success when the proc is called, so movement would never happen.

if(.)moveloop() Removing if(.) made it work

Do you have another client/New() somewhere in your source? Though what you have should be fine to use, there's no reason for there to be an issue here unless there's weirdness elsewhere.

The main issue is I want the object to simply move in the direction I'm moving in from it's own location. currently, it's moving the object to my location.

My mistake here:

Move(loc, dir)
// ...should be:
Move(src.loc, dir)


Though you might wanna rename the proc variables to make that bit less confusing, that way src is unnecessary.

I've noticed something else as well, and I think I understand what is happening here. It would appear that the object only moves as I move from one tile to the next. So if I move 8 pixels and don't enter a new tile, the object doesn't move at all either

It escaped me pixel movement is at play here. At a dirty level, I think you'd need something similar to this:

atom/movable
proc/pixel_move(pixels, dir)
var/dx = (dir & (EAST | WEST)) ? (dir & EAST) ? (pixels) : (-pixels) : 0
var/dy = (dir & (NORTH | SOUTH)) ? (dir & NORTH) ? (pixels) : (-pixels) : 0
return Move(loc, dir, step_x + dx, step_y + dy)


Then our new example object would look something like:

obj/example
on_move(move_loc, move_dir, parent_success)
if(parent_success)
pixel_move(parent_success, move_dir)


Hope this helped.
Hi FKI, sorry I haven't replied, life got hectic and I was only just now able to sit down and get back to work on this. So, I've plugged in everything you've helped me with, and it seems to work. the only issue I'm seeing now is, my actual character itself moves smoothly, but the object or mob I'm controlling moves not smoothly (it's jumpy, it doesn't seem to glide well). Is this perhaps because my player uses a movement loop, and the object I'm controlling does not? Would you by any chance have any idea on how to smooth out the movement on the object/mob im controlling? Below is the code I have now.

client
var
move_dir = 0
tmp
keys_pressed = 0
list/Keys_Pressed = new
movement_listeners[]

New()
. = ..()
moveloop()

proc
moveloop()
set waitfor = 0
while(src)
if(move_dir)
Move(mob.loc, move_dir)
sleep(world.tick_lag)

add_move_listener(atom/movable/m)
if(!movement_listeners)
movement_listeners = list()
movement_listeners += m

remove_move_listener(atom/movable/m)
if(!movement_listeners) return
movement_listeners -= m
if(!movement_listeners.len)
movement_listeners = null

Move(loc, dir)
. = ..(loc, dir)

if(movement_listeners)
for(var/atom/movable/m in movement_listeners)
m.on_move(loc, dir, mob.step_size)

atom/movable
proc/on_move(move_loc, move_dir, speed)

obj/example
icon = 'pixel projectile test.dmi'
on_move(move_loc, move_dir, speed)
pixel_move(speed, move_dir)

verb
example() //example of using this in action
var/obj/example/K = new/obj/example(loc)
K.loc = locate(x + 3,y,z)
usr.client.add_move_listener(K)

atom/movable
proc/pixel_move(pixels, dir)
var/dx = (dir & (EAST | WEST)) ? (dir & EAST) ? (pixels) : (-pixels) : 0
var/dy = (dir & (NORTH | SOUTH)) ? (dir & NORTH) ? (pixels) : (-pixels) : 0
return Move(loc, dir, step_x + dx, step_y + dy)
Welp, i've tried everything I can think of, but the movement on atoms in movement_listeners is still jumpy, no clue why. Any ideas?
No one? ;-; I'm stuck :P