aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorywang <yw05@forksworld.de>2021-05-30 12:16:09 +0200
committerywang <yw05@forksworld.de>2021-05-30 12:16:09 +0200
commitdcdd3ea702494e9e5bfeba96a72999f35aa2c91a (patch)
tree3104a3e204f4a4e237fc4f8fc4b2e29452b267d0
parent06002447242bc9dcc3e6d176981a5d30cc7a0ce9 (diff)
downloadadvtrains-dcdd3ea702494e9e5bfeba96a72999f35aa2c91a.tar.gz
advtrains-dcdd3ea702494e9e5bfeba96a72999f35aa2c91a.tar.bz2
advtrains-dcdd3ea702494e9e5bfeba96a72999f35aa2c91a.zip
round speed limit downward if needed; add basic distant signal implementation
-rw-r--r--advtrains_interlocking/database.lua2
-rw-r--r--advtrains_interlocking/distant_signals.lua83
-rw-r--r--advtrains_interlocking/init.lua1
-rw-r--r--advtrains_interlocking/routesetting.lua24
-rwxr-xr-xadvtrains_interlocking/tcb_ts_ui.lua1
-rwxr-xr-xadvtrains_signals_ks/init.lua15
6 files changed, 116 insertions, 10 deletions
diff --git a/advtrains_interlocking/database.lua b/advtrains_interlocking/database.lua
index a35d446..ee21db9 100644
--- a/advtrains_interlocking/database.lua
+++ b/advtrains_interlocking/database.lua
@@ -195,6 +195,8 @@ TCB data structure
signal_name = <string> -- The human-readable name of the signal, only for documenting purposes
routes = { <route definition> } -- a collection of routes from this signal
route_auto = <boolean> -- When set, we will automatically re-set the route (designated by routeset)
+ distant = { <sigd1> ... } -- a collection of sigd that points to a side of a TCB with a distant signal for this current signal.
+ distant_of = { <sigd>, <index> } -- the reverse of the above field, along with the index of the entry in the list (for easier lookup)
},
-- This is the "B" side of the TCB
[2] = { -- Variant: end of track-circuited area (initial state of TC)
diff --git a/advtrains_interlocking/distant_signals.lua b/advtrains_interlocking/distant_signals.lua
new file mode 100644
index 0000000..0da1c10
--- /dev/null
+++ b/advtrains_interlocking/distant_signals.lua
@@ -0,0 +1,83 @@
+local interlocking = advtrains.interlocking
+local ildb = advtrains.interlocking.db
+
+local function update_distant(tcbs)
+ if not (tcbs and tcbs.signal) then return end
+ if not tcbs.aspect then tcbs.aspect = table.copy(interlocking.DANGER) end
+ local asp = tcbs.aspect
+ if tcbs.distant_of then
+ asp.dst = (ildb.get_tcbs(tcbs.distant_of[1]).aspect or interlocking.DANGER).main
+ end
+ interlocking.update_signal_aspect(tcbs)
+ if tcbs.distant then
+ local dst = tcbs.distant
+ for i = 1, #dst do
+ local s = ildb.get_tcbs(dst[i])
+ if not s.aspect then s.aspect = table.copy(interlocking.DANGER) end
+ s.aspect.dst = asp.main
+ interlocking.update_signal_aspect(s)
+ end
+ end
+end
+
+local function unassign_distant(dsts)
+ if not dsts then return end
+ local dof = dsts.distant_of
+ if not dof then return end
+ if dsts.signal and dsts.aspect then
+ dsts.aspect.dst = nil
+ interlocking.update_signal_aspect(dsts)
+ end
+ local sigd, idx = dof[1], dof[2]
+ local tcbs = ildb.get_tcbs(sigd)
+ local dst = tcbs.distant
+ dsts.distant_of = nil
+ if idx == #dst then
+ dst[#dst] = nil
+ else
+ local ent = dst[#dst]
+ dst[idx] = ent
+ dst[#dst] = nil
+ local repl = ildb.get_tcbs(ent)
+ repl.distant_of[2] = idx
+ end
+end
+
+local function assign_distant(sigd, dstd)
+ if not sigd then return end
+ if not dstd then return end
+ local tcbs = ildb.get_tcbs(sigd)
+ local dsts = ildb.get_tcbs(dstd)
+ unassign_distant(dsts)
+ if not (tcbs.signal and dsts.signal) then return end
+ local dst = tcbs.distant
+ if not dst then
+ dst = {}
+ tcbs.distant = dst
+ end
+ local newidx = #dst+1
+ dsts.distant_of = {sigd, newidx}
+ dst[newidx] = dstd
+ update_distant(dsts)
+end
+
+local function remove_distant(tcbs)
+ if not tcbs then return end
+ if tcbs.distant_of then
+ unassign_distant(tcbs)
+ end
+ if tcbs.distant then
+ local dst = tcbs.distant
+ for i = #dst, 1, -1 do
+ local s = ildb.get_tcbs(dst[i])
+ unassign_distant(s)
+ end
+ end
+end
+
+interlocking.distant = {
+ assign = assign_distant,
+ unassign = unassign_distant,
+ remove = remove_distant,
+ update = update_distant,
+}
diff --git a/advtrains_interlocking/init.lua b/advtrains_interlocking/init.lua
index a2f5882..cfbb8e5 100644
--- a/advtrains_interlocking/init.lua
+++ b/advtrains_interlocking/init.lua
@@ -16,6 +16,7 @@ dofile(modpath.."database.lua")
dofile(modpath.."signal_api.lua")
dofile(modpath.."demosignals.lua")
dofile(modpath.."train_sections.lua")
+dofile(modpath.."distant_signals.lua")
dofile(modpath.."route_prog.lua")
dofile(modpath.."routesetting.lua")
dofile(modpath.."tcb_ts_ui.lua")
diff --git a/advtrains_interlocking/routesetting.lua b/advtrains_interlocking/routesetting.lua
index 67efaea..d801608 100644
--- a/advtrains_interlocking/routesetting.lua
+++ b/advtrains_interlocking/routesetting.lua
@@ -44,7 +44,7 @@ function ilrs.set_route(signal, route, try)
local i = 1
local rtename = route.name
local signalname = ildb.get_tcbs(signal).signal_name
- local c_tcbs, c_ts_id, c_ts, c_rseg, c_lckp
+ local c_tcbs, c_ts_id, c_ts, c_rseg, c_lckp, p_ssigd
while c_sigd and i<=#route do
c_tcbs = ildb.get_tcbs(c_sigd)
if not c_tcbs then
@@ -112,9 +112,16 @@ function ilrs.set_route(signal, route, try)
}
if c_tcbs.signal then
c_tcbs.route_committed = true
- c_tcbs.aspect = route.aspect or advtrains.interlocking.GENERIC_FREE
+ local asp = route.aspect or advtrains.interlocking.GENERIC_FREE
+ asp.dst = nil
+ c_tcbs.aspect = asp
c_tcbs.route_origin = signal
- advtrains.interlocking.update_signal_aspect(c_tcbs)
+ advtrains.interlocking.distant.update(c_tcbs)
+ -- Update the previous distant signal
+ if p_ssigd then
+ advtrains.interlocking.distant.assign(c_sigd, p_ssigd)
+ end
+ p_ssigd = c_sigd
end
end
-- advance
@@ -122,6 +129,17 @@ function ilrs.set_route(signal, route, try)
c_sigd = c_rseg.next
i = i + 1
end
+
+ if c_sigd and p_ssigd then
+ local e_tcbs = ildb.get_tcbs(c_sigd)
+ if e_tcbs.signal then
+ if p_stcb then
+ p_stcb.aspect.dst = (e_tcbs.aspect or advtrains.interlocking.DANGER).main
+ advtrains.interlocking.update_signal_aspect(p_stcb)
+ end
+ end
+ advtrains.interlocking.distant.assign(c_sigd, p_ssigd)
+ end
return true
end
diff --git a/advtrains_interlocking/tcb_ts_ui.lua b/advtrains_interlocking/tcb_ts_ui.lua
index 34fbf7f..2425bf2 100755
--- a/advtrains_interlocking/tcb_ts_ui.lua
+++ b/advtrains_interlocking/tcb_ts_ui.lua
@@ -778,6 +778,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
ildb.set_sigd_for_signal(signal_pos, nil)
tcbs.signal = nil
tcbs.aspect = nil
+ advtrains.interlocking.distant.remove(tcbs)
minetest.close_formspec(pname, formname)
minetest.chat_send_player(pname, "Signal has been unassigned. Name and routes are kept for reuse.")
return
diff --git a/advtrains_signals_ks/init.lua b/advtrains_signals_ks/init.lua
index a1f056c..3a2f4d0 100755
--- a/advtrains_signals_ks/init.lua
+++ b/advtrains_signals_ks/init.lua
@@ -4,15 +4,17 @@
-- Note that the group value of advtrains_signal is 2, which means "step 2 of signal capabilities"
-- advtrains_signal=1 is meant for signals that do not implement set_aspect.
-local supported_speed_limits = {
- [4] = true, [6] = true, [8] = true, [12] = true, [16] = true
-}
+local function asp_to_zs3type(asp)
+ local n = tonumber(asp)
+ if not n or n < 4 then return "off" end
+ if n < 8 then return 2*math.floor(n/2) end
+ return math.min(16,4*math.floor(n/4))
+end
local function setzs3(msp, lim, rot)
local pos = {x = msp.x, y = msp.y+1, z = msp.z}
local node = advtrains.ndb.get_node(pos)
- local asp = lim
- if not asp or not supported_speed_limits[lim] then asp = "off" end
+ local asp = asp_to_zs3type(lim)
if node.name:find("^advtrains_signals_ks:zs3_") then
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:zs3_"..asp.."_"..rot, param2 = node.param2})
end
@@ -31,8 +33,7 @@ end
local function setzs3v(msp, lim, rot)
local pos = {x = msp.x, y = msp.y-1, z = msp.z}
local node = advtrains.ndb.get_node(pos)
- local asp = lim
- if not asp or not supported_speed_limits[lim] then asp = "off" end
+ local asp = asp_to_zs3type(lim)
if node.name:find("^advtrains_signals_ks:zs3v_") then
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:zs3v_"..asp.."_"..rot, param2 = node.param2})
end