aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authororwell96 <orwell@bleipb.de>2019-02-19 21:54:17 +0100
committerorwell96 <orwell@bleipb.de>2019-02-19 21:54:17 +0100
commitf2c2aad32940311914cc0d8d9b6b216d02d34d55 (patch)
treec655349ff77e3202966edb7db89c93c7c0d17326
parent0684c6edd71a138ee2541971d1809fe7acae01cf (diff)
downloadadvtrains-f2c2aad32940311914cc0d8d9b6b216d02d34d55.tar.gz
advtrains-f2c2aad32940311914cc0d8d9b6b216d02d34d55.tar.bz2
advtrains-f2c2aad32940311914cc0d8d9b6b216d02d34d55.zip
Add ARS rules for stop rails
-rw-r--r--advtrains_interlocking/ars.lua81
-rw-r--r--advtrains_interlocking/route_ui.lua56
-rw-r--r--advtrains_line_automation/stoprail.lua52
3 files changed, 107 insertions, 82 deletions
diff --git a/advtrains_interlocking/ars.lua b/advtrains_interlocking/ars.lua
index e20d189..dd5ff40 100644
--- a/advtrains_interlocking/ars.lua
+++ b/advtrains_interlocking/ars.lua
@@ -23,23 +23,67 @@
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 default
- local line = train.line
- local routingcode = train.routingcode
for rteid, route in ipairs(routes) do
if route.ars then
if route.ars.default then
default = rteid
else
- for arskey, arsent in ipairs(route.ars) do
- --atdebug(arsent, line, routingcode)
- 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
+ if il.ars_check_rule_match(route.ars, train) then
+ return rteid
end
end
end
@@ -47,6 +91,25 @@ local function find_rtematch(routes, train)
return default
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)
local tcbs = il.db.get_tcbs(sigd)
if not tcbs or not tcbs.routes then return end
diff --git a/advtrains_interlocking/route_ui.lua b/advtrains_interlocking/route_ui.lua
index 45aaa82..4ddab0c 100644
--- a/advtrains_interlocking/route_ui.lua
+++ b/advtrains_interlocking/route_ui.lua
@@ -10,58 +10,6 @@ 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)
@@ -139,7 +87,7 @@ function atil.show_route_edit_form(pname, sigd, routeid)
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.."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]"
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
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)
end
diff --git a/advtrains_line_automation/stoprail.lua b/advtrains_line_automation/stoprail.lua
index 859813e..2e6072e 100644
--- a/advtrains_line_automation/stoprail.lua
+++ b/advtrains_line_automation/stoprail.lua
@@ -27,7 +27,7 @@ local function show_stoprailform(pos, player)
local stdata = advtrains.lines.stops[pe]
if not stdata then
advtrains.lines.stops[pe] = {
- stn="", track="", doors="R", wait=10
+ stn="", track="", doors="R", wait=10, ars={default=true},
}
stdata = advtrains.lines.stops[pe]
end
@@ -35,19 +35,21 @@ local function show_stoprailform(pos, player)
local stn = advtrains.lines.stations[stdata.stn]
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,2;7,1;stnname;"..attrans("Station Name")..";"..minetest.formspec_escape(stnname).."]"
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[3,3.5;1.5;reverse;---,Reverse;"..(stdata.reverse and 2 or 1).."]"
+ form = form.."dropdown[0.5,3;2;doors;Left,Right,Closed;"..door_dropdown[stdata.doors].."]"
+ 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,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)
end
@@ -107,6 +109,10 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
stdata.wait = tonumber(fields.wait) or 10
end
+ if fields.ars then
+ stdata.ars = advtrains.interlocking.text_to_ars(fields.ars)
+ end
+
--TODO: signal
updatemeta(pos)
@@ -136,13 +142,20 @@ local adefunc = function(def, preset, suffix, rotation)
advtrains = {
on_train_approach = function(pos,train_id, train, index)
if train.path_cn[index] == 1 then
- advtrains.interlocking.lzb_add_oncoming_npr(train, index, 2)
local pe = advtrains.encode_pos(pos)
local stdata = advtrains.lines.stops[pe]
if stdata and stdata.stn then
- local stn = advtrains.lines.stations[stdata.stn]
- local stnname = stn and stn.name or "Unknown Station"
- train.text_inside = "Next Stop:\n"..stnname
+
+ --TODO REMOVE AFTER SOME TIME (only migration)
+ 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,
@@ -151,18 +164,19 @@ local adefunc = function(def, preset, suffix, rotation)
local pe = advtrains.encode_pos(pos)
local stdata = advtrains.lines.stops[pe]
if not stdata then
- advtrains.atc.train_set_command(train, "B0", true)
- updatemeta(pos)
+ return
end
- local stn = advtrains.lines.stations[stdata.stn]
- local stnname = stn and stn.name or "Unknown Station"
-
- -- 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)
- train.text_inside = stnname
- if tonumber(stdata.wait) then
- minetest.after(tonumber(stdata.wait), function() train.text_inside = "" end)
+ if stdata.ars and (stdata.ars.default or advtrains.interlocking.ars_check_rule_match(stdata.ars, train) ) then
+ local stn = advtrains.lines.stations[stdata.stn]
+ local stnname = stn and stn.name or "Unknown Station"
+
+ -- 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)
+ train.text_inside = stnname
+ if tonumber(stdata.wait) then
+ minetest.after(tonumber(stdata.wait), function() train.text_inside = "" end)
+ end
end
end
end