local minetest, vector, nodecore, include = minetest, vector, nodecore, include local hud = include("hud") local rotate = include("rotate") local utility = include("utility") -- TODO: Add crosshair indicators for rotating around edges. -- TODO: Register only the nodes that should be rotatable. -- TODO: Replace `on_rightclick` of intended nodes. -- TODO: Add some more comments. -- Distance at which we want to rotate by "pushing" on an edge. local EDGE_DISTANCE = 1.5 / 16 -- 1.5 texels (at 16² texture resolution) local rotating_state = {} nodecore.register_playerstep({ label = "extended rotating update", action = function(player, player_data) local name = player:get_player_name() local state = {}; rotating_state[name] = state local pointed_thing = player_data.raycast() if (not pointed_thing) or pointed_thing.type ~= "node" then return nil end state.pos = pointed_thing.under state.node = minetest.get_node(state.pos) if not rotate.is_rotatable(state.node) then return end if vector.equals(pointed_thing.above, pointed_thing.under) then return end state.face = pointed_thing.above - pointed_thing.under local edge, distance = utility.find_closest_edge(state.node, pointed_thing) if edge and distance > EDGE_DISTANCE then state.axis = state.face state.mode = "face" else state.axis = state.face:cross(edge):normalize():round() state.mode = "edge" end state.invert = player:get_player_control().sneak hud.update_player_hud(player, state) end, }) minetest.register_on_leaveplayer(function(player) local name = player:get_player_name() rotating_state[name] = nil end) minetest.register_on_punchnode(function(pos, node, puncher, pointed_thing) if not minetest.is_player(puncher) then return end local name = puncher:get_player_name() local state = rotating_state[name] if not state then return end -- Make sure we're still the same node that we raycasted in `playerstep`. if not vector.equals(pos, state.pos) then return end if node.name ~= state.node.name or node.param2 ~= state.node.param2 then return end local degrees = state.invert and 90 or -90 rotate.rotate_node(state.pos, state.node, state.axis, degrees) end)