diff options
author | orwell <orwell@bleipb.de> | 2025-07-21 22:46:06 +0200 |
---|---|---|
committer | orwell <orwell@bleipb.de> | 2025-07-21 22:46:06 +0200 |
commit | 615631529ebfe934a66e0a0c57437a89b5d5d2df (patch) | |
tree | 55428348c6dae533a66bed08e8e1095a6ff3b2a2 | |
parent | 97e5554e34cfaa80716969eebee6577e4c4da000 (diff) | |
download | advtrains-615631529ebfe934a66e0a0c57437a89b5d5d2df.tar.gz advtrains-615631529ebfe934a66e0a0c57437a89b5d5d2df.tar.bz2 advtrains-615631529ebfe934a66e0a0c57437a89b5d5d2df.zip |
Linevars: Start timetable explicitly via stoprail departure mode, decouple from train line/RC
-rw-r--r-- | advtrains_line_automation/line_functions.lua | 93 | ||||
-rw-r--r-- | advtrains_line_automation/stoprail.lua | 79 |
2 files changed, 86 insertions, 86 deletions
diff --git a/advtrains_line_automation/line_functions.lua b/advtrains_line_automation/line_functions.lua index 3a369f7..a3be879 100644 --- a/advtrains_line_automation/line_functions.lua +++ b/advtrains_line_automation/line_functions.lua @@ -122,16 +122,21 @@ 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. + chg orwell: added linevar parameter, linevar no longer derived from the line/rc/stn ]] -local function line_start(train, stn, departure_rwtime) +local function line_start(train, stn, departure_rwtime, linevar) + if not linevar then + return false + end 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})) + -- chg orwell: no longer error here, instead cancel previous linevar + al.cancel_linevar(train) end - local linevar, linevar_def = al.try_get_linevar(train.line, stn, train.routingcode) + local linevar_def = al.try_get_linevar_def(linevar, stn) if linevar == nil or linevar_def.disabled then return false end @@ -162,11 +167,6 @@ 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 @@ -194,6 +194,7 @@ local function should_stop(pos, stdata, train) return "true" -- TODO: zastávky na znamení else + -- train not on a timetable local ars = stdata.ars -- vyhovuje vlak ARS pravidlům? local result = ars and (ars.default or advtrains.interlocking.ars_check_rule_match(ars, train)) @@ -218,7 +219,7 @@ 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 + local ls = train.line_status if ls == nil or ls.linevar == nil then return false end ls.linevar = nil ls.linevar_station = nil @@ -523,40 +524,24 @@ local is_visible_mode = al.is_visible_mode -- 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 + 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 + 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 + 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 + return nil, nil end --[[ @@ -599,19 +584,11 @@ function al.get_line_status(train) 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! +function al.on_train_approach(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] @@ -692,7 +669,10 @@ function al.on_train_enter(pos, train_id, train, index) -- naplánovat čas odjezdu local wait = tonumber(stdata.wait) or 0 - local interval = stdata.interval + local interval = nil + if stdata.dep_mode=="interval" or stdata.dep_mode=="ttbegin" then -- TODO: in ttbegin case, the interval should come from tt not from rail + interval = stdata.interval + end local last_dep = stdata.last_dep -- posl. odjezd z této zastávkové koleje if interval ~= nil and last_dep ~= nil then @@ -783,26 +763,23 @@ function al.on_train_enter(pos, train_id, train, index) 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 + if stdata.dep_mode == "ttbegin" then + -- if train may start a new line and departure mode is set to ttbegin, set the new linevar + if line_start(train, stn, planned_departure, stdata.tt_begin_linevar) 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 + 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) diff --git a/advtrains_line_automation/stoprail.lua b/advtrains_line_automation/stoprail.lua index e8de1dc..d1d7c20 100644 --- a/advtrains_line_automation/stoprail.lua +++ b/advtrains_line_automation/stoprail.lua @@ -51,6 +51,9 @@ local function get_stn_dropdown(stn, player_name) return table.concat(result) end +local depmode_to_dropdown = { normal=1, interval=2, ttbegin=3 } +local dropdown_to_depmode = { "normal", "interval", "ttbegin" } + local player_to_stn_override = {} local function show_stoprailform(pos, player) @@ -116,14 +119,37 @@ local function show_stoprailform(pos, player) "label[0.5,8.9;"..S("Depart:").."]".. "field[2,8.6;1.5,0.8;speed;"..S("Speed")..";"..minetest.formspec_escape(stdata.speed).."]".. "tooltip[speed;"..S("Speed that the train sets when departing. Set 'M' for maximum speed.").."]".. - --"label[4,8.4;"..S("Departure Mode").."<NI>]".. - --"dropdown[4,8.6;2.5,0.8;depmode;Normal,Interval,Begin Timetable;2;true]".. - --"tooltip[depmode;"..S("Select the time for departure:\nNormal: depart immediately after the stop time elapsed\nInterval: depart at the next time position set by interval and offset\nBegin Timetable: The train gets the given timetable assigned and departs according to its settings (currently not implemented)").."]".. - "field[7,8.6;1.8,0.8;interval;"..S("Interval:")..";"..minetest.formspec_escape(stdata.interval or "").."]".. - "tooltip[interval;"..S("The interval / time distance between departures in seconds. E.g. every two minutes -> set interval = 120").."]".. - "field[9,8.6;1.8,0.8;ioffset;"..S("Offset:")..";"..minetest.formspec_escape(stdata.ioffset or "0").."]".. - "tooltip[ioffset;"..S("The offset of departures from time 0:00 in seconds. E.g. interval 120 offset 60 -> departure at every odd minute").."]".. - "checkbox[7,10.6;keepopen;"..S("Keep doors open")..";"..(stdata.keepopen and "true" or "false").."]".. + "label[4,8.4;"..S("Departure Mode").."]".. + "dropdown[4,8.6;2.5,0.8;depmode;Normal,Interval,Begin Timetable;"..(depmode_to_dropdown[stdata.dep_mode] or 1)..";true]".. + "tooltip[depmode;"..S("Select the time for departure:\nNormal: depart immediately after the stop time elapsed\nInterval: depart at the next time position set by interval and offset\nBegin Timetable: The train gets the given timetable assigned and departs according to its settings (currently not implemented)").."]" + if stdata.dep_mode == "interval" then + formspec = formspec .. "field[7,8.6;1.8,0.8;interval;"..S("Interval:")..";"..minetest.formspec_escape(stdata.interval or "").."]".. + "tooltip[interval;"..S("The interval / time distance between departures in seconds. E.g. every two minutes -> set interval = 120").."]".. + "field[9,8.6;1.8,0.8;ioffset;"..S("Offset:")..";"..minetest.formspec_escape(stdata.ioffset or "0").."]".. + "tooltip[ioffset;"..S("The offset of departures from time 0:00 in seconds. E.g. interval 120 offset 60 -> departure at every odd minute").."]" + elseif stdata.dep_mode == "ttbegin" then + formspec = formspec .. "field[7,8.6;0.9,0.8;interval;"..S("Interval:")..";"..minetest.formspec_escape(stdata.interval or "").."]".. + "tooltip[interval;"..S("The interval / time distance between departures in seconds. E.g. every two minutes -> set interval = 120").."]".. + "field[8,8.6;0.9,0.8;ioffset;"..S("Offset:")..";"..minetest.formspec_escape(stdata.ioffset or "0").."]".. + "tooltip[ioffset;"..S("The offset of departures from time 0:00 in seconds. E.g. interval 120 offset 60 -> departure at every odd minute").."]" + -- TODO: interval and offset should be defined in the timetable, not here + -- build list of available linevars (it is convenient that linevars are defined in the station) + local avail_linevars = {} + local sel_linevar = 1 + if stn and stn.linevars then + for k,_ in pairs(stn.linevars) do + table.insert(avail_linevars, k) + if stdata.tt_begin_linevar==k then sel_linevar = #avail_linevars end + end + end + if #avail_linevars > 0 then + formspec = formspec .. "label[9,8.4;"..S("TT Linevar:").."]".. + "dropdown[9,8.6;2.0,0.8;tt_begin_linevar;"..table.concat(avail_linevars)..";"..(sel_linevar or 1)..",false]" -- this dropdown NOT using indexing! + else + formspec = formspec .. "label[9,8.6;"..S("No linevars\navailable!").."]" + end + end + formspec = formspec .. "checkbox[7,10.6;keepopen;"..S("Keep doors open")..";"..(stdata.keepopen and "true" or "false").."]".. "tooltip[keepopen;"..S("Do not close the doors when departing, if they are open").."]".. "checkbox[7,9.9;waitsig;"..S("Wait for signal to clear")..";"..(stdata.waitsig and "true" or "false").."]".. "tooltip[waitsig;"..S("Do not depart immediately, instead first enable ARS and wait until the next signal ahead clears (ATC G command) before closing the doors and departing.").."]".. @@ -172,7 +198,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) end end - if fields.save then + if fields.save or (fields.depmode and not fields.editstn) then -- must resend form when depmode dropdown is updated local new_index = player_to_stn_override[pname] if new_index ~= nil then if new_index == 1 then @@ -217,32 +243,29 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) if fields.speed then stdata.speed = to_int(fields.speed) or "M" end + + if fields.depmode then + stdata.dep_mode = dropdown_to_depmode[tonumber(fields.depmode)] + end if fields.interval then - if fields.interval == "" or fields.interval == "0" then - stdata.interval = nil + local n = to_int(fields.interval) + if n and 0 < n and n <= 3600 then + stdata.interval = n else - local n = to_int(fields.interval) - if 0 < n and n <= 3600 then - stdata.interval = n - end + stdata.interval = 60 end end - if stdata.interval == nil then - stdata.ioffset = nil - elseif set_offset ~= nil then - stdata.ioffset = set_offset - elseif fields.ioffset then - if fields.ioffset == "" or fields.ioffset == "0" then - stdata.ioffset = nil + if fields.ioffset then + local n = to_int(fields.ioffset) + if n and n > 0 then + stdata.ioffset = n % stdata.interval else - local n = to_int(fields.ioffset) - if n > 0 then - stdata.ioffset = n % stdata.interval - else - stdata.ioffset = nil - end + stdata.ioffset = 0 end end + if fields.tt_begin_linevar then + stdata.tt_begin_linevar = fields.tt_begin_linevar + end for k,v in pairs(tmp_checkboxes[pe]) do --handle checkboxes stdata[k] = v or nil |