parent
c3c96274be
commit
a751d1da9c
|
@ -0,0 +1,22 @@
|
||||||
|
-- ars.lua
|
||||||
|
-- automatic routesetting
|
||||||
|
|
||||||
|
--[[
|
||||||
|
The "ARS table" and its effects:
|
||||||
|
Every route has (or can have) an associated ARS table. This can either be
|
||||||
|
ars = { [n] = {ln="<line>"}/{rc="<routingcode>"}/{c="<a comment>"} }
|
||||||
|
a list of rules involving either line or routingcode matchers (or comments, those are ignored)
|
||||||
|
The first matching rule determines the route to set.
|
||||||
|
- or -
|
||||||
|
ars = {default = true}
|
||||||
|
this means that all trains that no other rule matches on should use this route
|
||||||
|
|
||||||
|
Compound ("and") conjunctions are not supported (--TODO should they?)
|
||||||
|
|
||||||
|
For editing, those tables are transformed into lines in a text area:
|
||||||
|
{ln=...} -> LN ...
|
||||||
|
{rc=...} -> RC ...
|
||||||
|
{c=...} -> #...
|
||||||
|
{default=true} -> *
|
||||||
|
See also route_ui.lua
|
||||||
|
]]
|
|
@ -19,9 +19,11 @@ dofile(modpath.."train_sections.lua")
|
||||||
dofile(modpath.."route_prog.lua")
|
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.."tool.lua")
|
dofile(modpath.."tool.lua")
|
||||||
|
|
||||||
dofile(modpath.."lzb.lua")
|
dofile(modpath.."lzb.lua")
|
||||||
|
dofile(modpath.."ars.lua")
|
||||||
|
|
||||||
|
|
||||||
minetest.register_privilege("interlocking", {description = "Can set up track sections, routes and signals.", give_to_singleplayer = true})
|
minetest.register_privilege("interlocking", {description = "Can set up track sections, routes and signals.", give_to_singleplayer = true})
|
||||||
|
|
|
@ -0,0 +1,196 @@
|
||||||
|
-- route_ui.lua
|
||||||
|
-- User interface for showing and editing routes
|
||||||
|
|
||||||
|
local atil = advtrains.interlocking
|
||||||
|
local ildb = atil.db
|
||||||
|
|
||||||
|
-- TODO duplicate
|
||||||
|
local lntrans = { "A", "B" }
|
||||||
|
local function sigd_to_string(sigd)
|
||||||
|
return minetest.pos_to_string(sigd.p).." / "..lntrans[sigd.s]
|
||||||
|
end
|
||||||
|
|
||||||
|
-- The ARS data are saved in a table format, but are entered in text format. Utility functions to transform between both.
|
||||||
|
local function ars_to_text(arstab)
|
||||||
|
if not arstab then
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
|
||||||
|
local txt = {}
|
||||||
|
|
||||||
|
for i, arsent in ipairs(arstab) do
|
||||||
|
if arsent.ln then
|
||||||
|
txt[#txt+1] = "LN "..arsent.ln
|
||||||
|
elseif arsent.rc then
|
||||||
|
txt[#txt+1] = "RC "..arsent.rc
|
||||||
|
elseif arsent.c then
|
||||||
|
txt[#txt+1] = "#"..arsent.c
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if arstab.default then
|
||||||
|
return "*\n" .. table.concat(txt, "\n")
|
||||||
|
end
|
||||||
|
return table.concat(txt, "\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function text_to_ars(t)
|
||||||
|
if t=="" then
|
||||||
|
return nil
|
||||||
|
elseif t=="*" then
|
||||||
|
return {default=true}
|
||||||
|
end
|
||||||
|
local arstab = {}
|
||||||
|
for line in string.gmatch(t, "[^\r\n]+") do
|
||||||
|
if line=="*" then
|
||||||
|
arstab.default = true
|
||||||
|
else
|
||||||
|
local c, v = string.match(line, "^(..)%s(.*)$")
|
||||||
|
if c and v then
|
||||||
|
local tt=string.upper(c)
|
||||||
|
if tt=="LN" then
|
||||||
|
arstab[#arstab+1] = {ln=v}
|
||||||
|
elseif tt=="RC" then
|
||||||
|
arstab[#arstab+1] = {rc=v}
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local ct = string.match(line, "^#(.*)$")
|
||||||
|
if ct then arstab[#arstab+1] = {c = ct} end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return arstab
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function atil.show_route_edit_form(pname, sigd, routeid)
|
||||||
|
|
||||||
|
if not minetest.check_player_privs(pname, {train_operator=true, interlocking=true}) then
|
||||||
|
minetest.chat_send_player(pname, "Insufficient privileges to use this!")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local tcbs = atil.db.get_tcbs(sigd)
|
||||||
|
if not tcbs then return end
|
||||||
|
local route = tcbs.routes[routeid]
|
||||||
|
if not route then return end
|
||||||
|
|
||||||
|
local form = "size[9,10]label[0.5,0.2;Route overview]"
|
||||||
|
form = form.."field[0.8,1.2;5.2,1;name;Route name;"..route.name.."]"
|
||||||
|
form = form.."button[5.5,0.9;1,1;setname;Set]"
|
||||||
|
|
||||||
|
-- construct textlist for route information
|
||||||
|
local tab = {}
|
||||||
|
local function itab(t)
|
||||||
|
tab[#tab+1] = string.gsub(t, ",", " ")
|
||||||
|
end
|
||||||
|
itab("TCB "..sigd_to_string(sigd).." ("..tcbs.signal_name..") Route #"..routeid)
|
||||||
|
|
||||||
|
-- this code is partially copy-pasted from routesetting.lua
|
||||||
|
-- we start at the tc designated by signal
|
||||||
|
local c_sigd = sigd
|
||||||
|
local i = 1
|
||||||
|
local c_tcbs, c_ts_id, c_ts, c_rseg, c_lckp
|
||||||
|
while c_sigd and i<=#route do
|
||||||
|
c_tcbs = ildb.get_tcbs(c_sigd)
|
||||||
|
c_ts_id = c_tcbs.ts_id
|
||||||
|
if not c_ts_id then
|
||||||
|
itab("-!- No track section adjacent to "..sigd_to_string(c_sigd)..". Please reconfigure route!")
|
||||||
|
end
|
||||||
|
c_ts = ildb.get_ts(c_ts_id)
|
||||||
|
|
||||||
|
c_rseg = route[i]
|
||||||
|
c_lckp = {}
|
||||||
|
|
||||||
|
itab(""..i.." Entry "..sigd_to_string(c_sigd).." -> Sec. "..c_ts.name.." -> Exit "..(c_rseg.next and sigd_to_string(c_rseg.next) or "END"))
|
||||||
|
|
||||||
|
for pts, state in pairs(c_rseg.locks) do
|
||||||
|
|
||||||
|
local pos = minetest.string_to_pos(pts)
|
||||||
|
itab(" Lock: "..pts.." -> "..state)
|
||||||
|
if not advtrains.is_passive(pos) then
|
||||||
|
itab("-!- No passive component at "..pts..". Please reconfigure route!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- advance
|
||||||
|
c_sigd = c_rseg.next
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
if c_sigd then
|
||||||
|
local e_tcbs = ildb.get_tcbs(c_sigd)
|
||||||
|
itab("Route end: "..sigd_to_string(c_sigd).." ("..(e_tcbs.signal_name or "-")..")")
|
||||||
|
else
|
||||||
|
itab("Route ends on dead-end")
|
||||||
|
end
|
||||||
|
|
||||||
|
form = form.."textlist[0.5,2;7,4;rtelog;"..table.concat(tab, ",").."]"
|
||||||
|
|
||||||
|
form = form.."button[0.5,6;2,1;back;<<< Back to signal]"
|
||||||
|
form = form.."button[3.5,6;2,1;aspect;Signal Aspect]"
|
||||||
|
form = form.."button[5.5,6;2,1;delete;Delete Route]"
|
||||||
|
|
||||||
|
atdebug(route.ars)
|
||||||
|
form = form.."textarea[1,7.3;5.2,3;ars;ARS Rule List;"..ars_to_text(route.ars).."]"
|
||||||
|
form = form.."button[6,7.7;1,1;savears;Save]"
|
||||||
|
|
||||||
|
minetest.show_formspec(pname, "at_il_routeedit_"..minetest.pos_to_string(sigd.p).."_"..sigd.s.."_"..routeid, form)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
|
local pname = player:get_player_name()
|
||||||
|
if not minetest.check_player_privs(pname, {train_operator=true, interlocking=true}) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local pts, connids, routeids = string.match(formname, "^at_il_routeedit_([^_]+)_(%d)_(%d+)$")
|
||||||
|
local pos, connid, routeid
|
||||||
|
if pts then
|
||||||
|
pos = minetest.string_to_pos(pts)
|
||||||
|
connid = tonumber(connids)
|
||||||
|
routeid = tonumber(routeids)
|
||||||
|
if not connid or connid<1 or connid>2 then return end
|
||||||
|
if not routeid then return end
|
||||||
|
end
|
||||||
|
if pos and connid and routeid and not fields.quit then
|
||||||
|
local sigd = {p=pos, s=connid}
|
||||||
|
local tcbs = ildb.get_tcbs(sigd)
|
||||||
|
if not tcbs then return end
|
||||||
|
local route = tcbs.routes[routeid]
|
||||||
|
if not route then return end
|
||||||
|
|
||||||
|
if fields.setname and fields.name then
|
||||||
|
route.name = fields.name
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.aspect then
|
||||||
|
local suppasp = advtrains.interlocking.signal_get_supported_aspects(tcbs.signal)
|
||||||
|
|
||||||
|
local callback = function(pname, asp)
|
||||||
|
route.aspect = asp
|
||||||
|
advtrains.interlocking.show_route_edit_form(pname, sigd, routeid)
|
||||||
|
end
|
||||||
|
|
||||||
|
advtrains.interlocking.show_signal_aspect_selector(pname, suppasp, route.name, callback, rte.aspect)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if fields.delete then
|
||||||
|
-- if something set the route in the meantime, make sure this doesn't break.
|
||||||
|
atil.route.update_route(sigd, tcbs, nil, true)
|
||||||
|
table.remove(tcbs.routes, routeid)
|
||||||
|
advtrains.interlocking.show_signalling_form(sigd, pname)
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.ars and fields.savears then
|
||||||
|
route.ars = text_to_ars(fields.ars)
|
||||||
|
atdebug(route.ars)
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.back then
|
||||||
|
advtrains.interlocking.show_signalling_form(sigd, pname)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end)
|
|
@ -568,7 +568,14 @@ function advtrains.interlocking.show_signalling_form(sigd, pname, sel_rte)
|
||||||
if not tcbs.route_origin then
|
if not tcbs.route_origin then
|
||||||
local strtab = {}
|
local strtab = {}
|
||||||
for idx, route in ipairs(tcbs.routes) do
|
for idx, route in ipairs(tcbs.routes) do
|
||||||
strtab[#strtab+1] = minetest.formspec_escape(route.name)
|
local clr = ""
|
||||||
|
if route.ars then
|
||||||
|
clr = "#FF5555"
|
||||||
|
if route.ars.default then
|
||||||
|
clr = "#55FF55"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
strtab[#strtab+1] = clr .. minetest.formspec_escape(route.name)
|
||||||
end
|
end
|
||||||
form = form.."label[0.5,2.5;Routes:]"
|
form = form.."label[0.5,2.5;Routes:]"
|
||||||
form = form.."textlist[0.5,3;5,3;rtelist;"..table.concat(strtab, ",").."]"
|
form = form.."textlist[0.5,3;5,3;rtelist;"..table.concat(strtab, ",").."]"
|
||||||
|
@ -576,9 +583,7 @@ function advtrains.interlocking.show_signalling_form(sigd, pname, sel_rte)
|
||||||
form = form.."button[0.5,6; 5,1;setroute;Set Route]"
|
form = form.."button[0.5,6; 5,1;setroute;Set Route]"
|
||||||
form = form.."button[0.5,7;2,1;dsproute;Show]"
|
form = form.."button[0.5,7;2,1;dsproute;Show]"
|
||||||
if hasprivs then
|
if hasprivs then
|
||||||
form = form.."button[2.5,7;1,1;delroute;Delete]"
|
form = form.."button[3.5,7;2,1;editroute;Edit]"
|
||||||
form = form.."button[3.5,7;1,1;editroute;Rename]"
|
|
||||||
form = form.."button[4.5,7;1,1;asproute;Aspect]"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if hasprivs then
|
if hasprivs then
|
||||||
|
@ -657,26 +662,11 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
minetest.after(10, function() advtrains.interlocking.clear_visu_context("disp_"..t) end)
|
minetest.after(10, function() advtrains.interlocking.clear_visu_context("disp_"..t) end)
|
||||||
end
|
end
|
||||||
if fields.editroute and hasprivs then
|
if fields.editroute and hasprivs then
|
||||||
local rte = tcbs.routes[sel_rte]
|
advtrains.interlocking.show_route_edit_form(pname, sigd, sel_rte)
|
||||||
minetest.show_formspec(pname, formname.."_renroute_"..sel_rte, "field[name;Enter new route name;"..rte.name.."]")
|
--local rte = tcbs.routes[sel_rte]
|
||||||
|
--minetest.show_formspec(pname, formname.."_renroute_"..sel_rte, "field[name;Enter new route name;"..rte.name.."]")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if fields.asproute and hasprivs then
|
|
||||||
local rte = tcbs.routes[sel_rte]
|
|
||||||
local suppasp = advtrains.interlocking.signal_get_supported_aspects(tcbs.signal)
|
|
||||||
|
|
||||||
local callback = function(pname, asp)
|
|
||||||
rte.aspect = asp
|
|
||||||
advtrains.interlocking.show_signalling_form(sigd, pname, sel_rte)
|
|
||||||
end
|
|
||||||
|
|
||||||
advtrains.interlocking.show_signal_aspect_selector(pname, suppasp, rte.name, callback, rte.aspect)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if fields.delroute and hasprivs then
|
|
||||||
table.remove(tcbs.routes, sel_rte)
|
|
||||||
sel_rte = nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue