diff options
Diffstat (limited to 'advtrains_interlocking/routesetting.lua')
-rw-r--r-- | advtrains_interlocking/routesetting.lua | 62 |
1 files changed, 53 insertions, 9 deletions
diff --git a/advtrains_interlocking/routesetting.lua b/advtrains_interlocking/routesetting.lua index 64b8c25..d619aac 100644 --- a/advtrains_interlocking/routesetting.lua +++ b/advtrains_interlocking/routesetting.lua @@ -45,12 +45,18 @@ function ilrs.set_route(signal, route, try) local rtename = route.name local signalname = (ildb.get_tcbs(signal).signal_name or "") .. sigd_to_string(signal) local c_tcbs, c_ts_id, c_ts, c_rseg, c_lckp + -- signals = { { pos = ., tcbs_ref = <tcbs>, role = "main_distant", masp_override = nil, dst_type = "next_main" or "none" } + local signals = {} + local nodst while c_sigd and i<=#route do c_tcbs = ildb.get_tcbs(c_sigd) if not c_tcbs then if not try then atwarn("Did not find TCBS",c_sigd,"while setting route",rtename,"of",signal) end return false, "No TCB found at "..sigd_to_string(c_sigd)..". Please update or reconfigure route!" end + if i == 1 then + nodst = c_tcbs.nodst + end c_ts_id = c_tcbs.ts_id if not c_ts_id then if not try then atwarn("Encountered End-Of-Interlocking while setting route",rtename,"of",signal) end @@ -62,11 +68,11 @@ function ilrs.set_route(signal, route, try) if c_ts.route then if not try then atwarn("Encountered ts lock during a real run of routesetting routine, at ts=",c_ts_id,"while setting route",rtename,"of",signal) end - return false, "Section '"..c_ts.name.."' already has route set from "..sigd_to_string(c_ts.route.origin)..":\n"..c_ts.route.rsn, c_ts_id, nil + return false, "Section '"..(c_ts.name or c_ts_id).."' already has route set from "..sigd_to_string(c_ts.route.origin)..":\n"..c_ts.route.rsn, c_ts_id, nil end if c_ts.trains and #c_ts.trains>0 then if not try then atwarn("Encountered ts occupied during a real run of routesetting routine, at ts=",c_ts_id,"while setting route",rtename,"of",signal) end - return false, "Section '"..c_ts.name.."' is occupied!", c_ts_id, nil + return false, "Section '"..(c_ts.name or c_ts_id).."' is occupied!", c_ts_id, nil end -- collect locks from rs cache and from route def @@ -133,9 +139,17 @@ 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 c_tcbs.route_origin = signal - advtrains.interlocking.update_signal_aspect(c_tcbs) + -- determine route role + local ndef = advtrains.ndb.get_ndef(c_tcbs.signal) + local sig_table = { + pos = c_tcbs.signal, + tcbs_ref = c_tcbs, + role = ndef and ndef.advtrains and ndef.advtrains.route_role, + masp_override = c_rseg.masp_override, --TODO implement masp_override on UI side + dst_type = "next_main", --TODO allow user differentiate + } + signals[#signals+1] = sig_table end end -- advance @@ -143,6 +157,33 @@ function ilrs.set_route(signal, route, try) c_sigd = c_rseg.next i = i + 1 end + + -- Get reference to signal at end of route + local last_mainsig = nil + if c_sigd then + local e_tcbs = ildb.get_tcbs(c_sigd) + local pos = e_tcbs and e_tcbs.signal + if pos then + last_mainsig = pos + end + end + for i = #signals, 1, -1 do + -- note the signals are iterated backwards. Switch depending on the role + local sig = signals[i] + -- apply mainaspect + sig.tcbs_ref.route_aspect = sig.masp_override or "_default" + if sig.role == "distant" or sig.role == "distant_repeater" or sig.role == "main_distant" then + -- assign the remote as the last mainsig + sig.tcbs_ref.route_remote = last_mainsig + end + if sig.role == "main" or sig.role == "main_distant" or sig.role == "end" then + -- record this as the new last mainsig + last_mainsig = sig.pos + end + -- for shunt signals nothing happens + -- update the signal aspect on map + advtrains.interlocking.signal.update_route_aspect(sig.tcbs_ref, i ~= 1) + end return true end @@ -247,12 +288,13 @@ function ilrs.cancel_route_from(sigd) --atdebug("cancelling",c_ts.route.rsn) -- clear signal aspect and routesetting state c_tcbs.route_committed = nil - c_tcbs.aspect = nil + c_tcbs.route_aspect = nil + c_tcbs.route_remote = nil c_tcbs.routeset = nil c_tcbs.route_auto = nil c_tcbs.route_origin = nil - advtrains.interlocking.update_signal_aspect(c_tcbs) + advtrains.interlocking.signal.update_route_aspect(c_tcbs) c_ts_id = c_tcbs.ts_id if not c_tcbs then @@ -302,7 +344,8 @@ function ilrs.update_route(sigd, tcbs, newrte, cancel) advtrains.interlocking.route.cancel_route_from(sigd) end tcbs.route_committed = nil - tcbs.aspect = nil + tcbs.route_aspect = nil + tcbs.route_remote = nil has_changed_aspect = true tcbs.routeset = nil tcbs.route_auto = nil @@ -331,12 +374,13 @@ function ilrs.update_route(sigd, tcbs, newrte, cancel) end else --atdebug("Committed Route:",tcbs.routeset) - has_changed_aspect = true + -- set_route now sets the signal aspects + --has_changed_aspect = true end end if has_changed_aspect then -- FIX: prevent an minetest.after() loop caused by update_signal_aspect dispatching path invalidation, which in turn calls ARS again - advtrains.interlocking.update_signal_aspect(tcbs) + advtrains.interlocking.signal.update_route_aspect(tcbs) end advtrains.interlocking.update_player_forms(sigd) end |