local math, ipairs, tostring = math, ipairs, tostring local minetest, vector, include = minetest, vector, include local function debug_tell(...) local text = "" for _, v in ipairs({...}) do text = text .. tostring(v) end minetest.chat_send_all(text) end local AXIS_LOOKUP = { vector.new( 0, 1, 0), -- +Y vector.new( 0, 0, 1), -- +Z vector.new( 0, 0, -1), -- -Z vector.new( 1, 0, 0), -- +X vector.new(-1, 0, 0), -- -X vector.new( 0, -1, 0), -- -Y } local function unit_vector_to_axis_index(vec) if vec.y == 1 then if vec.x == 0 and vec.z == 0 then return 1 end elseif vec.z == 1 then if vec.x == 0 and vec.y == 0 then return 2 end elseif vec.z == -1 then if vec.x == 0 and vec.y == 0 then return 3 end elseif vec.x == 1 then if vec.y == 0 and vec.z == 0 then return 4 end elseif vec.x == -1 then if vec.y == 0 and vec.z == 0 then return 5 end elseif vec.y == -1 then if vec.x == 0 and vec.z == 0 then return 6 end end error("Not a unit vector") end local FACEDIR_LOOKUP = {} for up_index, up in ipairs(AXIS_LOOKUP) do FACEDIR_LOOKUP[up_index] = {} for rot = 0, 3 do local facedir = (up_index - 1) * 4 + rot local back = minetest.facedir_to_dir(facedir) local back_index = unit_vector_to_axis_index(back) FACEDIR_LOOKUP[up_index][back_index] = facedir end end minetest.register_on_punchnode(function(pos, node, puncher, pointed_thing) local def = minetest.registered_nodes[node.name] if def.paramtype2 == "facedir" and pointed_thing.above and pointed_thing.under then local facedir = node.param2 -- Vector that points away from the punched face. local punched_face = vector.subtract(pointed_thing.above, pointed_thing.under) local up = AXIS_LOOKUP[1 + math.floor(facedir / 4)] local back = minetest.facedir_to_dir(facedir) up = up:rotate_around_axis(punched_face, math.rad(-90)):round() back = back:rotate_around_axis(punched_face, math.rad(-90)):round() local up_index = unit_vector_to_axis_index(up) local back_index = unit_vector_to_axis_index(back) facedir = FACEDIR_LOOKUP[up_index][back_index] if facedir == nil then minetest.chat_send_all("Could not look up facedir") end node.param2 = facedir minetest.set_node(pos, node) end end)