From ea074b2a3378c1b79d37d0dd94947ebbaf8ece32 Mon Sep 17 00:00:00 2001 From: orwell Date: Sun, 15 Oct 2023 16:40:10 +0200 Subject: Re-implement point origin handling (replace old points_split hack by proper solution) --- advtrains/init.lua | 2 +- advtrains/nodedb.lua | 2 +- advtrains/path.lua | 17 +++++++++++------ advtrains/trainlogic.lua | 48 ++++++++++++++++++++++++++++-------------------- 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 -- cgit v1.2.3