diff options
author | Singularis <singularis@volny.cz> | 2025-01-26 18:06:40 +0100 |
---|---|---|
committer | orwell <orwell@bleipb.de> | 2025-05-27 20:22:01 +0200 |
commit | 6ac6558b3b716a49bf29f6e5ce40cc6bc0443ae7 (patch) | |
tree | 53fa96b0e7d7beaed6d04999c10406d3374b2445 /advtrains_line_automation/line_functions.lua | |
parent | ef4ba201bf9bef7bdeaa573b4a549da8b06a5e07 (diff) | |
download | advtrains-6ac6558b3b716a49bf29f6e5ce40cc6bc0443ae7.tar.gz advtrains-6ac6558b3b716a49bf29f6e5ce40cc6bc0443ae7.tar.bz2 advtrains-6ac6558b3b716a49bf29f6e5ce40cc6bc0443ae7.zip |
[advtrains_line_automation] vývoj
- staničnímu rozhlasu přidán režim (odjezdy/příjezdy)
- do editoru variant linek přidána možnost pokračování a nastavení
předpokládané doby stání na zastávkách
- přidána podpora času ve formátu MM:SS
Diffstat (limited to 'advtrains_line_automation/line_functions.lua')
-rw-r--r-- | advtrains_line_automation/line_functions.lua | 300 |
1 files changed, 185 insertions, 115 deletions
diff --git a/advtrains_line_automation/line_functions.lua b/advtrains_line_automation/line_functions.lua index 0963676..41776c3 100644 --- a/advtrains_line_automation/line_functions.lua +++ b/advtrains_line_automation/line_functions.lua @@ -107,34 +107,10 @@ end -- 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 stops = assert(linevar_def.stops) - assert(stops[1]) - assert(stops[2]) -- každá definice linky musí obsahovat alespoň dvě zastávky - local i_first, i_last, i_firstx, i_lastx - for i, stop in ipairs(stops) do - local mode = stop.mode or MODE_NORMAL - if mode ~= MODE_DISABLED then - if i_first == nil then - if mode ~= MODE_HIDDEN and mode ~= MODE_FINAL_HIDDEN then - i_first = i -- první neskrytá zastávka - end - if i_firstx == nil then - i_firstx = i -- první nevypnutá zastávka (může být skrytá) - end - end - i_lastx = i - if mode == MODE_NORMAL or mode == MODE_REQUEST_STOP or mode == MODE_FINAL or mode == MODE_FINAL_CONTINUE then - i_last = i - end - if mode == MODE_FINAL or mode == MODE_FINAL_CONTINUE or mode == MODE_FINAL_HIDDEN then - break - end - end - end - if i_first ~= nil and i_last ~= nil then - return stops[i_first].stn, stops[i_last].stn - elseif i_firstx ~= nil and i_lastx ~= nil then - return stops[i_firstx].stn, stops[i_lastx].stn + 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 @@ -154,7 +130,6 @@ local function line_start(train, stn, departure_rwtime) end local linevar, linevar_def = al.try_get_linevar(train.line, stn, train.routingcode) if linevar == nil or linevar_def.disabled then - -- print("DEBUG: line_start() failed for "..(train.line or "").."/"..stn.."/"..(train.routingcode or "")) return false end ls.linevar = linevar @@ -171,7 +146,6 @@ local function line_start(train, stn, departure_rwtime) last_stop_uppercase = true, train_name = true, }) - -- print("DEBUG: line_start(): "..dump2({train_id = train.id, line_status = ls})) return true end @@ -183,13 +157,11 @@ end ]] local function should_stop(pos, stdata, train) if stdata == nil or stdata.stn == nil then - -- print("DEBUG: should_stop() == false, because stdata is invalid!") 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 - -- print("DEBUG: should_stop("..stdata.stn..") == false, because n_trainparts is not in interval") return nil end local stn = assert(stdata.stn) -- zastávka stále může být anonymní @@ -201,12 +173,10 @@ local function should_stop(pos, stdata, train) -- jde o linkový vlak? if linevar_def ~= nil then if next_index == nil then - -- print("DEBUG: should_stop("..stn..") == false, because linevar=='"..ls.linevar.."' and next_index == nil") 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 - -- print("DEBUG: should_stop("..stn..") == false, because the stop is limited to position "..stop.pos) return nil end if stop.mode ~= nil and stop.mode == MODE_REQUEST_STOP then @@ -218,17 +188,7 @@ local function should_stop(pos, stdata, train) return "on_request" end end - -- print("DEBUG: should_stop("..stn..") == true for "..linevar_def.name) return "true" - -- local result = next_index ~= nil -- zastávka má index => zastavit - --[[ - if result then - print("DEBUG: should_stop() == true, because linevar=='"..ls.linevar.."' and get_line_status() retuned next_index == "..next_index) - else - print("DEBUG: should_stop() == false, because linevar=='"..ls.linevar.."' and get_line_status() retuned next_index == nil") - end - ]] - -- return result -- TODO: zastávky na znamení else local ars = stdata.ars @@ -236,10 +196,8 @@ local function should_stop(pos, stdata, train) local result = ars and (ars.default or advtrains.interlocking.ars_check_rule_match(ars, train)) if result then return "true" - -- print("DEBUG: should_stop("..stn..") == true, because linevar==nil and ARS rules match") else return nil - -- print("DEBUG: should_stop("..stn..") == false, because linevar==nil and ARS rules don't match") end end end @@ -259,7 +217,6 @@ end function al.cancel_linevar(train) local ls = train.line_status if ls == nil or ls.linevar == nil then return false end - -- print("DEBUG: line_end(train_id = "..train.id..", linevar was: "..ls.linevar.."): "..dump2({line_status_old = ls})) ls.linevar = nil ls.linevar_station = nil ls.linevar_index = nil @@ -303,6 +260,48 @@ end 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) @@ -342,6 +341,9 @@ end 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 @@ -507,7 +509,6 @@ end -- 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 - -- print("DEBUG: try_get_linevar_def() => nil, because linevar == nil") return nil, nil end if linevar_station == nil then @@ -522,11 +523,7 @@ function al.try_get_linevar_def(linevar, linevar_station) t = t.linevars if t ~= nil then return t[linevar], linevar_station - -- else - -- print("DEBUG: no linevars for linevar_station '"..linevar_station.."'") end - -- else - -- print("DEBUG: no data for linevar_station '"..linevar_station.."'") end return nil, nil end @@ -541,11 +538,9 @@ function al.try_get_linevar(line, stn, rc) local linevar = line.."/"..stn.."/"..(rc or "") local result = al.try_get_linevar_def(linevar, stn) if result ~= nil then - -- print("DEBUG: linevar combination found: "..dump2({linevar = linevar, line = line, stn = stn, rc = rc or "", linevar_def = result})) return linevar, result end end - -- print("DEBUG: linevar combination not found for "..(line or "").."/"..(stn or "").."/"..(rc or "")) return nil, nil end @@ -560,7 +555,6 @@ function al.get_line_status(train) assert(train) if train.line_status == nil then train.line_status = {} - -- print("DEBUG: new empty line_status created for train "..train.id) return train.line_status, nil end local ls = train.line_status @@ -607,7 +601,6 @@ function al.on_train_approach(pos, train_id, train, index, has_entered) local pe = advtrains.encode_pos(pos) local stdata = advtrains.lines.stops[pe] if should_stop(pos, stdata, train) ~= nil then - -- print("DEBUG: on_train_approach(): will stop at station '"..stdata.stn.."'") advtrains.lzb_add_checkpoint(train, index, 2, nil) if train.line_status.linevar == nil then -- nelinkový vlak: @@ -700,7 +693,6 @@ function al.on_train_enter(pos, train_id, train, index) end local planned_departure = rwtime + wait debug_print("Vlak "..train_id.." zastavil na "..stn.." a odjede za "..wait.." sekund ("..planned_departure..").") - -- print("DEBUG: planned departure: "..planned_departure.." = "..rwtime.." + "..wait) stdata.last_dep = planned_departure -- naplánovaný čas odjezdu stdata.last_wait = wait -- naplánovaná doba čekání ls.standing_at = pe @@ -708,20 +700,17 @@ function al.on_train_enter(pos, train_id, train, index) -- zrušit stop_request, pokud jsme nezastavili na skryté zastávce: ls.stop_request = nil end - -- print("DEBUG: standing ls = "..dump2(ls)) local can_start_line local had_linevar = linevar_def ~= nil if linevar_def == nil then -- nelinkový vlak can_start_line = true - -- print("DEBUG: train "..train_id.." is non-line train, can start a new line") 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..")") - -- print("DEBUG: train "..train_id.." stopped at regular stop '"..stn.."': "..dump2({stop_def = stop_def})) 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 @@ -761,7 +750,6 @@ function al.on_train_enter(pos, train_id, train, index) 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 - -- print("DEBUG: "..dump2({can_start_line = can_start_line})) -- ATC příkaz local atc_command = "B0 W O"..stdata.doors..(stdata.kick and "K" or "").." D"..wait.. @@ -794,7 +782,6 @@ function al.on_train_enter(pos, train_id, train, index) train.text_inside = get_station_name(stn) -- core.after(wait, function() train.text_inside = "" end) end - -- print("DEBUG: the train will wait for "..wait.." seconds") end function al.on_train_leave(pos, train_id, train, index) @@ -812,7 +799,6 @@ function al.on_train_leave(pos, train_id, train, index) debug_print("Vlak "..train_id.." zaznamenán na odjezdu: "..stn.." "..core.pos_to_string(pos).." @ "..rwtime) end - -- print("DEBUG: *on_train_leave("..train_id..") from "..(stdata and stdata.stn or "nil")) if ls.standing_at == pe then -- vlak stál v této dopravně ls.standing_at = nil @@ -824,7 +810,6 @@ function al.on_train_leave(pos, train_id, train, index) ls.stop_request = nil -- zrušit stop_request při odjezdu ze zastávky, pokud není nekoncová skrytá end if stn ~= "" then - -- print("DEBUG: on_train_leave from non-anonymous stop") 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)") @@ -834,7 +819,6 @@ function al.on_train_leave(pos, train_id, train, index) end end else - -- print("DEBUG: on_train_leave from anonymous stop") debug_print("Vlak "..train_id.." odjel z anonymní zastávky "..core.pos_to_string(pos)..".") end train.text_inside = "" @@ -874,9 +858,9 @@ function al.on_train_leave(pos, train_id, train, index) --[[ průjezd? local stn = (stdata and stdata.stn) or "" if stn ~= "" then - debug_print("DEBUG: Vlak "..train_id.." projel (odjezd) zastávkou "..stn..".") + debug_print("Vlak "..train_id.." projel (odjezd) zastávkou "..stn..".") else - debug_print("DEBUG: Vlak "..train_id.." projel (odjezd) anonymní zastávkou "..core.pos_to_string(pos)..".") + debug_print("Vlak "..train_id.." projel (odjezd) anonymní zastávkou "..core.pos_to_string(pos)..".") end ]] end @@ -912,21 +896,6 @@ function al.get_last_passages(linevar_def) end end ---[[ DEBUG: -local debug_print = {} -function debug_print.print() - print(".") - core.after(1, debug_print.print) -end -debug_print.print() -]] - ---[[ -function al.rwt_to_cas() - return -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 @@ -983,11 +952,90 @@ local function get_train_position(line_status, linevar_def, rwtime) 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ý. Vrací: - {stn = string, track = string, stdata = table or nil, dep = int or nil, arr = int or nil, delay = int} + { + 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) +function al.predict_train(line_status, linevar_def, rwtime, allow_continue) assert(line_status) assert(linevar_def) local stops = linevar_def.stops @@ -1003,6 +1051,7 @@ function al.predict_train(line_status, linevar_def, rwtime) 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]) @@ -1012,9 +1061,10 @@ function al.predict_train(line_status, linevar_def, rwtime) track = stop.track or "", stdata = stdata, dep = assert(line_status.linevar_last_dep), - -- arr = nil, + dep_linevar_def = assert(linevar_def), + dep_index = index, + -- arr = nil, arr_index = nil, arr_linevar_def = nil, delay = delay, - index = index, hidden = stop.mode == MODE_HIDDEN }) end @@ -1024,31 +1074,43 @@ function al.predict_train(line_status, linevar_def, rwtime) 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 - table.insert(result, { + local arr = departure + stop.dep + delay + local record = { stn = assert(stop.stn), track = stop.track or "", stdata = stdata, - arr = line_status.linevar_dep + stop.dep + delay, + arr = arr, + arr_linevar_def = linevar_def, + arr_index = index, delay = delay, - index = index, 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 = line_status.linevar_dep + stop.dep + delay, -- TODO... - dep = line_status.linevar_dep + stop.dep + delay, + 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, - index = index, hidden = stop.mode == MODE_HIDDEN, }) end index = index + 1 end + -- print("DEBUG: "..dump2({prediction = prepare_prediction_for_dump(result)})) return result end @@ -1131,36 +1193,44 @@ def = { } core.register_chatcommand("vlaky+", def) --- DEBUG: def = { -- params = "", description = "(pro ladění)", privs = {server = true}, func = function(player_name, param) - print("----") - for linevar, passages in pairs(last_passages) do - print("LINEVAR "..linevar..":") - local linevar_def = al.try_get_linevar_def(linevar) - if linevar_def ~= nil then - local stops = linevar_def.stops - for i, passage in ipairs(passages) do - print(" Passage #"..i..":") - for j, stop in ipairs(stops) do - local s - if passage[j] ~= nil then - s = tostring(passage[j]) - else - s = "-" - end - print(" - "..stop.stn.." = "..s.." ["..j.."]") - end - end + 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 - print("ERROR! definition not found") + dep = "nil" end + result[i + 1] = "- "..record.stn.." ["..record.track.."] arr="..arr.." dep="..dep.." delay="..record.delay end - print("----") + table.insert(result, "----") + s = table.concat(result, "\n") + print(s) + core.chat_send_player(player_name, s) return true end, } -core.register_chatcommand("odjezdy", def) +core.register_chatcommand("jřád", def) +core.register_chatcommand("jrad", def) |