Minetest: Boxes: Fix connect_sides handling

Bug reported & similar fix proposed by Gregor Parzefall in 1d2b103abe
This commit is contained in:
Lars Mueller 2022-10-29 17:19:36 +02:00
parent e6c5860cb9
commit 2eaaca5de4

@ -13,6 +13,18 @@ end
local has_boxes_prop = {collision_box = "walkable", selection_box = "pointable"} local has_boxes_prop = {collision_box = "walkable", selection_box = "pointable"}
-- Required for raycast box IDs to be accurate
local connect_sides_order = {"top", "bottom", "front", "left", "back", "right"}
local connect_sides_directions = {
top = vector.new(0, 1, 0),
bottom = vector.new(0, -1, 0),
front = vector.new(0, 0, -1),
left = vector.new(-1, 0, 0),
back = vector.new(0, 0, 1),
right = vector.new(1, 0, 0),
}
--> list of collisionboxes in Minetest format --> list of collisionboxes in Minetest format
local function get_node_boxes(pos, type) local function get_node_boxes(pos, type)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
@ -63,19 +75,11 @@ local function get_node_boxes(pos, type)
end end
if box_type == "connected" then if box_type == "connected" then
boxes = table.copy(boxes) boxes = table.copy(boxes)
local connect_sides = { local connect_sides = connect_sides_directions -- (ab)use directions as a "set" of sides
top = {x = 0, y = 1, z = 0}, if node_def.connect_sides then -- build set of sides from given list
bottom = {x = 0, y = -1, z = 0}, connect_sides = {}
front = {x = 0, y = 0, z = -1}, for _, side in ipairs(node_def.connect_sides) do
left = {x = -1, y = 0, z = 0}, connect_sides[side] = true
back = {x = 0, y = 0, z = 1},
right = {x = 1, y = 0, z = 0}
}
if node_def.connect_sides then
for side in pairs(connect_sides) do
if not node_def.connect_sides[side] then
connect_sides[side] = nil
end
end end
end end
local function add_collisionbox(key) local function add_collisionbox(key)
@ -84,8 +88,8 @@ local function get_node_boxes(pos, type)
end end
end end
local matchers = {} local matchers = {}
for _, nodename_or_group in pairs(node_def.connects_to or {}) do for i, nodename_or_group in ipairs(node_def.connects_to or {}) do
table.insert(matchers, nodename_matcher(nodename_or_group)) matchers[i] = nodename_matcher(nodename_or_group)
end end
local function connects_to(nodename) local function connects_to(nodename)
for _, matcher in pairs(matchers) do for _, matcher in pairs(matchers) do
@ -95,13 +99,16 @@ local function get_node_boxes(pos, type)
end end
end end
local connected, connected_sides local connected, connected_sides
for side, direction in pairs(connect_sides) do for _, side in ipairs(connect_sides_order) do
if connect_sides[side] then
local direction = connect_sides_directions[side]
local neighbor = minetest.get_node(vector.add(pos, direction)) local neighbor = minetest.get_node(vector.add(pos, direction))
local connects = connects_to(neighbor.name) local connects = connects_to(neighbor.name)
connected = connected or connects connected = connected or connects
connected_sides = connected_sides or (side ~= "top" and side ~= "bottom") connected_sides = connected_sides or (side ~= "top" and side ~= "bottom")
add_collisionbox((connects and "connect_" or "disconnected_") .. side) add_collisionbox((connects and "connect_" or "disconnected_") .. side)
end end
end
if not connected then if not connected then
add_collisionbox("disconnected") add_collisionbox("disconnected")
end end