ID:151990
 
I have a function that'll find the cardinal (NESW) direction from one object to another by checking the distance from the tile in each direction to the targetted object, and finding which one has the smallest distance and returning that one.

It kinda sucks, is clunky and inefficient, and I don't much care for it.

I'm wondering if anyone else has a simple and effective way to calculate the cardinal direction from one object to another? No hacky workarounds, please.
Couldn't you just use the built in get_dir() proc, and then when you get a diagonal, just randomly get either of the two cardinals that make up that diagonal? Of course, that allows for randomness.
In response to Naokohiro
Naokohiro wrote:
Couldn't you just use the built in get_dir() proc, and then when you get a diagonal, just randomly get either of the two cardinals that make up that diagonal? Of course, that allows for randomness.

That would be a hacky workaround.
In response to Foomer
Or, instead of randomness, just figure out which is closer and use it.
Actually I think I just stumbled upon what I was looking for in [link].
In response to Foomer
XD, after I just made this to show you.
proc/cget_dir(var/turf/L1,var/turf/L2)
var/xdist=L2.x-L1.x
var/ydist=L2.y-L1.y
if(abs(xdist)>abs(ydist))
if(xdist>0)
return EAST
else
return WEST
return (rand(0,1)?EAST:WEST)
else
if(ydist>0)
return NORTH
else
return SOUTH
return (rand(0,1)?NORTH:SOUTH)
That's one way... May not work depending on what you want.
EDIT: Looks almost exactly like Garthor's code, except it account for when you're at a 1:1 x:y ratio (aka perfectly diagonal). Great minds think alike, though I suppose.
In response to Naokohiro
Naokohiro wrote:
Couldn't you just use the built in get_dir() proc, and then when you get a diagonal, just randomly get either of the two cardinals that make up that diagonal? Of course, that allows for randomness.

proc/get_cardinal_dir(atom/A, atom/B)
var/dx = abs(B.x - A.x)
var/dy = abs(B.y - A.y)
return get_dir(A, B) & (rand() * (dx+dy) < dy ? 3 : 12)


Lummox JR
In response to Naokohiro
Naokohiro wrote:
May not work depending on what you want.

That's the kind of thing you don't want to hear for a function as simple as finding a cardinal direction.

Appreciate the effort though.
In response to Foomer
It turns out, it was EXACTLY what you were looking for, except it was a bit better. It accounts for when Loc1 is directly diagonal from Loc2(Aka there's no specific cardinal direction to choose.), of course it doesn't account for when Loc1 is Loc2.
In response to Lummox JR
Lummox JR wrote:
Naokohiro wrote:
Couldn't you just use the built in get_dir() proc, and then when you get a diagonal, just randomly get either of the two cardinals that make up that diagonal? Of course, that allows for randomness.

proc/get_cardinal_dir(atom/A, atom/B)
> var/dx = abs(B.x - A.x)
> var/dy = abs(B.y - A.y)
> return get_dir(A, B) & (rand() * (dx+dy) < dy ? 3 : 12)

Lummox JR

I dunno, I kind of like it when my game is made up of code that I can understand.
In response to Foomer
Yeah, what I meant by, "depending on what you want" was that if you wanted a really special way of doing it that was really fancy, turned out you didn't, and that line I typed was pointless. :D
In response to Foomer
He used a bitwise operator, because he knows a lot about them, kind of makes me want to research them a bit more, since after someone found out that you could block diagonal movement very easily.
In response to Naokohiro
Foomer almost certainly knows he used bitwise operators. Your statement just puts out already-known knowledge, and doesn't expand on how it does what it does.
In response to Foomer
To put it simply, the stuff in the return makes it tend towards disabling the direction on the axis that is further. For example, if the x distance is 5 and the y distance is 15, it'll tend towards disabling the directions of the y axis (NORTH and SOUTH).
In response to Popisfizzy
Well, I shouldn't have posted then, because I don't have enough knowledge about bitwise operators, and how do you know he even knows that's what they're called?
In response to Naokohiro
Because he has made nearly two percent of the posts on these forums and has been here a while. I'm sure he, at some point, has come across the concept at least once.
In response to Naokohiro
Naokohiro wrote:
kind of makes me want to research them a bit more

Likewise, I just haven't found a good source that makes any real sense to me. At least, nothing beyond the basic turn-bit-on, turn-bit-off, if-bit, if-no-bit stuff.
In response to Foomer
Yeah, that's the easy stuff. I remember looking up how to do the bitwise OR and AND. I even figured out how to convert to and from binary.
There's also the XOR and whatnot, I'd just have to refresh my memory.
In response to Popisfizzy
Popisfizzy wrote:
To put it simply, the stuff in the return makes it tend towards disabling the direction on the axis that is further. For example, if the x distance is 5 and the y distance is 15, it'll tend towards disabling the directions of the y axis (NORTH and SOUTH).

Actually backwards; it favors the farthest axis, so the mob moves approximately toward the target along the quickest route.

Lummox JR
In response to Lummox JR
Lummox JR wrote:
proc/get_cardinal_dir(atom/A, atom/B)
> var/dx = abs(B.x - A.x)
> var/dy = abs(B.y - A.y)
> return get_dir(A, B) & (rand() * (dx+dy) < dy ? 3 : 12)


Does using the magic numbers "3" and "12" help any better than using (NORTH|SOUTH) and (EAST|WEST)? I thought the DM compiler was smart enough to optimise that during compile time.
Page: 1 2