aboutsummaryrefslogtreecommitdiff
path: root/advtrains_line_automation/line_functions.lua
diff options
context:
space:
mode:
Diffstat (limited to 'advtrains_line_automation/line_functions.lua')
-rw-r--r--advtrains_line_automation/line_functions.lua1377
1 files changed, 1377 insertions, 0 deletions
diff --git a/advtrains_line_automation/line_functions.lua b/advtrains_line_automation/line_functions.lua
new file mode 100644
index 0000000..ee8f238
--- /dev/null
+++ b/advtrains_line_automation/line_functions.lua
@@ -0,0 +1,1377 @@
+local al = advtrains.lines
+local rwt = assert(advtrains.lines.rwt)
+
+local MODE_NORMAL = 0 -- normální zastávka (výchozí nebo mezilehlá)
+local MODE_REQUEST_STOP = 1 -- zastávka na znamení (mezilehlá)
+local MODE_HIDDEN = 2 -- skrytá zastávka (výchozí nebo mezilehlá)
+local MODE_DISABLED = 3 -- vypnutá zastávka (mezilehlá nebo koncová)
+local MODE_FINAL = 4 -- koncová zastávka (linka zde jízdu končí)
+local MODE_FINAL_HIDDEN = 5 -- koncová zastávka skrytá
+local MODE_FINAL_CONTINUE = 6 -- koncová zastávka (vlak pokračuje jako jiná linka)
+
+local simple_modes = {
+ [MODE_NORMAL] = MODE_NORMAL,
+ [MODE_REQUEST_STOP] = MODE_NORMAL,
+ [MODE_HIDDEN] = MODE_NORMAL,
+ [MODE_DISABLED] = MODE_DISABLED,
+ [MODE_FINAL] = MODE_FINAL,
+ [MODE_FINAL_HIDDEN] = MODE_FINAL,
+ [MODE_FINAL_CONTINUE] = MODE_FINAL,
+}
+
+local current_passages = {--[[
+ [train_id] = {
+ [1] = rwtime,
+ ...,
+ [n] = rwtime (časy *odjezdu*, kromě koncových zastávek, kde jde o čas příjezdu)
+ wait = int or nil (původně naplánovaná doba čekání na výchozí zastávce)
+ }
+]]}
+
+local last_passages = {--[[
+ [linevar] = {
+ [1..10] = {[1] = rwtime, ..., wait} -- jízdy seřazeny od nejstarší (1) po nejnovější (až 10) podle odjezdu z výchozí zastávky
+ }
+]]}
+
+local diakritika_na_velka = {
+ ["á"] = "Á", ["ä"] = "Ä", ["č"] = "Č", ["ď"] = "Ď", ["é"] = "É", ["ě"] = "Ě", ["í"] = "Í", ["ĺ"] = "Ĺ", ["ľ"] = "Ľ",
+ ["ň"] = "Ň", ["ó"] = "Ó", ["ô"] = "Ô", ["ŕ"] = "Ŕ", ["ř"] = "Ř", ["š"] = "Š", ["ť"] = "Ť", ["ú"] = "Ú", ["ů"] = "Ů",
+ ["ý"] = "Ý", ["ž"] = "Ž",
+}
+
+local debug_print_i = 0
+
+-- LOCAL funkce:
+-- =========================================================================
+local function debug_print(s)
+ debug_print_i = debug_print_i + 1
+ -- core.chat_send_all("["..debug_print_i.."] "..tostring(s))
+ return s
+end
+
+-- Je-li stn kód stanice, vrací její jméno, jinak vrací "???". stn může být i nil.
+local function get_station_name(stn)
+ local station = advtrains.lines.stations[stn or ""]
+ if station ~= nil and station.name ~= nil then
+ return station.name
+ else
+ return "???"
+ end
+end
+al.get_station_name = get_station_name
+
+local function na_velka_pismena(s)
+ local l = #s
+ local i = 1
+ local res = ""
+ local c
+ while i <= l do
+ c = diakritika_na_velka[s:sub(i, i + 1)]
+ if c then
+ res = res .. c
+ i = i + 2
+ else
+ res = res .. s:sub(i, i)
+ i = i + 1
+ end
+ end
+ return string.upper(res)
+end
+
+--[[
+ -- Vrací index následujícího výskytu 'stn' v seznamu zastávek podle linevar_def.
+ -- Vrací i skryté zastávky, ale ne vypnuté.
+ -- Je-li linevar_def == nil nebo stn == nil nebo stn == "", vrací nil.
+ - line_status = table
+ - linevar_def = table or nil
+ - stn = string
+ return: int or nil
+]]
+local function find_next_index(line_status, linevar_def, stn)
+ assert(line_status)
+ if linevar_def ~= nil and stn ~= nil and stn ~= "" then
+ local stops = linevar_def.stops
+ if line_status.linevar_index < #stops then
+ for i = line_status.linevar_index + 1, #stops do
+ local stop = stops[i]
+ if stop.stn == stn and (stop.mode or MODE_NORMAL) ~= MODE_DISABLED then
+ return i
+ end
+ end
+ end
+ end
+end
+
+-- Vrací kódy výchozí a cílové stanice k zobrazení cestujícím: stn_first (string), stn_terminus (string)
+-- Předané linevar_def musí obsahovat platný seznam 'stops', ale nemusí obsahovat nic jiného (nemusí to být platná definice).
+-- V případě chyby vrací nil, nil.
+local function get_first_last_stations(linevar_def)
+ local a, b = linevar_def.index_vychozi, linevar_def.index_cil
+ if a ~= nil and b ~= nil then
+ local stops = linevar_def.stops
+ return stops[a].stn, stops[b].stn
+ else
+ return nil, nil
+ end
+end
+
+--[[
+ Používá se na *nelinkový* vlak stojící na *neanonymní* zastávce.
+ Zahájí jízdu na lince nalezené podle kombinace line/stn/rc, nebo vrátí false.
+]]
+local function line_start(train, stn, departure_rwtime)
+ assert(train)
+ assert(stn and stn ~= "")
+ assert(departure_rwtime)
+ local ls = al.get_line_status(train)
+ if ls.linevar ~= nil then
+ error("line_start() used on a train that is already on a line: "..dump2({train = train}))
+ end
+ local linevar, linevar_def = al.try_get_linevar(train.line, stn, train.routingcode)
+ if linevar == nil or linevar_def.disabled then
+ return false
+ end
+ ls.linevar = linevar
+ ls.linevar_station = stn
+ ls.linevar_index = 1
+ ls.linevar_dep = departure_rwtime
+ ls.linevar_last_dep = departure_rwtime
+ ls.linevar_last_stn = stn
+ ls.linevar_past = nil
+ train.text_outside = al.get_line_description(linevar_def, {
+ line_number = true,
+ last_stop = true,
+ last_stop_prefix = "",
+ last_stop_uppercase = true,
+ train_name = true,
+ })
+ return true
+end
+
+--[[
+ Vrací:
+ - "true", pokud má vlak zastavit
+ - nil, pokud zastavit nemá
+ - "on_request", pokud má zastavit na znamení, ale znamení zatím nebylo dáno
+]]
+local function should_stop(pos, stdata, train)
+ if stdata == nil or stdata.stn == nil then
+ return nil -- neplatná data
+ end
+ local n_trainparts = #assert(train.trainparts)
+ -- vyhovuje počet vagonů?
+ if not ((stdata.minparts or 0) <= n_trainparts and n_trainparts <= (stdata.maxparts or 128)) then
+ return nil
+ end
+ local stn = assert(stdata.stn) -- zastávka stále může být anonymní
+ local ls, linevar_def = al.get_line_status(train)
+ local next_index
+ if stn ~= "" then
+ next_index = find_next_index(ls, linevar_def, stn)
+ end
+ -- jde o linkový vlak?
+ if linevar_def ~= nil then
+ if next_index == nil then
+ return nil
+ end
+ local stop = assert(linevar_def.stops[next_index])
+ if stop.pos ~= nil and stop.pos ~= string.format("%d,%d,%d", pos.x, pos.y, pos.z) then
+ return nil
+ end
+ if stop.mode ~= nil and stop.mode == MODE_REQUEST_STOP then
+ if ls.stop_request ~= nil then
+ debug_print("Vlak "..train.id.." zastaví na zastávce na znamení.")
+ return "true"
+ else
+ debug_print("Vlak "..train.id.." možná zastaví na zastávce na znamení.")
+ return "on_request"
+ end
+ end
+ return "true"
+ -- TODO: zastávky na znamení
+ else
+ local ars = stdata.ars
+ -- vyhovuje vlak ARS pravidlům?
+ local result = ars and (ars.default or advtrains.interlocking.ars_check_rule_match(ars, train))
+ if result then
+ return "true"
+ else
+ return nil
+ end
+ end
+end
+
+local function update_value(train, key, setting)
+ if setting == "-" then
+ train[key] = nil
+ elseif setting ~= "" then
+ train[key] = setting
+ end
+ return train[key]
+end
+
+--[[
+ Pokud vlak jede na lince, odebere ho z této linky a vrátí true; jinak vrátí false.
+]]
+function al.cancel_linevar(train)
+ local ls = train.line_status
+ if ls == nil or ls.linevar == nil then return false end
+ ls.linevar = nil
+ ls.linevar_station = nil
+ ls.linevar_index = nil
+ ls.linevar_dep = nil
+ ls.linevar_last_dep = nil
+ ls.linevar_last_stn = nil
+ train.text_outside = ""
+ return true
+end
+
+-- Vrací seznam názvů neskrytých zastávek, počínaje od uvedeného indexu.
+-- Pokud by vrátila prázdný seznam, vrátí místo něj {"???"}.
+function al.get_stop_names(linevar_def, start_index)
+ local stations = advtrains.lines.stations
+ local result = {}
+ if linevar_def ~= nil then
+ local stops = linevar_def.stops
+ if start_index == nil then
+ start_index = 1
+ end
+ for i = start_index, #stops do
+ local stop = stops[i]
+ if stop.mode == nil or (stop.mode ~= MODE_HIDDEN and stop.mode ~= MODE_FINAL_HIDDEN and stop.mode ~= MODE_DISABLED) then
+ local station = stations[stop.stn]
+ if station ~= nil and station.name ~= nil and station.name ~= "" then
+ table.insert(result, station.name)
+ else
+ table.insert(result, "???")
+ end
+ end
+ end
+ end
+ if result[1] == nil then
+ result[1] = "???"
+ end
+ return result
+end
+
+--[[
+ Vrací:
+ a) index, stop_data -- pokud byla vyhovující předchozí zastávka nalezena
+ b) nil, nil -- pokud nalezena nebyla
+]]
+function al.get_first_stop(linevar_def, allow_hidden_stops)
+ if allow_hidden_stops then
+ return 1, linevar_def.stops[1]
+ else
+ local result = linevar_def.index_vychozi
+ if result ~= nil then
+ return result, linevar_def.stops[result]
+ else
+ return nil, nil
+ end
+ end
+end
+
+--[[
+ Vrací:
+ a) index, stop_data -- pokud byla vyhovující předchozí zastávka nalezena
+ b) nil, nil -- pokud nalezena nebyla
+]]
+function al.get_last_stop(linevar_def, allow_hidden_stops)
+ if allow_hidden_stops then
+ local stops = linevar_def.stops[result]
+ for i = linevar_def.index_cil, #stops do
+ local stop = stops[i]
+ local mode = stop.mode
+ if mode == MODE_FINAL or mode == MODE_FINAL_CONTINUE or mode == MODE_FINAL_HIDDEN then
+ return i, stop
+ end
+ end
+ else
+ local result = linevar_def.index_cil
+ if result ~= nil then
+ return result, linevar_def.stops[result]
+ end
+ end
+ return nil, nil
+end
+
+--[[
+ Vrací:
+ a) index, stop_data -- pokud byla vyhovující předchozí zastávka nalezena
+ b) nil, nil -- pokud nalezena nebyla
+]]
+function al.get_prev_stop(linevar_def, current_index, allow_hidden_stops)
+ local stops = assert(linevar_def.stops)
+ assert(current_index)
+ if current_index > 1 then
+ for i = current_index - 1, 1, -1 do
+ local mode = stops[i].mode
+ if mode == nil or (mode ~= MODE_DISABLED and ((mode ~= MODE_HIDDEN and mode ~= MODE_FINAL_HIDDEN) or allow_hidden_stops)) then
+ return i, stops[i]
+ end
+ end
+ end
+ return nil, nil
+end
+
+--[[
+ Vrací:
+ a) index, stop_data -- pokud byla vyhovující další zastávka nalezena
+ b) nil, nil -- pokud nalezena nebyla
+]]
+function al.get_next_stop(linevar_def, current_index, allow_hidden_stops)
+ local stops = assert(linevar_def.stops)
+ assert(current_index)
+ if current_index < #stops then
+ for i = current_index + 1, #stops do
+ local mode = stops[i].mode
+ if mode == nil or (mode ~= MODE_DISABLED and ((mode ~= MODE_HIDDEN and mode ~= MODE_FINAL_HIDDEN) or allow_hidden_stops)) then
+ return i, stops[i]
+ end
+ end
+ end
+ return nil, nil
+end
+
+--[[
+ Vrací:
+ a) index, stop_data -- pokud byla vyhovující koncová zastávka nalezena
+ b) nil, nil -- pokud nalezena nebyla
+]]
+function al.get_terminus(linevar_def, current_index, allow_hidden_stops)
+ if linevar_def.index_cil ~= nil then
+ return linevar_def.index_cil, linevar_def.stops[linevar_def.index_cil]
+ end
+ local stops = assert(linevar_def.stops)
+ local r_i, r_stop
+ if current_index < #stops then
+ for i = current_index + 1, #stops do
+ local mode = stops[i].mode or MODE_NORMAL
+ if mode ~= MODE_DISABLED and ((mode ~= MODE_HIDDEN and mode ~= MODE_FINAL_HIDDEN) or allow_hidden_stops) then
+ r_i, r_stop = i, stops[i]
+ end
+ if mode == MODE_FINAL or mode == MODE_FINAL_CONTINUE or mode == MODE_FINAL_HIDDEN then
+ break
+ end
+ end
+ end
+ return r_i, r_stop
+end
+
+--[[
+ options = {
+ line_number = bool or nil, -- zahrnout do popisu číslo linky? nil => false
+ first_stop = bool or nil, -- zahrnout do popisu název výchozí zastávky? nil => false
+ last_stop = bool or nil, -- zahrnout do popisu název cílové zastávky? nil => true
+ last_stop_prefix = string or nil, -- text před název cílové zastávky; nil => "⇒ "
+ last_stop_uppercase = bool or nil, -- je-li true, název cílové zastávky se před uvedením převede na velká písmena
+ train_name = bool or nil, -- zahrnout do popisu jméno vlaku, je-li k dispozici; nil => false
+ train_name_prefix = string or nil, -- text před jméno vlaku; nil => "\n"
+ }
+]]
+function al.get_line_description(linevar_def, options)
+ local line, stn = al.linevar_decompose(linevar_def.name)
+ local first_stn, last_stn = get_first_last_stations(linevar_def)
+ if line == nil or first_stn == nil or last_stn == nil then
+ return "???"
+ end
+ if options == nil then options = {} end
+ local s1, s2, s3, s4
+ if options.line_number then
+ s1 = "["..line.."] "
+ else
+ s1 = ""
+ end
+ if first_stn == last_stn and options.first_stop and (options.last_stop == nil or options.last_stop) then
+ s2 = get_station_name(last_stn)
+ if options.last_stop_uppercase then
+ s2 = na_velka_pismena(s2)
+ end
+ s3 = " (okružní)"
+ else
+ if options.first_stop then
+ s2 = get_station_name(first_stn).." "
+ else
+ s2 = ""
+ end
+ if options.last_stop == nil or options.last_stop then
+ s3 = get_station_name(last_stn)
+ if options.last_stop_uppercase then
+ s3 = na_velka_pismena(s3)
+ end
+ s3 = (options.last_stop_prefix or "⇒ ")..s3
+ else
+ s3 = ""
+ end
+ end
+ if options.train_name and linevar_def.train_name ~= nil then
+ s4 = (options.train_name_prefix or "\n")..linevar_def.train_name
+ else
+ s4 = ""
+ end
+ return s1..s2..s3..s4
+end
+
+function al.get_stop_description(stop_data, next_stop_data)
+ local s1, s2 = "", ""
+ if stop_data ~= nil then
+ local mode = stop_data.mode
+ if mode ~= MODE_DISABLED and mode ~= MODE_HIDDEN and mode ~= MODE_FINAL_HIDDEN then
+ s1 = get_station_name(stop_data.stn)
+ --[[
+ if
+ mode == MODE_FINAL or mode == MODE_FINAL_CONTINUE or
+ (next_stop_data ~= nil and next_stop_data.mode == MODE_FINAL_HIDDEN)
+ then
+ s2 = "Koncová zastávka"
+ end
+ ]]
+ end
+ end
+ if next_stop_data ~= nil then
+ local mode = next_stop_data.mode
+ if mode ~= MODE_DISABLED and mode ~= MODE_HIDDEN and mode ~= MODE_FINAL_HIDDEN then
+ s2 = "Příští zastávka/stanice: "..get_station_name(next_stop_data.stn)
+ if mode == MODE_REQUEST_STOP then
+ s2 = s2.." (na znamení)"
+ end
+ end
+ else
+ s2 = "Koncová zastávka"
+ end
+ if s1 ~= "" and s2 ~= "" then
+ return s1.."\n"..s2
+ else
+ return s1..s2
+ end
+end
+
+--[[
+ Není-li zpoždění k dispozici, vrací {text = ""}, jinak vrací:
+ {
+ has_delay = bool,
+ delay = int,
+ text = string,
+ }
+]]
+function al.get_delay_description(line_status, linevar_def, rwtime)
+ assert(line_status)
+ if linevar_def == nil then
+ return {text = ""}
+ end
+ local stops = linevar_def.stops
+ local expected_departure = line_status.linevar_dep + assert(stops[line_status.linevar_index]).dep
+ local real_departure = line_status.linevar_last_dep
+ local delay = real_departure - expected_departure
+
+ if rwtime ~= nil then
+ local expected_departure_next
+ for i = line_status.linevar_index + 1, #stops do
+ if stops[i] == nil then
+ break
+ else
+ local mode = stops[i].mode
+ if mode == nil or mode ~= MODE_DISABLED then
+ expected_departure_next = line_status.linevar_dep + stops[i].dep
+ break
+ end
+ end
+ end
+ if expected_departure_next ~= nil then
+ local delay2 = rwtime - expected_departure_next
+ if delay2 > delay then
+ delay = delay2
+ end
+ end
+ end
+
+ if delay < -1 or delay > 10 then
+ return {
+ has_delay = true,
+ delay = delay,
+ text = "zpoždění "..delay.." sekund",
+ }
+ else
+ return {
+ has_delay = false,
+ delay = delay,
+ text = "bez zpoždění",
+ }
+ end
+end
+
+-- Test na módy MODE_FINAL*
+function al.is_final_mode(stop_mode)
+ return stop_mode ~= nil and simple_modes[stop_mode] == MODE_FINAL
+end
+local is_final_mode = al.is_final_mode
+
+-- Test na skrytou zastávku. Vrací true, pokud zadaný mód neodpovídá skryté zastávce.
+function al.is_visible_mode(stop_mode)
+ return stop_mode == nil or (stop_mode ~= MODE_HIDDEN and stop_mode ~= MODE_FINAL_HIDDEN)
+end
+local is_visible_mode = al.is_visible_mode
+
+-- Pokud zadaná varianta linky existuje, vrátí:
+-- linevar_def, linevar_station
+-- Jinak vrací:
+-- nil, nil
+-- Je-li linevar_station == nil, doplní se z linevar. Je-li linevar == nil, vrátí nil, nil.
+function al.try_get_linevar_def(linevar, linevar_station)
+ if linevar == nil then
+ return nil, nil
+ end
+ if linevar_station == nil then
+ local line
+ line, linevar_station = al.linevar_decompose(linevar)
+ if line == nil then
+ return nil, nil
+ end
+ end
+ local t = advtrains.lines.stations[linevar_station]
+ if t ~= nil then
+ t = t.linevars
+ if t ~= nil then
+ return t[linevar], linevar_station
+ end
+ end
+ return nil, nil
+end
+
+--[[
+ Vrací:
+ a) nil, nil, pokud daná kombinace line/stn/rc nemá definovanou variantu linky
+ b) linevar, linevar_def, pokud má
+]]
+function al.try_get_linevar(line, stn, rc)
+ if line ~= nil and line ~= "" and stn ~= nil and stn ~= "" then
+ local linevar = line.."/"..stn.."/"..(rc or "")
+ local result = al.try_get_linevar_def(linevar, stn)
+ if result ~= nil then
+ return linevar, result
+ end
+ end
+ return nil, nil
+end
+
+--[[
+ Vrací 2 hodnoty:
+ - line_status = table -- tabulka train.line_status (může být prázdná)
+ - linevar_def = table or nil -- jde-li o linkový vlak, vrací definici linevar, jinak nil
+ Parametry:
+ - train = table (train)
+]]
+function al.get_line_status(train)
+ assert(train)
+ if train.line_status == nil then
+ train.line_status = {}
+ return train.line_status, nil
+ end
+ local ls = train.line_status
+ if ls.linevar == nil then
+ -- nelinkový vlak
+ local linevar_past = ls.linevar_past
+ if linevar_past ~= nil then
+ local rwtime = rwt.to_secs(rwt.get_time())
+ if train.line ~= linevar_past.line or rwtime - linevar_past.arrival >= 86400 then
+ -- smazat linevar_past, pokud se změnilo označení linky nebo uplynulo 24 hodin
+ ls.linevar_past = nil
+ end
+ end
+ return ls, nil
+ end
+ local rwtime = rwt.to_secs(rwt.get_time())
+ if rwtime - ls.linevar_dep >= 86400 then
+ core.log("warning", "Train "..train.id.." put out of linevar '"..ls.linevar.."', because it was riding more then 24 hours.")
+ al.cancel_linevar(train)
+ return ls, nil
+ end
+ local linevar_def = al.try_get_linevar_def(ls.linevar, ls.linevar_station)
+ if linevar_def == nil then
+ core.log("warning", "Train "..train.id.." was riding a non-existent (undefined) line '"..tostring(ls.linevar).."'!")
+ al.cancel_linevar(train)
+ elseif linevar_def.stops[ls.linevar_index] == nil then
+ core.log("warning", "Train "..train.id.." put out of linevar '"..ls.linevar.."', because its index "..ls.linevar_index.." became invalid.")
+ al.cancel_linevar(train)
+ linevar_def = nil
+ else
+ local train_line_prefix = (train.line or "").."/"
+ if train_line_prefix ~= ls.linevar:sub(1, train_line_prefix:len()) then
+ core.log("warning", "Train "..train.id.." put out of linevar '"..ls.linevar.."', because its line changed to '"..tostring(train.line).."'.")
+ al.cancel_linevar(train)
+ linevar_def = nil
+ end
+ end
+ return ls, linevar_def
+end
+
+function al.on_train_approach(pos, train_id, train, index, has_entered)
+ if has_entered then return end -- do not stop again!
+ if train.path_cn[index] ~= 1 then return end -- špatný směr
+ local pe = advtrains.encode_pos(pos)
+ local stdata = advtrains.lines.stops[pe]
+ if should_stop(pos, stdata, train) ~= nil then
+ advtrains.lzb_add_checkpoint(train, index, 2, nil)
+ if train.line_status.linevar == nil then
+ -- nelinkový vlak:
+ local stn = advtrains.lines.stations[stdata.stn]
+ local stnname = stn and stn.name or attrans("Unknown Station")
+ train.text_inside = attrans("Next Stop:") .. "\n"..stnname
+ end
+ advtrains.interlocking.ars_set_disable(train, true)
+ end
+end
+
+local function record_skipped_stops(train_id, linevar_def, linevar_index, next_index)
+ assert(linevar_def)
+ if next_index > linevar_index + 1 then
+ local skipped_stops = {}
+ for i = linevar_index + 1, next_index - 1 do
+ local mode = linevar_def.stops[i].mode or MODE_NORMAL
+ if mode ~= MODE_DISABLED then
+ table.insert(skipped_stops, linevar_def.stops[i].stn)
+ end
+ end
+ if #skipped_stops > 0 then
+ core.log("warning", "Train "..train_id.." of line '"..linevar_def.name.."' skipped "..#skipped_stops.." stops: "..
+ table.concat(skipped_stops, ", "))
+ end
+ return #skipped_stops
+ else
+ return 0
+ end
+end
+
+function al.on_train_enter(pos, train_id, train, index)
+ if train.path_cn[index] ~= 1 then return end -- špatný směr
+ local pe = advtrains.encode_pos(pos)
+ local stdata = advtrains.lines.stops[pe]
+ local stn = stdata.stn or ""
+ local rwtime = assert(rwt.to_secs(rwt.get_time()))
+ local ls, linevar_def = al.get_line_status(train)
+ local next_index
+ if stn ~= "" then
+ if linevar_def ~= nil then
+ next_index = find_next_index(ls, linevar_def, stn)
+ end
+ ls.last_enter = {stn = stn, encpos = pe, rwtime = rwtime}
+ debug_print("Vlak "..train_id.." zaznamenán: "..stn.." "..core.pos_to_string(pos).." @ "..rwtime)
+ end
+ local should_stop_result = should_stop(pos, stdata, train)
+ if should_stop_result == nil then
+ debug_print("Vlak "..train_id.." projel zastávkou "..stn)
+ return
+ elseif should_stop_result == "on_request" then
+ -- projetí zastávky na znamení
+ debug_print("Vlak "..train_id.." projel zastávkou na znamení "..stn)
+ if linevar_def ~= nil and next_index ~= nil then
+ local stop_def = assert(linevar_def.stops[next_index])
+ if stop_def.mode == nil or stop_def.mode ~= MODE_REQUEST_STOP then
+ error("Internal error: mode "..MODE_REQUEST_STOP.." expected, but the real mode is "..tostring(stop_def.mode).."!")
+ end
+ assert(stn ~= "")
+ record_skipped_stops(train_id, linevar_def, ls.linevar_index, next_index)
+ ls.linevar_index = next_index
+ ls.linevar_last_dep = rwtime -- u zastávky na znamení se průjezd počítá jako odjezd
+ ls.linevar_last_stn = stn
+ local next_stop_index, next_stop_data = al.get_next_stop(linevar_def, next_index)
+ train.text_inside = al.get_stop_description(nil, linevar_def.stops[next_stop_index or 0])
+ -- ATC command:
+ local atc_command = "A1 S" ..(stdata.speed or "M")
+ advtrains.atc.train_set_command(train, atc_command, true)
+ end
+ return
+ end
+
+ -- naplánovat čas odjezdu
+ local wait = tonumber(stdata.wait) or 0
+ local interval = stdata.interval
+ local last_dep = stdata.last_dep -- posl. odjezd z této zastávkové koleje
+
+ if interval ~= nil and last_dep ~= nil then
+ if last_dep > rwtime then
+ last_dep = rwtime
+ end
+ local ioffset = stdata.ioffset or 0
+ local normal_dep = rwtime + wait
+ local next_dep = last_dep + (interval - (last_dep + (interval - ioffset)) % interval)
+ if normal_dep < next_dep then
+ -- core.log("action", "[INFO] The train "..train_id.." will wait for "..(next_dep - normal_dep).." additional seconds due to interval at "..core.pos_to_string(pos)..".")
+ wait = wait + (next_dep - normal_dep)
+ -- else -- will wait normal time
+ end
+ end
+ local planned_departure = rwtime + wait
+ debug_print("Vlak "..train_id.." zastavil na "..stn.." a odjede za "..wait.." sekund ("..planned_departure..").")
+ stdata.last_dep = planned_departure -- naplánovaný čas odjezdu
+ stdata.last_wait = wait -- naplánovaná doba čekání
+ ls.standing_at = pe
+ if linevar_def == nil or next_index == nil or (linevar_def.stops[next_index].mode or MODE_NORMAL) ~= MODE_HIDDEN then
+ -- zrušit stop_request, pokud jsme nezastavili na skryté zastávce:
+ ls.stop_request = nil
+ end
+
+ local can_start_line
+ local had_linevar = linevar_def ~= nil
+ if linevar_def == nil then
+ -- nelinkový vlak
+ can_start_line = true
+ elseif next_index ~= nil then
+ -- linkový vlak zastavil na své řádné zastávce
+ assert(stn ~= "") -- dopravna musí mít kód
+ local stop_def = assert(linevar_def.stops[next_index])
+ debug_print("Vlak "..train_id.." je linkový vlak ("..ls.linevar..") a zastavil na své pravidelné zastávce "..stn.." (index = "..next_index..")")
+ record_skipped_stops(train_id, linevar_def, ls.linevar_index, next_index)
+ local stop_smode = simple_modes[stop_def.mode or 0]
+ if stop_smode == MODE_NORMAL then
+ -- mezilehlá zastávka
+ can_start_line = false
+ ls.linevar_index = next_index
+ ls.linevar_last_dep = planned_departure
+ ls.linevar_last_stn = stn
+ debug_print("Jde o mezilehlou zastávku.")
+ local next_stop_index, next_stop_data = al.get_next_stop(linevar_def, next_index)
+ train.text_inside = al.get_stop_description(linevar_def.stops[next_index], linevar_def.stops[next_stop_index or 0])
+ else
+ -- koncová zastávka
+ can_start_line = stop_def.mode == MODE_FINAL_CONTINUE
+ core.log("action", "Train "..train_id.." arrived at the final station "..stop_def.stn.." of linevar "..ls.linevar.." after "..(rwtime - ls.linevar_dep).." seconds.")
+ debug_print("Vlak "..train_id.." skončil jízdu na lince "..ls.linevar..", může pokračovat na jinou linku: "..(can_start_line and "ihned" or "na příští zastávce"))
+ train.text_inside = al.get_stop_description(linevar_def.stops[next_index])
+ local current_passage = current_passages[train_id]
+ if current_passage ~= nil then
+ current_passage[next_index] = rwtime
+ current_passages[train_id] = nil
+ end
+ al.cancel_linevar(train)
+ -- vyplnit linevar_past:
+ if train.line ~= nil and train.line ~= "" then
+ local past_linevar = assert(linevar_def.name)
+ local past_line = al.linevar_decompose(past_linevar)
+ ls.linevar_past = {
+ line = assert(past_line),
+ linevar = past_linevar,
+ station = stn,
+ arrival = rwtime,
+ }
+ end
+ end
+ else
+ -- linkový vlak zastavil na neznámé zastávce (nemělo by nastat)
+ core.log("warning", "Train "..train_id.." of linevar '"..ls.linevar.."' stopped at unknown station '"..stn.."' at "..core.pos_to_string(pos).."!")
+ debug_print("Vlak "..train_id.." je linkový vlak ("..ls.linevar.."), ale zastavil na sobě neznámé zastávce "..stn..", což by se nemělo stát.")
+ can_start_line = false
+ end
+
+ -- ATC příkaz
+ local atc_command = "B0 W O"..stdata.doors..(stdata.kick and "K" or "").." D"..wait..
+ (stdata.keepopen and " " or " OC ")..(stdata.reverse and "R" or "").." D"..(stdata.ddelay or 1)..
+ " A1 S" ..(stdata.speed or "M")
+ advtrains.atc.train_set_command(train, atc_command, true)
+
+ -- provést změny vlaku
+ local new_line = stdata.line or ""
+ local new_routingcode = stdata.routingcode or ""
+ update_value(train, "line", new_line)
+ update_value(train, "routingcode", new_routingcode)
+
+ -- začít novou linku?
+ if can_start_line and stn ~= nil and stn ~= "" and line_start(train, stn, planned_departure) then
+ debug_print("Vlak "..train_id.." zahájil jízdu na nové lince ("..ls.linevar..") ze stanice "..stn..".")
+ core.log("action", "Train "..train_id.." started a route with linevar '"..ls.linevar.."' at station '"..stn.."'.")
+ train.text_inside = get_station_name(stn)
+ assert(ls.linevar)
+ linevar_def = assert(al.try_get_linevar_def(ls.linevar))
+ local next_stop_index, next_stop_data = al.get_next_stop(linevar_def, 1)
+ if next_stop_index ~= nil then
+ train.text_inside = train.text_inside.."\nPříští zastávka/stanice: "..get_station_name(next_stop_data.stn)
+ if next_stop_data.mode ~= nil and next_stop_data.mode == MODE_REQUEST_STOP then
+ train.text_inside = train.text_inside.." (na znamení)"
+ end
+ end
+ elseif not had_linevar and ls.linevar == nil then
+ -- vlak, který nebyl a stále není linkový:
+ train.text_inside = get_station_name(stn)
+ -- core.after(wait, function() train.text_inside = "" end)
+ end
+end
+
+function al.on_train_leave(pos, train_id, train, index)
+ local pe = advtrains.encode_pos(pos)
+ local stdata = advtrains.lines.stops[pe]
+ if stdata == nil then
+ return -- neplatná zastávka
+ end
+ local stn = stdata.stn or ""
+ local ls, linevar_def = al.get_line_status(train)
+ local rwtime = assert(rwt.to_secs(rwt.get_time()))
+
+ if stn ~= "" then
+ ls.last_leave = {stn = stn, encpos = pe, rwtime = rwtime}
+ debug_print("Vlak "..train_id.." zaznamenán na odjezdu: "..stn.." "..core.pos_to_string(pos).." @ "..rwtime)
+ end
+
+ if ls.standing_at == pe then
+ -- vlak stál v této dopravně
+ ls.standing_at = nil
+ if
+ linevar_def == nil or ls.linevar_index == nil or
+ linevar_def.stops[ls.linevar_index] == nil or
+ (linevar_def.stops[ls.linevar_index].mode or MODE_NORMAL) ~= MODE_HIDDEN
+ then
+ ls.stop_request = nil -- zrušit stop_request při odjezdu ze zastávky, pokud není nekoncová skrytá
+ end
+ if stn ~= "" then
+ debug_print("Vlak "..train_id.." odjel ze zastávky "..stn)
+ if ls.linevar_last_dep ~= nil and ls.linevar_last_dep > rwtime then
+ debug_print("Vlak "..train_id.." předčasně odjel z dopravny "..stn.." (zbývalo "..(ls.linevar_last_dep - rwtime).." sekund)")
+ ls.linevar_last_dep = rwtime -- předčasný odjezd
+ if ls.linevar_index == 1 then
+ ls.linevar_dep = rwtime
+ end
+ end
+ else
+ debug_print("Vlak "..train_id.." odjel z anonymní zastávky "..core.pos_to_string(pos)..".")
+ end
+ train.text_inside = ""
+ if linevar_def ~= nil then
+ -- linkový vlak:
+ debug_print("Linkový vlak "..train_id.." odjel ze zastávky s indexem "..ls.linevar_index)
+ if ls.linevar_index == 1 then
+ -- odjezd z výchozí zastávky:
+ local new_passage = {rwtime}
+ if stdata.last_wait ~= nil then
+ new_passage.wait = stdata.last_wait
+ end
+ current_passages[train_id] = new_passage
+ local passages_by_linevar = last_passages[ls.linevar]
+ if passages_by_linevar == nil then
+ passages_by_linevar = {new_passage}
+ last_passages[ls.linevar] = passages_by_linevar
+ else
+ while #passages_by_linevar >= 10 do
+ table.remove(passages_by_linevar, 1)
+ end
+ table.insert(passages_by_linevar, new_passage)
+ end
+ else
+ -- odjezd z nácestné zastávky
+ local current_passage = current_passages[train_id]
+ if current_passage ~= nil then
+ current_passage[ls.linevar_index] = rwtime
+ end
+ end
+ local next_stop_index, next_stop_data = al.get_next_stop(linevar_def, ls.linevar_index)
+ if next_stop_index ~= nil then
+ train.text_inside = al.get_stop_description(nil, next_stop_data)
+ end
+ end
+ -- else
+ --[[ průjezd?
+ local stn = (stdata and stdata.stn) or ""
+ if stn ~= "" then
+ debug_print("Vlak "..train_id.." projel (odjezd) zastávkou "..stn..".")
+ else
+ debug_print("Vlak "..train_id.." projel (odjezd) anonymní zastávkou "..core.pos_to_string(pos)..".")
+ end
+ ]]
+ end
+end
+
+function al.linevar_decompose(linevar)
+ if linevar == nil then
+ return nil, nil, nil
+ end
+ local parts = string.split(linevar, "/", true, 3)
+ return parts[1], parts[2] or "", parts[3] or ""
+end
+
+--[[
+ Vrací:
+ a) pokud linevar existuje a má průjezdy:
+ passages, stops:
+ {{[1] = rwtime, ..., wait = int or nil}...}, {"kód", "název"}...}
+ b) jinak:
+ nil, nil
+]]
+function al.get_last_passages(linevar_def)
+ local lp = last_passages[linevar_def.name]
+ if linevar_def ~= nil and lp ~= nil and lp[1] ~= nil then
+ local passages, stops = {}, {}
+ for i, stop in ipairs(linevar_def.stops) do
+ stops[i] = {stop.stn, get_station_name(stop.stn)}
+ end
+ for i = 1, #lp do
+ passages[i] = table.copy(lp[i])
+ end
+ return passages, stops
+ end
+end
+
+local function get_last_pos(line_status)
+ assert(line_status)
+ local last_enter, last_leave, standing_at = line_status.last_enter, line_status.last_leave, line_status.standing_at
+ local last_pos, last_pos_type
+ if last_enter ~= nil then
+ last_pos, last_pos_type = last_enter, "enter"
+ if standing_at ~= nil and standing_at == last_enter.encpos then
+ last_pos_type = "standing"
+ elseif last_leave ~= nil and last_leave.rwtime > last_enter.rwtime then
+ last_pos, last_pos_type = last_leave, "leave"
+ end
+ elseif last_leave ~= nil then
+ last_pos, last_pos_type = last_leave, "leave"
+ else
+ result.type = "none"
+ return {type = "none"}
+ end
+ local result = {type = last_pos_type, last_pos = last_pos}
+ if last_enter ~= nil then
+ result.last_enter = last_enter
+ end
+ if last_leave ~= nil then
+ result.last_leave = last_leave
+ end
+ return result
+end
+
+function al.get_last_pos_station_name(line_status)
+ local result = get_last_pos(line_status)
+ if result.type ~= "none" then
+ return get_station_name(result.last_pos.stn)
+ else
+ return nil
+ end
+end
+
+local function get_train_position(line_status, linevar_def, rwtime)
+ if line_status ~= nil then
+ local last_pos_info = get_last_pos(line_status)
+ local last_pos = last_pos_info.last_pos
+ if last_pos ~= nil then
+ local result = "„"..get_station_name(last_pos.stn).."“"
+ local delay_info = al.get_delay_description(line_status, linevar_def, rwtime)
+ if last_pos_info.type ~= "standing" then
+ result = result.." (před "..(rwtime - last_pos.rwtime).." sekundami)"
+ end
+ if delay_info.has_delay ~= nil then
+ result = result.." ("..delay_info.text..")"
+ end
+ return result
+ end
+ end
+ return "???"
+end
+
+--[[
+local function prepare_prediction_for_dump(result)
+ local x = {}
+ for i, record in ipairs(result) do
+ local y = table.copy(record)
+ y.stdata = record.stdata.name
+ if y.arr_linevar_def ~= nil then
+ y.arr_linevar_def = y.arr_linevar_def.name
+ end
+ if y.dep_linevar_def ~= nil then
+ y.dep_linevar_def = y.dep_linevar_def.name
+ end
+ x[i] = y
+ end
+ return x
+end
+]]
+
+local function predict_train_continue(line, stn, rc, departure, result)
+ if line == nil or line == "" then
+ return
+ end
+ local linevar_def = al.try_get_linevar_def(line.."/"..stn.."/"..rc, stn)
+ if linevar_def == nil then
+ return
+ end
+ if #result == 0 then
+ return
+ end
+ local stops = assert(linevar_def.stops)
+ local last_record = result[#result]
+ last_record.dep = departure
+ last_record.dep_linevar_def = linevar_def
+ last_record.dep_index = 1
+ local index = 2
+ while stops[index] ~= nil do
+ local stop = stops[index]
+ local stdata = advtrains.lines.stations[stop.stn]
+ if stop.mode == MODE_FINAL or stop.mode == MODE_FINAL_CONTINUE or stop.mode == MODE_FINAL_HIDDEN then
+ -- koncová zastávka
+ local arr = departure + stop.dep
+ local record = {
+ stn = assert(stop.stn),
+ track = stop.track or "",
+ stdata = stdata,
+ arr = arr,
+ arr_linevar_def = linevar_def,
+ arr_index = index,
+ delay = 0,
+ hidden = stop.mode == MODE_FINAL_HIDDEN,
+ }
+ table.insert(result, record)
+ return
+ elseif stop.mode ~= MODE_DISABLED then
+ -- mezilehlá zastávka
+ local dep = departure + stop.dep
+ table.insert(result, {
+ stn = assert(stop.stn),
+ track = stop.track or "",
+ stdata = stdata,
+ arr = dep - (stop.wait or 10),
+ arr_linevar_def = linevar_def,
+ arr_index = index,
+ dep = dep,
+ dep_linevar_def = linevar_def,
+ dep_index = index,
+ delay = 0,
+ hidden = stop.mode == MODE_HIDDEN,
+ })
+ end
+ index = index + 1
+ end
+end
+
+--[[
+ Zadaný vlak musí být linkový.
+ Parametry:
+ line_status = table,
+ linevar_def = table,
+ rwtime = int,
+ allow_continue = bool,
+ Vrací *pole* následujících záznamů:
+ {
+ 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,
+ }
+]]
+function al.predict_train(line_status, linevar_def, rwtime, allow_continue)
+ assert(line_status)
+ assert(linevar_def)
+ local stops = linevar_def.stops
+ local result = {}
+ local index = assert(line_status.linevar_index)
+ if rwtime == nil then
+ rwtime = rwt.to_secs(rwt.get_time())
+ end
+ local delay_desc = al.get_delay_description(line_status, linevar_def, rwtime)
+ local delay
+ if delay_desc.has_delay then
+ delay = delay_desc.delay
+ else
+ delay = 0
+ end
+ local departure = line_status.linevar_dep
+ if line_status.standing_at ~= nil then
+ -- vlak stojí na zastávce
+ local stop = assert(stops[index])
+ local stdata = advtrains.lines.stations[stop.stn]
+ table.insert(result, {
+ stn = line_status.linevar_last_stn,
+ track = stop.track or "",
+ stdata = stdata,
+ dep = assert(line_status.linevar_last_dep),
+ dep_linevar_def = assert(linevar_def),
+ dep_index = index,
+ -- arr = nil, arr_index = nil, arr_linevar_def = nil,
+ delay = delay,
+ hidden = stop.mode == MODE_HIDDEN
+ })
+ end
+ index = index + 1
+ while stops[index] ~= nil do
+ local stop = stops[index]
+ local stdata = advtrains.lines.stations[stop.stn]
+ if stop.mode == MODE_FINAL or stop.mode == MODE_FINAL_CONTINUE or stop.mode == MODE_FINAL_HIDDEN then
+ -- koncová zastávka
+ local arr = departure + stop.dep + delay
+ local record = {
+ stn = assert(stop.stn),
+ track = stop.track or "",
+ stdata = stdata,
+ arr = arr,
+ arr_linevar_def = linevar_def,
+ arr_index = index,
+ delay = delay,
+ hidden = stop.mode == MODE_FINAL_HIDDEN,
+ final = true,
+ }
+ table.insert(result, record)
+ if allow_continue and (linevar_def.continue_line or "") ~= "" and stop.mode == MODE_FINAL_CONTINUE then
+ predict_train_continue(linevar_def.continue_line, stop.stn, linevar_def.continue_rc, arr + (stop.wait or 10), result)
+ end
+ break
+ elseif stop.mode ~= MODE_DISABLED then
+ -- mezilehlá zastávka
+ local dep = departure + stop.dep + delay
+ table.insert(result, {
+ stn = assert(stop.stn),
+ track = stop.track or "",
+ stdata = stdata,
+ arr = dep - (stop.wait or 10),
+ arr_linevar_def = linevar_def,
+ arr_index = index,
+ dep = dep,
+ dep_linevar_def = assert(linevar_def),
+ dep_index = index,
+ delay = delay,
+ hidden = stop.mode == MODE_HIDDEN,
+ })
+ end
+ index = index + 1
+ end
+ -- print("DEBUG: "..dump2({prediction = prepare_prediction_for_dump(result)}))
+ return result
+end
+
+--[[
+ Parametry:
+ linevar_def = table, -- definice linevar, z něhož se má analýza provádět
+ linevar_index = int,
+ rwtime = int or nil, -- (aktuální žel. čas; nepovinné)
+ trains = {train_table...} or nil, -- je-li zadáno, bude zkoumat pouze vlaky v tomto seznamu
+ Vrací *pole* záznamů (stejných jako al.predict_train) vztahujících se k odjezdu
+ z požadované zastávky, seřazené od nejbližšího odjezdu po nejvzdálenější.
+]]
+function al.predict_station_departures(linevar_def, linevar_index, rwtime, trains)
+ assert(linevar_def)
+ assert(linevar_index)
+ local linevar = linevar_def.name
+ local stop = assert(linevar_def.stops[linevar_index])
+ if trains == nil then
+ trains = al.get_trains_by_linevar()[linevar] or {}
+ end
+ if rwtime == nil then
+ rwtime = rwt.to_secs(rwt.get_time())
+ end
+ local result = {}
+ for _, train in ipairs(trains) do
+ local ls, lvdef = al.get_line_status(train)
+ if ls.linevar == linevar and ls.linevar_index <= linevar_index then
+ local prediction = al.predict_train(ls, linevar_def, rwtime, true)
+ for _, pr in ipairs(prediction) do
+ if
+ pr.dep ~= nil and pr.dep_linevar_def ~= nil and pr.dep_index ~= nil and
+ pr.dep_linevar_def.name == linevar and
+ pr.dep_index == linevar_index and
+ pr.dep > rwtime
+ then
+ table.insert(result, pr)
+ break
+ end
+ end
+ end
+ end
+ table.sort(result, function(a, b) return a.dep < b.dep end)
+ return result
+end
+
+--[[
+ => {{
+ linevar = string,
+ indices = {int,...},
+ linevar_def = linevar_def,
+ }...}
+]]
+function al.get_linevars_by_station(stn, track, options)
+ if options == nil then
+ options = {}
+ end
+ local include_hidden_stops = options.include_hidden_stops
+ local ignore_first_stop = options.ignore_first_stop
+ local ignore_last_stop = options.ignore_last_stop
+ local result = {}
+ assert(stn)
+ for lvstn, stdata in pairs(advtrains.lines.stations) do
+ if stdata.linevars ~= nil then
+ for linevar, linevar_def in pairs(stdata.linevars) do
+ local first_stop_index = al.get_first_stop(linevar_def, include_hidden_stops)
+ local last_stop_index = al.get_last_stop(linevar_def, include_hidden_stops)
+ if not (ignore_first_stop or ignore_last_stop) or (first_stop_index ~= nil and last_stop_index ~= nil) then
+ local ld
+ for i, stop in ipairs(linevar_def.stops) do
+ if
+ stop.stn == stn and
+ (track == nil or tostring(stop.track) == track) and
+ (include_hidden_stops or is_visible_mode(stop.mode)) and
+ ((not ignore_first_stop) or i ~= 1) and
+ ((not ignore_last_stop) or (not is_final_mode(stop.mode)))
+ then
+ if ld == nil then
+ ld = {linevar = linevar, linevar_def = linevar_def, indices = {i}}
+ table.insert(result, ld)
+ else
+ table.insert(ld.indices, i)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ if #result > 1 then
+ table.sort(result, function(a, b) return a.linevar < b.linevar end)
+ end
+ return result
+end
+
+--[[
+ => {
+ [linevar] = {train...}, -- generuje jen neprázdné seznamy
+ }
+]]
+function al.get_trains_by_linevar()
+ local result = {}
+ for train_id, train in pairs(advtrains.trains) do
+ local ls, linevar_def = al.get_line_status(train)
+ if linevar_def ~= nil then
+ local linevar = linevar_def.name
+ local list = result[linevar]
+ if list ~= nil then
+ table.insert(list, train)
+ else
+ list = {train}
+ result[linevar] = list
+ end
+ end
+ end
+ for linevar, list in pairs(result) do
+ if list[2] ~= nil then
+ table.sort(list, function(a, b) return a.id < b.id end)
+ end
+ end
+ return result
+end
+
+local function vlaky(param, past_trains_too)
+ local result = {}
+ if param:match("/") then
+ return result -- parametr nesmí obsahovat '/'
+ end
+ local train_line_prefix
+ if param ~= "" then
+ train_line_prefix = param.."/"
+ end
+ local rwtime = rwt.to_secs(rwt.get_time())
+ local players_per_train = {}
+ local results = {}
+ for player_name, train_id in pairs(advtrains.player_to_train_mapping) do
+ results[train_id] = (results[train_id] or 0) + 1
+ end
+ for train_id, train in pairs(advtrains.trains) do
+ local ls, linevar_def = al.get_line_status(train)
+ if linevar_def ~= nil then
+ if train_line_prefix == nil or train_line_prefix == ls.linevar:sub(1, #train_line_prefix) then
+ local direction_index, direction_stop = al.get_terminus(linevar_def, ls.linevar_index, false)
+ local direction = "???"
+ if direction_index ~= nil then
+ direction = get_station_name(direction_stop.stn)
+ end
+ local line = al.linevar_decompose(linevar_def.name)
+ local s = "("..train_id..") ["..line.."] směr „"..direction.."“, poloha: "..
+ get_train_position(ls, linevar_def, rwtime)
+ if results[train_id] ~= nil then
+ s = s.." ["..results[train_id].." cestující/ch]"
+ end
+ table.insert(results, {key = linevar_def.name.."/"..ls.linevar_index, value = s})
+ end
+ elseif past_trains_too and ls.linevar_past ~= nil and (train_line_prefix == nil or ls.linevar_past.line == param) then
+ local age = rwtime - ls.linevar_past.arrival
+ local s = "("..train_id..") ["..ls.linevar_past.line.."] služební, poloha: "..
+ get_station_name(ls.linevar_past.station).." (před "..age.." sekundami)"
+ if results[train_id] ~= nil then
+ s = s.." ["..results[train_id].." cestující/ch]"
+ end
+ table.insert(results, {
+ key = string.format("%s/~/%s/%05d", ls.linevar_past.line, ls.linevar_past.station, age),
+ value = s,
+ })
+ end
+ end
+ table.sort(results, function(a, b) return a.key < b.key end)
+ for i, v in ipairs(results) do
+ result[i] = v.value
+ end
+ return result
+end
+
+-- příkaz /vlaky
+local def = {
+ params = "[linka]",
+ description = "Vypíše všechny linkové vlaky na zadané lince (resp. na všech linkách)",
+ privs = {},
+ func = function(player_name, param)
+ local result = vlaky(param, false)
+ if #result == 0 then
+ return false, "Nenalezen žádný odpovídající vlak."
+ end
+ return true, "Nalezeno "..#result.." vlaků:\n- "..table.concat(result, "\n- ")
+ end,
+}
+core.register_chatcommand("vlaky", def)
+def = {
+ params = "[linka]",
+ description = "Vypíše všechny linkové vlaky na zadané lince (resp. na všech linkách) a ty, které nedávno jízdu na lince ukončily",
+ privs = {},
+ func = function(player_name, param)
+ local result = vlaky(param, true)
+ if #result == 0 then
+ return false, "Nenalezen žádný odpovídající vlak."
+ end
+ return true, "Nalezeno "..#result.." vlaků:\n- "..table.concat(result, "\n- ")
+ end,
+}
+core.register_chatcommand("vlaky+", def)
+
+def = {
+ -- params = "",
+ description = "(pro ladění)",
+ privs = {server = true},
+ func = function(player_name, param)
+ local train = advtrains.trains[param]
+ if train == nil then
+ return false, "Vlak "..param.." nenalezen!"
+ end
+ local line_status, linevar_def = al.get_line_status(train)
+ if linevar_def == nil then
+ return false, "Vlak "..param.." není linkový!"
+ end
+ -- function al.predict_train(line_status, linevar_def, rwtime, allow_continue)
+ local rwtime = rwt.to_secs(rwt.get_time())
+ local predictions = al.predict_train(line_status, linevar_def, rwtime, true)
+ local result = {"----"}
+ local s
+ for i, record in ipairs(predictions) do
+ local arr, dep
+ if record.arr ~= nil then
+ arr = "("..(record.arr - rwtime)..", lv="..record.arr_linevar_def.name..", i="..record.arr_index..")"
+ else
+ arr = "nil"
+ end
+ if record.dep ~= nil then
+ dep = "("..(record.dep - rwtime)..", lv="..record.dep_linevar_def.name..", i="..record.dep_index..")"
+ else
+ dep = "nil"
+ end
+ result[i + 1] = "- "..record.stn.." ["..record.track.."] arr="..arr.." dep="..dep.." delay="..record.delay
+ end
+ table.insert(result, "----")
+ s = table.concat(result, "\n")
+ print(s)
+ core.chat_send_player(player_name, s)
+ return true
+ end,
+}
+core.register_chatcommand("jřád", def)
+core.register_chatcommand("jrad", def)