aboutsummaryrefslogtreecommitdiff
path: root/trackplacer.lua
diff options
context:
space:
mode:
Diffstat (limited to 'trackplacer.lua')
-rw-r--r--trackplacer.lua133
1 files changed, 79 insertions, 54 deletions
diff --git a/trackplacer.lua b/trackplacer.lua
index a864b35..a2b64bb 100644
--- a/trackplacer.lua
+++ b/trackplacer.lua
@@ -43,23 +43,23 @@ function tp.add_worked(nnprefix, suffix, rotation, cycle_follows)
table.insert(tp.tracks[nnprefix].twrotate[suffix], rotation)
end
-function tp.find_adjacent_tracks(pos)--TODO vertical calculations(check node below)
- local conn1=0
- while conn1<16 and not advtrains.is_track_and_drives_on(minetest.get_node(advtrains.dirCoordSet(pos, conn1)).name, advtrains.all_tracktypes) do
- conn1=conn1+1
- end
- if conn1>=16 then
- return nil, nil
- end
- local conn2=0
- while conn2<16 and not advtrains.is_track_and_drives_on(minetest.get_node(advtrains.dirCoordSet(pos, conn2)).name, advtrains.all_tracktypes) or conn2==conn1 do
- conn2=conn2+1
- end
- if conn2>=16 then
- return conn1, nil
- end
- return conn1, conn2
-end
+
+--[[
+ rewrite algorithm.
+ selection criteria: these will never be changed or even selected:
+ - tracks being already connected on both sides
+ - tracks that are already connected on one side but are not bendable to the desired position
+ the following situations can occur:
+ 1. there are two more than two rails around
+ 1.1 there is one or more subset(s) that can be directly connected
+ -> choose the first possibility
+ 2.2 not
+ -> choose the first one and orient straight
+ 2. there's exactly 1 rail around
+ -> choose and orient straight
+ 3. there's no rail around
+ -> set straight
+]]
function tp.find_already_connected(pos)--TODO vertical calculations(check node below)
local function istrackandbc(pos, conn)
local cnode=minetest.get_node(advtrains.dirCoordSet(pos, conn))
@@ -70,51 +70,45 @@ function tp.find_already_connected(pos)--TODO vertical calculations(check node b
end
return false
end
- local conn1=0
- while conn1<16 and not istrackandbc(pos, conn1) do
- conn1=conn1+1
- end
- if conn1>=16 then
- return nil, nil
- end
- local conn2=0
- while conn2<16 and not istrackandbc(pos, conn2) or conn2==conn1 do
- conn2=conn2+1
+ local dnode=minetest.get_node(pos)
+ local dconn1, dconn2=advtrains.get_track_connections(dnode.name, dnode.param2)
+ local t={[true]="true", [false]="false"}
+ if istrackandbc(pos, dconn1) and istrackandbc(pos, dconn2) then return dconn1, dconn2
+ elseif istrackandbc(pos, dconn1) then return dconn1
+ elseif istrackandbc(pos, dconn2) then return dconn2
end
- if conn2>=16 then
- return conn1, nil
- end
- return conn1, conn2
+ return nil
end
-
-function tp.placetrack(pos, nnpref)
- local conn1, conn2=tp.find_adjacent_tracks(pos)
+function tp.rail_and_can_be_bent(originpos, conn, nnpref)
+ local pos=advtrains.dirCoordSet(originpos, conn)
+ local newdir=(conn+8)%16
+ local node=minetest.get_node(pos)
local tr=tp.tracks[nnpref]
- if not conn1 and not conn2 then
- minetest.set_node(pos, {name=nnpref.."_"..tr.default})
- elseif conn1 and not conn2 then
- if tr.single_conn[conn1] then
- tp.try_adjust_rail(tr, advtrains.dirCoordSet(pos, conn1), (conn1+8)%16)
- minetest.set_node(pos, tr.single_conn[conn1])
- else
- minetest.set_node(pos, {name=nnpref.."_"..tr.default})
+ if not advtrains.is_track_and_drives_on(node.name, advtrains.all_tracktypes) then
+ return false
+ end
+ --rail at other end?
+ local adj1, adj2=tp.find_already_connected(pos)
+ if adj1 and adj2 then
+ return false--dont destroy existing track
+ elseif adj1 and not adj2 then
+ if tr.double_conn[adj1.."_"..newdir] then
+ return true--if exists, connect new rail and old end
end
- elseif conn1 and conn2 then
- if tr.double_conn[conn1.."_"..conn2] then
- tp.try_adjust_rail(tr, advtrains.dirCoordSet(pos, conn1), (conn1+8)%16)
- tp.try_adjust_rail(tr, advtrains.dirCoordSet(pos, conn2), (conn1+8)%16)
- minetest.set_node(pos, tr.double_conn[conn1.."_"..conn2])
- elseif tr.single_conn[conn1] then --try at least one side
- tp.try_adjust_rail(tr, advtrains.dirCoordSet(pos, conn1), (conn1+8)%16)
- minetest.set_node(pos, tr.single_conn[conn1])
- else
- minetest.set_node(pos, {name=nnpref.."_"..tr.default})
+ return false
+ else
+ if tr.single_conn[newdir] then--just rotate old rail to right orientation
+ return true
end
+ return false
end
end
-function tp.try_adjust_rail(tr, pos, newdir)
- --is rail already connected?
+function tp.bend_rail(originpos, conn, nnpref)
+ local pos=advtrains.dirCoordSet(originpos, conn)
+ local newdir=(conn+8)%16
local node=minetest.get_node(pos)
+ local tr=tp.tracks[nnpref]
+ --is rail already connected? no need to bend.
local conn1, conn2=advtrains.get_track_connections(node.name, node.param2)
if newdir==conn1 or newdir==conn2 then
return
@@ -137,6 +131,37 @@ function tp.try_adjust_rail(tr, pos, newdir)
return false
end
end
+function tp.placetrack(pos, nnpref)
+ --1. find all rails that are likely to be connected
+ local tr=tp.tracks[nnpref]
+ local p_rails={}
+ for i=0,15 do
+ if tp.rail_and_can_be_bent(pos, i, nnpref) then
+ p_rails[#p_rails+1]=i
+ end
+ end
+ print(dump(p_rails))
+ if #p_rails==0 then
+ minetest.set_node(pos, {name=nnpref.."_"..tr.default})
+ elseif #p_rails==1 then
+ tp.bend_rail(pos, p_rails[1], nnpref)
+ minetest.set_node(pos, tr.single_conn[p_rails[1]])
+ else
+ --iterate subsets
+ for k1, conn1 in ipairs(p_rails) do
+ for k2, conn2 in ipairs(p_rails) do
+ if k1~=k2 then
+ if (tr.double_conn[conn1.."_"..conn2]) then
+ tp.bend_rail(pos, conn1, nnpref)
+ tp.bend_rail(pos, conn2, nnpref)
+ minetest.set_node(pos, tr.double_conn[conn1.."_"..conn2])
+ return
+ end
+ end
+ end
+ end
+ end
+end
function tp.register_track_placer(nnprefix, imgprefix, dispname)