aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authororwell <orwell@bleipb.de>2023-10-15 16:40:10 +0200
committerorwell <orwell@bleipb.de>2023-10-15 16:40:10 +0200
commitea074b2a3378c1b79d37d0dd94947ebbaf8ece32 (patch)
treef8dce610bf888a3c107aef6d75201415e6d2b250
parent2067ab0a90550b2fc513e032d4c4e54dd11a2290 (diff)
downloadadvtrains-ea074b2a3378c1b79d37d0dd94947ebbaf8ece32.tar.gz
advtrains-ea074b2a3378c1b79d37d0dd94947ebbaf8ece32.tar.bz2
advtrains-ea074b2a3378c1b79d37d0dd94947ebbaf8ece32.zip
Re-implement point origin handling (replace old points_split hack by proper solution)
-rw-r--r--advtrains/init.lua2
-rw-r--r--advtrains/nodedb.lua2
-rw-r--r--advtrains/path.lua17
-rw-r--r--advtrains/trainlogic.lua48
4 files changed, 41 insertions, 28 deletions
diff --git a/advtrains/init.lua b/advtrains/init.lua
index 78126e5..a5f12f7 100644
--- a/advtrains/init.lua
+++ b/advtrains/init.lua
@@ -474,7 +474,7 @@ advtrains.avt_save = function(remove_players_from_wagons)
"atc_brake_target", "atc_wait_finish", "atc_command", "atc_delay", "door_open",
"text_outside", "text_inside", "line", "routingcode",
"il_sections", "speed_restriction", "speed_restrictions_t", "is_shunt",
- "points_split", "autocouple", "atc_wait_autocouple", "ars_disable",
+ "path_ori_cp", "autocouple", "atc_wait_autocouple", "ars_disable",
})
--then save it
tmp_trains[id]=v
diff --git a/advtrains/nodedb.lua b/advtrains/nodedb.lua
index d903be7..ff07df4 100644
--- a/advtrains/nodedb.lua
+++ b/advtrains/nodedb.lua
@@ -264,7 +264,7 @@ end
--get_node with pseudoload. now we only need track data, so we can use the trackdb as second fallback
--nothing new will be saved inside the trackdb.
--returns:
---true, conn1, conn2, rely1, rely2, railheight in case everything's right.
+--true, conns, railheight, connmap in case everything's right.
--false if it's not a rail or the train does not drive on this rail, but it is loaded or
--nil if the node is neither loaded nor in trackdb
--the distraction between false and nil will be needed only in special cases.(train initpos)
diff --git a/advtrains/path.lua b/advtrains/path.lua
index 588140d..28df529 100644
--- a/advtrains/path.lua
+++ b/advtrains/path.lua
@@ -217,9 +217,8 @@ function advtrains.path_get(train, index)
advtrains.occ.set_item(train.id, adj_pos, pef)
local mconnid = advtrains.get_matching_conn(adj_connid, next_connmap)
- -- If we have split points, notify accordingly
- -- TODO readd support for split points (remember the cp and cn of points)
-
+ -- NO split points handling here. It is only required for backwards path calculation
+
adj_pos.y = adj_pos.y + nextrail_y
train.path_cp[pef] = adj_connid
train.path_cn[pef] = mconnid
@@ -253,9 +252,15 @@ function advtrains.path_get(train, index)
advtrains.occ.set_item(train.id, adj_pos, peb)
local mconnid = advtrains.get_matching_conn(adj_connid, next_connmap)
- -- If we have split points, notify accordingly
- -- TODO readd support for split points (remember the cp and cn of points)
-
+ -- If, for this position, we have remembered the origin conn, apply it here
+ if next_connmap then -- only needs to be done when this track is a turnout (>2 conns)
+ local origin_conn = train.path_ori_cp[advtrains.encode_pos(adj_pos)]
+ if origin_conn then
+ atdebug("Train",train.id,"at",adj_pos,"restoring turnout origin CP",origin_conn,"for path item",index)
+ mconnid = origin_conn
+ end
+ end
+
adj_pos.y = adj_pos.y + nextrail_y
train.path_cn[peb] = adj_connid
train.path_cp[peb] = mconnid
diff --git a/advtrains/trainlogic.lua b/advtrains/trainlogic.lua
index c6762c9..cb1f9a6 100644
--- a/advtrains/trainlogic.lua
+++ b/advtrains/trainlogic.lua
@@ -280,8 +280,10 @@ function advtrains.train_ensure_init(id, train)
assertdef(train, "velocity", 0)
--assertdef(train, "tarvelocity", 0)
assertdef(train, "acceleration", 0)
- assertdef(train, "id", id)
-
+ if train.id ~= id then
+ train.id = id
+ end
+ assertdef(train, "path_ori_cp", {})
if not train.max_speed then
--atprint("in ensure_init: missing properties, updating!")
@@ -861,13 +863,10 @@ local function tnc_call_enter_callback(pos, train_id, train, index)
run_callbacks_enter_node(pos, train_id, train, index)
-- check for split points
- if mregnode and mregnode.at_conns and #mregnode.at_conns == 3 and train.path_cp[index] == 3 then
- -- train came from connection 3 of a switch, so it split points.
- if not train.points_split then
- train.points_split = {}
- end
- train.points_split[advtrains.encode_pos(pos)] = true
- --atdebug(train_id,"split points at",pos)
+ if mregnode and mregnode.at_conn_map then
+ -- If this node has >2 conns (and a connmap), remember the connection where we came from to handle split points
+ atdebug("Train",train_id,"at",pos,"saving turnout origin CP",train.path_cp[index],"for path item",index)
+ train.path_ori_cp[advtrains.encode_pos(pos)] = train.path_cp[index]
end
end
local function tnc_call_leave_callback(pos, train_id, train, index)
@@ -882,18 +881,11 @@ local function tnc_call_leave_callback(pos, train_id, train, index)
run_callbacks_leave_node(pos, train_id, train, index)
-- split points do not matter anymore. clear them
- if train.points_split then
- if train.points_split[advtrains.encode_pos(pos)] then
- train.points_split[advtrains.encode_pos(pos)] = nil
- --atdebug(train_id,"has passed split points at",pos)
- end
- -- any entries left?
- for _,_ in pairs(train.points_split) do
- return
- end
- train.points_split = nil
+ if mregnode and mregnode.at_conn_map then
+ -- If this node has >2 conns (and a connmap), remember the connection where we came from to handle split points
+ atdebug("Train",train_id,"at",pos,"removing turnout origin CP for path item",index," because train has left it")
+ train.path_ori_cp[advtrains.encode_pos(pos)] = nil
end
- -- WARNING possibly unreachable place!
end
function advtrains.tnc_call_approach_callback(pos, train_id, train, index, lzbdata)
@@ -1189,8 +1181,24 @@ function advtrains.invert_train(train_id)
return
end
+ -- Before flipping the train, we must check if there are any points on the path
+ -- which will become split on rotating, and store their cn (which will become the cp)
+ local ori_cp_after_flip = {}
+ for index = atround(train.end_index),atround(train.index) do
+ local pos = advtrains.path_get(train, index)
+ local ok, conns, railheight, connmap = advtrains.get_rail_info_at(pos)
+ if ok and connmap then
+ atdebug("Reversing Train",train.id," ori_cp Checks: at",pos,"saving turnout origin CP",train.path_cn[index],"for path item",index)
+ ori_cp_after_flip[advtrains.encode_pos(pos)] = train.path_cn[index]
+ end
+ end
+
+ -- Actual rotation happens here! This sets the path restore position to the end of the train, inverting the connid.
advtrains.path_setrestore(train, true)
+ -- clear the origin cp list because it is now invalid, and replace it by what we built prior.
+ train.path_ori_cp = ori_cp_after_flip
+
-- rotate some other stuff
if train.door_open then
train.door_open = - train.door_open