From 34405b8431b7c758988b56cc09d21d6de74b727b Mon Sep 17 00:00:00 2001 From: "Y. Wang" Date: Sat, 13 Aug 2022 21:16:15 +0200 Subject: Allow assigning distant signals from the main signal --- advtrains/formspec.lua | 27 +++++++++++++++++ advtrains_interlocking/distant_ui.lua | 55 +++++++++++++++++++++++++++++++++-- 2 files changed, 80 insertions(+), 2 deletions(-) diff --git a/advtrains/formspec.lua b/advtrains/formspec.lua index 20dab59..58968da 100644 --- a/advtrains/formspec.lua +++ b/advtrains/formspec.lua @@ -32,6 +32,21 @@ local function f_dropdown(x, y, w, id, entries, sel, indexed) indexed and ";true" or "") end +local function f_image_button(x, y, w, h, texture, id, label, noclip, drawborder, pressed) + local st = {string.format("%f,%f;%f,%f;%s;%s;%s", x, y, w, h, fsescape(texture), fsescape(id), fsescape(label))} + if pressed then + st[#st+1] = tostring(noclip or false) + st[#st+1] = tostring(drawborder or false) + st[#st+1] = fsescape(pressed) + end + return sformat("image_button[%s]", table.concat(st, ";")) +end + +local function f_image_button_exit(x, y, w, h, texture, id, label) + local st = {string.format("%f,%f;%f,%f;%s;%s;%s", x, y, w, h, fsescape(texture), fsescape(id), fsescape(label))} + return sformat("image_button_exit[%s]", table.concat(st, ";")) +end + local function f_label(x, y, text) return sformat("label[%f,%f;%s]", x, y, fsescape(text)) end @@ -61,13 +76,25 @@ local function f_tabheader(x, y, w, h, id, entries, sel, transparent, border) return string.format("tabheader[%s]", table.concat(st, ";")) end +local function f_textlist(x, y, w, h, id, entries, sel, transparent) + local st = {string.format("%f,%f;%f,%f;%s;%s", x, y, w, h, id, make_list(entries))} + if sel then + st[#st+1] = tostring(sel) + st[#st+1] = tostring(transparent or false) + end + return string.format("textlist[%s]", table.concat(st, ";")) +end + return { button = f_button, S_button = S_button, button_exit = f_button_exit, S_button_exit = S_button_exit, dropdown = f_dropdown, + image_button = f_image_button, + image_button_exit = f_image_button_exit, label = f_label, S_label = S_label, tabheader = f_tabheader, + textlist = f_textlist, } diff --git a/advtrains_interlocking/distant_ui.lua b/advtrains_interlocking/distant_ui.lua index 4ec2255..e1e14b7 100644 --- a/advtrains_interlocking/distant_ui.lua +++ b/advtrains_interlocking/distant_ui.lua @@ -24,6 +24,16 @@ function advtrains.interlocking.show_distant_signal_form(pos, pname) else form[#form+1] = F.S_button_exit(0.5, 1.5, 6, 1, "assign_dst", "Assign") end + + local dsts = D.get_dst(pos) + local dstlist = {} + for pos, _ in pairs(dsts) do + dstlist[#dstlist+1] = 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.5, "dstlist", dstlist) + form[#form+1] = F.image_button_exit(5.5, 3.5, 1, 1, "cdb_add.png", "dst_add", "") + form[#form+1] = F.image_button_exit(5.5, 5, 1, 1, "cdb_clear.png", "dst_del", "") minetest.show_formspec(pname, "advtrains:distant_" .. minetest.pos_to_string(pos), table.concat(form)) end @@ -37,25 +47,46 @@ local function init_signal_assignment(pname, pos) minetest.chat_send_player(pname, attrans("Please punch the signal to use as the main signal.")) end +local distant_pos = {} +local function init_distant_assignment(pname, pos) + if not minetest.check_player_privs(pname, "interlocking") then + minetest.send_chat_player(pname, attrans("This operation is now allowed without the @1 privilege.", "interlocking")) + return + end + distant_pos[pname] = pos + minetest.chat_send_player(pname, attrans("Please punch the signal to use as the distant signal.")) +end + minetest.register_on_punchnode(function(pos, node, player, pointed_thing) local pname = player:get_player_name() if not minetest.check_player_privs(pname, "interlocking") then return end local spos = signal_pos[pname] + local distant = false if not spos then - return + spos = distant_pos[pname] + if not spos then + return + end + distant = true end signal_pos[pname] = nil + distant_pos[pname] = nil local is_signal = minetest.get_item_group(node.name, "advtrains_signal") >= 2 if not is_signal then minetest.chat_send_player(pname, attrans("Incompatible signal.")) return end minetest.chat_send_player(pname, attrans("Successfully assigned signal.")) - D.assign(pos, spos, "manual") + if distant then + D.assign(spos, pos, "manual") + else + D.assign(pos, spos, "manual") + end 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 "") @@ -72,5 +103,25 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) D.unassign_dst(pos) elseif fields.assign_dst then init_signal_assignment(pname, pos) + elseif fields.dst_add then + init_distant_assignment(pname, pos) + elseif fields.dstlist then + dstsel[pname] = minetest.explode_textlist_event(fields.dstlist).index + elseif fields.dst_del then + local selid = dstsel[pname] + if selid then + local dsts = D.get_dst(pos) + local pos + for p, _ in pairs(dsts) do + selid = selid-1 + if selid <= 0 then + pos = p + break + end + end + if pos then + D.unassign_dst(advtrains.decode_pos(pos)) + end + end end end) -- cgit v1.2.3