ID:301914
 
(See the best response by Forum_account.)
I'm just curious if it's possible for me to make it to where I can make enemies move in only a four-direction system while still moving towards an object or mob.

For Example:

I want my mob to be able to get from point A to point B without using any other direction but the cardinal directions.
Clarify in this: Are you asking for a path-finding algorithm for this, or just a way to disable diagonal movement?
Disabling diagonal movement altogether so the enemy can only travel in the four basic directions.
Well, there is that way where you can use step(). This means to define the movement, and determine the location, much similar to writing your own path finding. It might use a lot of CPU and if() statements.

I'm not sure if you can disable them in another way.
The only problem with that is the CPU wouldn't be able to get from point A to point B by itself, like by using step_to. I've contemplated the step idea, but it doesn't leave you with a lot of options.
One of the simplest ways is just to modify the Move() proc.

mob/Move(atom/loc)
var/dir = get_dir(loc, src)

if( ((get_dist(loc, src) <= 1) && ((dir & (dir - 1))
return 0
else
return ..()


The get_dist() stuff keeps this from working when you're trying to move the mob long distances (perhaps through teleportation). As for the (dir & (dir - 1)) bit, that's a bit... more complicated. Just know that it checks whether the direction is cardinal. If it's true, it's an ordinal direction, and if it's false it's a cardinal direction.

[Edit]

Note that the standard automated movement procs will still work for this, but they will fail when they generate an ordinal direction. It'd be best to re-implement them yourself for this, or attempt to implement a wrapper around them.
What you gave me worked, but it ended up doing the same thing when I tried doing it my own way. It just stalls the mob until it eventually get's a direction that isn't ordinal, which basically just looks like it's moving maybe every 5 seconds.

I'm thinking..

What I'm currently doing is picking an object that is in the current world for the mob to move to, but would it be easier for me to just pick an object that is in a cardinal direction of the mob?
The easiest thing would be to just write your own random movement proc. As a quick tip, here are three ways to generate a random cardinal direction:

// Method one, the most intuitive and easy.
var
list/directions = list(NORTH, SOUTH, EAST, WEST)
dir = pick(directions)

// Method two, which makes use of the fact that the directions
// are powers of two between 0 and 8.
var/dir = 2 ** rand(0, 3)

// Method three, which is similar to the above but using
// bitwise math.
var/dir = rand(0, 3) << 1
I appreciate the help, I've got what I was looking for! Thank you!
Just a question, where you asking for a way to have <font size = 0.5>walk_rand()</font> use cardinals only or the <font size = 0.5>walk_to()</font>
step_to.
Best response
Sometimes you're better off just overriding Move() so you can still use walk_rand() or walk_to(). For example:

mob
Move(atom/new_loc)
var/d = get_dir(src, new_loc)

var/is_diagonal = d & (d - 1)

if(is_diagonal)

// d1 and d2 are the component directions
var/d1 = d & (NORTH | SOUTH)
var/d2 = d & (EAST | WEST)

// swap d1 and d2 50% of the time so we don't favor any direction
if(prob(50))
var/t = d1
d1 = d2
d2 = t

// try moving in the d1 direction
dir = d1
if(step(src, d1))
return 1

// if that fails, try moving in the d2 direction
dir = d2
if(step(src, d2))
return 1

return 0

// if the move wasn't diagonal
else
return ..()

That detects when the mob tries to make a diagonal move and makes a single move in a cardinal direction instead. If the mob tries to move northeast, it'll move them either north or east.
Thank you Forum_Account, that produced exactly what I was looking for!