ID:152096
 
Well I know the old:
rtg.dir = get_dir(rtg,trg)
Works almost perfect, but if your game only supports 4-way directions it will mess up.

So say if you set an arg that if your direction is say NORTHWEST/NORTHEAST and it doesn't support that, you can easily just go the obj will go NORTH. Now while this works, what if the trg your aiming at is y+1,x-5, now the games rtg.dir = get_dir(rtg,trg) will set the rtg's dir to NORTHWEST, which will set it to NORTH, when WEST was the more obvious way to fire, thus making this auto-target system faulty.

Now, BYOND has a very smart and cool system of making your icon direction in the right direction when it has only 4 states, so say if you move from north to northwest it stays north. But if you move from west to northwest it stays west. That would help a lil' in the aiming if I made a proc to set the jutsu dir in what icon_state dir your in.

Though still if your icon_state dir was NORTH, and the obj was y+1,x-5, it would still go NORTH. So I was wondering if there was some kind of way I can have a better check for this? Like maybe a path finding kind of thing that makes obj's and if more go west then your attack will go west, or something. Any ideas? Or is there pre-set args for this?
proc/Get_Dir(atom/U,atom/ref)
var/degree=arctan2(U.y-ref.y,U.x-ref.x)
return angle2dir(degree)

//below are functions i use periodically that you need.

proc
angle2dir(angle)
angle = normalize_angle(angle)
switch(angle)
if(-180 to -157.5, 157.5 to 180)
return WEST
if(-157.5 to -112.5)
return SOUTHWEST
if(-112.5 to -67.5)
return SOUTH
if(-67.5 to -22.5)
return SOUTHEAST
if(-22.5 to 22.5)
return EAST
if(22.5 to 67.5)
return NORTHEAST
if(67.5 to 112.5)
return NORTH
if(112.5 to 157.5)
return NORTHWEST


proc/arctan2(dy, dx)
if(dy == 0)
if(dx > 0)
//if(usr) usr << " return 0"
return 0
else if(dx == 0)
//if(usr) usr << " return 0"
return 0
else
//if(usr) usr << " return 180"
return 180
if(dx == 0)
if(dy > 0)
//if(usr) usr << " return 90"
return 90
else if(dy == 0)
//if(usr) usr << " return 0"
return 0
else
//if(usr) usr << " return -90"
return -90
else
var/angle = arctan(dy/dx)
if(dx < 0)
angle = 180 - angle
if(dy < 0)
angle = -angle
//if(usr) usr << " return [angle]"
return angle

proc
normalize_angle(angle)
while(angle > 180)
angle -= 360
while(angle <= -180)
angle += 360
return angle
proc/get_cardinal(var/atom/A, var/atom/B)
var/dx = B.x - A.x
var/dy = B.y - A.y
if(abs(dx) > abs(dy))
if(dx < 0)
return WEST
else
return EAST
else
if(dy < 0)
return SOUTH
else
return NORTH
In response to Masterdan
That... is more than a little bit inefficient for something this simple.
In response to Garthor
Its complicated but it gets guaranteed desired results and it wouldnt be that hard on the cpu because its simple math really. His biggest request was for all 8 directions without having very slight angles causing a diagonal direction necessarily. So yeah.
In response to Masterdan
You seem to think that there is always a correlation between something being efficient and something executing quickly.
In response to Masterdan
No, he just wanted N/S/E/W.
In response to Popisfizzy
you could own me with something as precise with less lines of code. Its a programming copout to insult my definition of things.
In response to Garthor
Garthor wrote:
No, he just wanted N/S/E/W.

well. my bad. Hahahah
In response to Garthor
Thanks Gathor works perfectly ^^.