Compare commits
2 Commits
2239ba314b
...
c145e5db74
Author | SHA1 | Date |
---|---|---|
orwell | c145e5db74 | |
orwell | 3606a9bdfc |
|
@ -33,7 +33,7 @@ advtrains = {trains={}, player_to_train_mapping={}}
|
||||||
|
|
||||||
-- =======================Development/debugging settings=====================
|
-- =======================Development/debugging settings=====================
|
||||||
-- DO NOT USE FOR NORMAL OPERATION
|
-- DO NOT USE FOR NORMAL OPERATION
|
||||||
local DUMP_DEBUG_SAVE = false
|
local DUMP_DEBUG_SAVE = true
|
||||||
-- dump the save files in human-readable format into advtrains_DUMP
|
-- dump the save files in human-readable format into advtrains_DUMP
|
||||||
|
|
||||||
local GENERATE_ATRICIFIAL_LAG = false
|
local GENERATE_ATRICIFIAL_LAG = false
|
||||||
|
|
|
@ -22,6 +22,7 @@ dofile(modpath.."route_prog.lua")
|
||||||
dofile(modpath.."routesetting.lua")
|
dofile(modpath.."routesetting.lua")
|
||||||
dofile(modpath.."tcb_ts_ui.lua")
|
dofile(modpath.."tcb_ts_ui.lua")
|
||||||
dofile(modpath.."route_ui.lua")
|
dofile(modpath.."route_ui.lua")
|
||||||
|
dofile(modpath.."smartroute.lua")
|
||||||
dofile(modpath.."tool.lua")
|
dofile(modpath.."tool.lua")
|
||||||
|
|
||||||
dofile(modpath.."approach.lua")
|
dofile(modpath.."approach.lua")
|
||||||
|
|
|
@ -86,6 +86,9 @@ function atil.show_route_edit_form(pname, sigd, routeid)
|
||||||
form = form.."textlist[0.5,2;3,3.9;rtelog;"..table.concat(tab, ",").."]"
|
form = form.."textlist[0.5,2;3,3.9;rtelog;"..table.concat(tab, ",").."]"
|
||||||
|
|
||||||
form = form.."button[0.5,6;3,1;back;<<< Back to signal]"
|
form = form.."button[0.5,6;3,1;back;<<< Back to signal]"
|
||||||
|
if route.smartroute_generated then
|
||||||
|
form = form.."button[3.5,6;2,1;noautogen;Clr Autogen]"
|
||||||
|
end
|
||||||
form = form.."button[5.5,6;3,1;delete;Delete Route]"
|
form = form.."button[5.5,6;3,1;delete;Delete Route]"
|
||||||
|
|
||||||
--atdebug(route.ars)
|
--atdebug(route.ars)
|
||||||
|
@ -135,6 +138,11 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
advtrains.interlocking.show_signal_aspect_selector(pname, suppasp, route.name, callback, route.aspect or advtrains.interlocking.GENERIC_FREE)
|
advtrains.interlocking.show_signal_aspect_selector(pname, suppasp, route.name, callback, route.aspect or advtrains.interlocking.GENERIC_FREE)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if fields.noautogen then
|
||||||
|
route.smartroute_generated = nil
|
||||||
|
end
|
||||||
|
|
||||||
if fields.delete then
|
if fields.delete then
|
||||||
-- if something set the route in the meantime, make sure this doesn't break.
|
-- if something set the route in the meantime, make sure this doesn't break.
|
||||||
atil.route.update_route(sigd, tcbs, nil, true)
|
atil.route.update_route(sigd, tcbs, nil, true)
|
||||||
|
|
|
@ -419,12 +419,29 @@ end
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
function signal.can_dig(pos)
|
function signal.can_dig(pos)
|
||||||
return not advtrains.interlocking.db.get_sigd_for_signal(pos)
|
local sigd = advtrains.interlocking.db.get_sigd_for_signal(pos)
|
||||||
|
if sigd then
|
||||||
|
local tcbs = advtrains.interlocking.db.get_tcbs(sigd)
|
||||||
|
if tcbs.routeset then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
function signal.after_dig(pos)
|
function signal.after_dig(pos, oldnode, oldmetadata, player)
|
||||||
|
-- unassign signal if necessary
|
||||||
|
local sigd = advtrains.interlocking.db.get_sigd_for_signal(pos)
|
||||||
|
if sigd then
|
||||||
|
local tcbs = advtrains.interlocking.db.get_tcbs(sigd)
|
||||||
|
advtrains.interlocking.db.set_sigd_for_signal(pos, nil)
|
||||||
|
tcbs.signal = nil
|
||||||
|
tcbs.route_aspect = nil
|
||||||
|
tcbs.route_remote = nil
|
||||||
|
minetest.chat_send_player(player:get_player_name(), "Signal has been unassigned. Name and routes are kept for reuse.")
|
||||||
|
end
|
||||||
-- TODO clear influence point
|
-- TODO clear influence point
|
||||||
advtrains.interlocking.signal.clear_aspect(pos)
|
advtrains.interlocking.signal.unregister_aspect(pos)
|
||||||
end
|
end
|
||||||
|
|
||||||
function signal.on_rightclick(pos, node, player, itemstack, pointed_thing)
|
function signal.on_rightclick(pos, node, player, itemstack, pointed_thing)
|
||||||
|
|
|
@ -83,6 +83,7 @@ function advtrains.interlocking.show_ip_sa_form(pos, pname)
|
||||||
-- Create Signal aspect formspec elements
|
-- Create Signal aspect formspec elements
|
||||||
local ndef = advtrains.ndb.get_ndef(pos)
|
local ndef = advtrains.ndb.get_ndef(pos)
|
||||||
if ndef and ndef.advtrains then
|
if ndef and ndef.advtrains then
|
||||||
|
form[#form+1] = F.label(0.5, 2, "Signal Aspect:")
|
||||||
-- main aspect list
|
-- main aspect list
|
||||||
if ndef.advtrains.main_aspects then
|
if ndef.advtrains.main_aspects then
|
||||||
local entries = { "<none>" }
|
local entries = { "<none>" }
|
||||||
|
|
|
@ -0,0 +1,149 @@
|
||||||
|
-- smartroute.lua
|
||||||
|
-- Implementation of the advtrains auto-route search
|
||||||
|
|
||||||
|
local atil = advtrains.interlocking
|
||||||
|
local ildb = atil.db
|
||||||
|
local sr = {}
|
||||||
|
|
||||||
|
|
||||||
|
local function otherside(s)
|
||||||
|
if s==1 then return 2 else return 1 end
|
||||||
|
end
|
||||||
|
|
||||||
|
--route search implementation
|
||||||
|
-- Note this is similar to recursively_find_routes in database.lua, there used for the rscache
|
||||||
|
|
||||||
|
local function recursively_find_routes(s_pos, s_connid, searching_shunt, tcbseq, mark_pos, result_table, scan_limit)
|
||||||
|
--atdebug("Recursively restarting at ",s_pos, s_connid, "limit left", scan_limit)
|
||||||
|
local ti = advtrains.get_track_iterator(s_pos, s_connid, scan_limit, false)
|
||||||
|
local pos, connid, bconnid = ti:next_branch()
|
||||||
|
pos, connid, bconnid = ti:next_track()-- step once to get ahead of previous turnout
|
||||||
|
local last_pos
|
||||||
|
repeat
|
||||||
|
-- record position in mark_pos
|
||||||
|
local pts = advtrains.encode_pos(pos)
|
||||||
|
mark_pos[pts] = true
|
||||||
|
|
||||||
|
local node = advtrains.ndb.get_node_or_nil(pos)
|
||||||
|
atdebug("(SmartRoute) Walk ",pos, "nodename", node.name, "entering at conn",bconnid)
|
||||||
|
local ndef = minetest.registered_nodes[node.name]
|
||||||
|
if ndef.advtrains and ndef.advtrains.node_state_map then
|
||||||
|
-- Stop, this is a switchable node. Find out which conns we can go at
|
||||||
|
atdebug("(SmartRoute) Found turnout ",pos, "nodename", node.name, "entering at conn",bconnid)
|
||||||
|
local out_conns = ildb.get_possible_out_connids(node.name, bconnid)
|
||||||
|
for oconnid, state in pairs(out_conns) do
|
||||||
|
--atdebug("Going in direction",oconnid,"state",state)
|
||||||
|
recursively_find_routes(pos, oconnid, searching_shunt, table.copy(tcbseq), table.copy(mark_pos), result_table, ti.limit)
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
--otherwise, this might be a tcb
|
||||||
|
local tcb = ildb.get_tcb(pos)
|
||||||
|
if tcb then
|
||||||
|
local fsigd = { p = pos, s = connid }
|
||||||
|
atdebug("(SmartRoute) Encounter TCB ",fsigd)
|
||||||
|
tcbseq[#tcbseq+1] = fsigd
|
||||||
|
-- check if this is a possible route endpoint
|
||||||
|
local tcbs = tcb[connid]
|
||||||
|
if tcbs.signal then
|
||||||
|
local ndef = advtrains.ndb.get_ndef(tcbs.signal)
|
||||||
|
if ndef and ndef.advtrains then
|
||||||
|
if ndef.advtrains.route_role == "main" or ndef.advtrains.route_role == "main_distant"
|
||||||
|
or ndef.advtrains.route_role == "end" or ndef.advtrains.route_role == "shunt" then
|
||||||
|
-- signal is suitable target
|
||||||
|
local is_mainsignal = ndef.advtrains.route_role ~= "shunt"
|
||||||
|
-- record the found route in the results
|
||||||
|
result_table[#result_table+1] = {
|
||||||
|
tcbseq = table.copy(tcbseq),
|
||||||
|
mark_pos = table.copy(mark_pos),
|
||||||
|
shunt_route = not is_mainsignal,
|
||||||
|
to_end_of_track = false,
|
||||||
|
name = tcbs.signal_name or atil.sigd_to_string(fsigd)
|
||||||
|
}
|
||||||
|
-- if this is a main signal and/or we are only searching shunt routes, stop the search here
|
||||||
|
if is_mainsignal or searching_shunt then
|
||||||
|
atdebug("(SmartRoute) Terminating here because it is main or only shunt routes searched")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Go forward
|
||||||
|
last_pos = pos
|
||||||
|
pos, connid, bconnid = ti:next_track()
|
||||||
|
until not pos -- this stops the loop when either the track end is reached or the limit is hit
|
||||||
|
--atdebug("recursively_find_routes: Reached track end or limit at", last_pos, ". This path is not saved, returning")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function build_route_from_foundroute(froute, name)
|
||||||
|
local route = {
|
||||||
|
name = froute.name,
|
||||||
|
use_rscache = true,
|
||||||
|
smartroute_generated = true,
|
||||||
|
}
|
||||||
|
for _, sigd in ipairs(froute.tcbseq) do
|
||||||
|
route[#route+1] = { next = sigd, locks = {} }
|
||||||
|
end
|
||||||
|
return route
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Maximum scan length for track iterator
|
||||||
|
local TS_MAX_SCAN = 1000
|
||||||
|
|
||||||
|
function sr.init(pname, sigd)
|
||||||
|
-- is start signal a shunt signal?
|
||||||
|
local is_startsignal_shunt = false
|
||||||
|
local tcbs = ildb.get_tcbs(sigd)
|
||||||
|
if tcbs.signal then
|
||||||
|
local ndef = advtrains.ndb.get_ndef(tcbs.signal)
|
||||||
|
if ndef and ndef.advtrains then
|
||||||
|
if ndef.advtrains.route_role == "shunt" then
|
||||||
|
is_startsignal_shunt = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local result_table = {}
|
||||||
|
recursively_find_routes(sigd.p, sigd.s, is_startsignal_shunt, {}, {}, result_table, TS_MAX_SCAN)
|
||||||
|
|
||||||
|
atdebug("Smartroute search finished:",result_table)
|
||||||
|
|
||||||
|
-- Short-circuit logic right now for testing
|
||||||
|
-- go through and delete all routes that are autogenerated
|
||||||
|
local i = 1
|
||||||
|
while i<=#tcbs.routes do
|
||||||
|
if tcbs.routes[i].smartroute_generated then
|
||||||
|
table.remove(tcbs.routes, i)
|
||||||
|
else
|
||||||
|
i=i+1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- just plainly create routes!
|
||||||
|
for idx, froute in ipairs(result_table) do
|
||||||
|
tcbs.routes[#tcbs.routes+1] = build_route_from_foundroute(froute)
|
||||||
|
end
|
||||||
|
atwarn("Smartroute done!")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--[[
|
||||||
|
player1 = {
|
||||||
|
origin = <sigd>
|
||||||
|
found_routes = {
|
||||||
|
{ tcbseq = {<sigd1>, <sigd2>, <end_sigd>}, mark_pos = { table with keys being encoded_pos of rails constituting route }, to_end_of_track = false, shunt_route = false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]]--
|
||||||
|
local player_smartroute = {}
|
||||||
|
|
||||||
|
minetest.register_on_punchnode(function(pos, node, player, pointed_thing)
|
||||||
|
local pname = player:get_player_name()
|
||||||
|
if not minetest.check_player_privs(pname, "interlocking") then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
-- TODO
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
advtrains.interlocking.smartroute = sr
|
|
@ -616,6 +616,9 @@ function advtrains.interlocking.show_signalling_form(sigd, pname, sel_rte, calle
|
||||||
local strtab = {}
|
local strtab = {}
|
||||||
for idx, route in ipairs(tcbs.routes) do
|
for idx, route in ipairs(tcbs.routes) do
|
||||||
local clr = ""
|
local clr = ""
|
||||||
|
if route.smartroute_generated then
|
||||||
|
clr = "#FFFF55"
|
||||||
|
end
|
||||||
if route.ars then
|
if route.ars then
|
||||||
clr = "#FF5555"
|
clr = "#FF5555"
|
||||||
if route.ars.default then
|
if route.ars.default then
|
||||||
|
@ -639,8 +642,8 @@ function advtrains.interlocking.show_signalling_form(sigd, pname, sel_rte, calle
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if hasprivs then
|
if hasprivs then
|
||||||
form = form.."button[0.5,8;2.5,1;newroute;New Route]"
|
form = form.."button[0.5,8;2.5,1;smartroute;Smart Route]"
|
||||||
form = form.."button[ 3,8;2.5,1;unassign;Unassign Signal]"
|
form = form.."button[ 3,8;2.5,1;newroute;New (Manual)]"
|
||||||
form = form..string.format("checkbox[0.5,8.75;ars;Automatic routesetting;%s]", not tcbs.ars_disabled)
|
form = form..string.format("checkbox[0.5,8.75;ars;Automatic routesetting;%s]", not tcbs.ars_disabled)
|
||||||
end
|
end
|
||||||
elseif sigd_equal(tcbs.route_origin, sigd) then
|
elseif sigd_equal(tcbs.route_origin, sigd) then
|
||||||
|
@ -730,6 +733,12 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
tcbs.ars_ignore_next = nil
|
tcbs.ars_ignore_next = nil
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
if fields.smartroute and hasprivs then
|
||||||
|
advtrains.interlocking.smartroute.init(pname, sigd)
|
||||||
|
minetest.close_formspec(pname, formname)
|
||||||
|
tcbs.ars_ignore_next = nil
|
||||||
|
return
|
||||||
|
end
|
||||||
if sel_rte and tcbs.routes[sel_rte] then
|
if sel_rte and tcbs.routes[sel_rte] then
|
||||||
if fields.setroute then
|
if fields.setroute then
|
||||||
ilrs.update_route(sigd, tcbs, sel_rte)
|
ilrs.update_route(sigd, tcbs, sel_rte)
|
||||||
|
@ -748,24 +757,6 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if fields.unassign and hasprivs then
|
|
||||||
-- unassigning the signal from the tcbs
|
|
||||||
-- only when no route is set.
|
|
||||||
-- Routes and name remain saved, in case the player wants to reassign a new signal
|
|
||||||
if not tcbs.routeset then
|
|
||||||
local signal_pos = tcbs.signal
|
|
||||||
ildb.set_sigd_for_signal(signal_pos, nil)
|
|
||||||
tcbs.signal = nil
|
|
||||||
tcbs.route_aspect = nil
|
|
||||||
tcbs.route_remote = nil
|
|
||||||
minetest.close_formspec(pname, formname)
|
|
||||||
minetest.chat_send_player(pname, "Signal has been unassigned. Name and routes are kept for reuse.")
|
|
||||||
return
|
|
||||||
else
|
|
||||||
minetest.chat_send_player(pname, "Please cancel route first!")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if fields.ars then
|
if fields.ars then
|
||||||
tcbs.ars_disabled = not minetest.is_yes(fields.ars)
|
tcbs.ars_disabled = not minetest.is_yes(fields.ars)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue