Rotate optics and doors from NodeCore with ease.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

73 lines
2.9 KiB

local minetest, nodecore
= minetest, nodecore
local registry = {}
local registered_rotatables = {}
-- Registered rotatable nodes will call this function when their `on_rightclick`
-- is triggered instead of their default implementation. Can be overwritten.
registry.custom_on_rightclick = function(pos, node, clicker, item_stack, pointed_thing) end
local function register_rotatable(name, facedir_lookup)
local def = minetest.registered_nodes[name]
if not def then error("Unknown node '" .. name .. "'") end
if def.paramtype2 ~= "facedir" then error("Node '" .. name .. "' must be 'facedir'") end
def.on_rightclick = function(...) registry.custom_on_rightclick(...) end
registered_rotatables[name] = { lookup = facedir_lookup }
end
registry.register_rotatable = register_rotatable
-- Returns whether the specified `node` is rotatable by this mod.
local function is_rotatable(node)
local name = node and node.name or ""
return not not registered_rotatables[name]
end
registry.is_rotatable = is_rotatable
-- Fixes facedir for the specified `node` when rotated to `facedir`.
-- * Returns `nil` if the node can't rotate this way.
-- * Returns `facedir` when the node can rotate this way.
-- * Returns another facedir when the node should rotate another equivalent way.
local function fix_rotatable_facedir(node, facedir)
local name = node and node.name or ""
local entry = registered_rotatables[name]
if not entry then return nil end
if not entry.lookup then return facedir end
return entry.lookup[facedir]
end
registry.fix_rotatable_facedir = fix_rotatable_facedir
--------------------------------------------
-- Register rotatable nodes from NodeCore --
--------------------------------------------
local function nodecore_filtered_lookup(eq_func)
local lookup = {}
for i = 0, 23 do
local facedir = nodecore.facedirs[i]
for j = 0, #lookup - 1 do
local other = nodecore.facedirs[lookup[j]]
if eq_func(facedir, other) then lookup[i] = j; break end
end
lookup[i] = lookup[i] or i
end
return lookup
end
local LENS_FILTERED_LOOKUP = nodecore_filtered_lookup(
function(a, b) return vector.equals(a.f, b.f) end)
local PRISM_FILTERED_LOOKUP = nodecore_filtered_lookup(
function(a, b) return vector.equals(a.f, b.r) and vector.equals(a.r, b.f) end)
local PANEL_FILTERED_LOOKUP = nodecore_filtered_lookup(
function(a, b) return vector.equals(a.f, b.r) and vector.equals(a.r, b.f) end)
for _, lens_state in ipairs({ "", "_on", "_glow", "_glow_start" }) do
register_rotatable("nc_optics:lens" .. lens_state, LENS_FILTERED_LOOKUP) end
for _, prism_state in ipairs({ "", "_on", "_gated" }) do
register_rotatable("nc_optics:prism" .. prism_state, PRISM_FILTERED_LOOKUP) end
register_rotatable("nc_doors:panel_plank" , PANEL_FILTERED_LOOKUP)
register_rotatable("nc_doors:panel_cobble", PANEL_FILTERED_LOOKUP)
return registry