aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSingularis <singularis@volny.cz>2025-03-22 16:35:18 +0100
committerorwell <orwell@bleipb.de>2025-05-27 20:22:01 +0200
commit0d641f4b3b1b0208a6f127d6ad8dc552da0ea699 (patch)
treeaae47c12140dd09082fed37dbc2893fe12f28f34
parent4f2bb527d47524fc39460b8a8ce8457af5adc1e7 (diff)
downloadadvtrains-0d641f4b3b1b0208a6f127d6ad8dc552da0ea699.tar.gz
advtrains-0d641f4b3b1b0208a6f127d6ad8dc552da0ea699.tar.bz2
advtrains-0d641f4b3b1b0208a6f127d6ad8dc552da0ea699.zip
[advtrains_line_automation,ch_overrides_gplv3] implementován jízdní řád (ve dvou variantách)
-rw-r--r--README.md2
-rw-r--r--advtrains_line_automation/line_functions.lua141
-rw-r--r--advtrains_line_automation/station_editor.lua663
-rw-r--r--advtrains_line_automation/textures/advtrains_line_automation_jrad.pngbin0 -> 2516 bytes
-rw-r--r--advtrains_line_automation/time_table.lua0
5 files changed, 800 insertions, 6 deletions
diff --git a/README.md b/README.md
index e80e4b5..b64dfb0 100644
--- a/README.md
+++ b/README.md
@@ -51,6 +51,7 @@ Various features and bugfixes have been contributed by:
- gpcf
- Blockhead
- ywang
+- Singularis
Small code contributions:
@@ -84,6 +85,7 @@ Small code contributions:
* Node texture for LuaATC controller: Jeija (from Mesecons)
* Mod Description : hajo
* 45 degree platforms design : Och_Noe
+* advtrains_line_automation_jrad.png : Singularis
#### Sounds:
diff --git a/advtrains_line_automation/line_functions.lua b/advtrains_line_automation/line_functions.lua
index 41776c3..43bde50 100644
--- a/advtrains_line_automation/line_functions.lua
+++ b/advtrains_line_automation/line_functions.lua
@@ -502,6 +502,18 @@ function al.get_delay_description(line_status, linevar_def, rwtime)
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í:
@@ -1027,9 +1039,16 @@ end
--[[
Zadaný vlak musí být linkový.
- Vrací:
+ 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,
+ 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,
@@ -1114,6 +1133,124 @@ function al.predict_train(line_status, linevar_def, rwtime, allow_continue)
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
+ 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
diff --git a/advtrains_line_automation/station_editor.lua b/advtrains_line_automation/station_editor.lua
index a08ccba..5af9005 100644
--- a/advtrains_line_automation/station_editor.lua
+++ b/advtrains_line_automation/station_editor.lua
@@ -1,6 +1,7 @@
local def
local F = minetest.formspec_escape
local ifthenelse = ch_core.ifthenelse
+local rwt = assert(advtrains.lines.rwt)
local function load_stations()
local result = {}
@@ -203,11 +204,12 @@ local function get_formspec(custom_state)
ifthenelse(pinfo.role == "admin", "field[10.5,7;4,0.75;owner;spravuje:;", "label[10.5,6.75;spravuje:\n")..
spravuje.."]")
if pinfo.role ~= "new" then
- table.insert(formspec, "button[0.5,8;4.5,0.75;vytvorit;vytvořit novou]")
+ table.insert(formspec, "button[0.5,8;4.5,0.75;vytvorit;vytvořit novou]"..
+ "button[10,8;4.5,0.75;jrad;jízdní řády...]")
if st and (pinfo.role == "admin" or st.owner == pinfo.player_name) then
table.insert(formspec, "button[5.25,8;4.5,0.75;ulozit;uložit změny]")
if st.tracks[1] == nil then
- table.insert(formspec, "button[12.5,8;2,0.75;smazat;smazat]")
+ table.insert(formspec, "button[15.25,8;3,0.75;smazat;smazat]")
end
end
end
@@ -366,5 +368,658 @@ def = {
privs = {ch_registered_player = true},
func = function(player_name, param) show_formspec(minetest.get_player_by_name(player_name)) end,
}
-minetest.register_chatcommand("zastavky", def)
-minetest.register_chatcommand("zastávky", def)
+core.register_chatcommand("zastavky", def)
+core.register_chatcommand("zastávky", def)
+
+
+-- Jízdní řád
+
+--[[
+ custom_state = {
+ pos = vector or nil, -- node position (will use metadata to determine the owner)
+ player_name = string, -- player to whom the formspec is to be shown (will use this to determine privs)
+ stn = int, -- station selection from stns
+ stns = {
+ {stn = "", fs = "(vyberte dopravnu)", name_fs = ""},
+ {stn = string, fs = string, name_fs = string}...
+ }, -- the list of stations to select from; the first must be "", which means no station
+ track = int, -- selection of track from "tracks" list
+ tracks = {"", string...}, -- the list of tracks to select from; the first must be "", which means all tracks
+ linevar = int,
+ linevars = {{
+ stn = string, -- station from linevar
+ linevar = string, -- linevar
+ line_fs = string, -- line for formspec
+ target_fs = string, -- terminus name for formspec
+ track_fs = string, -- track info for formspec ("" if not available)
+ status_fs = string, -- line status for formspec (including color column)
+ linevar_index = int, -- index of the selected station (stn) in linevar_def.stops of this linevar
+ }...},
+ stop = int,
+ stops = {{
+ stn = string,
+ name_fs = string,
+ track_fs = string,
+ dep = int,
+ wait = int,
+ linevar_index = int, -- index of this stop in linevar_def.stops
+ }...},
+ message = string, -- message for label[] on the bottom; "" to disable
+ }
+]]
+
+local all_stations_record = {stn = "", fs = F("(vyberte dopravnu)"), name_fs = ""}
+local is_visible_mode = assert(advtrains.lines.is_visible_mode)
+
+-- refresh custom_state.stops according to custom_state.linevar
+local function jr_refresh_stops(custom_state, stn_to_select)
+ if stn_to_select == "" then
+ stn_to_select = nil
+ end
+ local linevar_info = custom_state.linevars[custom_state.linevar]
+ local index_to_select = 0
+ local result = {}
+ if linevar_info ~= nil then
+ local linevar_def = advtrains.lines.try_get_linevar_def(linevar_info.linevar, linevar_info.stn)
+ if linevar_def == nil then
+ -- invalid linevar => no stops
+ core.log("error", "Player "..custom_state.player_name.." selected invalid linevar "..linevars[linevar].linevar.."!")
+ else
+ local stops = linevar_def.stops
+ for linevar_index, stop_data in ipairs(linevar_def.stops) do
+ if is_visible_mode(stop_data.mode) then
+ local r = {
+ stn = assert(stop_data.stn),
+ name_fs = F(advtrains.lines.get_station_name(stop_data.stn)),
+ track_fs = stop_data.track or "",
+ dep = stop_data.dep,
+ wait = stop_data.wait or 10,
+ linevar_index = linevar_index,
+ }
+ if r.track_fs ~= "" then
+ r.track_fs = F("["..r.track_fs.."]")
+ end
+ table.insert(result, r)
+ if stn_to_select ~= nil and index_to_select == 0 and r.stn == stn_to_select then
+ index_to_select = #result -- stop selected
+ end
+ end
+ end
+ end
+ end
+ custom_state.stop = index_to_select
+ custom_state.stops = result
+ custom_state.message = ""
+end
+
+local function get_all_linevars()
+ local result = {}
+ local empty_table = {}
+ local trains_by_linevar = advtrains.lines.get_trains_by_linevar()
+ for stn, stdata in pairs(advtrains.lines.stations) do
+ for linevar, linevar_def in pairs(stdata.linevars or empty_table) do
+ local line, stn = advtrains.lines.linevar_decompose(linevar)
+ local target_fs = F(advtrains.lines.get_line_description(linevar_def, {line_number = false, last_stop = true, last_stop_prefix = "",
+ last_stop_uppercase = false, train_name = false}))
+ local status_fs
+ if trains_by_linevar[linevar] ~= nil then
+ status_fs = "#00ff00,v provozu"
+ else
+ status_fs = "#999999,neznámý"
+ end
+ table.insert(result, {
+ stn = stn,
+ linevar = linevar,
+ line_fs = F(line),
+ target_fs = target_fs,
+ track_fs = "",
+ status_fs = status_fs,
+ linevar_index = 1,
+ })
+ end
+ end
+ table.sort(result, function(a, b) return a.linevar < b.linevar end)
+ return result
+end
+
+--[[
+ stn_filter = string,
+ track_filter = string or nil,
+]]
+local function get_linevars_by_filter(stn_filter, track_filter)
+ local result = {}
+ local empty_table = {}
+ local line_description_options = {line_number = false, last_stop = true, last_stop_prefix = "", last_stop_uppercase = false, train_name = false}
+ local trains_by_linevar = advtrains.lines.get_trains_by_linevar()
+ assert(stn_filter)
+ if track_filter == "" then
+ track_filter = nil
+ end
+ for stn, stdata in pairs(advtrains.lines.stations) do
+ for linevar, linevar_def in pairs(stdata.linevars or empty_table) do
+ local last_stop_index = advtrains.lines.get_last_stop(linevar_def, false)
+ if last_stop_index ~= nil then
+ for linevar_index = 1, last_stop_index - 1 do -- NOTE: the last visible station is intentionally ignored here!
+ local stop_data = linevar_def.stops[linevar_index]
+ local initialized = false
+ local line, stn, line_fs, target_fs, status_fs
+ if
+ stop_data.stn == stn_filter and
+ is_visible_mode(stop_data.mode) and
+ (track_filter == nil or track_filter == stop_data.track)
+ then
+ if not initialized then
+ initialized = true
+ line, stn = advtrains.lines.linevar_decompose(linevar)
+ line_fs = F(line)
+ target_fs = F(advtrains.lines.get_line_description(linevar_def, line_description_options))
+ if trains_by_linevar[linevar] ~= nil then
+ status_fs = "#00ff00,v provozu"
+ else
+ status_fs = "#999999,neznámý"
+ end
+ end
+ local track_fs = stop_data.track
+ if track_fs == nil or track_fs == "" then
+ track_fs = ""
+ else
+ track_fs = F("["..track_fs.."]")
+ end
+ table.insert(result, {
+ stn = stn,
+ linevar = linevar,
+ line_fs = line_fs,
+ target_fs = target_fs,
+ track_fs = track_fs,
+ status_fs = status_fs,
+ linevar_index = assert(linevar_index),
+ })
+ end
+ end
+ end
+ end
+ end
+ table.sort(result, function(a, b)
+ if a.linevar ~= b.linevar then
+ return a.linevar < b.linevar
+ else
+ return a.linevar_index < b.linevar_index
+ end
+ end)
+ return result
+end
+
+local function is_jr_node_name(name)
+ return core.get_item_group(name, "ch_jrad") ~= 0
+end
+
+-- refresh custom_state.linevars according to custom_state.stn and custom_state.track
+local function jr_refresh_linevars(custom_state, linevar_to_select, linevar_index_to_select)
+ if linevar_to_select == "" then
+ linevar_to_select = nil
+ end
+ assert(linevar_index_to_select == nil or type(linevar_index_to_select) == "number")
+ local stn = assert(custom_state.stn)
+ local stn_info = assert(custom_state.stns[stn])
+ local track = assert(custom_state.track)
+ local tracks = assert(custom_state.tracks)
+
+ local new_linevars
+ if stn_info.stn == "" then
+ new_linevars = get_all_linevars()
+ else
+ new_linevars = get_linevars_by_filter(stn_info.stn, assert(tracks[track]))
+ end
+ local index_to_select = 1
+ if linevar_to_select ~= nil then
+ for i, r in ipairs(new_linevars) do
+ if r.linevar == linevar_to_select and (linevar_index_to_select == nil or r.linevar_index == linevar_index_to_select) then
+ index_to_select = i
+ break
+ end
+ end
+ end
+ if new_linevars[index_to_select] == nil then
+ index_to_select = 0
+ end
+ custom_state.linevars = new_linevars
+ custom_state.linevar = index_to_select
+ custom_state.message = ""
+
+ local pos = custom_state.pos
+ if pos ~= nil and is_jr_node_name(core.get_node(pos).name) then
+ local meta = core.get_meta(pos)
+ meta:set_string("stn", custom_state.stns[custom_state.stn].stn)
+ meta:set_string("track", custom_state.tracks[custom_state.track])
+ local infotext = {"jízdní řád\n"}
+ if stn_info.stn == "" then
+ table.insert(infotext, "<všechny linky>")
+ else
+ table.insert(infotext, advtrains.lines.get_station_name(stn_info.stn))
+ if custom_state.tracks[custom_state.track] ~= "" then
+ table.insert(infotext, " ["..custom_state.tracks[custom_state.track].."]")
+ end
+ end
+ if new_linevars[1] ~= nil then
+ local prefix = "\n"
+ local set = {[""] = true}
+ for _, linevar_info in ipairs(new_linevars) do
+ local line = advtrains.lines.linevar_decompose(linevar_info.linevar)
+ if not set[line] then
+ set[line] = true
+ table.insert(infotext, prefix.."["..line.."]")
+ prefix = " "
+ end
+ end
+ end
+ meta:set_string("infotext", table.concat(infotext))
+ end
+end
+
+-- refresh custom_state.tracks according to custom_state.stn
+-- and selects a specified track, if available
+local function jr_refresh_tracks(custom_state, track_to_select)
+ if track_to_select == "" then
+ track_to_select = nil
+ end
+ local result = {""}
+ local index_to_select = 1
+ local current_stn = custom_state.stns[custom_state.stn].stn
+ if current_stn ~= "" and advtrains.lines.stations[current_stn] ~= nil then
+ local track_set = {[""] = true}
+ -- search for tracks:
+ for epos, stdata in pairs(advtrains.lines.stops) do
+ if stdata.stn == current_stn and stdata.track ~= nil and not track_set[stdata.track] then
+ track_set[stdata.track] = true
+ table.insert(result, tostring(stdata.track))
+ end
+ end
+ if #result > 1 then
+ table.sort(result)
+ assert(result[1] == "")
+ if track_to_select ~= nil then
+ for i, track in ipairs(result) do
+ if track_to_select == track then
+ index_to_select = i
+ end
+ end
+ end
+ end
+ end
+ custom_state.tracks = result
+ custom_state.track = index_to_select
+ custom_state.message = ""
+end
+
+--[[
+ -- will refresh custom_state.stns[] and (optionally) select a wanted station if it's on the list,
+ -- otherwise the default 'select station' option will be chosen
+ custom_state = table,
+ stn_to_select = string or nil,
+]]
+local function jr_refresh_stns(custom_state, stn_to_select)
+ if stn_to_select == "" then
+ stn_to_select = nil
+ end
+ local result = {all_stations_record}
+ local index_to_select = 1
+ for i, st in ipairs(load_stations()) do
+ result[1 + i] = {
+ stn = assert(st.stn),
+ fs = F(st.stn.." | "..st.name),
+ name_fs = F(st.name),
+ }
+ if stn_to_select ~= nil and st.stn == stn_to_select then
+ index_to_select = 1 + i
+ end
+ end
+ custom_state.stns = result
+ custom_state.stn = index_to_select
+ custom_state.message = ""
+end
+
+-- will refresh a departure message according to linevar + stop
+local function jr_refresh_departure(custom_state)
+ local linevar_info = custom_state.linevars[custom_state.linevar]
+ local stop_info = custom_state.stops[custom_state.stop]
+ if linevar_info == nil or stop_info == nil then
+ custom_state.message = ""
+ return
+ end
+ local linevar_def = advtrains.lines.try_get_linevar_def(linevar_info.linevar)
+ if linevar_def == nil then
+ custom_state.message = ""
+ return
+ end
+ local rwtime = rwt.to_secs(rwt.get_time())
+ local prediction = advtrains.lines.predict_station_departures(linevar_def, assert(stop_info.linevar_index), rwtime)
+ if #prediction == 0 then
+ custom_state.message = "v nejbližší době nenalezeny žádné odjezdy zvolené linky"
+ return
+ end
+ local deps = {}
+ for i, pred in ipairs(prediction) do
+ deps[i] = tostring(pred.dep - rwtime)
+ end
+ custom_state.message = "nejbližší odjezdy zvolené linky za: "..table.concat(deps, ", ").." s"
+end
+
+local function get_jr_formspec(custom_state)
+ local formspec = {
+ ch_core.formspec_header({
+ formspec_version = 6,
+ size = {20, 12},
+ auto_background = true,
+ })
+ }
+ local access_level = "player" -- player | owner | admin
+ local node_owner
+ if custom_state.pos ~= nil then
+ node_owner = core.get_meta(custom_state.pos):get_string("owner")
+ if node_owner == "" then
+ node_owner = nil
+ end
+ end
+ local stn, stn_owner
+ if custom_state.stn > 1 and custom_state.stns[custom_state.stn] ~= nil then
+ stn_owner = (advtrains.lines.stations[custom_state.stns[custom_state.stn].stn] or {}).owner -- may be nil
+ end
+
+ if ch_core.get_player_role(custom_state.player_name) == "admin" then
+ access_level = "admin"
+ elseif custom_state.player_name == node_owner or custom_state.player_name == stn_owner then
+ access_level = "owner"
+ end
+
+ if access_level ~= "player" then
+ -- admin or owner:
+ table.insert(formspec, "label[0.5,0.6;Jízdní řády]"..
+ "dropdown[5,0.3;10,0.6;dopravna;")
+ for i, r in ipairs(custom_state.stns) do
+ table.insert(formspec, ifthenelse(i == 1, r.fs, ","..r.fs))
+ end
+ table.insert(formspec, ";"..custom_state.stn..";true]"..
+ "dropdown[15.25,0.3;3.5,0.6;kolej;")
+ for i, r in ipairs(custom_state.tracks) do
+ if i == 1 then
+ table.insert(formspec, "(všechny koleje)")
+ else
+ table.insert(formspec, ","..F(r))
+ end
+ end
+ table.insert(formspec, ";"..custom_state.track..";true]")
+ else
+ -- player (including 'new' players)
+ local stn_info = custom_state.stns[custom_state.stn]
+ if stn_info.stn == "" then
+ table.insert(formspec, "label[0.5,0.6;Jízdní řády (všechny linky)]")
+ else
+ local track = custom_state.tracks[custom_state.track]
+ if track ~= "" then
+ track = F(" ["..track.."]")
+ end
+ table.insert(formspec, "label[0.5,0.6;"..F("Jízdní řády: ")..stn_info.name_fs..track.."]")
+ end
+ end
+
+ if access_level ~= "admin" then
+ table.insert(formspec, "label[0.5,1.65;vlastník/ice j. řádu: ")
+ if node_owner ~= nil then
+ table.insert(formspec, ch_core.prihlasovaci_na_zobrazovaci(node_owner))
+ else
+ table.insert(formspec, "???")
+ end
+ if stn_owner ~= nil then
+ table.insert(formspec, " | dopravnu spravuje: ")
+ table.insert(formspec, ch_core.prihlasovaci_na_zobrazovaci(stn_owner))
+ end
+ table.insert(formspec, "]")
+ else
+ if node_owner ~= nil then
+ table.insert(formspec, "label[0.5,1.65;vlastník/ice:]"..
+ "field[2.75,1.25;5,0.75;owner;;")
+ table.insert(formspec, ch_core.prihlasovaci_na_zobrazovaci(node_owner))
+ table.insert(formspec, "]button[8,1.25;3,0.75;setowner;nastavit]")
+ end
+ if stn_owner ~= nil then
+ table.insert(formspec, "label[11.25,1.65;dopravnu spravuje: "..ch_core.prihlasovaci_na_zobrazovaci(stn_owner).."]")
+ end
+ end
+
+ table.insert(formspec, "tablecolumns[text,align=right,tooltip=linka;text,width=12,tooltip=cíl;text,tooltip=kolej;color;text,tooltip=stav]"..
+ "table[0.5,2.25;11,5;linka;")
+ for i, r in ipairs(custom_state.linevars) do
+ if i > 1 then
+ table.insert(formspec, ",")
+ end
+ table.insert(formspec, r.line_fs..","..r.target_fs..","..r.track_fs..","..r.status_fs)
+ end
+ table.insert(formspec, ifthenelse(custom_state.linevar > 0, ";"..custom_state.linevar.."]", ";]"))
+ table.insert(formspec, "tablecolumns[text,align=right;text;text]"..
+ "table[12.5,2.25;7,8.75;zastavka;")
+ if custom_state.stops[1] ~= nil then
+ local selected_stop_index = custom_state.stop
+ if custom_state.stops[selected_stop_index] == nil then
+ selected_stop_index = 1
+ end
+ local base_dep
+ for i, r in ipairs(custom_state.stops) do
+ if i > 1 then
+ table.insert(formspec, ",")
+ end
+ if i >= selected_stop_index then
+ if i == selected_stop_index then
+ base_dep = assert(r.dep)
+ table.insert(formspec, "0,")
+ else
+ table.insert(formspec, (r.dep - base_dep)..",")
+ end
+ else
+ table.insert(formspec, " ,")
+ end
+ table.insert(formspec, r.name_fs..","..r.track_fs)
+ end
+ table.insert(formspec, ";"..selected_stop_index.."]")
+ else
+ table.insert(formspec, ";]") -- empty list
+ end
+ table.insert(formspec, "button_exit[18.75,0.3;0.75,0.75;close;X]")
+ if custom_state.message ~= "" then
+ table.insert(formspec, "label[5.25,11.35;"..F(custom_state.message).."]")
+ end
+ table.insert(formspec, "button[0.5,11;4.5,0.75;refresh;zjistit nejbližší odjezdy...]")
+ return table.concat(formspec)
+end
+
+local function jr_formspec_callback(custom_state, player, formname, fields)
+ --[[
+ fields:
+ - dopravna (dropdown)
+ - kolej (dropdown)
+ - owner (field)
+ - setowner (button)
+ - linka (table)
+ - zastavka (table)
+ - close (button_exit)
+ - refresh (button)
+ ]]
+ if fields.dopravna then
+ local new_stn = tonumber(fields.dopravna)
+ if new_stn ~= nil and new_stn ~= custom_state.stn and custom_state.stns[new_stn] ~= nil then
+ custom_state.stn = new_stn
+ local current_track = custom_state.tracks[custom_state.track] or ""
+ local current_linevar_info = custom_state.linevars[custom_state.linevar]
+ jr_refresh_tracks(custom_state, current_track)
+ if current_linevar_info ~= nil then
+ jr_refresh_linevars(custom_state, current_linevar_info.linevar, current_linevar_info.linevar_index)
+ else
+ jr_refresh_linevars(custom_state)
+ end
+ jr_refresh_stops(custom_state, custom_state.stns[new_stn].stn)
+ jr_refresh_departure(custom_state)
+ return get_jr_formspec(custom_state)
+ end
+ end
+ if fields.kolej then
+ local new_track = tonumber(fields.kolej)
+ if new_track ~= nil and new_track ~= custom_state.track and custom_state.tracks[new_track] ~= nil then
+ custom_state.track = new_track
+ local current_linevar_info = custom_state.linevars[custom_state.linevar]
+ if current_linevar_info ~= nil then
+ jr_refresh_linevars(custom_state, current_linevar_info.linevar, current_linevar_info.linevar_index)
+ else
+ jr_refresh_linevars(custom_state)
+ end
+ jr_refresh_stops(custom_state, custom_state.stns[custom_state.stn].stn)
+ jr_refresh_departure(custom_state)
+ return get_jr_formspec(custom_state)
+ end
+ end
+ if fields.setowner then
+ -- TODO: implementovat změnu vlastníka/ice
+ return get_jr_formspec(custom_state)
+ end
+ if fields.linka then
+ local event = core.explode_table_event(fields.linka)
+ local new_line
+ if event.type == "CHG" or event.type == "DCL" then
+ new_line = tonumber(event.row)
+ end
+ if new_line ~= nil and new_line ~= custom_state.linevar then
+ local new_linevar_info = custom_state.linevars[new_line]
+ if new_linevar_info ~= nil then
+ jr_refresh_linevars(custom_state, new_linevar_info.linevar, new_linevar_info.linevar_index)
+ else
+ jr_refresh_linevars(custom_state)
+ end
+ jr_refresh_stops(custom_state, custom_state.stns[custom_state.stn].stn)
+ jr_refresh_departure(custom_state)
+ return get_jr_formspec(custom_state)
+ end
+ end
+ if fields.zastavka then
+ local event = core.explode_table_event(fields.zastavka)
+ if event.type == "CHG" or event.type == "DCL" then
+ local new_stop = tonumber(event.row)
+ if new_stop ~= nil and new_stop ~= custom_state.stop and custom_state.stops[new_stop] ~= nil then
+ custom_state.stop = new_stop
+ if event.type == "DCL" then
+ jr_refresh_departure(custom_state)
+ end
+ return get_jr_formspec(custom_state)
+ end
+ end
+ end
+ if fields.refresh then
+ jr_refresh_departure(custom_state)
+ return get_jr_formspec(custom_state)
+ end
+end
+
+local function show_jr_formspec(player, pos, stn, track, linevar, stop_stn)
+ assert(core.is_player(player))
+ local custom_state = {
+ player_name = player:get_player_name(),
+ stn = 1,
+ stns = {all_stations_record},
+ track = 1,
+ tracks = {""},
+ linevar = 0,
+ linevars = {},
+ stop = 0,
+ stops = {},
+ message = "",
+ }
+ if pos ~= nil then
+ custom_state.pos = pos
+ end
+ jr_refresh_stns(custom_state, stn)
+ jr_refresh_tracks(custom_state, track)
+ jr_refresh_linevars(custom_state, linevar)
+ if stop_stn == nil then
+ stop_stn = custom_state.stns[custom_state.stn].stn
+ end
+ jr_refresh_stops(custom_state, stop_stn)
+ jr_refresh_departure(custom_state)
+
+ -- show formspec:
+ return ch_core.show_formspec(player, "advtrains_line_automation:jizdni_rad",
+ get_jr_formspec(custom_state), jr_formspec_callback, custom_state, {})
+end
+
+local visual_scale = 15/16
+local node_box = {type = "fixed", fixed = {
+ -16/32, -16/32, 15/32 / visual_scale,
+ 16/32, 16/32, 16/32 / visual_scale,
+}}
+local sbox = {type = "fixed", fixed = {
+ -16/32 * visual_scale, -16/32 * visual_scale, 15/32,
+ 16/32 * visual_scale, 16/32 * visual_scale, 16/32,
+}}
+
+local def = {
+ description = "jízdní řád",
+ drawtype = "nodebox",
+ node_box = node_box,
+ selection_box = sbox,
+ collision_box = sbox,
+ tiles = {
+ {name = "ch_core_white_pixel.png^[multiply:#aaaaaa"},
+ {name = "ch_core_white_pixel.png^[multiply:#aaaaaa"},
+ {name = "ch_core_white_pixel.png^[multiply:#aaaaaa"},
+ {name = "ch_core_white_pixel.png^[multiply:#aaaaaa"},
+ {name = "advtrains_line_automation_jrad.png"},
+ {name = "advtrains_line_automation_jrad.png"},
+ },
+ paramtype = "light",
+ paramtype2 = "4dir",
+ sunlight_propagates = true,
+ groups = {cracky = 3, ch_jrad = 1},
+ sounds = default.node_sound_metal_defaults(),
+ visual_scale = visual_scale,
+ after_place_node = function(pos, placer, itemstack, pointed_thing)
+ local player_name = placer and placer:get_player_name()
+ if player_name ~= nil then
+ local meta = core.get_meta(pos)
+ meta:set_string("infotext", "jízdní řád")
+ meta:set_string("owner", player_name)
+ end
+ end,
+ can_dig = function(pos, player)
+ if player == nil then
+ return false
+ end
+ local player_name = player:get_player_name()
+ if ch_core.get_player_role(player_name) == "admin" then
+ return true
+ end
+ if core.is_protected(pos, player_name) then
+ core.record_protection_violation(pos, player_name)
+ return false
+ end
+ local meta = core.get_meta(pos)
+ local owner = meta:get_string("owner")
+ return owner == "" or owner == player_name
+ end,
+ on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
+ if clicker ~= nil and core.is_player(clicker) then
+ local meta = core.get_meta(pos)
+ show_jr_formspec(clicker, pos, meta:get_string("stn"), meta:get_string("track"))
+ end
+ end,
+}
+
+core.register_node("advtrains_line_automation:jrad", table.copy(def))
+def.description = "jízdní řád (na tyč)"
+def.node_box = {type = "fixed", fixed = {
+ -16/32, -16/32, 27/32 / visual_scale,
+ 16/32, 16/32, 28/32 / visual_scale,
+}}
+def.selection_box = {type = "fixed", fixed = {
+ -16/32 * visual_scale, -16/32 * visual_scale, 27/32,
+ 16/32 * visual_scale, 16/32 * visual_scale, 28/32,
+}}
+def.collision_box = def.selection_box
+def.tiles = table.copy(def.tiles)
+def.tiles[5] = def.tiles[1]
+core.register_node("advtrains_line_automation:jrad_on_pole", def)
diff --git a/advtrains_line_automation/textures/advtrains_line_automation_jrad.png b/advtrains_line_automation/textures/advtrains_line_automation_jrad.png
new file mode 100644
index 0000000..627ddf8
--- /dev/null
+++ b/advtrains_line_automation/textures/advtrains_line_automation_jrad.png
Binary files differ
diff --git a/advtrains_line_automation/time_table.lua b/advtrains_line_automation/time_table.lua
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/advtrains_line_automation/time_table.lua