From 2067ab0a90550b2fc513e032d4c4e54dd11a2290 Mon Sep 17 00:00:00 2001 From: orwell Date: Sun, 15 Oct 2023 15:48:59 +0200 Subject: Use conn_map in the path calculation --- advtrains/debugitems.lua | 19 +++++++++++++++++++ advtrains/helpers.lua | 41 +++++++++++++++++++++++++++-------------- advtrains/nodedb.lua | 4 ++-- advtrains/passive.lua | 2 ++ advtrains/path.lua | 28 +++++++++++----------------- advtrains/track_reg_helper.lua | 6 +++--- advtrains/tracks.lua | 4 +++- 7 files changed, 67 insertions(+), 37 deletions(-) diff --git a/advtrains/debugitems.lua b/advtrains/debugitems.lua index a59efc7..2236cba 100644 --- a/advtrains/debugitems.lua +++ b/advtrains/debugitems.lua @@ -118,3 +118,22 @@ minetest.register_tool("advtrains:trackitest", end, } ) + +minetest.register_chatcommand("at_trackdef_audit", + { + params = "", + description = "Performs an audit of all track definitions currently loaded and checks for potential problems", + func = function(name, param) + for name, ndef in pairs(minetest.registered_nodes) do + --TODO finish this! + if ndef.at_conns then + -- check if conn_map is there and if it has enough entries + if #ndef.at_conns > 2 then + if #ndef.at_conn_map < #ndef.at_conns then + atwarn("AUDIT: Node",name,"- Not enough connmap entries! Check ndef:",ndef) + end + end + end + end + end, +}) diff --git a/advtrains/helpers.lua b/advtrains/helpers.lua index 7a774d9..d7e691d 100644 --- a/advtrains/helpers.lua +++ b/advtrains/helpers.lua @@ -292,7 +292,7 @@ function advtrains.conn_matches_to(conn, other_conns) end -- Going from the rail at pos (does not need to be rounded) along connection with id conn_idx, if there is a matching rail, return it and the matching connid --- returns: , , , +-- returns: , , , , (adjacent conns table), (adjacent connmap table) -- parameter this_conns_p is connection table of this rail and is optional, is determined by get_rail_info_at if not provided. function advtrains.get_adjacent_rail(this_posnr, this_conns_p, conn_idx) local this_pos = advtrains.round_vector_floor_y(this_posnr) @@ -303,8 +303,8 @@ function advtrains.get_adjacent_rail(this_posnr, this_conns_p, conn_idx) end if not conn_idx then for coni, _ in ipairs(this_conns) do - local adj_pos, adj_conn_idx, _, nry, nco = advtrains.get_adjacent_rail(this_pos, this_conns, coni) - if adj_pos then return adj_pos,adj_conn_idx,coni,nry, nco end + local adj_pos, adj_conn_idx, _, nry, nco, ncm = advtrains.get_adjacent_rail(this_pos, this_conns, coni) + if adj_pos then return adj_pos,adj_conn_idx,coni,nry, nco, ncm end end return nil end @@ -318,29 +318,40 @@ function advtrains.get_adjacent_rail(this_posnr, this_conns_p, conn_idx) adj_pos.y = adj_pos.y + 1 end - local nextnode_ok, nextconns, nextrail_y=advtrains.get_rail_info_at(adj_pos) + local nextnode_ok, nextconns, nextrail_y, nextconnmap=advtrains.get_rail_info_at(adj_pos) if not nextnode_ok then adj_pos.y = adj_pos.y - 1 conn_y = conn_y + 1 - nextnode_ok, nextconns, nextrail_y=advtrains.get_rail_info_at(adj_pos) + nextnode_ok, nextconns, nextrail_y, nextconnmap=advtrains.get_rail_info_at(adj_pos) if not nextnode_ok then return nil end end local adj_connid = advtrains.conn_matches_to({c=conn.c, y=conn_y}, nextconns) if adj_connid then - return adj_pos, adj_connid, conn_idx, nextrail_y, nextconns + return adj_pos, adj_connid, conn_idx, nextrail_y, nextconns, nextconnmap end return nil end -- when a train enters a rail on connid 'conn', which connid will it go out? --- nconns: number of connections in connection table: --- 2 = straight rail; 3 = turnout, 4 = crossing, 5 = three-way turnout (5th entry is a stub) +-- Since 2.5: This mapping is contained in the conn_map table in the node definition! -- returns: connid_out -local connlku={[2]={2,1}, [3]={2,1,1}, [4]={2,1,4,3}, [5]={2,1,1,1}} -function advtrains.get_matching_conn(conn, nconns) - return connlku[nconns][conn] +function advtrains.get_matching_conn(conn, conn_map) + if tonumber(conn_map) then + error("Legacy call to get_matching_conn! Instead of nconns, conn_map needs to be provided!") + end + if not conn_map then + --OK for two-conn rails, just return the other + if conn==1 then return 2 end + if conn==2 then return 1 end + error("get_matching_conn: For connid >=3, conn_map must not be nil!") + end + local cout = conn_map[conn] + if not cout then + error("get_matching_conn: Connid "..conn.." not found in conn_map which is "..atdump(conn_map)) + end + return cout end function advtrains.random_id(lenp) @@ -495,10 +506,11 @@ local trackiter_mt = { next_branch = function(self) local br = table.remove(self.branches, 1) -- Advance internal state - local adj_pos, adj_connid, _, _, adj_conns = advtrains.get_adjacent_rail(br.pos, nil, br.connid) + local adj_pos, adj_connid, _, _, adj_conns, adj_connmap = advtrains.get_adjacent_rail(br.pos, nil, br.connid) self.pos = adj_pos self.bconnid = adj_connid self.tconns = adj_conns + self.tconnmap = adj_connmap self.limit = br.limit - 1 self.visited[advtrains.encode_pos(br.pos)] = true self.last_track_already_visited = false @@ -524,7 +536,7 @@ local trackiter_mt = { end -- select next conn (main conn to follow is the associated connection) local old_bconnid = self.bconnid - local mconnid = advtrains.get_matching_conn(self.bconnid, #self.tconns) + local mconnid = advtrains.get_matching_conn(self.bconnid, self.tconnmap) if self.visited[advtrains.encode_pos(pos)] then -- node was already seen -- Due to special requirements for the track section updater, return this first already visited track once @@ -540,10 +552,11 @@ local trackiter_mt = { end end -- Advance internal state - local adj_pos, adj_connid, _, _, adj_conns = advtrains.get_adjacent_rail(pos, self.tconns, mconnid) + local adj_pos, adj_connid, _, _, adj_conns, adj_connmap = advtrains.get_adjacent_rail(pos, self.tconns, mconnid) self.pos = adj_pos self.bconnid = adj_connid self.tconns = adj_conns + self.tconnmap = adj_connmap self.limit = self.limit - 1 self.visited[advtrains.encode_pos(pos)] = true self.last_track_already_visited = false diff --git a/advtrains/nodedb.lua b/advtrains/nodedb.lua index 39106b2..d903be7 100644 --- a/advtrains/nodedb.lua +++ b/advtrains/nodedb.lua @@ -278,9 +278,9 @@ function advtrains.get_rail_info_at(pos) if(not advtrains.is_track(nodename)) then return false end - local conns, railheight = advtrains.get_track_connections(node.name, node.param2) + local conns, railheight, connmap = advtrains.get_track_connections(node.name, node.param2) - return true, conns, railheight + return true, conns, railheight, connmap end local IGNORE_WORLD = advtrains.IGNORE_WORLD diff --git a/advtrains/passive.lua b/advtrains/passive.lua index 76da720..741d7df 100644 --- a/advtrains/passive.lua +++ b/advtrains/passive.lua @@ -68,6 +68,8 @@ function advtrains.setstate(parpos, newstate, pnode) if ndef.advtrains.node_on_switch_state then ndef.advtrains.node_on_switch_state(pos, new_node, old_state, newstate) end + -- invalidate paths (only relevant if this is a track) + advtrains.invalidate_all_paths(pos) return true end diff --git a/advtrains/path.lua b/advtrains/path.lua index 72ee05d..588140d 100644 --- a/advtrains/path.lua +++ b/advtrains/path.lua @@ -38,11 +38,11 @@ -- false - node definitely gone, remove train function advtrains.path_create(train, pos, connid, rel_index) local posr = advtrains.round_vector_floor_y(pos) - local node_ok, conns, rhe = advtrains.get_rail_info_at(pos) + local node_ok, conns, rhe, connmap = advtrains.get_rail_info_at(pos) if not node_ok then return node_ok end - local mconnid = advtrains.get_matching_conn(connid, #conns) + local mconnid = advtrains.get_matching_conn(connid, connmap) train.index = rel_index train.path = { [0] = { x=posr.x, y=posr.y+rhe, z=posr.z } } train.path_cn = { [0] = connid } @@ -206,22 +206,19 @@ function advtrains.path_get(train, index) while index > pef do local pos = train.path[pef] local connid = train.path_cn[pef] - local node_ok, this_conns, adj_pos, adj_connid, conn_idx, nextrail_y, next_conns + local node_ok, this_conns, adj_pos, adj_connid, conn_idx, nextrail_y, next_conns, next_connmap if pef == train.path_trk_f then node_ok, this_conns = advtrains.get_rail_info_at(pos) if not node_ok then error("For train "..train.id..": Path item "..pef.." on-track but not a valid node!") end - adj_pos, adj_connid, conn_idx, nextrail_y, next_conns = advtrains.get_adjacent_rail(pos, this_conns, connid) + adj_pos, adj_connid, conn_idx, nextrail_y, next_conns, next_connmap = advtrains.get_adjacent_rail(pos, this_conns, connid) end pef = pef + 1 if adj_pos then 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 - local mconnid = advtrains.get_matching_conn(adj_connid, #next_conns) - if #next_conns==3 and adj_connid==1 and train.points_split and train.points_split[advtrains.encode_pos(adj_pos)] then - --atdebug(id,"has split points restored at",adj_pos) - mconnid = 3 - end + -- TODO readd support for split points (remember the cp and cn of points) adj_pos.y = adj_pos.y + nextrail_y train.path_cp[pef] = adj_connid @@ -245,22 +242,19 @@ function advtrains.path_get(train, index) while index < peb do local pos = train.path[peb] local connid = train.path_cp[peb] - local node_ok, this_conns, adj_pos, adj_connid, conn_idx, nextrail_y, next_conns + local node_ok, this_conns, adj_pos, adj_connid, conn_idx, nextrail_y, next_conns, next_connmap if peb == train.path_trk_b then node_ok, this_conns = advtrains.get_rail_info_at(pos) if not node_ok then error("For train "..train.id..": Path item "..peb.." on-track but not a valid node!") end - adj_pos, adj_connid, conn_idx, nextrail_y, next_conns = advtrains.get_adjacent_rail(pos, this_conns, connid) + adj_pos, adj_connid, conn_idx, nextrail_y, next_conns, next_connmap = advtrains.get_adjacent_rail(pos, this_conns, connid) end peb = peb - 1 if adj_pos then 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 - local mconnid = advtrains.get_matching_conn(adj_connid, #next_conns) - if #next_conns==3 and adj_connid==1 and train.points_split and train.points_split[advtrains.encode_pos(adj_pos)] then - -- atdebug(id,"has split points restored at",adj_pos) - mconnid = 3 - end + -- TODO readd support for split points (remember the cp and cn of points) adj_pos.y = adj_pos.y + nextrail_y train.path_cn[peb] = adj_connid diff --git a/advtrains/track_reg_helper.lua b/advtrains/track_reg_helper.lua index ad73a40..dbb2d53 100644 --- a/advtrains/track_reg_helper.lua +++ b/advtrains/track_reg_helper.lua @@ -129,7 +129,7 @@ advtrains.ap.t_s3way={ switchalt = "s", switchst="l", switchprefix = "", - conn_map = {2,1,1}, + conn_map = {2,1,1,1}, stmref = "sw", }, s={ @@ -138,7 +138,7 @@ advtrains.ap.t_s3way={ switchalt ="r", switchst = "s", switchprefix = "", - conn_map = {3,1,1}, + conn_map = {3,1,1,1}, stmref = "sw", tpsingle = true, }, @@ -148,7 +148,7 @@ advtrains.ap.t_s3way={ switchalt = "l", switchst="r", switchprefix = "", - conn_map = {4,1,1}, + conn_map = {4,1,1,1}, stmref = "sw", } }, diff --git a/advtrains/tracks.lua b/advtrains/tracks.lua index 1abef59..661da8a 100644 --- a/advtrains/tracks.lua +++ b/advtrains/tracks.lua @@ -235,6 +235,8 @@ function advtrains.is_track(nodename) return false end +-- returns the connection tables of the track with given node details +-- returns: conns table, railheight, conn_map table function advtrains.get_track_connections(name, param2) local nodedef=minetest.registered_nodes[name] if not nodedef then atprint(" get_track_connections couldn't find nodedef for nodename "..(name or "nil")) return nil end @@ -246,7 +248,7 @@ function advtrains.get_track_connections(name, param2) return nil end --atdebug("Track connections of ",name,param2,":",nodedef.at_conns) - return advtrains.rotate_conn_by(nodedef.at_conns, noderot*AT_CMAX/4), (nodedef.at_rail_y or 0), tracktype + return advtrains.rotate_conn_by(nodedef.at_conns, noderot*AT_CMAX/4), (nodedef.at_rail_y or 0), nodedef.at_conn_map end -- Function called when a track is about to be dug or modified by the trackworker -- cgit v1.2.3