263 lines
6.9 KiB
Lua
263 lines
6.9 KiB
Lua
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)
|