aboutsummaryrefslogtreecommitdiff
path: root/advtrains_interlocking
diff options
context:
space:
mode:
Diffstat (limited to 'advtrains_interlocking')
-rw-r--r--advtrains_interlocking/distant_ui.lua76
-rw-r--r--advtrains_interlocking/signal_api.lua75
-rw-r--r--advtrains_interlocking/signal_aspect_ui.lua232
-rwxr-xr-xadvtrains_interlocking/tcb_ts_ui.lua5
4 files changed, 227 insertions, 161 deletions
diff --git a/advtrains_interlocking/distant_ui.lua b/advtrains_interlocking/distant_ui.lua
index a7ff406..0907684 100644
--- a/advtrains_interlocking/distant_ui.lua
+++ b/advtrains_interlocking/distant_ui.lua
@@ -2,39 +2,52 @@ local F = advtrains.formspec
local D = advtrains.distant
local I = advtrains.interlocking
-function advtrains.interlocking.show_distant_signal_form(pos, pname)
- local form = {"size[7,6.5]"}
- form[#form+1] = advtrains.interlocking.make_signal_formspec_tabheader(pname, pos, 7, 3)
+function I.make_short_dst_formspec_component(pos, x, y, w)
local main, set_by = D.get_main(pos)
if main then
local pts_main = minetest.pos_to_string(main)
- form[#form+1] = F.S_label(0.5, 0.5, "This signal is a distant signal of @1.", pts_main)
+ local desc = attrans("The assignment is made with an unknown method.")
if set_by == "manual" then
- form[#form+1] = F.S_label(0.5, 1, "The assignment is made manually.")
+ desc = attrans("The assignment is made manually.")
elseif set_by == "routesetting" then
- form[#form+1] = F.S_label(0.5, 1, "The assignment is made by the routesetting system.")
+ desc = attrans("The assignment is made by the routesetting system.")
end
+ return table.concat {
+ F.S_label(x, y, "This signal is a distant signal of @1.", pts_main),
+ F.label(x, y+0.5, desc),
+ F.S_button_exit(x, y+1, w/2-0.125, "dst_assign", "Reassign"),
+ F.S_button_exit(x+w/2+0.125, y+1, w/2-0.125, "dst_unassign", "Unassign"),
+ }
else
- form[#form+1] = F.S_label(0.5, 0.5, "This signal is not assigned to a main signal.")
- form[#form+1] = F.S_label(0.5, 1, "The distant aspect of the signal is not used.")
- end
- if set_by ~= nil then
- form[#form+1] = F.S_button_exit(0.5, 1.5, 3, 1, "unassign_dst", "Unassign")
- form[#form+1] = F.S_button_exit(3.5, 1.5, 3, 1, "assign_dst", "Reassign")
- else
- form[#form+1] = F.S_button_exit(0.5, 1.5, 6, 1, "assign_dst", "Assign")
+ return table.concat {
+ F.S_label(x, y, "This signal is not assigned to a main signal."),
+ F.S_label(x, y+0.5, "The distant aspect of the signal is not used."),
+ F.S_button_exit(x, y+1, w, "dst_assign", "Assign")
+ }
end
+end
- local dsts = D.get_dst(pos)
+function I.make_dst_list_formspec_component(pos, x, y, w, h)
+ local ymid = y+0.25+h/2
local dstlist = {}
- for pos, _ in pairs(dsts) do
- dstlist[#dstlist+1] = minetest.pos_to_string(advtrains.decode_pos(pos))
+ for pos, _ in pairs(D.get_dst(pos)) do
+ table.insert(dstlist, minetest.pos_to_string(advtrains.decode_pos(pos)))
end
- form[#form+1] = F.S_label(0.5, 2.5, "This signal has the following distant signals:")
- form[#form+1] = F.textlist(0.5, 3, 4.5, 3, "dstlist", dstlist)
- form[#form+1] = F.image_button_exit(5.5, 3.25, 1, 1, "cdb_add.png", "dst_add", "")
- form[#form+1] = F.image_button_exit(5.5, 4.75, 1, 1, "cdb_clear.png", "dst_del", "")
- minetest.show_formspec(pname, "advtrains:distant_" .. minetest.pos_to_string(pos), table.concat(form))
+ return table.concat {
+ F.S_label(x, y, "Distant signals:"),
+ F.textlist(x, y+0.5, w-1, h-0.5, "dstlist", dstlist),
+ F.image_button_exit(x+w-0.75, ymid-0.875, 0.75, 0.75, "cdb_add.png", "dst_add", ""),
+ F.image_button_exit(x+w-0.75, ymid+0.125, 0.75, 0.75, "cdb_clear.png", "dst_del", ""),
+ }
+end
+
+function I.make_dst_formspec_component(pos, x, y, w, h)
+ return I.make_short_dst_formspec_component(pos, x, y, w, h)
+ .. I.make_dst_list_formspec_component(pos, x, y+2, w, h-2)
+end
+
+function I.show_distant_signal_form(pos, pname)
+ return I.show_ip_form(pos, pname)
end
local signal_pos = {}
@@ -87,21 +100,14 @@ minetest.register_on_punchnode(function(pos, node, player, pointed_thing)
end)
local dstsel = {}
-minetest.register_on_player_receive_fields(function(player, formname, fields)
- local pname = player:get_player_name()
- local pos = minetest.string_to_pos(string.match(formname, "^advtrains:distant_(.+)$") or "")
- if not pos then
- return
- end
- if not minetest.check_player_privs(pname, "interlocking") then
+
+function advtrains.interlocking.handle_dst_formspec_fields(pname, pos, fields)
+ if not (pos and minetest.check_player_privs(pname, "interlocking")) then
return
end
- if advtrains.interlocking.handle_signal_formspec_tabheader_fields(pname, fields) then
- return true
- end
- if fields.unassign_dst then
+ if fields.dst_unassign then
D.unassign_dst(pos)
- elseif fields.assign_dst then
+ elseif fields.dst_assign then
init_signal_assignment(pname, pos)
elseif fields.dst_add then
init_distant_assignment(pname, pos)
@@ -124,4 +130,4 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
end
end
end
-end)
+end
diff --git a/advtrains_interlocking/signal_api.lua b/advtrains_interlocking/signal_api.lua
index 8bb92bf..cd408d7 100644
--- a/advtrains_interlocking/signal_api.lua
+++ b/advtrains_interlocking/signal_api.lua
@@ -1,5 +1,7 @@
-- Signal API implementation
+local F = advtrains.formspec
+
local DANGER = {
main = 0,
shunt = false,
@@ -131,57 +133,68 @@ local function ipmarker(ipos, connid)
})
end
--- shows small info form for signal IP state/assignment
+function advtrains.interlocking.make_ip_formspec_component(pos, x, y, w)
+ advtrains.interlocking.db.check_for_duplicate_ip(pos)
+ local pts, connid = advtrains.interlocking.db.get_ip_by_signalpos(pos)
+ if pts then
+ return table.concat {
+ F.S_label(x, y, "Influence point is set at @1.", string.format("%s/%s", pts, connid)),
+ F.S_button_exit(x, y+0.5, w/2-0.125, "ip_set", "Modify"),
+ F.S_button_exit(x+w/2+0.125, y+0.5, w/2-0.125, "ip_clear", "Clear"),
+ }, pts, connid
+ else
+ return table.concat {
+ F.S_label(x, y, "Influence point is not set."),
+ F.S_button_exit(x, y+0.5, w, "ip_set", "Set influence point"),
+ }
+ end
+end
+
+-- shows small info form for signal properties
+-- This function is named show_ip_form because it was originally only intended
+-- for assigning/changing the influence point.
-- only_notset: show only if it is not set yet (used by signal tcb assignment)
function advtrains.interlocking.show_ip_form(pos, pname, only_notset)
if not minetest.check_player_privs(pname, "interlocking") then
return
end
- local form = "size[7,6.5]label[0.5,0.5;Signal at "..minetest.pos_to_string(pos).."]"
- local node = advtrains.ndb.get_node(pos)
- local ndef = minetest.registered_nodes[node.name] or {}
- if ndef.advtrains and ndef.advtrains.set_aspect then
- form = form .. advtrains.interlocking.make_signal_formspec_tabheader(pname, pos, 7, 2)
- end
- advtrains.interlocking.db.check_for_duplicate_ip(pos)
- local pts, connid = advtrains.interlocking.db.get_ip_by_signalpos(pos)
+ local ipform, pts, connid = advtrains.interlocking.make_ip_formspec_component(pos, 0.5, 0.5, 7)
+ local form = table.concat {
+ "formspec_version[4]",
+ "size[8,6.75]",
+ ipform,
+ advtrains.interlocking.make_dst_formspec_component(pos, 0.5, 2, 7, 4.25),
+ }
if pts then
- form = form.."label[0.5,1.5;Influence point is set at "..pts.."/"..connid.."]"
- form = form.."button_exit[0.5,4.25; 6,1;set;Move]"
- form = form.."button_exit[0.5,5.25; 6,1;clear;Clear]"
local ipos = minetest.string_to_pos(pts)
ipmarker(ipos, connid)
- else
- form = form.."label[0.5,1.5;Influence point is not set.]"
- form = form.."label[0.5,2.0;It is recommended to set an influence point.]"
- form = form.."label[0.5,2.5;This is the point where trains will obey the signal.]"
-
- form = form.."button_exit[0.5,5.25; 6,1;set;Set]"
end
if not only_notset or not pts then
- minetest.show_formspec(pname, "at_il_ipassign_"..minetest.pos_to_string(pos), form)
+ minetest.show_formspec(pname, "at_il_propassign_"..minetest.pos_to_string(pos), form)
end
end
-minetest.register_on_player_receive_fields(function(player, formname, fields)
- local pname = player:get_player_name()
- if advtrains.interlocking.handle_signal_formspec_tabheader_fields(pname, fields) then
- return true
- end
- if not minetest.check_player_privs(pname, {train_operator=true, interlocking=true}) then
+function advtrains.interlocking.handle_ip_formspec_fields(pname, pos, fields)
+ if not (pos and minetest.check_player_privs(pname, {train_operator=true, interlocking=true})) then
return
end
- local pts = string.match(formname, "^at_il_ipassign_([^_]+)$")
+ if fields.ip_set then
+ advtrains.interlocking.signal_init_ip_assign(pos, pname)
+ elseif fields.ip_clear then
+ advtrains.interlocking.db.clear_ip_by_signalpos(pos)
+ end
+end
+
+minetest.register_on_player_receive_fields(function(player, formname, fields)
+ local pname = player:get_player_name()
+ local pts = string.match(formname, "^at_il_propassign_([^_]+)$")
local pos
if pts then
pos = minetest.string_to_pos(pts)
end
if pos then
- if fields.set then
- advtrains.interlocking.signal_init_ip_assign(pos, pname)
- elseif fields.clear then
- advtrains.interlocking.db.clear_ip_by_signalpos(pos)
- end
+ advtrains.interlocking.handle_ip_formspec_fields(pname, pos, fields)
+ advtrains.interlocking.handle_dst_formspec_fields(pname, pos, fields)
end
end)
diff --git a/advtrains_interlocking/signal_aspect_ui.lua b/advtrains_interlocking/signal_aspect_ui.lua
index 6de21e6..ddab793 100644
--- a/advtrains_interlocking/signal_aspect_ui.lua
+++ b/advtrains_interlocking/signal_aspect_ui.lua
@@ -37,6 +37,20 @@ advtrains.interlocking.describe_t1_main_aspect = describe_t1_main_aspect
advtrains.interlocking.describe_t1_shunt_aspect = describe_t1_shunt_aspect
advtrains.interlocking.describe_t1_distant_aspect = describe_t1_distant_aspect
+local function dsel(p, q, x, y)
+ if p == nil then
+ if q then
+ return x
+ else
+ return y
+ end
+ elseif p then
+ return x
+ else
+ return y
+ end
+end
+
local function describe_supported_aspects_t1(suppasp, isasp)
local t = {}
@@ -50,11 +64,22 @@ local function describe_supported_aspects_t1(suppasp, isasp)
end
t.main = entries
t.main_current = selid
+ t.main_string = tostring(isasp.main)
+ if t.main == nil then
+ t.main_string = ""
+ end
- if suppasp.shunt == nil then
- t.shunt = true
- t.shunt_current = isasp and isasp.shunt
+ t.shunt = {
+ attrans("No shunting"),
+ attrans("Shunting allowed"),
+ attrans("Proceed as main"),
+ }
+
+ t.shunt_current = dsel(suppasp.shunt, isasp.shunt, 2, 1)
+ if dsel(suppasp.proceed_as_main, isasp.proceed_as_main, t.shunt_current == 1) then
+ t.shunt_current = 3
end
+ t.shunt_const = suppasp.shunt ~= nil
entries = {}
selid = 1
@@ -71,96 +96,98 @@ end
advtrains.interlocking.describe_supported_aspects_t1 = describe_supported_aspects_t1
-local signal_tabheader_map = {}
-
-local function make_signal_formspec_tabheader(pname, pos, width, selid)
- signal_tabheader_map[pname] = pos
- local firstlabel = attrans("Signal aspect")
- if advtrains.interlocking.db.get_sigd_for_signal(pos) then
- firstlabel = attrans("Routesetting")
- end
- local options = {
- firstlabel,
- attrans("Influence point"),
- attrans("Distant signalling"),
- }
- return F.tabheader(0, 0, nil, nil, "signal_tab", options, selid)
-end
-
-local function handle_signal_formspec_tabheader_fields(pname, fields)
- local n = tonumber(fields.signal_tab)
- local pos = signal_tabheader_map[pname]
- if not (n and pos) then
- return false
- end
- if n == 1 then
- local node = advtrains.ndb.get_node(pos)
- advtrains.interlocking.show_signal_form(pos, node, pname)
- elseif n == 2 then
- advtrains.interlocking.show_ip_form(pos, pname)
- elseif n == 3 then
- advtrains.interlocking.show_distant_signal_form(pos, pname)
- end
- return true
-end
-
-advtrains.interlocking.make_signal_formspec_tabheader = make_signal_formspec_tabheader
-advtrains.interlocking.handle_signal_formspec_tabheader_fields = handle_signal_formspec_tabheader_fields
-
local function make_signal_aspect_selector_t1(suppasp, purpose, isasp)
- local form = {"size[7,6.5]"}
local t = describe_supported_aspects_t1(suppasp, isasp)
+ local formmode = 1
+
+ local pos
if type(purpose) == "table" then
- form[#form+1] = make_signal_formspec_tabheader(purpose.pname, purpose.pos, 7, 1)
- purpose = ""
+ formmode = 2
+ pos = purpose.pos
end
- form[#form+1] = F.S_label(0.5, 0.5, "Select signal aspect")
- form[#form+1] = F.label(0.5, 1, purpose)
- form[#form+1] = F.S_label(0.5, 1.5, "Main aspect")
- form[#form+1] = F.dropdown(0.5, 2, 6, "main", t.main, t.main_current, true)
+ local form = {
+ "formspec_version[4]",
+ string.format("size[8,%f]", ({5.75, 9.25})[formmode]),
+ F.S_label(0.5, 0.5, "Select signal aspect"),
+ }
+ if formmode == 1 then
+ form[#form+1] = F.label(0.5, 1, purpose)
+ else
+ form[#form+1] = F.S_label(0.5, 1, "Signal at @1", minetest.pos_to_string(pos))
+ end
- form[#form+1] = F.S_label(0.5, 3, "Distant aspect")
- form[#form+1] = F.dropdown(0.5, 3.5, 6, "dst", t.dst, t.dst_current, true)
+ form[#form+1] = F.S_label(0.5, 1.5, "Main aspect")
+ if formmode == 1 then
+ form[#form+1] = F.field(0.5, 2, 7, "asp_mainval", "", t.main_string)
+ else
+ form[#form+1] = F.dropdown(0.5, 2, 7, "asp_mainsel", t.main, t.main_current, true)
+ end
- if t.shunt then
- form[#form+1] = F.S_checkbox(0.5, 4.25, "shunt", t.shunt_current, "Allow shunting")
+ form[#form+1] = F.S_label(0.5, 3, "Shunt aspect")
+ if formmode == 2 and t.shunt_const then
+ form[#form+1] = F.label(0.5, 3.5, t.shunt[t.shunt_current])
+ form[#form+1] = F.S_label(0.5, 4, "The shunt aspect cannot be changed.")
else
- form[#form+1] = F.S_label(0.5, 4.5, "The shunt aspect cannot be changed.")
+ form[#form+1] = F.dropdown(0.5, 3.5, 7, "asp_shunt", t.shunt, t.shunt_current, true)
+ end
+
+ form[#form+1] = F.S_button_exit(0.5, 4.5, 7, "asp_save", "Save signal aspect")
+
+ if formmode == 2 then
+ form[#form+1] = advtrains.interlocking.make_ip_formspec_component(pos, 0.5, 5.5, 7)
+ form[#form+1] = advtrains.interlocking.make_short_dst_formspec_component(pos, 0.5, 7, 7)
end
- form[#form+1] = F.S_button_exit(0.5, 5.25, 6, 1, "save", "Save signal aspect")
return table.concat(form)
end
local function make_signal_aspect_selector_t2(suppasp, purpose, isasp)
- local form = {"size[7,6.5]"}
local def = advtrains.interlocking.aspects.get_type2_definition(suppasp.group)
if not def then
return nil
end
+ local formmode = 1
+
+ local pos
if type(purpose) == "table" then
- form[#form+1] = make_signal_formspec_tabheader(purpose.pname, purpose.pos, 7, 1)
- purpose = ""
+ formmode = 2
+ pos = purpose.pos
+ end
+ local form = {
+ "formspec_version[4]",
+ string.format("size[8,%f]", ({4.25, 10.25})[formmode]),
+ F.S_label(0.5, 0.5, "Select signal aspect")
+ }
+ if formmode == 1 then
+ form[#form+1] = F.label(0.5, 1, purpose)
+ else
+ form[#form+1] = F.S_label(0.5, 1, "Signal at @1", minetest.pos_to_string(pos))
end
- form[#form+1] = F.S_label(0.5, 0.5, "Select signal aspect")
- form[#form+1] = F.label(0.5, 1, purpose)
local entries = {}
- local selid = 1
- for idx, spv in ipairs(def.main) do
- if isasp and isasp.type2name == spv.name then
- selid = idx
+ local selid = #def.main
+ if isasp then
+ if isasp.type2name ~= def.main[selid].name then
+ selid = 1
end
- entries[idx] = spv.label
end
+ if selid > 1 then
+ selid = 2
+ end
+ local entries = {
+ def.main[1].label,
+ def.main[#def.main].label,
+ }
form[#form+1] = F.S_label(0.5, 1.5, "Signal group: @1", def.label)
- form[#form+1] = F.dropdown(0.5, 2, 6, "asp", entries, selid, true)
- form[#form+1] = F.S_label(0.5, 3, "Aspect in effect:")
- form[#form+1] = F.label(0.5, 3.5, describe_t1_main_aspect(isasp.main))
- form[#form+1] = F.label(0.5, 4, describe_t1_distant_aspect(isasp.dst))
- form[#form+1] = F.label(0.5, 4.5, describe_t1_shunt_aspect(isasp.shunt))
- form[#form+1] = F.S_button_exit(0.5, 5.25, 6, 1, "save", "Save signal aspect")
+ form[#form+1] = F.dropdown(0.5, 2, 7, "asp_sel", entries, selid, true)
+ form[#form+1] = F.S_button_exit(0.5, 3, 7, "asp_save", "Save signal aspect")
+
+ if formmode == 2 then
+ form[#form+1] = advtrains.interlocking.make_ip_formspec_component(pos, 0.5, 4, 7)
+ form[#form+1] = advtrains.interlocking.make_dst_formspec_component(pos, 0.5, 5.5, 7, 4.25)
+ end
+
return table.concat(form)
end
@@ -188,13 +215,14 @@ function advtrains.interlocking.show_signal_aspect_selector(pname, p_suppasp, p_
local token = advtrains.random_id()
minetest.show_formspec(pname, "at_il_sigaspdia_"..token, form)
- --minetest.after(1, function()
- players_aspsel[pname] = {
- suppasp = suppasp,
- callback = callback,
- token = token,
- }
- --end)
+ minetest.after(0, function()
+ players_aspsel[pname] = {
+ purpose = purpose,
+ suppasp = suppasp,
+ callback = callback,
+ token = token,
+ }
+ end)
end
local function usebool(sup, val, free)
@@ -206,20 +234,45 @@ local function usebool(sup, val, free)
end
local function get_aspect_from_formspec_t1(suppasp, fields, psl)
- local maini = tonumber(fields.main)
- if not maini then return end
- local dsti = tonumber(fields.dst)
- if not dsti then return end
+ local maini = tonumber(fields.asp_mainsel)
+ local main = suppasp.main[maini]
+ if not maini then
+ local mainval = fields.asp_mainval
+ if mainval == "-1" then
+ main = -1
+ elseif string.match(mainval, "^%d+$") then
+ main = tonumber(mainval)
+ else
+ main = nil
+ end
+ end
+ local shunti = tonumber(fields.asp_shunt)
+ local shunt = suppasp.shunt
+ if shunt == nil then
+ shunt = shunti == 2
+ end
+ local proceed_as_main = suppasp.proceed_as_main
+ if proceed_as_main == nil then
+ proceed_as_main = shunti == 3
+ end
return {
- main = suppasp.main[maini],
- dst = suppasp.dst[dsti],
- shunt = usebool(suppasp.shunt, psl.shunt, "true"),
+ main = main,
+ shunt = shunt,
+ proceed_as_main = proceed_as_main,
info = {},
}
end
local function get_aspect_from_formspec_t2(suppasp, fields, psl)
- local asp = advtrains.interlocking.aspects.type2_to_type1(suppasp, tonumber(fields.asp))
+ local sel = tonumber(fields.asp_sel)
+ local def = advtrains.interlocking.aspects.get_type2_definition(suppasp.group)
+ if not (sel and def) then
+ return
+ end
+ if sel ~= 1 then
+ sel = #def.main
+ end
+ local asp = advtrains.interlocking.aspects.type2_to_type1(suppasp, sel)
return asp
end
@@ -229,13 +282,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
if psl then
if formname == "at_il_sigaspdia_"..psl.token then
local suppasp = psl.suppasp
- if handle_signal_formspec_tabheader_fields(pname, fields) then
- return true
- end
- if fields.shunt then
- psl.shunt = fields.shunt
- end
- if fields.save then
+ if fields.asp_save then
local asp
if suppasp.type == 2 then
asp = get_aspect_from_formspec_t2(suppasp, fields, psl)
@@ -246,6 +293,11 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
psl.callback(pname, asp)
end
end
+ if type(psl.purpose) == "table" then
+ local pos = psl.purpose.pos
+ advtrains.interlocking.handle_ip_formspec_fields(pname, pos, fields)
+ advtrains.interlocking.handle_dst_formspec_fields(pname, pos, fields)
+ end
else
players_aspsel[pname] = nil
end
diff --git a/advtrains_interlocking/tcb_ts_ui.lua b/advtrains_interlocking/tcb_ts_ui.lua
index 3898d73..9aea18c 100755
--- a/advtrains_interlocking/tcb_ts_ui.lua
+++ b/advtrains_interlocking/tcb_ts_ui.lua
@@ -614,7 +614,6 @@ function advtrains.interlocking.show_signalling_form(sigd, pname, sel_rte, calle
if not tcbs.routes then tcbs.routes = {} end
local form = "size[7,10.25]label[0.5,0.5;Signal at "..minetest.pos_to_string(sigd.p).."]"
- form = form .. advtrains.interlocking.make_signal_formspec_tabheader(pname, tcbs.signal, 7, 1)
form = form.."field[0.8,1.5;5.2,1;name;Signal name;"..minetest.formspec_escape(tcbs.signal_name).."]"
form = form.."button[5.5,1.2;1,1;setname;Set]"
@@ -708,10 +707,6 @@ end
minetest.register_on_player_receive_fields(function(player, formname, fields)
local pname = player:get_player_name()
- if string.find(formname, "^at_il_signalling_")
- and advtrains.interlocking.handle_signal_formspec_tabheader_fields(pname, fields) then
- return true
- end
if not minetest.check_player_privs(pname, "train_operator") then
return
end