Optional argument ignore_positions for LuaSurface::find_non_colliding_position

Place to ask discuss and request the modding support of Factorio. Don't request mods here.
Post Reply
Pi-C
Smart Inserter
Smart Inserter
Posts: 1655
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Optional argument ignore_positions for LuaSurface::find_non_colliding_position

Post 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 308 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.
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!

Post Reply

Return to “Modding interface requests”