Properly handle repeater signals
This commit is contained in:
parent
34405b8431
commit
30a0f86248
|
@ -4,6 +4,27 @@ local I = advtrains.interlocking
|
|||
local N = advtrains.ndb
|
||||
local pts = advtrains.roundfloorpts
|
||||
|
||||
local signal_aspect_metatable = {
|
||||
__tostring = function(asp)
|
||||
local st = {}
|
||||
if asp.type2group and asp.type2name then
|
||||
table.insert(st, string.format("%q in group %q", asp.type2name, asp.type2group))
|
||||
end
|
||||
if asp.main then
|
||||
table.insert(st, string.format("current %d", asp.main))
|
||||
end
|
||||
if asp.main ~= 0 then
|
||||
if asp.dst then
|
||||
table.insert(st, string.format("next %d", asp.dst))
|
||||
end
|
||||
if asp.proceed_as_main then
|
||||
table.insert(st, "proceed as main")
|
||||
end
|
||||
end
|
||||
return string.format("[%s]", table.concat(st, ", "))
|
||||
end,
|
||||
}
|
||||
|
||||
local get_aspect
|
||||
|
||||
local supposed_aspects = {}
|
||||
|
@ -11,6 +32,9 @@ local supposed_aspects = {}
|
|||
function I.load_supposed_aspects(tbl)
|
||||
if tbl then
|
||||
supposed_aspects = tbl
|
||||
for _, v in pairs(tbl) do
|
||||
setmetatable(v, signal_aspect_metatable)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -41,11 +65,14 @@ end
|
|||
|
||||
local function adjust_aspect(pos, asp)
|
||||
asp = table.copy(I.signal_convert_aspect_if_necessary(asp))
|
||||
setmetatable(asp, signal_aspect_metatable)
|
||||
|
||||
local mainpos = D.get_main(pos)
|
||||
local nxtasp
|
||||
if asp.main ~= 0 and mainpos then
|
||||
if mainpos then
|
||||
nxtasp = get_aspect(mainpos)
|
||||
end
|
||||
if asp.main ~= 0 and mainpos then
|
||||
asp.dst = nxtasp.main
|
||||
else
|
||||
asp.dst = nil
|
||||
|
@ -59,7 +86,10 @@ local function adjust_aspect(pos, asp)
|
|||
if stype == 2 then
|
||||
local group = suppasp.group
|
||||
local name
|
||||
if asp.main ~= 0 and nxtasp and nxtasp.type2group == group and nxtasp.type2name then
|
||||
if suppasp.dst_shift and nxtasp then
|
||||
asp.main = nil
|
||||
name = A.type1_to_type2main(nxtasp, group, suppasp.dst_shift)
|
||||
elseif asp.main ~= 0 and nxtasp and nxtasp.type2group == group and nxtasp.type2name then
|
||||
name = A.get_type2_dst(group, nxtasp.type2name)
|
||||
else
|
||||
name = A.type1_to_type2main(asp, group)
|
||||
|
@ -79,7 +109,7 @@ local function get_real_aspect(pos)
|
|||
local asp = ndef.advtrains.get_aspect(pos, node) or I.DANGER
|
||||
local suppasp = get_supported_aspects(pos)
|
||||
if suppasp.type == 2 then
|
||||
asp = A.type2main_to_type1(suppasp.group, asp)
|
||||
asp = A.type2_to_type1(suppasp, asp)
|
||||
end
|
||||
return adjust_aspect(pos, asp)
|
||||
end
|
||||
|
@ -108,11 +138,6 @@ local function set_aspect(pos, asp, skipdst)
|
|||
if (not skipdst) and aspect_changed then
|
||||
D.update_main(pos)
|
||||
end
|
||||
--[[
|
||||
local dbgmsg = string.format("[%s]set_aspect(%s,%s,%s)", os.clock(), minetest.pos_to_string(pos), minetest.serialize(asp), tostring(skipdst))
|
||||
dbgmsg = debug.traceback(dbgmsg, 2)
|
||||
minetest.chat_send_all(dbgmsg)
|
||||
--]]
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -219,7 +219,7 @@ local function get_aspect_from_formspec_t1(suppasp, fields)
|
|||
end
|
||||
|
||||
local function get_aspect_from_formspec_t2(suppasp, fields)
|
||||
local asp = advtrains.interlocking.aspects.type2main_to_type1(suppasp.group, tonumber(fields.asp))
|
||||
local asp = advtrains.interlocking.aspects.type2_to_type1(suppasp, tonumber(fields.asp))
|
||||
return asp
|
||||
end
|
||||
|
||||
|
|
|
@ -67,7 +67,9 @@ local function get_type2_dst(group, name)
|
|||
return def.main[math.max(1, aspidx-1)].name
|
||||
end
|
||||
|
||||
local function type2main_to_type1(name, asp)
|
||||
local function type2_to_type1(suppasp, asp)
|
||||
local name = suppasp.group
|
||||
local shift = suppasp.dst_shift
|
||||
local def = type2defs[name]
|
||||
if not def then
|
||||
return nil
|
||||
|
@ -78,18 +80,26 @@ local function type2main_to_type1(name, asp)
|
|||
else
|
||||
aspidx = def.main[asp] or 2
|
||||
end
|
||||
local asptbl = def.main[aspidx]
|
||||
local realidx = math.min(#def.main, aspidx+(shift or 0))
|
||||
local asptbl = def.main[realidx]
|
||||
if not asptbl then
|
||||
return nil
|
||||
end
|
||||
if type(asp) == "number" then
|
||||
asp = asptbl.name
|
||||
end
|
||||
local dst = def.main[math.min(#def.main, aspidx+1)].main
|
||||
local main, shunt, dst
|
||||
if shift then
|
||||
dst = asptbl.main
|
||||
else
|
||||
main = asptbl.main
|
||||
shunt = asptbl.shunt
|
||||
dst = def.main[math.min(#def.main, aspidx+1)].main
|
||||
end
|
||||
|
||||
local t = {
|
||||
main = asptbl.main,
|
||||
shunt = asptbl.shunt,
|
||||
main = main,
|
||||
shunt = shunt,
|
||||
proceed_as_main = asptbl.proceed_as_main,
|
||||
type2name = asp,
|
||||
type2group = name,
|
||||
|
@ -101,31 +111,28 @@ local function type2main_to_type1(name, asp)
|
|||
return t
|
||||
end
|
||||
|
||||
local function type1_to_type2main(asp, group)
|
||||
local function type1_to_type2main(asp, group, shift)
|
||||
local def = type2defs[group]
|
||||
if not def then
|
||||
return nil
|
||||
end
|
||||
if group == asp.type2group and def.main[asp.type2name] then
|
||||
return asp.type2name
|
||||
end
|
||||
local t_main = def.main
|
||||
local idx
|
||||
if not asp.main or asp.main == -1 then
|
||||
if group == asp.type2group and t_main[asp.type2name] then
|
||||
idx = t_main[asp.type2name]
|
||||
elseif not asp.main or asp.main == -1 then
|
||||
idx = 1
|
||||
elseif asp.main == 0 then
|
||||
idx = #t_main
|
||||
else
|
||||
idx = math.max(#t_main-1, 1)
|
||||
idx = #t_main-1
|
||||
end
|
||||
return t_main[idx].name
|
||||
return t_main[math.max(1, idx-(shift or 0))].name
|
||||
end
|
||||
|
||||
local function equalp(asp1, asp2)
|
||||
if asp1 == asp2 then -- same reference
|
||||
return true
|
||||
elseif asp1.type2group and asp1.type2group == asp2.type2group then -- type2 with the same group
|
||||
return asp1.type2name == asp2.type2name
|
||||
else
|
||||
for _, k in pairs {"main", "shunt", "dst"} do
|
||||
if asp1[k] ~= asp2[k] then
|
||||
|
@ -133,6 +140,9 @@ local function equalp(asp1, asp2)
|
|||
end
|
||||
end
|
||||
end
|
||||
if asp1.type2group and asp1.type2group == asp2.type2group then
|
||||
return asp1.type2name == asp2.type2name
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
|
@ -144,7 +154,7 @@ return {
|
|||
register_type2 = register_type2,
|
||||
get_type2_definition = get_type2_definition,
|
||||
get_type2_dst = get_type2_dst,
|
||||
type2main_to_type1 = type2main_to_type1,
|
||||
type2_to_type1 = type2_to_type1,
|
||||
type1_to_type2main = type1_to_type2main,
|
||||
equalp = equalp,
|
||||
not_equalp = not_equalp,
|
||||
|
|
|
@ -44,7 +44,7 @@ world.layout {
|
|||
|
||||
describe("API for supposed signal aspects", function()
|
||||
it("should load and save data properly", function()
|
||||
local tbl = {_foo = true}
|
||||
local tbl = {_foo = {}}
|
||||
I.load_supposed_aspects(tbl)
|
||||
assert.same(tbl, I.save_supposed_aspects())
|
||||
end)
|
||||
|
|
|
@ -198,20 +198,24 @@ minetest.register_on_punchnode(function(pos, node, player, pointed_thing)
|
|||
if is_signal then
|
||||
local ndef = minetest.registered_nodes[node.name]
|
||||
if ndef and ndef.advtrains and ndef.advtrains.set_aspect then
|
||||
local tcbs = ildb.get_tcbs(sigd)
|
||||
if tcbs then
|
||||
tcbs.signal = pos
|
||||
if not tcbs.signal_name then
|
||||
tcbs.signal_name = "Signal at "..minetest.pos_to_string(sigd.p)
|
||||
if ndef.advtrains.supported_aspects and not ndef.advtrains.supported_aspects.dst_shift then
|
||||
local tcbs = ildb.get_tcbs(sigd)
|
||||
if tcbs then
|
||||
tcbs.signal = pos
|
||||
if not tcbs.signal_name then
|
||||
tcbs.signal_name = "Signal at "..minetest.pos_to_string(sigd.p)
|
||||
end
|
||||
if not tcbs.routes then
|
||||
tcbs.routes = {}
|
||||
end
|
||||
ildb.set_sigd_for_signal(pos, sigd)
|
||||
minetest.chat_send_player(pname, "Configuring TCB: Successfully assigned signal.")
|
||||
advtrains.interlocking.show_ip_form(pos, pname, true)
|
||||
else
|
||||
minetest.chat_send_player(pname, "Configuring TCB: Internal error, TCBS doesn't exist. Aborted.")
|
||||
end
|
||||
if not tcbs.routes then
|
||||
tcbs.routes = {}
|
||||
end
|
||||
ildb.set_sigd_for_signal(pos, sigd)
|
||||
minetest.chat_send_player(pname, "Configuring TCB: Successfully assigned signal.")
|
||||
advtrains.interlocking.show_ip_form(pos, pname, true)
|
||||
else
|
||||
minetest.chat_send_player(pname, "Configuring TCB: Internal error, TCBS doesn't exist. Aborted.")
|
||||
minetest.chat_send_player(pname, "Configuring TCB: Cannot use distant signal. Aborted.")
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(pname, "Configuring TCB: Cannot use static signals for routesetting. Aborted.")
|
||||
|
|
|
@ -401,6 +401,7 @@ for _, rtab in ipairs {
|
|||
supported_aspects = {
|
||||
type = 2,
|
||||
group = siginfo.typename,
|
||||
dst_shift = siginfo.isdst and 0,
|
||||
},
|
||||
get_aspect = function()
|
||||
return asp
|
||||
|
|
Loading…
Reference in New Issue