ID:157489
 
i wanted to make a click and walk system that wouldnt move northwest,northeast,southwest,and southeast because moving in those directions is ugly in the isometric byond system when you are near a wall.
mob/Move(atom/newloc)
var/dir = get_dir(loc, newloc) // Get the direction from
// where we're at now to
// where we're going to be.
if(dir & (dir - 1))
// This is a fancy way of checking if the direction
// is diagonal. If it is, don't allow movement in
// that direction.
return 0

return ..() // Otherwise, do whatever is normally done.
In response to Popisfizzy (#1)
Yeah this works but if the mob would move diagnol the walk_to proc stops and that makes the movement by clicking very bad, is there a way to make the mob choose other directions than diagnol and not to stop moving?
In response to Karffebon (#2)
You can change Move() to make it split up diagonal directions into two parts, though that might not always work.
In response to Jeff8500 (#3)
    if(dir==NORTHEAST)
var/atom/A=getstep(M,NORTH)
if(A.density==1)
var/atom/S=getstep(M,EAST)
if(S.density==1)
return 0
else
step(M,East)
else
step(M,NORTH)

this is my basic idea i would do it with every direction but how would i insert it in move proc? or is there any other way?
In response to Karffebon (#4)
That's a pretty bad way to do it. I would split the direction, then call Move(direction1) and then Move(direction2), though if the first one doesn't work, then I'd call Move(direction2) then Move(direction1). It's not exactly perfect, and you can implement one of BYOND's pathfinding libraries instead, but it's a decent fix.

Regardless, you don't really know what you're doing, you should read the DM guide.
Like Jeff8500 mentioned, I would use one of the pathfinding libraries available. (See hub://kuraudo.libpathfinder and hub://theodis.pathfinder.) If you just prevented movement in diagonal directions you run the risk of walk_to() getting stuck in an example like so:

<pre>..... .XO.. .@X.. .....</pre>
Key: X = Wall, O = Target, @ = Ref

(@ gets stuck because it is trying to move NORTHEAST to O, but blocking NORTHEAST movement prevents it from making it through. Attempting to break it into a NORTH step followed by an EAST step also fails.)

If, for example, you were using hub://kuraudo.libpathfinder, you could implement a proc similar to walk_to() and step_to() like so:
/******************************************************************************
First, I'm going to define a sub-type of /pathfinder/astar for the example:
*******************************************************************************/


pathfinder/astar/astar_example

// And define its neighbors() proc:
neighbors(turf/t) // List of non-dense turfs NORTH, SOUTH, EAST, and WEST of t with no dense objects
. = new/list
for(var/n in list(NORTH, SOUTH, EAST, WEST))
var/turf/t2 = get_step(t, n)
if(t2 && !t2.density)
var/empty = TRUE
for(var/atom/a in t2)
if(a.density)
empty = FALSE
break
if(empty)
. += t2

/******************************************************************************
Now to define a move_to() proc to resemble the built-in ones:
*******************************************************************************/


proc/move_to(atom/movable/ref, trg, min=0, delay=0)
var/static/pathfinder/astar/astar_example/pfinder = new

spawn // return immediately, process in background
var/list/path = pfinder.search(ref.loc, trg)
if(path)
var/path_index = 1
while(get_dist(ref, trg) > min)
var/move_success = ref.Move(path[path_index++])

if(!move_success) // Unable to follow current path, calculate a new one
path = pfinder.search(ref.loc, trg)
if(!path) // Stop walking if unable to calculate new path
break
path_index = 1

sleep(delay)

(See libpathfinder's documentation for more information regarding how to use it.)

That emulates much of the functionality of walk_to(), with the caveat that you can't cancel it after you start it. You could of course modify this to add in such functionality if you wished. You also might want to prevent the atom from otherwise moving until move_to() finishes (as it would interfere with the movement).
In response to Kuraudo (#6)
How do i use that? i dont understand it's too complicated my head hurts
i donwloaded the library and activated it and your code, and i replaced the walk_to in my click and move to move_to but it doenst show walking animations and it stills move in the diagnol
In response to Karffebon (#7)
I would need to see some of your code to know what is going wrong, obviously.
In response to Kuraudo (#8)
/******************************************************************************
First, I'm going to define a sub-type of /pathfinder/astar for the example:
*******************************************************************************/


pathfinder/astar/astar_example

// And define its neighbors() proc:
proc
neighbors(turf/t) // List of non-dense turfs NORTH, SOUTH, EAST, and WEST of t with no dense objects
. = new/list
for(var/n in list(NORTH, SOUTH, EAST, WEST))
var/turf/t2 = get_step(t, n)
if(t2 && !t2.density)
var/empty = TRUE
for(var/atom/a in t2)
if(a.density)
empty = FALSE
break
if(empty)
. += t2

/******************************************************************************
Now to define a move_to() proc to resemble the built-in ones:
*******************************************************************************/


proc/move_to(atom/movable/ref, trg, min=0, delay=0)
var/static/pathfinder/astar/astar_example/pfinder = new

spawn // return immediately, process in background
var/list/path = pfinder.search(ref.loc, trg)
if(path)
var/path_index = 1
while(get_dist(ref, trg) > min)
var/move_success = ref.Move(path[path_index++])//HEre how can i make this not telport the character but make him walk?

if(!move_success) // Unable to follow current path, calculate a new one
path = pfinder.search(ref.loc, trg)
if(!path) // Stop walking if unable to calculate new path
break
path_index = 1

sleep(delay)
client.Click(O)
if(O:density==1)
return
var/o=image('tiles.dmi',O,"3")
move_to(usr,O)
src << o
sleep(2)
del(o)

var/move_success = ref.Move(path[path_index++]) -> he just gets teleported, i wanted him to walk(in code he walks i think but not in the visual