Page 1 of 1
[0.14.19] Glitchy LuaEntity.get_connected_rail method
Posted: Fri Nov 04, 2016 10:55 pm
by icedevml
Hello,
I want to use LuaEntity.get_connected_rail together with LuaTrain.front_rail and LuaTrain.rail_direction_from_front_rail. So in my mod I implemented the following algorithm (pseudocode):
Code: Select all
local front_rail = some_train.front_rail
local dir = some_train.rail_direction_from_front_rail
local n = 0
local path = {}
while n < 10 do
table.insert(path, front_rail)
front_rail = front_rail.get_connected_rail{rail_direction=dir, rail_connection_direction=defines.rail_connection_direction.straight}
n = n+1
end
So at the end, "path" table was supposed to contain next 10 rail objects which are straight ahead. Everything works in case of rails placed in north, south, west and east direction. In case of rails placed in northeast, southeast etc. direction, incorrect values are returned every second time, so the path after performing above algorithm looks like this: { rail1, rail2, rail1, rail2, rail1, rail2 }.
For the first time it actually returns NEXT rail, but for the next time in the same direction it returns PREVIOUS rail o_O At the moment this method is kinda unusable due to this problem.
I could share some code or screenshots if needed.
Re: Glitchy LuaEntity.get_connected_rail method
Posted: Fri Nov 04, 2016 11:06 pm
by Loewchen
Please post a minimal working example, its output and the output you would expect. And please state the version of the game.
Re: Glitchy LuaEntity.get_connected_rail method
Posted: Fri Nov 04, 2016 11:11 pm
by icedevml
Steps to reproduce:
1. build some simple rail path without junctions
2. build a diesel locomotive and enter it
3. run the following lua function:
Code: Select all
function inspect_path()
local train = game.player.vehicle.train
local fr = train.front_rail
local dir = train.rail_direction_from_front_rail
local n = 0
while n < 10 do
local cr = fr.get_connected_rail{rail_direction=dir, rail_connection_direction=defines.rail_connection_direction.straight}
game.player.print("#" .. n .. ": " .. cr.position.x .. " " .. cr.position.y)
fr = cr
n = n + 1
end
end
Enclosed you may find three screenshots with the paths generated by above function. Situation on r1 screenshot is okay, while on r2 we could see a strange loop and on r3 it yields nil after approaching curved rail.
I would expect that the above code would give me next 10 consecutive rail entities which are ahead.
Tested with Factorio 0.14.16 and Factorio 0.14.19
Re: [0.14.19] Glitchy LuaEntity.get_connected_rail method
Posted: Sat Nov 05, 2016 3:46 am
by osldgoth
I think perhaps that is caused by the diagonal rails alternating direction, so you'll need to write your code to account for that (annoying)
Re: [0.14.19] Glitchy LuaEntity.get_connected_rail method
Posted: Sat Nov 05, 2016 9:52 am
by icedevml
osldgoth wrote:I think perhaps that is caused by the diagonal rails alternating direction, so you'll need to write your code to account for that (annoying)
I also realized that, regardless of how intuitive it is. Let's add a direction inverting in case of diagonal rails:
Code: Select all
function inspect_path()
local train = game.player.vehicle.train
local fr = train.front_rail
local dir = train.rail_direction_from_front_rail
local n = 0
while n < 10 do
local cr = fr.get_connected_rail{rail_direction=dir, rail_connection_direction=defines.rail_connection_direction.straight}
if cr.name == 'straight-rail' and cr.direction % 2 == 1 then
if dir == defines.rail_direction.front then
dir = defines.rail_direction.back
else
dir = defines.rail_direction.front
end
end
game.player.print("#" .. n .. ": " .. cr.position.x .. " " .. cr.position.y)
fr = cr
n = n + 1
end
end
So now it works if we have only straight rails or only diagonal rails. If there is a curved rail in the middle of path it works only sometimes.
I have trouble with understanding the philosophy and implementation details behind this and it's not documented at all.
Re: [0.14.19] Glitchy LuaEntity.get_connected_rail method
Posted: Sat Nov 05, 2016 10:07 am
by icedevml
Okay, I realized that in case of curved rail we have to go to the left or to the right. So the new inspect_path including that:
Code: Select all
function inspect_path()
local train = game.player.vehicle.train
local fr = train.front_rail
local dir = train.rail_direction_from_front_rail
local n = 0
while n < 10 do
local rail_ahead = fr.get_connected_rail{rail_direction=dir, rail_connection_direction=defines.rail_connection_direction.straight}
local rail_left = fr.get_connected_rail{rail_direction=dir, rail_connection_direction=defines.rail_connection_direction.left}
local rail_right = fr.get_connected_rail{rail_direction=dir, rail_connection_direction=defines.rail_connection_direction.right}
local use_rail = nil
if rail_ahead and rail_left == nil and rail_right == nil then
use_rail = rail_ahead
game.player.print("#" .. n .. ": using ahead")
elseif rail_left and rail_ahead == nil and rail_right == nil then
use_rail = rail_left
game.player.print("#" .. n .. ": using left")
elseif rail_right and rail_ahead == nil and rail_left == nil then
use_rail = rail_right
game.player.print("#" .. n .. ": using right")
else
game.player.print("no path / junction detected, stopping")
return nil
end
if (use_rail.name == 'straight-rail' and use_rail.direction % 2 == 1) then
if dir == defines.rail_direction.front then
dir = defines.rail_direction.back
else
dir = defines.rail_direction.front
end
end
game.player.print("#" .. n .. ": " .. use_rail.position.x .. " " .. use_rail.position.y)
fr = use_rail
n = n + 1
end
end
Still doesn't work when it comes to curved rail (or in some cases it works, in some does not). By not working I mean catching an infinite loop at the curved rail.
Probably according to this logic I have to write some condition for inverting direction in case of curved rails but I could not get a clear idea how to do that. I guess API should be more straightforward.
Re: [0.14.19] Glitchy LuaEntity.get_connected_rail method
Posted: Sun Nov 06, 2016 11:43 am
by Klonan
Thanks for the report,
However I can't see anything wrong with the Lua method, many other mods have used it an never had an issue,
So i will move this to not a bug...
If you find a specific issue with its usage, please make a new bug report
Re: [0.14.19] Glitchy LuaEntity.get_connected_rail method
Posted: Mon Nov 07, 2016 3:26 pm
by kovarex
The most simple way to iterate rails is: (pseudocode)
Code: Select all
local direction = (the direction I want to go)
local rail = (the initial rail).
local new_rail = rail.getNext(direction)
local new_direction = opposite_direction(direction_to_rail(new_rail, rail))
direction = new_direction
rail = new_rail
(repeat)
You just need the direction_to_rail method, which simply takes one rail, and tries to find out which connection connect it to the other rail.
Then you need the opposite_direction method, which is probably something like (x + 1)% 2