Page 1 of 1

Optional argument ignore_positions for LuaSurface::find_non_colliding_position

Posted: Sun Apr 16, 2023 2:29 pm
by Pi-C
What?
Please add an optional argument ignore_positions (array of positions) that will be ignored by LuaSurface::find_non_colliding_position! If the argument is nil, return the first non-colliding position found, otherwise return the first non-colliding position which is not listed in ignore_positions.
Use case
In Autodrive, I use LuaSurface::request_path to get a path from a vehicle's position to the position selected by a player. If no path is found, I look for a non-colliding position in a certain radius around the vehicle, teleport it there, and request a new path from the vehicle's current position to the destination. Repeat if necessary.

This usually works, but I've got into a situation where the vehicle is teleported continuously between the same two positions because it can't find a path from neither:
bumping.png
bumping.png (759.93 KiB) Viewed 333 times
I'm not sure how find_non_colliding_position works, but I suppose it is like this:
The function is called as surface.find_non_colliding_position(name, center, radius, precision). Starting from the angle given by vehicle.orientation, a circle with the radius "precision" is searched (either clockwise or anticlockwise). If no suitable position has been found, the radius is extended by "precision" until either a non-colliding position could be found or the maximum defined by "radius" has been searched.
Problem
It seems that LuaSurface::find_non_colliding_position will always return the first position found. If i can't get a path for a vehicle at position A, teleport it to the first position found (position B), don't find a path there and look for a new position and get back to A, this is a vicious circle. There could be a position C or D, but I'll never get to know these because the function always returns after finding position A or B.
Solution
If I've teleported the vehicle to a new position and can't find a path from there, I'd store this position with the vehicle data for use with ignore_positions. Next time I'd call LuaSurface::find_non_colliding_position, I'd pass on my array of forbidden positions and try to find another position from which I'd request a path. When I get a path, everything is alright. Should LuaSurface::find_non_colliding_position return nil, I'd know for good that the selected destination is unreachable from the vehicle's position, and I could cancel repathing or take some other measure to avoid wasting UPS on surface searches and path requests.