Fully implement and test new aspect support/distant signalling on ks and japan signals
This commit is contained in:
parent
eb03b5f301
commit
1f74697e85
|
@ -80,7 +80,7 @@ ndef.advtrains = {
|
|||
-- Node can set any other fields at its discretion. They are not touched.
|
||||
-- Note: On first call advtrains automatically inserts into the ndef.advtrains table a main_aspects_lookup hashtable
|
||||
-- Note: Pure distant signals (that cannot show halt) should NOT have a main_aspects table
|
||||
apply_aspect = function(pos, main_aspect, rem_aspect, rem_aspinfo)
|
||||
apply_aspect = function(pos, node, main_aspect, rem_aspect, rem_aspinfo)
|
||||
-- set the node to show the desired aspect
|
||||
-- called by advtrains when this signal's aspect group or the remote signal's aspect changes
|
||||
-- MAY return the aspect_info. If it returns nil then get_aspect_info will be queried at a later point.
|
||||
|
@ -120,7 +120,7 @@ Signals that are possible start and end points for a route must satisfy:
|
|||
-- Database
|
||||
-- Signal Aspect store
|
||||
-- Stores for each signal the main aspect and other info, like the assigned remote signal
|
||||
-- [signal encodePos] = { main_aspect = "proceed", [speed = 12], [remote = encodedPos] }
|
||||
-- [signal encodePos] = { name = "proceed", [speed = 12], [remote = encodedPos] }
|
||||
signal.aspects = {}
|
||||
|
||||
-- Distant signal notification. Records for each signal the distant signals that refer to it
|
||||
|
@ -162,10 +162,11 @@ function signal.set_aspect(pos, main_asp_name, main_asp_speed, rem_pos, skip_dst
|
|||
|
||||
-- if remote has changed, unregister from old remote
|
||||
if old_remote and old_remote~=new_remote and signal.distant_refs[old_remote] then
|
||||
atdebug("unregister old remote: ",old_remote,"from",main_pts)
|
||||
signal.distant_refs[old_remote][main_pts] = nil
|
||||
end
|
||||
|
||||
signal.aspects[main_pts] = { main_aspect = main_asp_name, speed = main_asp_speed, remote = new_remote }
|
||||
signal.aspects[main_pts] = { name = main_asp_name, speed = main_asp_speed, remote = new_remote }
|
||||
-- apply aspect on main signal, this also checks new_remote
|
||||
signal.reapply_aspect(main_pts)
|
||||
|
||||
|
@ -198,10 +199,12 @@ end
|
|||
-- Notify distant signals of main_pts of a change in the aspect of this signal
|
||||
--
|
||||
function signal.notify_distants_of(main_pts, limit)
|
||||
atdebug("notify_distants_of",advtrains.decode_pos(main_pts),"limit",limit)
|
||||
if limit <= 0 then
|
||||
return
|
||||
end
|
||||
local dstrefs = signal.distant_refs[main_pts]
|
||||
atdebug("dstrefs",dstrefs,"")
|
||||
if dstrefs then
|
||||
for dst,_ in pairs(dstrefs) do
|
||||
-- ensure that the backref is still valid
|
||||
|
@ -253,7 +256,7 @@ local function cache_mainaspects(ndefat)
|
|||
-- always define halt aspect
|
||||
halt = signal.MASP_HALT
|
||||
}
|
||||
for _,ma in ipairs(ndefat.main_aspects) then
|
||||
for _,ma in ipairs(ndefat.main_aspects) do
|
||||
ndefat.main_aspects_lookup[ma.name] = ma
|
||||
end
|
||||
end
|
||||
|
@ -263,32 +266,37 @@ function signal.get_aspect_internal(pos, aspt)
|
|||
-- oh, no main aspect, nevermind
|
||||
return nil, aspt.remote, nil
|
||||
end
|
||||
atdebug("get_aspect_internal",pos,aspt)
|
||||
-- look aspect in nodedef
|
||||
local node = advtrains.ndb.get_node_or_nil(pos)
|
||||
local ndef = node and minetest.registered_nodes[node.name]
|
||||
local ndefat = ndef and ndef.advtrains
|
||||
-- only if signal defines main aspect and its set in aspt
|
||||
if ndefat and ndefat.main_aspects and aspt.main_aspect then
|
||||
if ndefat and ndefat.main_aspects and aspt.name then
|
||||
if not ndefat.main_aspects_lookup then
|
||||
cache_mainaspects(ndefat)
|
||||
end
|
||||
local masp = ndefat.main_aspects_lookup[aspt.name]
|
||||
if not masp then
|
||||
atwarn(pos,"invalid main aspect",aspt.name,"valid are",ndefat.main_aspects_lookup)
|
||||
return nil, aspt.remote, node, ndef
|
||||
end
|
||||
-- if speed, then apply speed
|
||||
if masp.speed and aspt.speed then
|
||||
masp = table.copy(masp)
|
||||
masp.speed = aspt.speed
|
||||
end
|
||||
return masp, aspt.remote, ndef
|
||||
return masp, aspt.remote, node, ndef
|
||||
end
|
||||
-- invalid node or no main aspect, return nil for masp
|
||||
return nil, aspt.remote, ndef
|
||||
return nil, aspt.remote, node, ndef
|
||||
end
|
||||
|
||||
-- For the signal at pos, get the "aspect info" table. This contains the speed signalling information at this location
|
||||
function signal.get_aspect_info(pos)
|
||||
-- get aspect internal
|
||||
local aspt = signal.aspects[advtrains.encode_pos(pos)]
|
||||
local masp, remote, ndef = signal.get_aspect_internal(pos, aspt)
|
||||
local masp, remote, node, ndef = signal.get_aspect_internal(pos, aspt)
|
||||
-- call into ndef
|
||||
if ndef.advtrains and ndef.advtrains.get_aspect_info then
|
||||
return ndef.advtrains.get_aspect_info(pos, masp)
|
||||
|
@ -305,30 +313,38 @@ end
|
|||
function signal.reapply_aspect(pts)
|
||||
-- get aspt
|
||||
local aspt = signal.aspects[pts]
|
||||
atdebug("reapply_aspect",advtrains.decode_pos(pts),"aspt",aspt)
|
||||
if not aspt then
|
||||
return -- oop, nothing to do
|
||||
end
|
||||
-- resolve mainaspect table by name
|
||||
local pos = advtrains.decode_pos(pts)
|
||||
-- note: masp may be nil, when aspt.main_aspect was nil. Valid case for distant-only signals
|
||||
local masp, remote, ndef = signal.get_aspect_internal(pos, aspt)
|
||||
-- note: masp may be nil, when aspt.name was nil. Valid case for distant-only signals
|
||||
local masp, remote, node, ndef = signal.get_aspect_internal(pos, aspt)
|
||||
-- if we have remote, resolve remote
|
||||
local rem_masp, rem_aspi
|
||||
if remote then
|
||||
-- register in remote signal as distant
|
||||
if not signal.distant_refs[remote] then
|
||||
signal.distant_refs[remote] = {}
|
||||
end
|
||||
signal.distant_refs[remote][pts] = true
|
||||
local rem_aspt = signal.aspects[remote]
|
||||
atdebug("resolving remote",advtrains.decode_pos(remote),"aspt",rem_aspt)
|
||||
if rem_aspt and rem_aspt.name then
|
||||
local rem_pos = advtrains.decode_pos(remote)
|
||||
rem_masp, _, rem_ndef = signal.get_aspect_internal(rem_pos, rem_aspt)
|
||||
rem_masp, _, _, rem_ndef = signal.get_aspect_internal(rem_pos, rem_aspt)
|
||||
if rem_masp then
|
||||
if rem_ndef.advtrains and rem_ndef.advtrains.get_aspect_info then
|
||||
rem_aspi = rem_ndef.advtrains.get_aspect_info(pos, rem_masp)
|
||||
rem_aspi = rem_ndef.advtrains.get_aspect_info(rem_pos, rem_masp)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- call into ndef
|
||||
atdebug("applying to",pos,": main_asp",masp,"rem_masp",rem_masp,"rem_aspi",rem_aspi)
|
||||
if ndef.advtrains and ndef.advtrains.apply_aspect then
|
||||
return ndef.advtrains.apply_aspect(pos, masp, rem_masp, rem_aspi)
|
||||
ndef.advtrains.apply_aspect(pos, node, masp, rem_masp, rem_aspi)
|
||||
end
|
||||
-- notify trains
|
||||
signal.notify_trains(pos)
|
||||
|
|
|
@ -275,6 +275,7 @@ minetest.register_node("advtrains_signals_japan:pole_0", {
|
|||
drop = "advtrains_signals_japan:pole_0",
|
||||
})
|
||||
|
||||
--[[
|
||||
advtrains.interlocking.aspect.register_group {
|
||||
name = "advtrains_signals_japan:5a",
|
||||
label = S("Japanese signal"),
|
||||
|
@ -301,7 +302,7 @@ advtrains.interlocking.aspect.register_group {
|
|||
"restrictedspeed",
|
||||
"danger",
|
||||
}
|
||||
}
|
||||
}]]
|
||||
|
||||
local sigdefs = {}
|
||||
local lightcolors = {
|
||||
|
@ -316,6 +317,7 @@ local function process_signal(name, sigdata, isrpt)
|
|||
def.textures = tx
|
||||
def.desc = sigdata.desc
|
||||
def.isdst = isrpt
|
||||
def.aspects = sigdata.aspects
|
||||
local lights = sigdata.lights
|
||||
local lightcount = #lights
|
||||
if isrpt then
|
||||
|
@ -359,16 +361,17 @@ for sigtype, sigdata in pairs {
|
|||
desc = "5A",
|
||||
lights = {"yellow", "yellow", "red", "yellow", "green"},
|
||||
aspects = {
|
||||
{name = "clear", lights = {5}, main = -1},
|
||||
{name = "reducedspeed", lights = {2, 5}},
|
||||
{name = "caution", lights = {4}},
|
||||
{name = "restrictedspeed", lights = {1, 4}},
|
||||
{name = "danger", lights = {3}, main = 0},
|
||||
{name = "clear", description = S"Clear (proceed)", lights = {5}, main = -1},
|
||||
{name = "reducedspeed", description = S"Reduced speed", lights = {2, 5}, main = 12},
|
||||
{name = "caution", description = S"Caution", lights = {4}},
|
||||
{name = "restrictedspeed", description = S"Restricted speed", lights = {1, 4}, main = 6},
|
||||
{name = "danger", description = S"Danger (halt)", lights = {3}, main = 0},
|
||||
}
|
||||
}
|
||||
} do
|
||||
sigdefs["main_"..sigtype] = process_signal(sigtype, sigdata)
|
||||
sigdefs["rpt_"..sigtype] = process_signal(sigtype, sigdata, true)
|
||||
-- TODO re-enable this once ready
|
||||
--sigdefs["rpt_"..sigtype] = process_signal(sigtype, sigdata, true)
|
||||
end
|
||||
|
||||
for k in pairs(sigdefs) do
|
||||
|
@ -412,6 +415,24 @@ for _, rtab in ipairs {
|
|||
inventory_image = siginfo.inventory_image,
|
||||
drop = "advtrains_signals_japan:"..sigtype.."_danger_0",
|
||||
advtrains = {
|
||||
main_aspects = siginfo.aspects,
|
||||
apply_aspect = function(pos, node, main_aspect, rem_aspect, rem_aspinfo)
|
||||
local asp_name = main_aspect and main_aspect.name or "danger"
|
||||
-- if this signal is clear and remote signal is restrictive (<= 10) then degrade to caution aspect
|
||||
if not main_aspect or main_aspect.name == "halt" then
|
||||
asp_name = "danger"
|
||||
elseif main_aspect.name == "clear" and rem_aspinfo and rem_aspinfo.main and rem_aspinfo.main >= 0 and rem_aspinfo.main <= 10 then
|
||||
asp_name = "caution"
|
||||
end
|
||||
advtrains.ndb.swap_node(pos, {name="advtrains_signals_japan:"..sigtype.."_"..asp_name.."_"..rot, param2 = node.param2})
|
||||
end,
|
||||
get_aspect_info = function(pos, main_aspect)
|
||||
return {
|
||||
main = main_aspect.main,
|
||||
proceed_as_main = true,
|
||||
}
|
||||
end,
|
||||
--[[
|
||||
supported_aspects = {
|
||||
group = "advtrains_signals_japan:5a",
|
||||
name = siginfo.suppasp_names,
|
||||
|
@ -428,6 +449,7 @@ for _, rtab in ipairs {
|
|||
set_aspect = function(pos, node, asp)
|
||||
advtrains.ndb.swap_node(pos, {name = "advtrains_signals_japan:"..sigtype.."_"..(asp.name).."_"..rot, param2 = node.param2})
|
||||
end,
|
||||
]]
|
||||
},
|
||||
on_rightclick = advtrains.interlocking.signal_rc_handler,
|
||||
can_dig = advtrains.interlocking.signal_can_dig,
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
name=advtrains_signals_japan
|
||||
title=Advtrains Interlocking Signal Set - Japanese Signals
|
||||
description=Japanese signal set for the Advanced Trains Interlocking system
|
||||
author=yw05
|
||||
|
||||
depends=advtrains_interlocking
|
|
@ -51,7 +51,7 @@ end
|
|||
local applyaspectf_main = function(rot)
|
||||
return function(pos, node, main_aspect, dst_aspect, dst_aspect_info)
|
||||
-- set zs3 signal to show speed according to main_aspect
|
||||
setzs3(pos, asp.zs3, rot)
|
||||
setzs3(pos, main_aspect.zs3, rot)
|
||||
-- select appropriate lamps based on mainaspect and dst
|
||||
if main_aspect.shunt then
|
||||
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_shunt_"..rot, param2 = node.param2})
|
||||
|
@ -81,43 +81,43 @@ end
|
|||
-- Actual signal aspect is chosen based on this and the Dst signal.
|
||||
local mainaspects_main = {
|
||||
{
|
||||
name = "proceed"
|
||||
name = "proceed",
|
||||
description = "Proceed",
|
||||
zs3 = "off"
|
||||
},
|
||||
{
|
||||
name = "shunt"
|
||||
name = "shunt",
|
||||
description = "Shunt",
|
||||
zs3 = "off",
|
||||
shunt = true,
|
||||
},
|
||||
{
|
||||
name = "proceed_16"
|
||||
name = "proceed_16",
|
||||
description = "Proceed (speed 16)",
|
||||
zs3 = "16",
|
||||
},
|
||||
{
|
||||
name = "proceed_12"
|
||||
name = "proceed_12",
|
||||
description = "Proceed (speed 12)",
|
||||
zs3 = "12",
|
||||
},
|
||||
{
|
||||
name = "proceed_8"
|
||||
name = "proceed_8",
|
||||
description = "Proceed (speed 8)",
|
||||
zs3 = "8",
|
||||
},
|
||||
{
|
||||
name = "proceed_6"
|
||||
name = "proceed_6",
|
||||
description = "Proceed (speed 6)",
|
||||
zs3 = "6",
|
||||
},
|
||||
{
|
||||
name = "proceed_4"
|
||||
name = "proceed_4",
|
||||
description = "Proceed (speed 4)",
|
||||
zs3 = "4",
|
||||
},
|
||||
{
|
||||
name = "halt"
|
||||
name = "halt",
|
||||
description = "Halt",
|
||||
zs3 = "off",
|
||||
halt = true,
|
||||
|
@ -140,12 +140,12 @@ end
|
|||
-- Shunt signals have only two states, distant doesn't matter
|
||||
local mainaspects_shunt = {
|
||||
{
|
||||
name = "shunt"
|
||||
name = "shunt",
|
||||
description = "Shunt",
|
||||
shunt = true,
|
||||
},
|
||||
{
|
||||
name = "halt"
|
||||
name = "halt",
|
||||
description = "Halt",
|
||||
halt = true,
|
||||
},
|
||||
|
@ -168,7 +168,7 @@ for _, rtab in ipairs({
|
|||
}) do
|
||||
local rot = rtab.rot
|
||||
for typ, prts in pairs({
|
||||
danger = {asp = advtrains.interlocking.DANGER, n = "slow", ici=true},
|
||||
danger = {asp = advtrains.interlocking.signal.ASPI_HALT, n = "slow", ici=true},
|
||||
slow = {
|
||||
asp = function(pos)
|
||||
return { main = getzs3(pos) or -1, proceed_as_main = true, dst = 0 }
|
||||
|
@ -230,7 +230,7 @@ for _, rtab in ipairs({
|
|||
drop = "advtrains_signals_ks:hs_danger_0",
|
||||
inventory_image = "advtrains_signals_ks_hs_inv.png",
|
||||
advtrains = {
|
||||
main_aspects = mainaspects_main
|
||||
main_aspects = mainaspects_main,
|
||||
apply_aspect = applyaspectf_main(rot),
|
||||
get_aspect_info = afunc,
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue