Add ARS rules for stop rails
This commit is contained in:
parent
0684c6edd7
commit
f2c2aad329
|
@ -23,23 +23,67 @@
|
||||||
|
|
||||||
local il = advtrains.interlocking
|
local il = advtrains.interlocking
|
||||||
|
|
||||||
|
-- The ARS data are saved in a table format, but are entered in text format. Utility functions to transform between both.
|
||||||
|
function il.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
|
||||||
|
|
||||||
|
function il.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
|
||||||
|
|
||||||
local function find_rtematch(routes, train)
|
local function find_rtematch(routes, train)
|
||||||
local default
|
local default
|
||||||
local line = train.line
|
|
||||||
local routingcode = train.routingcode
|
|
||||||
for rteid, route in ipairs(routes) do
|
for rteid, route in ipairs(routes) do
|
||||||
if route.ars then
|
if route.ars then
|
||||||
if route.ars.default then
|
if route.ars.default then
|
||||||
default = rteid
|
default = rteid
|
||||||
else
|
else
|
||||||
for arskey, arsent in ipairs(route.ars) do
|
if il.ars_check_rule_match(route.ars, train) then
|
||||||
--atdebug(arsent, line, routingcode)
|
return rteid
|
||||||
if arsent.ln and line and arsent.ln == line then
|
|
||||||
return rteid
|
|
||||||
elseif arsent.rc and routingcode and string.find(" "..routingcode.." ", " "..arsent.rc.." ", nil, true) then
|
|
||||||
return rteid
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -47,6 +91,25 @@ local function find_rtematch(routes, train)
|
||||||
return default
|
return default
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Checks whether ARS rule explicitly matches. This does not take into account the "default" field, since a wider context is required for this.
|
||||||
|
-- Returns the rule number that matched, or nil if nothing matched
|
||||||
|
function il.ars_check_rule_match(ars, train)
|
||||||
|
if not ars then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local line = train.line
|
||||||
|
local routingcode = train.routingcode
|
||||||
|
for arskey, arsent in ipairs(ars) do
|
||||||
|
--atdebug(arsent, line, routingcode)
|
||||||
|
if arsent.ln and line and arsent.ln == line then
|
||||||
|
return arskey
|
||||||
|
elseif arsent.rc and routingcode and string.find(" "..routingcode.." ", " "..arsent.rc.." ", nil, true) then
|
||||||
|
return arskey
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
function advtrains.interlocking.ars_check(sigd, train)
|
function advtrains.interlocking.ars_check(sigd, train)
|
||||||
local tcbs = il.db.get_tcbs(sigd)
|
local tcbs = il.db.get_tcbs(sigd)
|
||||||
if not tcbs or not tcbs.routes then return end
|
if not tcbs or not tcbs.routes then return end
|
||||||
|
|
|
@ -10,58 +10,6 @@ local function sigd_to_string(sigd)
|
||||||
return minetest.pos_to_string(sigd.p).." / "..lntrans[sigd.s]
|
return minetest.pos_to_string(sigd.p).." / "..lntrans[sigd.s]
|
||||||
end
|
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)
|
function atil.show_route_edit_form(pname, sigd, routeid)
|
||||||
|
@ -139,7 +87,7 @@ function atil.show_route_edit_form(pname, sigd, routeid)
|
||||||
form = form.."button[5.5,6;2,1;delete;Delete Route]"
|
form = form.."button[5.5,6;2,1;delete;Delete Route]"
|
||||||
|
|
||||||
--atdebug(route.ars)
|
--atdebug(route.ars)
|
||||||
form = form.."textarea[1,7.3;5.2,3;ars;ARS Rule List;"..ars_to_text(route.ars).."]"
|
form = form.."textarea[1,7.3;5.2,3;ars;ARS Rule List;"..atil.ars_to_text(route.ars).."]"
|
||||||
form = form.."button[6,7.7;1,1;savears;Save]"
|
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)
|
minetest.show_formspec(pname, "at_il_routeedit_"..minetest.pos_to_string(sigd.p).."_"..sigd.s.."_"..routeid, form)
|
||||||
|
@ -192,7 +140,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
end
|
end
|
||||||
|
|
||||||
if fields.ars and fields.savears then
|
if fields.ars and fields.savears then
|
||||||
route.ars = text_to_ars(fields.ars)
|
route.ars = atil.text_to_ars(fields.ars)
|
||||||
--atdebug(route.ars)
|
--atdebug(route.ars)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ local function show_stoprailform(pos, player)
|
||||||
local stdata = advtrains.lines.stops[pe]
|
local stdata = advtrains.lines.stops[pe]
|
||||||
if not stdata then
|
if not stdata then
|
||||||
advtrains.lines.stops[pe] = {
|
advtrains.lines.stops[pe] = {
|
||||||
stn="", track="", doors="R", wait=10
|
stn="", track="", doors="R", wait=10, ars={default=true},
|
||||||
}
|
}
|
||||||
stdata = advtrains.lines.stops[pe]
|
stdata = advtrains.lines.stops[pe]
|
||||||
end
|
end
|
||||||
|
@ -35,19 +35,21 @@ local function show_stoprailform(pos, player)
|
||||||
local stn = advtrains.lines.stations[stdata.stn]
|
local stn = advtrains.lines.stations[stdata.stn]
|
||||||
local stnname = stn and stn.name or ""
|
local stnname = stn and stn.name or ""
|
||||||
|
|
||||||
local form = "size[8,6.5]"
|
local form = "size[8,7]"
|
||||||
form = form.."field[0.5,1;7,1;stn;"..attrans("Station Code")..";"..minetest.formspec_escape(stdata.stn).."]"
|
form = form.."field[0.5,1;7,1;stn;"..attrans("Station Code")..";"..minetest.formspec_escape(stdata.stn).."]"
|
||||||
form = form.."field[0.5,2;7,1;stnname;"..attrans("Station Name")..";"..minetest.formspec_escape(stnname).."]"
|
form = form.."field[0.5,2;7,1;stnname;"..attrans("Station Name")..";"..minetest.formspec_escape(stnname).."]"
|
||||||
|
|
||||||
|
|
||||||
form = form.."label[0.5,3;Door side:]"
|
form = form.."label[0.5,3;Door side:]"
|
||||||
form = form.."dropdown[0.5,3.5;2;doors;Left,Right,Closed;"..door_dropdown[stdata.doors].."]"
|
form = form.."dropdown[0.5,3;2;doors;Left,Right,Closed;"..door_dropdown[stdata.doors].."]"
|
||||||
form = form.."dropdown[3,3.5;1.5;reverse;---,Reverse;"..(stdata.reverse and 2 or 1).."]"
|
form = form.."dropdown[3,3;1.5;reverse;---,Reverse;"..(stdata.reverse and 2 or 1).."]"
|
||||||
|
|
||||||
form = form.."field[5,3.5;2,1;track;"..attrans("Track")..";"..stdata.track.."]"
|
form = form.."field[5,3.5;2,1;track;"..attrans("Track")..";"..stdata.track.."]"
|
||||||
form = form.."field[5,4.5;2,1;wait;"..attrans("Stop Time")..";"..stdata.wait.."]"
|
form = form.."field[5,4.5;2,1;wait;"..attrans("Stop Time")..";"..stdata.wait.."]"
|
||||||
|
|
||||||
form = form.."button[0.5,5.5;7,1;save;"..attrans("Save").."]"
|
form = form.."textarea[0.5,4;4,2;ars;Trains stopping here (ARS rules);"..advtrains.interlocking.ars_to_text(stdata.ars).."]"
|
||||||
|
|
||||||
|
form = form.."button[0.5,6;7,1;save;"..attrans("Save").."]"
|
||||||
|
|
||||||
minetest.show_formspec(pname, "at_lines_stop_"..pe, form)
|
minetest.show_formspec(pname, "at_lines_stop_"..pe, form)
|
||||||
end
|
end
|
||||||
|
@ -107,6 +109,10 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
stdata.wait = tonumber(fields.wait) or 10
|
stdata.wait = tonumber(fields.wait) or 10
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if fields.ars then
|
||||||
|
stdata.ars = advtrains.interlocking.text_to_ars(fields.ars)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--TODO: signal
|
--TODO: signal
|
||||||
updatemeta(pos)
|
updatemeta(pos)
|
||||||
|
@ -136,13 +142,20 @@ local adefunc = function(def, preset, suffix, rotation)
|
||||||
advtrains = {
|
advtrains = {
|
||||||
on_train_approach = function(pos,train_id, train, index)
|
on_train_approach = function(pos,train_id, train, index)
|
||||||
if train.path_cn[index] == 1 then
|
if train.path_cn[index] == 1 then
|
||||||
advtrains.interlocking.lzb_add_oncoming_npr(train, index, 2)
|
|
||||||
local pe = advtrains.encode_pos(pos)
|
local pe = advtrains.encode_pos(pos)
|
||||||
local stdata = advtrains.lines.stops[pe]
|
local stdata = advtrains.lines.stops[pe]
|
||||||
if stdata and stdata.stn then
|
if stdata and stdata.stn then
|
||||||
local stn = advtrains.lines.stations[stdata.stn]
|
|
||||||
local stnname = stn and stn.name or "Unknown Station"
|
--TODO REMOVE AFTER SOME TIME (only migration)
|
||||||
train.text_inside = "Next Stop:\n"..stnname
|
if not stdata.ars then
|
||||||
|
stdata.ars = {default=true}
|
||||||
|
end
|
||||||
|
if stdata.ars and (stdata.ars.default or advtrains.interlocking.ars_check_rule_match(stdata.ars, train) ) then
|
||||||
|
advtrains.interlocking.lzb_add_oncoming_npr(train, index, 2)
|
||||||
|
local stn = advtrains.lines.stations[stdata.stn]
|
||||||
|
local stnname = stn and stn.name or "Unknown Station"
|
||||||
|
train.text_inside = "Next Stop:\n"..stnname
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
@ -151,18 +164,19 @@ local adefunc = function(def, preset, suffix, rotation)
|
||||||
local pe = advtrains.encode_pos(pos)
|
local pe = advtrains.encode_pos(pos)
|
||||||
local stdata = advtrains.lines.stops[pe]
|
local stdata = advtrains.lines.stops[pe]
|
||||||
if not stdata then
|
if not stdata then
|
||||||
advtrains.atc.train_set_command(train, "B0", true)
|
return
|
||||||
updatemeta(pos)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local stn = advtrains.lines.stations[stdata.stn]
|
if stdata.ars and (stdata.ars.default or advtrains.interlocking.ars_check_rule_match(stdata.ars, train) ) then
|
||||||
local stnname = stn and stn.name or "Unknown Station"
|
local stn = advtrains.lines.stations[stdata.stn]
|
||||||
|
local stnname = stn and stn.name or "Unknown Station"
|
||||||
|
|
||||||
-- Send ATC command and set text
|
-- Send ATC command and set text
|
||||||
advtrains.atc.train_set_command(train, "B0 W O"..stdata.doors.." D"..stdata.wait.." OC D1 "..(stdata.reverse and "R" or "").." SM", true)
|
advtrains.atc.train_set_command(train, "B0 W O"..stdata.doors.." D"..stdata.wait.." OC D1 "..(stdata.reverse and "R" or "").." SM", true)
|
||||||
train.text_inside = stnname
|
train.text_inside = stnname
|
||||||
if tonumber(stdata.wait) then
|
if tonumber(stdata.wait) then
|
||||||
minetest.after(tonumber(stdata.wait), function() train.text_inside = "" end)
|
minetest.after(tonumber(stdata.wait), function() train.text_inside = "" end)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue