diff options
Diffstat (limited to 'advtrains_interlocking/signal_aspect_ui.lua')
-rw-r--r-- | advtrains_interlocking/signal_aspect_ui.lua | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/advtrains_interlocking/signal_aspect_ui.lua b/advtrains_interlocking/signal_aspect_ui.lua new file mode 100644 index 0000000..a81b7fe --- /dev/null +++ b/advtrains_interlocking/signal_aspect_ui.lua @@ -0,0 +1,262 @@ +local F = advtrains.formspec +local players_aspsel = {} + +local function describe_main_aspect(spv) + if spv == 0 then + return attrans("Danger (halt)") + elseif spv == -1 then + return attrans("Continue at maximum speed") + elseif not spv then + return attrans("Continue with current speed limit") + else + return attrans("Continue with the speed limit of @1", tostring(spv)) + end +end + +local function describe_shunt_aspect(shunt) + if shunt then + return attrans("Shunting allowed") + else + return attrans("No shunting") + end +end + +local function describe_distant_aspect(spv) + if spv == 0 then + return attrans("Expect to stop at the next signal") + elseif spv == -1 then + return attrans("Expect to continue at maximum speed") + elseif not spv then + return attrans("No distant signal information") + else + return attrans("Expect to continue with a speed limit of @1", tostring(spv)) + end +end + +advtrains.interlocking.describe_main_aspect = describe_main_aspect +advtrains.interlocking.describe_shunt_aspect = describe_shunt_aspect +advtrains.interlocking.describe_distant_aspect = describe_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(suppasp, isasp) + local t = {} + + local entries = {attrans("Use default value")} + local selid = 0 + local mainasps = suppasp.main + if type(mainasps) ~= "table" then + mainasps = {mainasps} + end + for idx, spv in ipairs(mainasps) do + if isasp and spv == rawget(isasp, "main") then + selid = idx + end + entries[idx+1] = describe_main_aspect(spv) + end + t.main = entries + t.main_current = selid+1 + t.main_string = tostring(isasp.main) + if t.main == nil then + t.main_string = "" + end + + 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 + + if suppasp.group then + local gdef = advtrains.interlocking.aspect.get_group_definition(suppasp.group) + if gdef then + t.group = suppasp.group + t.groupdef = gdef + local entries = {} + local selid = 1 + for idx, name in ipairs(suppasp.name or {}) do + entries[idx] = gdef.aspects[name].label + if suppasp.group == isasp.group and name == isasp.name then + selid = idx + end + end + t.name = entries + t.name_current = selid + end + end + + return t +end + +advtrains.interlocking.describe_supported_aspects = describe_supported_aspects + +local function make_signal_aspect_selector(suppasp, purpose, isasp) + local t = describe_supported_aspects(suppasp, isasp) + local formmode = 1 + + local pos + if type(purpose) == "table" then + formmode = 2 + pos = purpose.pos + end + + local form = { + "formspec_version[4]", + string.format("size[8,%f]", ({5.75, 10.75})[formmode]), + F.S_label(0.5, 0.5, "Select signal aspect"), + } + local h0 = ({0, 1.5})[formmode] + form[#form+1] = F.S_label(0.5, 1.5+h0, "Main aspect") + form[#form+1] = F.S_label(0.5, 3+h0, "Shunt aspect") + form[#form+1] = F.S_button_exit(0.5, 4.5+h0, 7, "asp_save", "Save signal aspect") + if formmode == 1 then + form[#form+1] = F.label(0.5, 1, purpose) + form[#form+1] = F.field(0.5, 2, 7, "asp_mainval", "", t.main_string) + elseif formmode == 2 then + if t.group then + form[#form+1] = F.S_label(0.5, 1.5, "Signal aspect group: @1", t.groupdef.label) + form[#form+1] = F.dropdown(0.5, 2, 7, "asp_namesel", t.name, t.name_current, true) + else + form[#form+1] = F.S_label(0.5, 1.5, "This signal does not belong to a signal aspect group.") + form[#form+1] = F.S_label(0.5, 2, "You can not use a predefined signal aspect.") + end + form[#form+1] = F.S_label(0.5, 1, "Signal at @1", minetest.pos_to_string(pos)) + form[#form+1] = F.dropdown(0.5, 3.5, 7, "asp_mainsel", t.main, t.main_current, true) + form[#form+1] = advtrains.interlocking.make_ip_formspec_component(pos, 0.5, 7, 7) + form[#form+1] = advtrains.interlocking.make_short_dst_formspec_component(pos, 0.5, 8.5, 7) + end + + if formmode == 2 and t.shunt_const then + form[#form+1] = F.label(0.5, 3.5+h0, t.shunt[t.shunt_current]) + form[#form+1] = F.S_label(0.5, 4+h0, "The shunt aspect cannot be changed.") + else + form[#form+1] = F.dropdown(0.5, 3.5+h0, 7, "asp_shunt", t.shunt, t.shunt_current, true) + end + + return table.concat(form) +end + +function advtrains.interlocking.show_signal_aspect_selector(pname, p_suppasp, p_purpose, callback, isasp) + local suppasp = p_suppasp or { + main = {0, -1}, + dst = {false}, + shunt = false, + info = {}, + } + local purpose = p_purpose or "" + local pos + if type(p_purpose) == "table" then + pos = p_purpose + purpose = {pname = pname, pos = pos} + end + + local form = make_signal_aspect_selector(suppasp, purpose, isasp) + if not form then + return + end + + local token = advtrains.random_id() + minetest.show_formspec(pname, "at_il_sigaspdia_"..token, form) + minetest.after(0, function() + players_aspsel[pname] = { + purpose = purpose, + suppasp = suppasp, + callback = callback, + token = token, + } + end) +end + +local function usebool(sup, val, free) + if sup == nil then + return val == free + else + return sup + end +end + +local function get_aspect_from_formspec(suppasp, fields, psl) + local namei, group, name = tonumber(fields.asp_namesel), suppasp.group, nil + local gdef = advtrains.interlocking.aspect.get_group_definition(group) + if gdef then + local names = suppasp.name or {} + name = names[namei] or names[names] + else + group = nil + end + local maini = tonumber(fields.asp_mainsel) + local main = (suppasp.main or {})[(maini or 0)-1] + if not maini then + local mainval = fields.asp_mainval + if mainval == "-1" then + main = -1 + elseif mainval == "x" then + main = false + elseif string.match(mainval, "^%d+$") then + main = tonumber(mainval) + else + main = nil + end + elseif maini <= 1 then + main = nil + 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 advtrains.interlocking.aspect { + main = main, + shunt = shunt, + proceed_as_main = proceed_as_main, + info = {}, + name = name, + group = group, + } +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + local pname = player:get_player_name() + local psl = players_aspsel[pname] + if psl then + if formname == "at_il_sigaspdia_"..psl.token then + local suppasp = psl.suppasp + if fields.asp_save then + local asp + asp = get_aspect_from_formspec(suppasp, fields, psl) + if asp then + 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 + end +end) |