aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--advtrains/atc.lua8
-rw-r--r--advtrains/init.lua2
-rw-r--r--advtrains/lzb.lua3
-rw-r--r--advtrains/occupation.lua4
-rw-r--r--advtrains/path.lua11
-rw-r--r--advtrains/trainhud.lua76
-rw-r--r--advtrains/trainlogic.lua16
-rw-r--r--advtrains/wagons.lua2
-rw-r--r--advtrains_interlocking/database.lua5
-rw-r--r--advtrains_interlocking/route_prog.lua2
-rw-r--r--advtrains_interlocking/route_ui.lua2
-rw-r--r--advtrains_interlocking/routesetting.lua14
-rw-r--r--advtrains_interlocking/signal_api.lua9
-rw-r--r--advtrains_interlocking/signal_aspect_ui.lua4
-rw-r--r--advtrains_interlocking/smartroute.lua24
-rwxr-xr-xadvtrains_interlocking/tcb_ts_ui.lua5
-rw-r--r--advtrains_interlocking/train_sections.lua53
-rw-r--r--advtrains_line_automation/stoprail.lua15
-rw-r--r--advtrains_luaautomation/environment.lua10
-rwxr-xr-xadvtrains_signals_ks/init.lua10
-rwxr-xr-xmake_release.sh53
21 files changed, 235 insertions, 93 deletions
diff --git a/advtrains/atc.lua b/advtrains/atc.lua
index b572cdc..8e54b08 100644
--- a/advtrains/atc.lua
+++ b/advtrains/atc.lua
@@ -94,6 +94,7 @@ function atc.train_reset_command(train, keep_tarvel)
train.atc_brake_target=nil
train.atc_wait_finish=nil
train.atc_wait_autocouple=nil
+ train.atc_wait_signal=nil
train.atc_arrow=nil
if not keep_tarvel then
train.tarvelocity=nil
@@ -278,6 +279,10 @@ local matchptn={
train.atc_wait_autocouple=true
return 3
end,
+ ["G"]=function(id, train)
+ train.atc_wait_signal=true
+ return 1
+ end,
}
eval_conditional = function(command, arrow, speed)
@@ -375,7 +380,8 @@ function atc.execute_atc_command(id, train)
train.atc_command=string.sub(command, patlen+1)
if train.atc_delay<=0
and not train.atc_wait_finish
- and not train.atc_wait_autocouple then
+ and not train.atc_wait_autocouple
+ and not train.atc_wait_signal then
--continue (recursive, cmds shouldn't get too long, and it's a end-recursion.)
atc.execute_atc_command(id, train)
end
diff --git a/advtrains/init.lua b/advtrains/init.lua
index ad66200..fe29260 100644
--- a/advtrains/init.lua
+++ b/advtrains/init.lua
@@ -33,7 +33,7 @@ advtrains = {trains={}, player_to_train_mapping={}}
-- =======================Development/debugging settings=====================
-- DO NOT USE FOR NORMAL OPERATION
-local DUMP_DEBUG_SAVE = true
+local DUMP_DEBUG_SAVE = false
-- dump the save files in human-readable format into advtrains_DUMP
local GENERATE_ATRICIFIAL_LAG = false
diff --git a/advtrains/lzb.lua b/advtrains/lzb.lua
index 2853218..116777c 100644
--- a/advtrains/lzb.lua
+++ b/advtrains/lzb.lua
@@ -265,7 +265,8 @@ end
advtrains.te_register_on_new_path(function(id, train)
advtrains.lzb_invalidate(train)
-- Taken care of in pre-move hook (see train_step_b)
- --look_ahead(id, train)
+ -- 2025-01-28 - do anyway, there seems to be an issue
+ look_ahead(id, train)
end)
advtrains.te_register_on_invalidate_ahead(function(id, train, start_idx)
diff --git a/advtrains/occupation.lua b/advtrains/occupation.lua
index 26e1f79..20a986e 100644
--- a/advtrains/occupation.lua
+++ b/advtrains/occupation.lua
@@ -89,8 +89,8 @@ function o.set_item(train_id, pos, idx)
assert(idx)
local i = 1
while t[i] do
- if t[i]==train_id and t[i+1]==index then
- break
+ if t[i]==train_id and t[i+1]==idx then
+ return
end
i = i + 2
end
diff --git a/advtrains/path.lua b/advtrains/path.lua
index 4807361..57829ad 100644
--- a/advtrains/path.lua
+++ b/advtrains/path.lua
@@ -112,14 +112,21 @@ end
-- before returning from the calling function.
function advtrains.path_invalidate(train, ignore_lock)
if advtrains.lock_path_inval and not ignore_lock then
- atwarn("Train ",train.train_id,": Illegal path invalidation has occured during train step:")
+ atwarn("Train ",train.id,": Illegal path invalidation has occured during train step:")
atwarn(debug.traceback())
end
-
if train.path then
+ --atdebug("path_invalidate for",train.id)
+ local _cnt = 0
for i,p in pairs(train.path) do
+ _cnt = _cnt + 1
+ if _cnt > 10000 then
+ atdebug(train)
+ error("Loop trap in advtrains.path_invalidate was triggered!")
+ end
advtrains.occ.clear_all_items(train.id, advtrains.round_vector_floor_y(p))
end
+ --atdebug("occ cleared")
end
train.path = nil
train.path_dist = nil
diff --git a/advtrains/trainhud.lua b/advtrains/trainhud.lua
index c133a54..9d9d475 100644
--- a/advtrains/trainhud.lua
+++ b/advtrains/trainhud.lua
@@ -233,40 +233,41 @@ function advtrains.hud_train_format(train, flip)
if train.tarvelocity then
hud:add(1+train.tarvelocity*11, 85, T"advtrains_hud_arrow.png":transform"FY":multiply"cyan")
end
- local lzbdisp
local lzb = train.lzb
- if lzb and lzb.checkpoints then
- local oc = lzb.checkpoints
- for i = 1, #oc do
- if advtrains.interlocking then
- local udata = oc[i].udata
- if udata and udata.signal_pos then
- local sigd = advtrains.interlocking.db.get_sigd_for_signal(udata.signal_pos)
- if sigd then
- local tcbs = advtrains.interlocking.db.get_tcbs(sigd) or {}
- if tcbs.route_rsn then
- table.insert(st, ("%s: %s"):format(minetest.pos_to_string(sigd.p), tcbs.route_rsn))
- end
- end
+ local lzbdisp = {c = "darkslategray", d = 888}
+ if lzb and lzb.checkpoints and lzb.checkpoints[1] then
+ local cp = lzb.checkpoints[1]
+ if advtrains.interlocking and cp.udata and cp.udata.signal_pos then
+ local sigd = advtrains.interlocking.db.get_sigd_for_signal(cp.udata.signal_pos)
+ if sigd then
+ local tcbs = advtrains.interlocking.db.get_tcbs(sigd) or {}
+ if tcbs.route_rsn then
+ table.insert(st, ("%s: %s"):format(minetest.pos_to_string(sigd.p), tcbs.route_rsn))
end
end
- local spd = oc[i].speed
- spd = advtrains.speed.min(spd, train.speed_restriction)
- if spd == -1 then spd = nil end
- local c = not spd and "lime" or (type(spd) == "number" and (spd == 0) and "red" or "orange") or nil
- if c then
- if spd and spd~=0 then
- hud:add(1+spd*11, 50, T"advtrains_hud_arrow.png":multiply"red")
- end
- local dist = math.floor(((oc[i].index or train.index)-train.index))
- dist = math.max(0, math.min(999, dist))
- lzbdisp = {c = c, d = dist}
- break
- end
end
- end
- if not lzbdisp then
- lzbdisp = {c = "darkslategray", d = 888}
+ local spd = cp.speed
+ local c, arrow
+ if not spd or spd == -1 then
+ c = "lime"
+ elseif spd == 0 then
+ c = "red"
+ elseif not res or spd <= res then
+ c = "orange"
+ arrow = true
+ elseif spd <= max then
+ c = "yellow"
+ arrow = true
+ else
+ c = "cyan"
+ arrow = true
+ end
+ if arrow then
+ hud:add(1+spd*11, 50, T"advtrains_hud_arrow.png":multiply"red")
+ end
+ local dist = math.floor(((cp.index or train.index)-train.index))
+ dist = math.max(0, math.min(999, dist))
+ lzbdisp = {c = c, d = dist}
end
hud:add_fill(130, 10, 30, 5, lzbdisp.c)
hud:add_fill(130, 35, 30, 5, lzbdisp.c)
@@ -277,7 +278,20 @@ function advtrains.hud_train_format(train, flip)
end
if train.atc_command then
- table.insert(st, ("ATC: %s%s"):format(train.atc_delay and advtrains.abs_ceil(train.atc_delay).."s " or "", train.atc_command or ""))
+ local delay_str = ""
+ if train.atc_delay and train.atc_delay >= 0 then
+ delay_str = advtrains.abs_ceil(train.atc_delay).."s "
+ end
+ if train.atc_wait_finish then
+ delay_str = delay_str.."[W] "
+ end
+ if train.atc_wait_autocouple then
+ delay_str = delay_str.."[Cpl] "
+ end
+ if train.atc_wait_signal then
+ delay_str = delay_str.."[G] "
+ end
+ table.insert(st, ("ATC: %s%s"):format(delay_str, train.atc_command or ""))
end
return table.concat(st,"\n"), tostring(hud)
diff --git a/advtrains/trainlogic.lua b/advtrains/trainlogic.lua
index e4939df..c49d7e3 100644
--- a/advtrains/trainlogic.lua
+++ b/advtrains/trainlogic.lua
@@ -427,7 +427,8 @@ function advtrains.train_step_b(id, train, dtime)
if train.atc_command then
if (not train.atc_delay or train.atc_delay<=0)
and not train.atc_wait_finish
- and not train.atc_wait_autocouple then
+ and not train.atc_wait_autocouple
+ and not train.atc_wait_signal then
advtrains.atc.execute_atc_command(id, train)
elseif train.atc_delay and train.atc_delay > 0 then
train.atc_delay=train.atc_delay-dtime
@@ -456,6 +457,15 @@ function advtrains.train_step_b(id, train, dtime)
train.atc_wait_finish=nil
end
end
+ -- clear atc_wait_signal immediately when the next LZB checkpoint is not a "stop"
+ -- (but make sure lzb is initialized, otherwise wait for it)
+ if train.atc_wait_signal and train.lzb then
+ local first_ckp = train.lzb.checkpoints and train.lzb.checkpoints[1]
+ -- no checkpoint exists, or it has a speed of either nil or >0
+ if not first_ckp or first_ckp.speed ~= 0 then
+ train.atc_wait_signal = nil
+ end
+ end
if train.tarvelocity and train.tarvelocity>v0 then
--atprint("in train_step_b: applying ATC ACCEL", train.tarvelocity)
@@ -630,7 +640,7 @@ function advtrains.train_step_b(id, train, dtime)
local ocn = otrn.path_cn[ob_idx]
local ocp = otrn.path_cp[ob_idx]
- local target_is_inside, ref_index, facing
+ local target_is_inside, ref_index, facing, same_dir
if base_cn == ocn then
-- same direction
@@ -1049,7 +1059,7 @@ function advtrains.update_trainpart_properties(train_id, invert_flipstate)
if not wagon then
local ent = advtrains.wagon_objects[w_id]
local pdesc
- if ent then
+ if ent and ent:get_pos() then
pdesc = "at " .. minetest.pos_to_string(ent:get_pos())
elseif train.last_pos then
pdesc = "near " .. minetest.pos_to_string(train.last_pos)
diff --git a/advtrains/wagons.lua b/advtrains/wagons.lua
index ef057e5..01c60ec 100644
--- a/advtrains/wagons.lua
+++ b/advtrains/wagons.lua
@@ -1333,7 +1333,7 @@ function advtrains.get_wagon_prototype(data)
end
local rt, proto = advtrains.resolve_wagon_alias(wt)
if not rt then
- atwarn("Unable to load wagon type",wt,", using placeholder")
+ --atwarn("Unable to load wagon type",wt,", using placeholder")
rt = "advtrains:wagon_placeholder"
proto = advtrains.wagon_prototypes[rt]
end
diff --git a/advtrains_interlocking/database.lua b/advtrains_interlocking/database.lua
index 0a5094b..d80fb76 100644
--- a/advtrains_interlocking/database.lua
+++ b/advtrains_interlocking/database.lua
@@ -412,6 +412,7 @@ function ildb.check_and_repair_ts_at_pos(pos, tcb_connid, notify_pname, force_cr
return ildb.repair_ts_merge_all(all_tcbs, force_create, notify_pname)
end
--tsrepair_notify(notify_pname, "Found section", ts.name or ts_id, "here.")
+ ildb.update_rs_cache(ts_id)
return ts_id
end
@@ -457,7 +458,7 @@ function ildb.get_all_tcbs_adjacent(inipos, inidir, per_track_callback)
pos, connid = ti:next_branch()
--atdebug("get_all_tcbs_adjacent: BRANCH: ",pos, connid)
bconnid = nil
- is_branch_start = true
+ local is_branch_start = true
repeat
-- callback
if per_track_callback then
@@ -535,7 +536,7 @@ function ildb.repair_ts_merge_all(all_tcbs, force_create, notify_pname)
end
-- Create a new fresh track section with all the TCBs we have in our collection
local new_ts_id, new_ts = ildb.create_ts_from_tcb_list(all_tcbs)
- tsrepair_notify(notify_pname, "Created track section",new_ts_id,"from TCBs:", all_tcbs)
+ tsrepair_notify(notify_pname, "Created track section",new_ts_id,"from",#all_tcbs,"TCBs")
return new_ts_id
end
diff --git a/advtrains_interlocking/route_prog.lua b/advtrains_interlocking/route_prog.lua
index 3bdf6d6..71ebdf3 100644
--- a/advtrains_interlocking/route_prog.lua
+++ b/advtrains_interlocking/route_prog.lua
@@ -537,7 +537,7 @@ minetest.register_on_punchnode(function(pos, node, player, pointed_thing)
show_routing_form(pname, tcbpos)
advtrains.interlocking.visualize_route(rp.origin, rp.route, "prog_"..pname, rp.tmp_lcks, pname)
return
- elseif advtrains.interlocking.database.get_tcb(pos) then
+ elseif advtrains.interlocking.db.get_tcb(pos) then
-- the punched node itself is a TCB
show_routing_form(pname, pos)
advtrains.interlocking.visualize_route(rp.origin, rp.route, "prog_"..pname, rp.tmp_lcks, pname)
diff --git a/advtrains_interlocking/route_ui.lua b/advtrains_interlocking/route_ui.lua
index 7dddc6e..3c7bd64 100644
--- a/advtrains_interlocking/route_ui.lua
+++ b/advtrains_interlocking/route_ui.lua
@@ -67,7 +67,7 @@ function atil.show_route_edit_form(pname, sigd, routeid, sel_rpartidx)
if c_rseg.locks then
for pts, state in pairs(c_rseg.locks) do
- local pos = minetest.string_to_pos(pts)
+ local pos = advtrains.decode_pos(pts)
itab(i, "L "..pts.." -> "..state, "lock", pos)
if not advtrains.is_passive(pos) then
itab(i, "-!- No passive component at "..pts..". Please reconfigure route!", "err", nil)
diff --git a/advtrains_interlocking/routesetting.lua b/advtrains_interlocking/routesetting.lua
index 28c8c3c..6544a92 100644
--- a/advtrains_interlocking/routesetting.lua
+++ b/advtrains_interlocking/routesetting.lua
@@ -104,7 +104,7 @@ function ilrs.set_route(signal, route, try)
end
for lp, state in pairs(c_locks) do
- local confl = ilrs.has_route_lock(pts, state)
+ local confl = ilrs.has_route_lock(lp, state)
local pos = advtrains.decode_pos(lp)
if advtrains.is_passive(pos) then
@@ -131,7 +131,8 @@ function ilrs.set_route(signal, route, try)
local nvar = c_rseg.next
if nvar then
local re_tcbs = ildb.get_tcbs({p = nvar.p, s = (nvar.s==1) and 2 or 1})
- if not re_tcbs or not re_tcbs.ts_id or re_tcbs.ts_id~=c_ts_id then
+ if (not re_tcbs or not re_tcbs.ts_id or re_tcbs.ts_id~=c_ts_id)
+ and route[i+1] then --FIX 2025-01-08: in old worlds the final TCB may be wrong (it didn't matter back then), don't error out here (route still shown invalid in UI)
if not try then atwarn("Encountered inconsistent ts (front~=back) while a real run of routesetting routine, at position",pts,"while setting route",rtename,"of",signal) end
return false, "TCB at "..minetest.pos_to_string(nvar.p).." has different section than previous TCB. Please update track section or reconfigure route!"
end
@@ -264,6 +265,11 @@ function ilrs.free_route_locks(ts, lcks, nocallbacks)
end
function ilrs.free_route_locks_indiv(pts, ts, nocallbacks)
+ -- legacy: if starts with bracket then pts is still in old pos_to_string format (may happen because ts.route_post is not migrated)
+ if string.match(pts, "^%(") then
+ atdebug("free_route_locks_indiv: converting position",pts)
+ pts = advtrains.encode_pos(minetest.string_to_pos(pts))
+ end
local e = ilrs.rte_locks[pts]
if not e then return nil
elseif #e==0 then
@@ -413,7 +419,9 @@ function ilrs.update_route(sigd, tcbs, newrte, cancel)
-- set_route now sets the signal aspects
--has_changed_aspect = true
-- route success. apply default_autoworking flag if requested
- tcbs.route_auto = route.default_autoworking
+ if route.default_autoworking then
+ tcbs.route_auto = true --FIX 2025-01-08: never set it to false if it was true!
+ end
end
end
if has_changed_aspect then
diff --git a/advtrains_interlocking/signal_api.lua b/advtrains_interlocking/signal_api.lua
index 9989907..f624f7a 100644
--- a/advtrains_interlocking/signal_api.lua
+++ b/advtrains_interlocking/signal_api.lua
@@ -375,6 +375,7 @@ function signal.reapply_aspect(pts)
local rem_aspt = signal.aspects[remote]
--atdebug("resolving remote",advtrains.decode_pos(remote),"aspt",rem_aspt)
local rem_pos = advtrains.decode_pos(remote)
+ local _,rem_ndef
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
@@ -441,7 +442,7 @@ function signal.can_dig(pos, player)
-- check privileges
if not player or not minetest.check_player_privs(player:get_player_name(), "interlocking") then
if not player then -- intermediate debug to uncover hard-to-find bugz
- atdebug("advtrains.interlocking.signal.can_dig(",pos,") called with player==nil!")
+ atwarn("advtrains.interlocking.signal.can_dig(",pos,") called with player==nil!")
end
return false
end
@@ -461,7 +462,11 @@ function signal.after_dig(pos, oldnode, oldmetadata, player)
advtrains.interlocking.db.unassign_signal_for_tcbs(sigd)
minetest.chat_send_player(player:get_player_name(), "Signal has been unassigned. Name and routes are kept for reuse.")
end
- -- TODO clear influence point
+ -- clear influence point
+ local ipts,iconnid = advtrains.interlocking.db.get_ip_by_signalpos(pos)
+ if ipts then
+ advtrains.interlocking.db.clear_ip_signal(ipts, iconnid)
+ end
advtrains.interlocking.signal.unregister_aspect(pos)
end
diff --git a/advtrains_interlocking/signal_aspect_ui.lua b/advtrains_interlocking/signal_aspect_ui.lua
index d67572c..98a332a 100644
--- a/advtrains_interlocking/signal_aspect_ui.lua
+++ b/advtrains_interlocking/signal_aspect_ui.lua
@@ -247,7 +247,9 @@ minetest.register_on_punchnode(function(pos, node, player, pointed_thing)
ipmarker(pos, plconnid)
minetest.chat_send_player(pname, "Configuring Signal: Successfully set influence point")
-- Try to find a TCB ahead and auto assign this signal there
- try_auto_assign_to_tcb(signalpos, pos, plconnid, pname)
+ if advtrains.interlocking.signal.get_signal_cap_level(signalpos) >= 2 then
+ try_auto_assign_to_tcb(signalpos, pos, plconnid, pname)
+ end
else
minetest.chat_send_player(pname, "Configuring Signal: Influence point of another signal is already present!")
end
diff --git a/advtrains_interlocking/smartroute.lua b/advtrains_interlocking/smartroute.lua
index 6479e44..f03ece0 100644
--- a/advtrains_interlocking/smartroute.lua
+++ b/advtrains_interlocking/smartroute.lua
@@ -64,7 +64,7 @@ function sr.rescan(pname, sigd, tcbs, find_more_than, searching_shunt, pname)
end
if not cur_restart then
-- we have no candidates left. Give up and return what we have
- atdebug("(SR) No Candidates left, end rescan")
+ --atdebug("(SR) No Candidates left, end rescan")
return found_routes
end
-- check if we need to stop due to having found enough routes
@@ -72,14 +72,14 @@ function sr.rescan(pname, sigd, tcbs, find_more_than, searching_shunt, pname)
if cur_len > last_len then
-- one level is finished, check if enoufh routes are found
if #found_routes > find_more_than then
- atdebug("(SR) Layer finished and enough routes found, end rescan")
+ --atdebug("(SR) Layer finished and enough routes found, end rescan")
return found_routes
end
last_len = cur_len
end
-- our current restart point is nouw in cur_restart
local c_sigd = cur_restart.sigd
- atdebug("(SR) Search continues at",c_sigd,"seqlen",#cur_restart.tcbseq)
+ --atdebug("(SR) Search continues at",c_sigd,"seqlen",#cur_restart.tcbseq)
-- do a TS repair, this also updates the RS cache should it be out of date
local c_ts_id = ildb.check_and_repair_ts_at_pos(c_sigd.p, c_sigd.s, pname, false)
if c_ts_id then
@@ -90,7 +90,7 @@ function sr.rescan(pname, sigd, tcbs, find_more_than, searching_shunt, pname)
for _, end_sigd in ipairs(c_ts.tc_breaks) do
end_pkey = advtrains.encode_pos(end_sigd.p)
if rsout[end_pkey] then
- atdebug("(SR) Section",c_ts_id,c_ts.name,"has way",c_sigd,"->",end_sigd)
+ --atdebug("(SR) Section",c_ts_id,c_ts.name,"has way",c_sigd,"->",end_sigd)
local nsigd = {p=end_sigd.p, s = end_sigd.s==1 and 2 or 1} -- invert to other side
-- record nsigd in the tcbseq
local ntcbseq = table.copy(cur_restart.tcbseq)
@@ -105,7 +105,7 @@ function sr.rescan(pname, sigd, tcbs, find_more_than, searching_shunt, pname)
or ndef.advtrains.route_role == "end" or ndef.advtrains.route_role == "shunt" then
-- signal is suitable target
local is_mainsignal = ndef.advtrains.route_role ~= "shunt"
- atdebug("(SR) Suitable end signal at",nsigd,", recording route!")
+ --atdebug("(SR) Suitable end signal at",nsigd,", recording route!")
-- record the found route in the results
found_routes[#found_routes+1] = {
tcbseq = ntcbseq,
@@ -114,7 +114,7 @@ function sr.rescan(pname, sigd, tcbs, find_more_than, searching_shunt, pname)
}
-- if this is a main signal and/or we are only searching shunt routes, stop the search here
if is_mainsignal or searching_shunt then
- atdebug("(SR) Not continuing this branch!")
+ --atdebug("(SR) Not continuing this branch!")
shall_continue = false
end
end
@@ -127,10 +127,10 @@ function sr.rescan(pname, sigd, tcbs, find_more_than, searching_shunt, pname)
end
end
else
- atdebug("(SR) Section",c_ts_id,c_ts.name,"found no rscache entry for start ",bgn_pts)
+ --atdebug("(SR) Section",c_ts_id,c_ts.name,"found no rscache entry for start ",bgn_pts)
end
else
- atdebug("(SR) Stop at",c_sigd,"because no sec ahead")
+ --atdebug("(SR) Stop at",c_sigd,"because no sec ahead")
end
end
end
@@ -200,10 +200,10 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
local endpoint = route[#route].next -- 'next' field of the last route segment (the segment with index==len)
if valid and endpoint then
local endstr = advtrains.interlocking.sigd_to_string(endpoint)
- atdebug("(Smartroute) Find existing endpoint:",route.name,"ends at",endstr)
+ --atdebug("(Smartroute) Find existing endpoint:",route.name,"ends at",endstr)
ex_endpts[endstr] = route.name
else
- atdebug("(Smartroute) Find existing endpoint:",route.name," not considered, endpoint",endpoint,"valid",valid)
+ --atdebug("(Smartroute) Find existing endpoint:",route.name," not considered, endpoint",endpoint,"valid",valid)
end
end
local new_frte = {}
@@ -213,7 +213,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
if not ex_endpts[endstr] then
new_frte[#new_frte+1] = froute
else
- atdebug("(Smartroute) Throwing away",froute.name,"because endpoint",endstr,"already reached by route",ex_endpts[endstr])
+ --atdebug("(Smartroute) Throwing away",froute.name,"because endpoint",endstr,"already reached by route",ex_endpts[endstr])
end
end
@@ -244,7 +244,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
end
end
end
- atdebug("Smartroute done!")
+ --atdebug("Smartroute done!")
advtrains.interlocking.show_signalling_form(sigd, pname, sel_rte)
players_smartroute_actions[pname] = nil
end
diff --git a/advtrains_interlocking/tcb_ts_ui.lua b/advtrains_interlocking/tcb_ts_ui.lua
index 59d3be4..814a11a 100755
--- a/advtrains_interlocking/tcb_ts_ui.lua
+++ b/advtrains_interlocking/tcb_ts_ui.lua
@@ -776,7 +776,7 @@ function advtrains.interlocking.check_route_valid(route, sigd)
if c_rseg.locks then
for pts, state in pairs(c_rseg.locks) do
- local pos = minetest.string_to_pos(pts)
+ local pos = advtrains.decode_pos(pts)
if not advtrains.is_passive(pos) then
return false, "No passive component for lock at "..pts
end
@@ -795,6 +795,9 @@ function advtrains.interlocking.check_route_valid(route, sigd)
i = i + 1
end
-- check end TCB
+ if not c_sigd then
+ return false, "Final TCBS unset (legacy-style buffer route)"
+ end
c_tcbs = ildb.get_tcbs(c_sigd)
if not c_tcbs then
return false, "Final TCBS missing at "..sigd_to_string(c_sigd)
diff --git a/advtrains_interlocking/train_sections.lua b/advtrains_interlocking/train_sections.lua
index 3dda7e8..a1ee87f 100644
--- a/advtrains_interlocking/train_sections.lua
+++ b/advtrains_interlocking/train_sections.lua
@@ -40,37 +40,50 @@ local function itkexist(tbl, ikey, com)
return false
end
-local function itremove(tbl, com)
+local function itremove(tbl, com, once)
local i=1
while i <= #tbl do
if tbl[i] == com then
table.remove(tbl, i)
+ if once then return end
else
i = i + 1
end
end
end
-local function itkremove(tbl, ikey, com)
+local function itkremove(tbl, ikey, com, once)
local i=1
while i <= #tbl do
if tbl[i][ikey] == com then
table.remove(tbl, i)
+ if once then return end
else
i = i + 1
end
end
end
-local function setsection(tid, train, ts_id, ts, sigd)
+local function setsection(tid, train, ts_id, ts, sigd, only_if_not_exist)
-- train
if not train.il_sections then train.il_sections = {} end
- if not itkexist(train.il_sections, "ts_id", ts_id) then
+ if only_if_not_exist then
+ -- called for the back connid on enter, only to ensure that section is blocked if train was so far not registered
+ if not itkexist(train.il_sections, "ts_id", ts_id) then
+ table.insert(train.il_sections, {ts_id = ts_id, origin = sigd})
+ end
+ else
+ -- insert always, this leads to duplicate entries if the train enters the same section a second time
table.insert(train.il_sections, {ts_id = ts_id, origin = sigd})
end
-- ts
if not ts.trains then ts.trains = {} end
- if not itexist(ts.trains, tid) then
+ if only_if_not_exist then
+ -- called for the back connid on enter, only to ensure that section is blocked if train was so far not registered
+ if not itexist(ts.trains, tid) then
+ table.insert(ts.trains, tid)
+ end
+ else
table.insert(ts.trains, tid)
end
@@ -110,15 +123,16 @@ local function setsection(tid, train, ts_id, ts, sigd)
end
end
-local function freesection(tid, train, ts_id, ts)
+local function freesection(tid, train, ts_id, ts, clear_all)
-- train
if not train.il_sections then train.il_sections = {} end
- itkremove(train.il_sections, "ts_id", ts_id)
+ itkremove(train.il_sections, "ts_id", ts_id, not clear_all)
-- ts
if not ts.trains then ts.trains = {} end
- itremove(ts.trains, tid)
+ itremove(ts.trains, tid, not clear_all)
+ -- route locks
if ts.route_post then
advtrains.interlocking.route.free_route_locks(ts_id, ts.route_post.locks)
if ts.route_post.next then
@@ -140,12 +154,18 @@ end
-- This sets the section for both directions, to be failsafe
advtrains.tnc_register_on_enter(function(pos, id, train, index)
local tcb = ildb.get_tcb(pos)
- if tcb then
- for connid=1,2 do
- local ts = tcb[connid].ts_id and ildb.get_ts(tcb[connid].ts_id)
- if ts then
- setsection(id, train, tcb[connid].ts_id, ts, {p=pos, s=connid})
- end
+ if tcb and train.path_cp[index] and train.path_cn[index] then
+ -- forward conn
+ local connid = train.path_cn[index]
+ local ts = tcb[connid] and tcb[connid].ts_id and ildb.get_ts(tcb[connid].ts_id)
+ if ts then
+ setsection(id, train, tcb[connid].ts_id, ts, {p=pos, s=connid})
+ end
+ -- backward conn (safety only)
+ connid = train.path_cp[index]
+ ts = tcb[connid] and tcb[connid].ts_id and ildb.get_ts(tcb[connid].ts_id)
+ if ts then
+ setsection(id, train, tcb[connid].ts_id, ts, {p=pos, s=connid}, true)
end
end
end)
@@ -155,8 +175,9 @@ end)
advtrains.tnc_register_on_leave(function(pos, id, train, index)
local tcb = ildb.get_tcb(pos)
if tcb and train.path_cp[index] then
+ -- backward conn
local connid = train.path_cp[index]
- local ts = tcb[connid].ts_id and ildb.get_ts(tcb[connid].ts_id)
+ local ts = tcb[connid] and tcb[connid].ts_id and ildb.get_ts(tcb[connid].ts_id)
if ts then
freesection(id, train, tcb[connid].ts_id, ts)
end
@@ -173,7 +194,7 @@ advtrains.te_register_on_create(function(id, train)
if ts_id then
local ts = ildb.get_ts(ts_id)
if ts then
- setsection(id, train, ts_id, ts, nil)
+ setsection(id, train, ts_id, ts, nil, true)
else
atwarn("While placing train, TS didnt exist ",ts_id)
end
diff --git a/advtrains_line_automation/stoprail.lua b/advtrains_line_automation/stoprail.lua
index 2c96d6c..ba3977d 100644
--- a/advtrains_line_automation/stoprail.lua
+++ b/advtrains_line_automation/stoprail.lua
@@ -59,8 +59,9 @@ local function show_stoprailform(pos, player)
form = form.."field[6.05,2.0;1.75,1;wait;"..attrans("Stop Time")..";"..stdata.wait.."]"
form = form.."label[0.5,2.6;"..attrans("Door Side").."]"
form = form.."dropdown[0.51,3.0;2;doors;Left,Right,Closed;"..door_dropdown[stdata.doors].."]"
- form = form.."checkbox[3.00,2.7;reverse;"..attrans("Reverse train")..";"..(stdata.reverse and "true" or "false").."]"
- form = form.."checkbox[3.00,3.1;kick;"..attrans("Kick out passengers")..";"..(stdata.kick and "true" or "false").."]"
+ form = form.."checkbox[3.00,2.4;reverse;"..attrans("Reverse train")..";"..(stdata.reverse and "true" or "false").."]"
+ form = form.."checkbox[3.00,2.8;kick;"..attrans("Kick out passengers")..";"..(stdata.kick and "true" or "false").."]"
+ form = form.."checkbox[3.00,3.2;waitsig;"..attrans("Wait for signal to clear")..";"..(stdata.waitsig and "true" or "false").."]"
form = form.."textarea[0.8,4.2;7,2;ars;Trains stopping here (ARS rules);"..advtrains.interlocking.ars_to_text(stdata.ars).."]"
form = form.."button[0.5,6;7,1;save;"..attrans("Save").."]"
@@ -87,6 +88,9 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
if fields.reverse then
tmp_checkboxes[pe].reverse = (fields.reverse == "true")
end
+ if fields.waitsig then
+ tmp_checkboxes[pe].waitsig = (fields.waitsig == "true")
+ end
if fields.save then
if fields.stn and stdata.stn ~= fields.stn and fields.stn ~= "" then
local stn = advtrains.lines.stations[fields.stn]
@@ -153,7 +157,7 @@ local adefunc = function(def, preset, suffix, rotation)
after_place_node=function(pos)
local pe = advtrains.encode_pos(pos)
advtrains.lines.stops[pe] = {
- stn="", track="", doors="R", wait=10
+ stn="", track="", doors="R", wait=10, waitsig = true
}
updatemeta(pos)
end,
@@ -199,7 +203,10 @@ local adefunc = function(def, preset, suffix, rotation)
local stnname = stn and stn.name or "Unknown Station"
-- Send ATC command and set text
- advtrains.atc.train_set_command(train, "B0 W O"..stdata.doors..(stdata.kick and "K" or "").." D"..stdata.wait.." OC "..(stdata.reverse and "R" or "").."D"..(stdata.ddelay or 1) .. " A1 S" ..(stdata.speed or "M"), true)
+ advtrains.atc.train_set_command(train, "B0 W O"..stdata.doors..(stdata.kick and "K" or "")
+ .." D"..stdata.wait.." "..(stdata.reverse and "R" or "")
+ .." A1 "..(stdata.waitsig and "G" or "")
+ .." OC D"..(stdata.ddelay or 1) .. " S" ..(stdata.speed or "M"), true)
train.text_inside = stnname
if tonumber(stdata.wait) then
minetest.after(tonumber(stdata.wait), function() train.text_inside = "" end)
diff --git a/advtrains_luaautomation/environment.lua b/advtrains_luaautomation/environment.lua
index b54d45c..a6ed2c7 100644
--- a/advtrains_luaautomation/environment.lua
+++ b/advtrains_luaautomation/environment.lua
@@ -226,11 +226,15 @@ if advtrains.interlocking then
end
static_env.get_aspect = function(signal)
local pos = atlatc.pcnaming.resolve_pos(signal)
- return advtrains.interlocking.signal_get_aspect(pos)
+ return advtrains.interlocking.signal.get_aspect_info(pos)
end
- static_env.set_aspect = function(signal, asp)
+ static_env.set_aspect = function(signal, main_asp, rem_signal)
+ if type(main_asp) == "table" then
+ error("set_aspect: Parameters of this method have changed to (signal, main_asp, rem_signal) with introduction of distant signalling: parameter 2 is now the main aspect name (a string)")
+ end
local pos = atlatc.pcnaming.resolve_pos(signal)
- return advtrains.interlocking.signal_set_aspect(pos,asp)
+ local rem_pos = rem_signal and atlatc.pcnaming.resolve_pos(rem_signal)
+ return advtrains.interlocking.signal_set_aspect(pos, main_asp, rem_pos)
end
--section_occupancy()
diff --git a/advtrains_signals_ks/init.lua b/advtrains_signals_ks/init.lua
index 7c78dea..326c631 100755
--- a/advtrains_signals_ks/init.lua
+++ b/advtrains_signals_ks/init.lua
@@ -476,7 +476,7 @@ for _, rtab in ipairs({
["16"] = {main = 16, n = "e"},
["e"] = {main = -1, n = "4"},
} do
- local tile2 = "advtrains_signals_ks_sign_lf7.png^(advtrains_signals_ks_sign_"..typ..".png^[makealpha:255,255,255)"..(typ == "e" and "" or "^[multiply:orange")
+ local tile2 = "advtrains_signals_ks_sign_lf7.png^(advtrains_signals_ks_sign_"..typ..".png^[makealpha:255,255,255)^[multiply:orange"
local inv = "advtrains_signals_ks_sign_lf7.png^(advtrains_signals_ks_sign_8.png^[makealpha:255,255,255)^[multiply:orange"
register_sign("sign_lf", typ, prts.n, "Temporary local speed restriction sign", "sign", tile2, "8", inv, {main = prts.main, shunt = true, type = "temp"})
end
@@ -486,8 +486,8 @@ for _, rtab in ipairs({
["6"] = {main = 6, n = "8"},
["8"] = {main = 8, n = "12"},
["12"] = {main = 12, n = "16"},
- ["16"] = {main = 16, n = "20"},
- ["20"] = {main = 20, n = "4"},
+ ["16"] = {main = 16, n = "e"},
+ ["e"] = {main = -1, n = "4"},
} do
local tile2 = "advtrains_signals_ks_sign_lf7.png^(advtrains_signals_ks_sign_"..typ..".png^[makealpha:255,255,255)"
local inv = "advtrains_signals_ks_sign_lf7.png^(advtrains_signals_ks_sign_8.png^[makealpha:255,255,255)"
@@ -532,7 +532,7 @@ for _, rtab in ipairs({
t.advtrains = {
trackworker_next_rot = "advtrains_signals_ks:zs3_"..typ.."_"..rtab.nextrot,
trackworker_rot_incr_param2 = (rot=="60")
- },
+ }
minetest.register_node("advtrains_signals_ks:zs3_"..typ.."_"..rot, t)
--TODO add rotation using trackworker
@@ -545,7 +545,7 @@ for _, rtab in ipairs({
t.advtrains = {
trackworker_next_rot = "advtrains_signals_ks:zs3v_"..typ.."_"..rtab.nextrot,
trackworker_rot_incr_param2 = (rot=="60")
- },
+ }
minetest.register_node("advtrains_signals_ks:zs3v_"..typ.."_"..rot, t)
--TODO add rotation using trackworker
end
diff --git a/make_release.sh b/make_release.sh
new file mode 100755
index 0000000..d6ae82a
--- /dev/null
+++ b/make_release.sh
@@ -0,0 +1,53 @@
+#!/bin/sh
+
+# get version argument
+VERS="$1"
+if [ ! "$VERS" ];then
+ echo "Argument version expected: example ./make_release.sh 2.5.0"
+ exit 1
+fi
+
+# cd to root dir
+cd "$(dirname "$0")"
+AROOT="$(pwd)"
+echo "Working directory is: $AROOT"
+# create temp directory
+TMP=$(mktemp -d -t advtrains-XXXX)
+echo "Temp directory is: $TMP"
+mkdir "$TMP/advtrains"
+TDIR="$TMP/advtrains/"
+
+# copy dirs
+cp -r "advtrains" "$TDIR"
+cp -r "advtrains_interlocking" "$TDIR"
+cp -r "advtrains_line_automation" "$TDIR"
+cp -r "advtrains_luaautomation" "$TDIR"
+cp -r "advtrains_signals_ks" "$TDIR"
+cp -r "advtrains_signals_japan" "$TDIR"
+cp -r "advtrains_signals_muc_ubahn" "$TDIR"
+cp -r "advtrains_train_track" "$TDIR"
+cp -r "serialize_lib" "$TDIR"
+
+# copy files
+cp "atc_command.txt" "$TDIR"
+cp "description.txt" "$TDIR"
+cp "license.txt" "$TDIR"
+cp "license_media.txt" "$TDIR"
+cp "modpack.conf" "$TDIR"
+cp "privilege_guide.txt" "$TDIR"
+cp "README.md" "$TDIR"
+cp "screenshot.png" "$TDIR"
+
+# compress to zip archive
+ZIPNAME="$AROOT/advtrains_$VERS.zip"
+echo "Target ZIP file is: $ZIPNAME"
+cd "$TMP"
+zip -r "$ZIPNAME" "advtrains"
+cd "$AROOT"
+
+# success
+echo "Release $VERS created at: $ZIPNAME"
+
+# remove tempdir
+rm -rf "$TMP"
+