aboutsummaryrefslogtreecommitdiff
path: root/advtrains_line_automation/station_announcement.lua
diff options
context:
space:
mode:
Diffstat (limited to 'advtrains_line_automation/station_announcement.lua')
-rw-r--r--advtrains_line_automation/station_announcement.lua351
1 files changed, 276 insertions, 75 deletions
diff --git a/advtrains_line_automation/station_announcement.lua b/advtrains_line_automation/station_announcement.lua
index d465fd5..4f2e8fb 100644
--- a/advtrains_line_automation/station_announcement.lua
+++ b/advtrains_line_automation/station_announcement.lua
@@ -10,6 +10,10 @@ local has_signs_api = core.get_modpath("signs_api")
local has_unifieddyes = core.get_modpath("unifieddyes")
local rozhlas_node_name = "advtrains_line_automation:stanicni_rozhlas_experimental"
+local RMODE_DEP = 1
+local RMODE_ARR = 2
+local RMODE_BOTH = 3
+
local PAGE_SETUP_1 = 1
local PAGE_SETUP_2 = 2
local PAGE_IMPORT = 3
@@ -229,7 +233,6 @@ local function dosadit(format, data, defaults)
success, min, max, align = lengths_from_string(tagfmt)
end
tag = tag_name
- -- print("DEBUG: tag("..tag..") tagname("..tag_name..")")
if tag:len() < 4 and ch_core.utf8_length(tag) == 1 and alphanum_chars_set[tag] == nil then
-- speciální případ: zopakovat znak alespoň min-krát
if min ~= nil then
@@ -416,7 +419,6 @@ local function init_ann_data(stn, epos)
version = 1,
}
anns[epos] = result
- -- print("DEBUG: ann data initialized for '"..stn.."'/"..epos..": "..dump2(result))
return result
end
@@ -608,9 +610,12 @@ local function get_setup_formspec(custom_state)
"label[7,0.5;omezit jen na koleje:]"..
"field[10,0.2;4,0.6;koleje;;",
data.fs_koleje or "",
- "]container_end[]",
+ "]label[0,1.25;režim:]"..
+ "dropdown[1.75,1;3,0.6;rmode;odjezdy,příjezdy,odjezdy i příjezdy;",
+ tostring(data.rmode),
+ ";true]container_end[]",
-- ----
- "container[0.5,2.75]"..
+ "container[0.5,3.25]"..
"checkbox[0,0.25;fn_firstupper;první písmeno řádky odjezdu vždy velké;",
ifthenelse(ifthenelse(custom_state.fn_firstupper ~= nil, custom_state.fn_firstupper, data.fn_firstupper), "true", "false"),
"]field[0,1;3.25,0.75;fmt_nodelay;bez zpoždění;", F(data.fmt_nodelay or ""), "]"..
@@ -732,7 +737,6 @@ local function get_setup_formspec(custom_state)
end
local function setup_formspec_callback(custom_state, player, formname, fields)
- -- print("DEBUG: setup_formspec_callback(): "..dump2({custom_state = custom_state, fields = fields, player_name = custom_state.player_name}))
assert(player:get_player_name() == custom_state.player_name)
local node = core.get_node(custom_state.pos)
if node.name ~= rozhlas_node_name then
@@ -753,6 +757,12 @@ local function setup_formspec_callback(custom_state, player, formname, fields)
-- přepnout dopravnu
custom_state.station_index = tonumber(fields.dopravna)
end
+ if fields.rmode then
+ local new_rmode = tonumber(fields.rmode)
+ if new_rmode ~= nil and new_rmode ~= data.rmode then
+ data.rmode = new_rmode
+ end
+ end
-- zaškrtávací pole:
if fields.fn_firstupper then
@@ -831,6 +841,14 @@ local function setup_formspec_callback(custom_state, player, formname, fields)
end
set_ann_data(stn, custom_state.epos, data)
custom_state.data = get_ann_data(stn, custom_state.epos, true)
+ -- update infotext:
+ local meta = core.get_meta(custom_state.pos)
+ local station_name = al.get_station_name(meta:get_string("stn"))
+ local koleje = custom_state.data.fs_koleje
+ if koleje ~= "" then
+ koleje = " ["..koleje:gsub("\\", "").."]"
+ end
+ meta:set_string("infotext", "staniční rozhlas\n"..station_name..koleje)
end
elseif page == PAGE_SETUP_2 then
-- update fields:
@@ -856,7 +874,6 @@ local function setup_formspec_callback(custom_state, player, formname, fields)
new_cedule[i] = table.copy(data.cedule[i])
end
get_ann_data(stn, custom_state.epos, false).cedule = new_cedule
- -- print("DEBUG: new_cedule saved, ann_data = "..dump2(get_ann_data(stn, custom_state.epos, false)))
return get_setup_formspec(custom_state)
else
for i = 1, 4 do
@@ -949,65 +966,123 @@ end
local debug_counter = 0
-local function update_ann(stn, epos, signs, deps, rwtime)
- -- print("DEBUG: update_ann(): "..dump2({stn = stn, epos = epos, signs = signs, deps = deps, rwtime = rwtime}))
+local function fill(line, prefix, rwtime_now, rwtime_value)
+ if rwtime_value == nil then
+ return
+ end
+ local secs = math.ceil((rwtime_value - rwtime_now) / 5) * 5
+ if secs < 0 then
+ secs = -secs
+ line[prefix.."_Z"] = "-"
+ end
+ local n_s = secs % 60
+ local n_m = (secs - n_s) / 60
+ local s = tostring(n_s)
+ local m = tostring(n_m)
+ line[prefix] = tostring(secs)
+ line[prefix.."_M"] = m
+ line[prefix.."_S"] = s
+ if n_m < 10 then
+ line[prefix.."_MM"] = "0"..m
+ else
+ line[prefix.."_MM"] = m
+ end
+ if n_s < 10 then
+ line[prefix.."_SS"] = "0"..s
+ else
+ line[prefix.."_SS"] = s
+ end
+end
+
+--[[
+ records je tabulka záznamů z al.predict_train(), doplněných o následující pole:
+ start = string or nil, -- název výchozí zastávky, pokud vlak odněkud přijíždí, jinak ""
+ destination = string, -- název cílové zastávky, pokud vlak někam pokračuje, jinak ""
+ prev_stop = string, -- název předchozí zastávky, pokud vlak odněkud přijíždí a pokud jde o jinou zastávku než 'start', jinak ""
+ next_stop = string, -- název násl. zast., pokud vlak pokračuje a pokud jde o jinou zastávku než 'destination', jinak ""
+ last_pos = string, -- název poslední známé polohy vlaku, nebo ""
+ --
+ stn = string, track = string, delay = int,
+ stdata = table or nil,
+ dep = int or nil, dep_linevar_def = table or nil, dep_index = int or nil,
+ arr = int or nil, arr_linevar_def = table or nil, arr_index = int or nil,
+]]
+
+local function update_ann(stn, epos, signs, records, rwtime)
local ann = get_ann_data(stn, epos)
if ann == nil then
core.log("error", "update_ann() called for "..stn.."/"..epos..", but ann is nil!")
return
end
- local tracks = ann.koleje
- if tracks ~= nil and type(tracks) ~= "table" then
- if tracks == "" then
- tracks = nil
- else
- tracks = {[tracks] = true}
- end
- end
+ local tracks
local any_line = {
- KOLEJE = "TODO", -- [ ] TODO
ZDE = al.get_station_name(stn),
}
- -- print("DEBUG: "..dump2({tracks = tracks}))
+ if ann.fs_koleje ~= "" then
+ any_line.KOLEJE = ann.fs_koleje:gsub("\\", "")
+ tracks = ann.koleje
+ if tracks ~= nil and type(tracks) ~= "table" then
+ if tracks == "" then
+ tracks = nil
+ else
+ tracks = {[tracks] = true}
+ end
+ end
+ end
local lines = {}
- -- update_ann(assert(stn), assert(ann.rozh_epos), signs, deps)
- for _, dep in ipairs(deps) do
- if (tracks == nil or tracks[dep.track]) and (dep.dep == nil or dep.dep > rwtime) then
- local linevar_def = dep.linevar_def
+ for _, record in ipairs(records) do
+ assert(record.start ~= nil)
+ assert(record.destination ~= nil)
+ assert(record.prev_stop ~= nil)
+ assert(record.next_stop ~= nil)
+ assert(record.last_pos ~= nil)
+ if
+ (tracks == nil or tracks[record.track]) and (
+ (ann.rmode == RMODE_ARR and record.arr ~= nil) or
+ (ann.rmode == RMODE_DEP and record.dep ~= nil) or
+ (ann.rmode == RMODE_BOTH and (record.arr ~= nil or record.dep ~= nil))
+ )
+ then
+ local linevar_def, index
+ if record.dep ~= nil then
+ linevar_def, index = record.dep_linevar_def, record.dep_index
+ else
+ linevar_def, index = record.arr_linevar_def, record.arr_index
+ end
local stops = linevar_def.stops
local line = setmetatable({}, {__index = any_line})
line.LINKA = linevar_def.line or ""
- line.VYCHOZI = al.get_line_description(linevar_def, {line_number = false, first_stop = true, last_stop = false})
- line.CIL = dep.destination
- if dep.track ~= "" then
- line.KOLEJ = dep.track
+ if record.start ~= "" then
+ line.VYCHOZI = record.start
end
- if dep.arr ~= nil then
- line.PRIJZA = math.ceil((dep.arr - rwtime) / 5) * 5
+ if record.destination ~= "" then
+ line.CIL = record.destination
end
- if dep.dep ~= nil then
- line.ODJZA = math.ceil((dep.dep - rwtime) / 5) * 5
+ if record.track ~= "" then
+ line.KOLEJ = record.track
end
- local abs_delay = math.abs(dep.delay)
+ fill(line, "PRIJZA", rwtime, record.arr)
+ fill(line, "ODJZA", rwtime, record.dep)
+ local abs_delay = math.abs(record.delay)
if abs_delay < 5 then
line.ZPOZDENI = ann.fmt_nodelay or ""
else
line.ZPOZDENI = dosadit(
- ifthenelse(dep.delay > 0, ann.fmt_delay or "{}", ann.fmt_negdelay or "-{}"),
+ ifthenelse(record.delay > 0, ann.fmt_delay or "{}", ann.fmt_negdelay or "-{}"),
{[""] = tostring(5 * math.ceil(abs_delay / 5))}
)
end
-- PREDCH
- if dep.prev_stop ~= nil then
- line.PREDCH = dep.prev_stop
+ if record.prev_stop ~= "" then
+ line.PREDCH = record.prev_stop
end
-- NASL
- if dep.next_stop ~= nil then
- line.NASL = dep.next_stop
+ if record.next_stop ~= "" then
+ line.NASL = record.next_stop
end
-- POLOHA
- if dep.last_pos ~= nil then
- line.POLOHA = dep.last_pos
+ if record.last_pos ~= "" then
+ line.POLOHA = record.last_pos
end
-- JMVLAKU
if linevar_def.train_name ~= nil then
@@ -1063,6 +1138,64 @@ local function update_ann(stn, epos, signs, deps, rwtime)
end
local globalstep_time = -5
+local first_run = true
+
+local function first_globalstep()
+ for stn, stdata in pairs(advtrains.lines.stations) do
+ local anns = stdata.anns
+ if stdata.anns ~= nil then
+ for rozh_epos, ann in pairs(stdata.anns) do
+ if ann.version < 2 then
+ if ann.version == 1 then
+ -- upgrade version 1 to version 2:
+ ann.rmode = RMODE_DEP
+ ann.version = 2
+ end
+ end
+ end
+ end
+ end
+end
+
+local function get_start_by_linevar_def(cache, linevar_def)
+ local result = cache[linevar_def.name]
+ if result == nil then
+ result = al.get_line_description(linevar_def, {first_stop = true, last_stop = false, last_stop_prefix = ""})
+ if result == "???" then
+ result = ""
+ end
+ cache[linevar_def.name] = result
+ end
+ return result
+end
+
+local function get_destination_by_linevar_def(cache, linevar_def)
+ local result = cache[linevar_def.name]
+ if result == nil then
+ result = al.get_line_description(linevar_def, {first_stop = false, last_stop = true, last_stop_prefix = ""})
+ if result == "???" then
+ result = ""
+ end
+ cache[linevar_def.name] = result
+ end
+ return result
+end
+
+local function get_name_by_stn(cache, stn, alt)
+ local result = cache[stn]
+ if result == nil then
+ result = al.get_station_name(stn)
+ if result == "???" then
+ result = ""
+ end
+ cache[stn] = result
+ end
+ if result == "" then
+ return alt
+ else
+ return result
+ end
+end
local function globalstep(dtime)
globalstep_time = globalstep_time + dtime
@@ -1071,7 +1204,13 @@ local function globalstep(dtime)
end
globalstep_time = globalstep_time - 5
+ if first_run then
+ first_run = false
+ return first_globalstep()
+ end
+
local rwtime = rwt.to_secs(rwt.get_time())
+ local rwtime_limit = rwtime + 3600
-- Shromáždit rozhlasy:
local subscriptions = {--[[
[stn] = {{
@@ -1101,65 +1240,127 @@ local function globalstep(dtime)
end
if signs_count > 0 then
-- nějaké cedule jsou aktivní
- -- print("DEBUG: - "..rozh_epos.." : added ("..stn.."), because has "..signs_count.." active signs")
table.insert(goa(subscriptions, stn), {rozh_pos = rozh_pos, rozh_epos = rozh_epos, rozh_def = ann, signs = signs})
signs = {}
elseif core.compare_block_status(rozh_pos, "active") then
-- cedule nejsou aktivní, ale rozhlas ano
- -- print("DEBUG: - "..rozh_epos.." : added ("..stn.."), because is active")
table.insert(goa(subscriptions, stn), {rozh_pos = rozh_pos, rozh_epos = rozh_epos, rozh_def = ann})
end
end
- else
- -- print("DEBUG: - "..stn.." not added (anns: "..ifthenelse(stdata.anns == nil, "nil", "non-nil")..")")
end
end
-- Shromáždit vlaky:
- local deps_by_stn = {}
+ local by_stn = {}
for stn, _ in pairs(subscriptions) do
- deps_by_stn[stn] = {}
+ by_stn[stn] = {}
end
+ local start_by_linevar = {}
+ local destination_by_linevar = {}
+ local name_by_stn = {}
+
for _, train in pairs(advtrains.trains) do
local ls, linevar_def = al.get_line_status(train)
if linevar_def ~= nil then
- local prediction = al.predict_train(ls, linevar_def, rwtime)
- local last_pos = al.get_last_pos_station_name(ls)
- local destination = "???"
- for i = #prediction, 1, -1 do
- local p = prediction[i]
- if not p.hidden then
- destination = al.get_station_name(p.stn)
- break
- end
- end
- for _, record in ipairs(prediction) do
- local deps = deps_by_stn[record.stn]
- if deps ~= nil and record.dep ~= nil then
- local record_index = assert(record.index)
- local other_index, other_data = al.get_prev_stop(linevar_def, record_index, false)
- if other_index ~= nil then
- record.prev_stop = al.get_station_name(other_data.stn)
- end
- other_index, other_data = al.get_next_stop(linevar_def, record_index, false)
- if other_index ~= nil then
- record.next_stop = al.get_station_name(other_data.stn)
- end
+ local prediction = al.predict_train(ls, linevar_def, rwtime, true)
+ local last_pos = al.get_last_pos_station_name(ls) or ""
+ for i, record in ipairs(prediction) do
+ local records = by_stn[record.stn]
+ if
+ records ~= nil and
+ (record.dep ~= nil or record.arr ~= nil) and
+ (record.dep == nil or record.dep < rwtime_limit) and
+ (record.arr == nil or record.arr < rwtime_limit)
+ then
+ -- nutno doplnit: start, destination, prev_stop, next_stop, last_pos
record.last_pos = last_pos -- název poslední dopravny, kde byl vlak spatřen
- record.linevar = linevar_def.name
- record.linevar_def = linevar_def
- record.destination = destination
- table.insert(deps, record)
+ if record.final and record.arr ~= nil and record.dep ~= nil and record.arr_linevar_def.name ~= record.dep_linevar_def.name then
+ -- změna linky => rozdělit na příjezd a odjezd
+ local record2 = table.copy(record)
+ record2.dep = nil
+ record2.dep_linevar_def = nil
+ record2.dep_index = nil
+ record2.start = get_start_by_linevar_def(start_by_linevar, record.arr_linevar_def)
+ local other_index, other_data = al.get_prev_stop(record.arr_linevar_def, record.arr_index, false)
+ if other_index ~= nil then
+ record2.prev_stop = get_name_by_stn(name_by_stn, other_data.stn, "")
+ end
+ record2.next_stop = ""
+ record2.destination = get_destination_by_linevar_def(destination_by_linevar, record.arr_linevar_def)
+ table.insert(records, record2)
+ record.arr = nil
+ record.arr_linevar_def = nil
+ record.arr_index = nil
+ record.start = get_start_by_linevar_def(start_by_linevar, record.dep_linevar_def)
+ record.prev_stop = ""
+ other_index, other_data = al.get_next_stop(record.dep_linevar_def, record.dep_index, false)
+ if other_index ~= nil then
+ record.next_stop = get_name_by_stn(name_by_stn, other_data.stn, "")
+ end
+ record.destination = get_destination_by_linevar_def(destination_by_linevar, record.dep_linevar_def)
+ table.insert(records, record)
+ elseif record.dep ~= nil then
+ -- odjezd nebo příjezd/odjezd (ale na stejné lince!)
+ local linevar_def = record.dep_linevar_def
+ local index = record.dep_index
+ record.start = get_start_by_linevar_def(start_by_linevar, linevar_def)
+ record.destination = get_destination_by_linevar_def(destination_by_linevar, linevar_def)
+ record.prev_stop = ""
+ record.next_stop = ""
+ local other_index, other_data
+ if record.arr ~= nil then
+ other_index, other_data = al.get_prev_stop(linevar_def, index, false)
+ if other_index ~= nil then
+ record.prev_stop = get_name_by_stn(name_by_stn, other_data.stn, "")
+ end
+ end
+ other_index, other_data = al.get_next_stop(linevar_def, index, false)
+ if other_index ~= nil then
+ record.next_stop = get_name_by_stn(name_by_stn, other_data.stn, "")
+ end
+ record.destination = get_destination_by_linevar_def(destination_by_linevar, linevar_def)
+ table.insert(records, record)
+ elseif record.arr ~= nil then
+ -- jen příjezd
+ local linevar_def = record.arr_linevar_def
+ local index = record.arr_index
+ record.start = get_start_by_linevar_def(start_by_linevar, linevar_def)
+ local other_index, other_data = al.get_prev_stop(linevar_def, index, false)
+ if other_index ~= nil then
+ record.prev_stop = get_name_by_stn(name_by_stn, other_data.stn, "")
+ else
+ record.prev_stop = ""
+ end
+ record.next_stop = ""
+ record.destination = get_destination_by_linevar_def(destination_by_linevar, linevar_def)
+ table.insert(records, record)
+ end
end
end
end
end
-- Aktualizovat rozhlasy:
- for stn, deps in pairs(deps_by_stn) do
- table.sort(deps, function(a, b) return assert(a.dep) < assert(b.dep) end)
+ for stn, records in pairs(by_stn) do
+ local deps = records
+ local arrs = table.copy(records)
+ table.sort(deps, function(a, b)
+ return assert(a.dep or a.arr) < assert(b.dep or b.arr)
+ end)
+ table.sort(arrs, function(a, b)
+ return (a.arr or 1.0e+100) < (b.arr or 1.0e+100)
+ end)
+ for i = #arrs, 1, -1 do
+ if arrs[i].arr == nil then
+ arrs[i] = nil -- ponechat jen příjezdy v rámci nejbližší hodiny
+ end
+ end
for _, ann in ipairs(subscriptions[stn]) do
- update_ann(assert(stn), assert(ann.rozh_epos), ann.signs, deps, rwtime)
+ if ann.rmode ~= RMODE_ARR then
+ update_ann(assert(stn), assert(ann.rozh_epos), ann.signs, deps, rwtime)
+ else
+ update_ann(assert(stn), assert(ann.rozh_epos), ann.signs, arrs, rwtime)
+ end
end
end
end
@@ -1324,8 +1525,8 @@ end
local box = {
type = "fixed",
fixed = {
- {-0.25, -0.25, 0, 0.25, 0.25, 0.5},
- {-0.5, -0.4, -0.25, 0.5, 0.4, 0},
+ {-0.125, 0.125, 0.25, 0.125, 0.5, 0.5},
+ {-0.25, 0.05, 0, 0.25, 0.45, 0.25},
},
}