-- autorouting for pneumatic tubes local function is_tube(nodename) return pipeworks.table_contains(pipeworks.tubenodes, nodename) end --a function for determining which side of the node we are on local function nodeside(node, tubedir) if node.param2 < 0 or node.param2 > 23 then node.param2 = 0 end local backdir = minetest.facedir_to_dir(node.param2) local back = pipeworks.vector_dot(backdir, tubedir) if back == 1 then return "back" elseif back == -1 then return "front" end local topdir = pipeworks.facedir_to_top_dir(node.param2) local top = pipeworks.vector_dot(topdir, tubedir) if top == 1 then return "top" elseif top == -1 then return "bottom" end local rightdir = pipeworks.facedir_to_right_dir(node.param2) local right = pipeworks.vector_dot(rightdir, tubedir) if right == 1 then return "right" else return "left" end end local vts = {0, 3, 1, 4, 2, 5} local tube_table = {[0] = 1, 2, 2, 4, 2, 4, 4, 5, 2, 3, 4, 6, 4, 6, 5, 7, 2, 4, 3, 6, 4, 5, 6, 7, 4, 6, 6, 8, 5, 7, 7, 9, 2, 4, 4, 5, 3, 6, 6, 7, 4, 6, 5, 7, 6, 8, 7, 9, 4, 5, 6, 7, 6, 7, 8, 9, 5, 7, 7, 9, 7, 9, 9, 10} local tube_table_facedirs = {[0] = 0, 0, 5, 0, 3, 4, 3, 0, 2, 0, 2, 0, 6, 4, 3, 0, 7, 12, 5, 12, 7, 4, 5, 5, 18, 20, 16, 0, 7, 4, 7, 0, 1, 8, 1, 1, 1, 13, 1, 1, 10, 8, 2, 2, 17, 4, 3, 6, 9, 9, 9, 9, 21, 13, 1, 1, 10, 10, 11, 2, 19, 4, 3, 0} local function tube_autoroute(pos) local active = {0, 0, 0, 0, 0, 0} local nctr = minetest.get_node(pos) if not is_tube(nctr.name) then return end local adjustments = { {x = -1, y = 0, z = 0}, {x = 1, y = 0, z = 0}, {x = 0, y = -1, z = 0}, {x = 0, y = 1, z = 0}, {x = 0, y = 0, z = -1}, {x = 0, y = 0, z = 1} } -- xm = 1, xp = 2, ym = 3, yp = 4, zm = 5, zp = 6 local adjlist = {} -- this will be used in item_transport for i, adj in ipairs(adjustments) do local position = vector.add(pos, adj) local node = minetest.get_node(position) local idef = minetest.registered_nodes[node.name] -- handle the tubes themselves if is_tube(node.name) then active[i] = 1 table.insert(adjlist, adj) -- handle new style connectors elseif idef and idef.tube and idef.tube.connect_sides then if idef.tube.connect_sides[nodeside(node, vector.multiply(adj, -1))] then active[i] = 1 table.insert(adjlist, adj) end end end minetest.get_meta(pos):set_string("adjlist", minetest.serialize(adjlist)) -- all sides checked, now figure which tube to use. local nodedef = minetest.registered_nodes[nctr.name] local basename = nodedef.basename if nodedef.style == "old" then local nsurround = "" for _, n in ipairs(active) do nsurround = nsurround..n end nctr.name = basename.."_"..nsurround elseif nodedef.style == "6d" then local s = 0 for i, n in ipairs(active) do if n == 1 then s = s + 2^vts[i] end end nctr.name = basename.."_"..tube_table[s] nctr.param2 = tube_table_facedirs[s] end minetest.swap_node(pos, nctr) end function pipeworks.scan_for_tube_objects(pos) for side = 0, 6 do tube_autoroute(vector.add(pos, pipeworks.directions.side_to_dir(side))) end end function pipeworks.after_place(pos) pipeworks.scan_for_tube_objects(pos) end function pipeworks.after_dig(pos) pipeworks.scan_for_tube_objects(pos) end -- Screwdriver calls this function before rotating a node. -- However, connections must be updated *after* the node is rotated -- So, this function does the rotation itself and returns `true`. -- (Note: screwdriver already checks for protected areas.) -- This should only be used for tubes that don't autoconnect. -- (For example, one-way tubes.) -- Autoconnecting tubes will just revert back to their original state -- when they are updated. function pipeworks.on_rotate(pos, node, user, mode, new_param2) node.param2 = new_param2 minetest.swap_node(pos, node) pipeworks.scan_for_tube_objects(pos) return true end if minetest.get_modpath("mesecons_mvps") then mesecon.register_on_mvps_move(function(moved_nodes) for _, n in ipairs(moved_nodes) do pipeworks.scan_for_tube_objects(n.pos) pipeworks.scan_for_tube_objects(n.oldpos) end end) end