ID:2154496
 
So I want to know how to compare distances between objects in a list called by the for() procedure.


example:

for(var/mob/M in oview(10))


now if there are 3 mobs on the screen, how do I make it select the closest one to the player and cycle between the mobs closest to farthest.



Try this.
use the documentation luke
This doesnt answer my question, I already know how to get_dist but I need to know how to get the dist between multiple mobs in a for() and checking which one is closest.

Doesnt even have to be for() maybe there is a better method, I just need help getting and idea on how to do that. Thanks
In response to Syama108
When you use a for() loop, the code indented below it (AKA the "body" of the loop) is run "for each" of the objects in a given list (in this case, the list returned by calling the oview(10) proc).
for(var/mob/M in oview(10))
src << "[M] is [get_dist(src, M)] tile\s away from you, [src]!"


With that, you can get a distance between the player and each of the mobs.

Since you can't determine the "closest" mobs without having to check each of the mobs, you'll need multiple loops: one loop to get the distance to each mob, and more loops to sort the list in order of increasing distance. There are many well-known sorting algorithms out there that can be applied to DM's lists.

If you only need to know the single closest mob (ignoring the rest), here's how I'd do it:
var
mob
target
closest_target
distance
shortest_distance = 1#INF

for(target in oview(10, src))
distance = get_dist(src, target)
if(distance < shortest_distance)
closest_target = target
shortest_distance = distance

if(closest_target)
src << "Closest target is [closest_target], [shortest_distance] tiles away!
Just as a point of interest: oview() and the like go from closest to farthest already, so you can find the closest by just doing

var/mob/target

for (target in oview(10,src))
break

if (!target) return


That breaks the "for" loop as soon as it finds a target. Because you defined var/mob/target outside the for loop, it remembers what it found. The if (!target) return line ends the proc early if there's no target; this may or may not be what you want it to do. If there are some things that need to happen even if no target is found, rewrite the if statement accordingly.

Now, the downside of that is that if there are multiple targets the same distance in tiles away, I think it will always default to the same one (I believe the one closest to the southwest corner, but don't quote me on that). If you want to get fancier than that, you could do something like:

var/list/targets = list()
var/mob/target
var/distance

for (target in oview(10,src))
if (distance && get_dist(target,src) > distance) break
distance = get_dist(target,src)
targets += target

if (!target) return

target = pick(targets)


What this will do is collect possible targets to a ist (targets), and terminate the loop as soon as it finds a potential target whose distance is greater than any previous targets, before adding that target to the list. It will then randomly choose among them for your final target.
Thanks guys these are both good responses so my vote is for both.