209 lines
5.7 KiB
Lua
209 lines
5.7 KiB
Lua
|
|
--- API Methods
|
|
--
|
|
-- @topic api
|
|
|
|
|
|
--- Get new rotation for that is opened or closed.
|
|
--
|
|
-- @local
|
|
-- @tparam int old_rot Previous node rotation.
|
|
-- @tparam string paramtype2 Node paramtype2.
|
|
-- @tparam[opt] bool open Whether door is being opened or closed (default: true).
|
|
-- @tparam[opt] bool inward Whether door opens inward or outward (default: true).
|
|
-- @tparam[opt] bool invert If `true`, door swings in opposite direction.
|
|
-- @treturn int New rotation.
|
|
local get_door_rotation = function(old_rot, paramtype2, open, inward, invert)
|
|
-- only facedir is supported
|
|
if not string.find(paramtype2, "facedir") then return end
|
|
local color_info = core.strip_param2_color(old_rot, paramtype2)
|
|
if color_info then
|
|
old_rot = old_rot - color_info
|
|
end
|
|
|
|
open = open ~= false
|
|
inward = inward ~= false
|
|
invert = invert == true
|
|
|
|
local new_rot = old_rot
|
|
if (not invert and ((open and inward) or (not open and not inward))) or
|
|
(invert and ((not open and inward) or (open and not inward))) then
|
|
new_rot = new_rot-1
|
|
if new_rot < 0 then
|
|
new_rot = 3
|
|
end
|
|
else
|
|
new_rot = new_rot+1
|
|
if new_rot > 3 then
|
|
new_rot = 0
|
|
end
|
|
end
|
|
|
|
if color_info then
|
|
new_rot = new_rot + color_info
|
|
end
|
|
|
|
return new_rot
|
|
end
|
|
|
|
local get_paramtype2 = function(node)
|
|
local node_def = core.registered_nodes[node.name]
|
|
if node_def then
|
|
return node_def.paramtype2
|
|
end
|
|
end
|
|
|
|
|
|
--- Helper method for inward opening door-like nodes.
|
|
--
|
|
-- @function simple_models:door_inward_open
|
|
-- @tparam vector pos Position of node.
|
|
-- @tparam string new_node Technical name of node replacement.
|
|
-- @tparam bool invert If `true`, door swings in opposite direction (right instead of left).
|
|
simple_models.door_inward_open = function(self, pos, new_node, invert)
|
|
local node = core.get_node_or_nil(pos)
|
|
if not node then return end
|
|
|
|
local new_rot = get_door_rotation(node.param2, get_paramtype2(node), true, true, invert)
|
|
if not new_rot then return end
|
|
|
|
core.swap_node(pos, {
|
|
name = new_node,
|
|
param1 = node.param1,
|
|
param2 = new_rot,
|
|
})
|
|
end
|
|
|
|
--- Helper method for inward closing door-like nodes.
|
|
--
|
|
-- @function simple_models:door_inward_close
|
|
-- @tparam vector pos Position of node.
|
|
-- @tparam string new_node Technical name of node replacement.
|
|
-- @tparam bool invert If `true`, door swings in opposite direction (right instead of left).
|
|
simple_models.door_inward_close = function(self, pos, new_node, invert)
|
|
local node = core.get_node_or_nil(pos)
|
|
if not node then return end
|
|
|
|
local new_rot = get_door_rotation(node.param2, get_paramtype2(node), false, true, invert)
|
|
if not new_rot then return end
|
|
|
|
core.swap_node(pos, {
|
|
name = new_node,
|
|
param1 = node.param1,
|
|
param2 = new_rot,
|
|
})
|
|
end
|
|
|
|
local get_pos_front = function(pos, param2, paramtype2)
|
|
local new_pos = table.copy(pos)
|
|
|
|
local rot = param2
|
|
local color_info = core.strip_param2_color(param2, paramtype2)
|
|
if color_info then
|
|
rot = rot - color_info
|
|
end
|
|
|
|
if rot == 0 then
|
|
new_pos.z = new_pos.z-1
|
|
elseif rot == 2 then
|
|
new_pos.z = new_pos.z+1
|
|
elseif rot == 1 then
|
|
new_pos.x = new_pos.x-1
|
|
elseif rot == 3 then
|
|
new_pos.x = new_pos.x+1
|
|
end
|
|
|
|
return new_pos
|
|
end
|
|
|
|
local get_pos_behind = function(pos, param2, paramtype2, invert)
|
|
local new_pos = table.copy(pos)
|
|
|
|
local rot = param2
|
|
local color_info = core.strip_param2_color(param2, paramtype2)
|
|
if color_info then
|
|
rot = rot - color_info
|
|
end
|
|
|
|
local addto = 1
|
|
if invert then
|
|
addto = -addto
|
|
end
|
|
|
|
if rot == 0 then
|
|
new_pos.x = new_pos.x - addto
|
|
elseif rot == 2 then
|
|
new_pos.x = new_pos.x + addto
|
|
elseif rot == 1 then
|
|
new_pos.z = new_pos.z + addto
|
|
elseif rot == 3 then
|
|
new_pos.z = new_pos.z - addto
|
|
end
|
|
|
|
return new_pos
|
|
end
|
|
|
|
--- Helper method for outward opening door-like nodes.
|
|
--
|
|
-- @function simple_models:door_outward_open
|
|
-- @tparam vector pos Position of node.
|
|
-- @tparam string new_node Technical name of node replacement.
|
|
-- @tparam bool invert If `true`, door swings in opposite direction (right instead of left).
|
|
simple_models.door_outward_open = function(self, pos, new_node, invert)
|
|
local node = core.get_node_or_nil(pos)
|
|
if not node then return end
|
|
|
|
local paramtype2 = get_paramtype2(node)
|
|
local new_pos = get_pos_front(pos, node.param2, paramtype2)
|
|
|
|
local blocker = core.get_node(new_pos)
|
|
-- something is blocking door or new_pos is same as old
|
|
if blocker and blocker.name ~= "air" then return end
|
|
|
|
local new_rot = get_door_rotation(node.param2, paramtype2, true, false, invert)
|
|
if not new_rot then return end
|
|
|
|
local old_meta_table = core.get_meta(pos):to_table()
|
|
core.remove_node(pos)
|
|
core.set_node(new_pos, {
|
|
name = new_node,
|
|
param1 = node.param1,
|
|
param2 = new_rot,
|
|
})
|
|
|
|
-- transfer meta to new pos
|
|
core.get_meta(new_pos):from_table(old_meta_table)
|
|
end
|
|
|
|
--- Helper method for outward closing door-like nodes.
|
|
--
|
|
-- @function simple_models:door_outward_close
|
|
-- @tparam vector pos Position of node.
|
|
-- @tparam string new_node Technical name of node replacement.
|
|
-- @tparam bool invert If `true`, door swings in opposite direction (right instead of left).
|
|
simple_models.door_outward_close = function(self, pos, new_node, invert)
|
|
local node = core.get_node_or_nil(pos)
|
|
if not node then return end
|
|
|
|
local paramtype2 = get_paramtype2(node)
|
|
local new_pos = get_pos_behind(pos, node.param2, paramtype2, invert)
|
|
|
|
local blocker = core.get_node(new_pos)
|
|
-- something is blocking door or new_pos is same as old
|
|
if blocker and blocker.name ~= "air" then return end
|
|
|
|
local new_rot = get_door_rotation(node.param2, paramtype2, false, false, invert)
|
|
if not new_rot then return end
|
|
|
|
local old_meta_table = core.get_meta(pos):to_table()
|
|
core.remove_node(pos)
|
|
core.set_node(new_pos, {
|
|
name = new_node,
|
|
param1 = node.param1,
|
|
param2 = new_rot,
|
|
})
|
|
|
|
-- transfer meta to new pos
|
|
core.get_meta(new_pos):from_table(old_meta_table)
|
|
end
|