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 N = advtrains.ndb
|
||||||
local pts = advtrains.roundfloorpts
|
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 get_aspect
|
||||||
|
|
||||||
local supposed_aspects = {}
|
local supposed_aspects = {}
|
||||||
|
@ -11,6 +32,9 @@ local supposed_aspects = {}
|
||||||
function I.load_supposed_aspects(tbl)
|
function I.load_supposed_aspects(tbl)
|
||||||
if tbl then
|
if tbl then
|
||||||
supposed_aspects = tbl
|
supposed_aspects = tbl
|
||||||
|
for _, v in pairs(tbl) do
|
||||||
|
setmetatable(v, signal_aspect_metatable)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -41,11 +65,14 @@ end
|
||||||
|
|
||||||
local function adjust_aspect(pos, asp)
|
local function adjust_aspect(pos, asp)
|
||||||
asp = table.copy(I.signal_convert_aspect_if_necessary(asp))
|
asp = table.copy(I.signal_convert_aspect_if_necessary(asp))
|
||||||
|
setmetatable(asp, signal_aspect_metatable)
|
||||||
|
|
||||||
local mainpos = D.get_main(pos)
|
local mainpos = D.get_main(pos)
|
||||||
local nxtasp
|
local nxtasp
|
||||||
if asp.main ~= 0 and mainpos then
|
if mainpos then
|
||||||
nxtasp = get_aspect(mainpos)
|
nxtasp = get_aspect(mainpos)
|
||||||
|
end
|
||||||
|
if asp.main ~= 0 and mainpos then
|
||||||
asp.dst = nxtasp.main
|
asp.dst = nxtasp.main
|
||||||
else
|
else
|
||||||
asp.dst = nil
|
asp.dst = nil
|
||||||
|
@ -59,7 +86,10 @@ local function adjust_aspect(pos, asp)
|
||||||
if stype == 2 then
|
if stype == 2 then
|
||||||
local group = suppasp.group
|
local group = suppasp.group
|
||||||
local name
|
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)
|
name = A.get_type2_dst(group, nxtasp.type2name)
|
||||||
else
|
else
|
||||||
name = A.type1_to_type2main(asp, group)
|
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 asp = ndef.advtrains.get_aspect(pos, node) or I.DANGER
|
||||||
local suppasp = get_supported_aspects(pos)
|
local suppasp = get_supported_aspects(pos)
|
||||||
if suppasp.type == 2 then
|
if suppasp.type == 2 then
|
||||||
asp = A.type2main_to_type1(suppasp.group, asp)
|
asp = A.type2_to_type1(suppasp, asp)
|
||||||
end
|
end
|
||||||
return adjust_aspect(pos, asp)
|
return adjust_aspect(pos, asp)
|
||||||
end
|
end
|
||||||
|
@ -108,11 +138,6 @@ local function set_aspect(pos, asp, skipdst)
|
||||||
if (not skipdst) and aspect_changed then
|
if (not skipdst) and aspect_changed then
|
||||||
D.update_main(pos)
|
D.update_main(pos)
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -219,7 +219,7 @@ local function get_aspect_from_formspec_t1(suppasp, fields)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_aspect_from_formspec_t2(suppasp, fields)
|
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
|
return asp
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,9 @@ local function get_type2_dst(group, name)
|
||||||
return def.main[math.max(1, aspidx-1)].name
|
return def.main[math.max(1, aspidx-1)].name
|
||||||
end
|
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]
|
local def = type2defs[name]
|
||||||
if not def then
|
if not def then
|
||||||
return nil
|
return nil
|
||||||
|
@ -78,18 +80,26 @@ local function type2main_to_type1(name, asp)
|
||||||
else
|
else
|
||||||
aspidx = def.main[asp] or 2
|
aspidx = def.main[asp] or 2
|
||||||
end
|
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
|
if not asptbl then
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
if type(asp) == "number" then
|
if type(asp) == "number" then
|
||||||
asp = asptbl.name
|
asp = asptbl.name
|
||||||
end
|
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 = {
|
local t = {
|
||||||
main = asptbl.main,
|
main = main,
|
||||||
shunt = asptbl.shunt,
|
shunt = shunt,
|
||||||
proceed_as_main = asptbl.proceed_as_main,
|
proceed_as_main = asptbl.proceed_as_main,
|
||||||
type2name = asp,
|
type2name = asp,
|
||||||
type2group = name,
|
type2group = name,
|
||||||
|
@ -101,31 +111,28 @@ local function type2main_to_type1(name, asp)
|
||||||
return t
|
return t
|
||||||
end
|
end
|
||||||
|
|
||||||
local function type1_to_type2main(asp, group)
|
local function type1_to_type2main(asp, group, shift)
|
||||||
local def = type2defs[group]
|
local def = type2defs[group]
|
||||||
if not def then
|
if not def then
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
if group == asp.type2group and def.main[asp.type2name] then
|
|
||||||
return asp.type2name
|
|
||||||
end
|
|
||||||
local t_main = def.main
|
local t_main = def.main
|
||||||
local idx
|
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
|
idx = 1
|
||||||
elseif asp.main == 0 then
|
elseif asp.main == 0 then
|
||||||
idx = #t_main
|
idx = #t_main
|
||||||
else
|
else
|
||||||
idx = math.max(#t_main-1, 1)
|
idx = #t_main-1
|
||||||
end
|
end
|
||||||
return t_main[idx].name
|
return t_main[math.max(1, idx-(shift or 0))].name
|
||||||
end
|
end
|
||||||
|
|
||||||
local function equalp(asp1, asp2)
|
local function equalp(asp1, asp2)
|
||||||
if asp1 == asp2 then -- same reference
|
if asp1 == asp2 then -- same reference
|
||||||
return true
|
return true
|
||||||
elseif asp1.type2group and asp1.type2group == asp2.type2group then -- type2 with the same group
|
|
||||||
return asp1.type2name == asp2.type2name
|
|
||||||
else
|
else
|
||||||
for _, k in pairs {"main", "shunt", "dst"} do
|
for _, k in pairs {"main", "shunt", "dst"} do
|
||||||
if asp1[k] ~= asp2[k] then
|
if asp1[k] ~= asp2[k] then
|
||||||
|
@ -133,6 +140,9 @@ local function equalp(asp1, asp2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if asp1.type2group and asp1.type2group == asp2.type2group then
|
||||||
|
return asp1.type2name == asp2.type2name
|
||||||
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -144,7 +154,7 @@ return {
|
||||||
register_type2 = register_type2,
|
register_type2 = register_type2,
|
||||||
get_type2_definition = get_type2_definition,
|
get_type2_definition = get_type2_definition,
|
||||||
get_type2_dst = get_type2_dst,
|
get_type2_dst = get_type2_dst,
|
||||||
type2main_to_type1 = type2main_to_type1,
|
type2_to_type1 = type2_to_type1,
|
||||||
type1_to_type2main = type1_to_type2main,
|
type1_to_type2main = type1_to_type2main,
|
||||||
equalp = equalp,
|
equalp = equalp,
|
||||||
not_equalp = not_equalp,
|
not_equalp = not_equalp,
|
||||||
|
|
|
@ -44,7 +44,7 @@ world.layout {
|
||||||
|
|
||||||
describe("API for supposed signal aspects", function()
|
describe("API for supposed signal aspects", function()
|
||||||
it("should load and save data properly", function()
|
it("should load and save data properly", function()
|
||||||
local tbl = {_foo = true}
|
local tbl = {_foo = {}}
|
||||||
I.load_supposed_aspects(tbl)
|
I.load_supposed_aspects(tbl)
|
||||||
assert.same(tbl, I.save_supposed_aspects())
|
assert.same(tbl, I.save_supposed_aspects())
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -198,20 +198,24 @@ minetest.register_on_punchnode(function(pos, node, player, pointed_thing)
|
||||||
if is_signal then
|
if is_signal then
|
||||||
local ndef = minetest.registered_nodes[node.name]
|
local ndef = minetest.registered_nodes[node.name]
|
||||||
if ndef and ndef.advtrains and ndef.advtrains.set_aspect then
|
if ndef and ndef.advtrains and ndef.advtrains.set_aspect then
|
||||||
local tcbs = ildb.get_tcbs(sigd)
|
if ndef.advtrains.supported_aspects and not ndef.advtrains.supported_aspects.dst_shift then
|
||||||
if tcbs then
|
local tcbs = ildb.get_tcbs(sigd)
|
||||||
tcbs.signal = pos
|
if tcbs then
|
||||||
if not tcbs.signal_name then
|
tcbs.signal = pos
|
||||||
tcbs.signal_name = "Signal at "..minetest.pos_to_string(sigd.p)
|
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
|
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
|
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
|
end
|
||||||
else
|
else
|
||||||
minetest.chat_send_player(pname, "Configuring TCB: Cannot use static signals for routesetting. Aborted.")
|
minetest.chat_send_player(pname, "Configuring TCB: Cannot use static signals for routesetting. Aborted.")
|
||||||
|
|
|
@ -401,6 +401,7 @@ for _, rtab in ipairs {
|
||||||
supported_aspects = {
|
supported_aspects = {
|
||||||
type = 2,
|
type = 2,
|
||||||
group = siginfo.typename,
|
group = siginfo.typename,
|
||||||
|
dst_shift = siginfo.isdst and 0,
|
||||||
},
|
},
|
||||||
get_aspect = function()
|
get_aspect = function()
|
||||||
return asp
|
return asp
|
||||||
|
|
Loading…
Reference in New Issue