move some code around in preparation for testing swing volume for obstruction
This commit is contained in:
parent
7b295226db
commit
8c6defab4f
@ -23,16 +23,18 @@ local get_dirs = function(facedir)
|
|||||||
return dirs
|
return dirs
|
||||||
end
|
end
|
||||||
|
|
||||||
local interpret_hinge = function(hinge_def, pos, node_dirs)
|
local dir_to_axis = function(dir)
|
||||||
local axis_dir = node_dirs[hinge_def.axis]
|
if dir.x ~= 0 then
|
||||||
local axis
|
return "x"
|
||||||
if axis_dir.x ~= 0 then
|
elseif dir.y ~= 0 then
|
||||||
axis = "x"
|
return "y"
|
||||||
elseif axis_dir.y ~= 0 then
|
|
||||||
axis = "y"
|
|
||||||
else
|
else
|
||||||
axis = "z"
|
return "z"
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local interpret_hinge = function(hinge_def, pos, node_dirs)
|
||||||
|
local axis = dir_to_axis(node_dirs[hinge_def.axis])
|
||||||
|
|
||||||
local placement
|
local placement
|
||||||
if type(hinge_def.offset) == "string" then
|
if type(hinge_def.offset) == "string" then
|
||||||
@ -50,6 +52,60 @@ local interpret_hinge = function(hinge_def, pos, node_dirs)
|
|||||||
return axis, placement
|
return axis, placement
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Rotation (slightly more complex than sliding)
|
||||||
|
|
||||||
|
local facedir_rotate = {
|
||||||
|
['x'] = {
|
||||||
|
[-1] = {[0]=4, 5, 6, 7, 22, 23, 20, 21, 0, 1, 2, 3, 13, 14, 15, 12, 19, 16, 17, 18, 10, 11, 8, 9}, -- 270 degrees
|
||||||
|
[1] = {[0]=8, 9, 10, 11, 0, 1, 2, 3, 22, 23, 20, 21, 15, 12, 13, 14, 17, 18, 19, 16, 6, 7, 4, 5}, -- 90 degrees
|
||||||
|
},
|
||||||
|
['y'] = {
|
||||||
|
[-1] = {[0]=3, 0, 1, 2, 19, 16, 17, 18, 15, 12, 13, 14, 7, 4, 5, 6, 11, 8, 9, 10, 21, 22, 23, 20}, -- 270 degrees
|
||||||
|
[1] = {[0]=1, 2, 3, 0, 13, 14, 15, 12, 17, 18, 19, 16, 9, 10, 11, 8, 5, 6, 7, 4, 23, 20, 21, 22}, -- 90 degrees
|
||||||
|
},
|
||||||
|
['z'] = {
|
||||||
|
[-1] = {[0]=16, 17, 18, 19, 5, 6, 7, 4, 11, 8, 9, 10, 0, 1, 2, 3, 20, 21, 22, 23, 12, 13, 14, 15}, -- 270 degrees
|
||||||
|
[1] = {[0]=12, 13, 14, 15, 7, 4, 5, 6, 9, 10, 11, 8, 20, 21, 22, 23, 0, 1, 2, 3, 16, 17, 18, 19}, -- 90 degrees
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--90 degrees CW about x-axis: (x, y, z) -> (x, -z, y)
|
||||||
|
--90 degrees CCW about x-axis: (x, y, z) -> (x, z, -y)
|
||||||
|
--90 degrees CW about y-axis: (x, y, z) -> (-z, y, x)
|
||||||
|
--90 degrees CCW about y-axis: (x, y, z) -> (z, y, -x)
|
||||||
|
--90 degrees CW about z-axis: (x, y, z) -> (y, -x, z)
|
||||||
|
--90 degrees CCW about z-axis: (x, y, z) -> (-y, x, z)
|
||||||
|
local rotate_pos = function(axis, direction, pos)
|
||||||
|
if axis == "x" then
|
||||||
|
if direction < 0 then
|
||||||
|
return {x= pos.x, y= -pos.z, z= pos.y}
|
||||||
|
else
|
||||||
|
return {x= pos.x, y= pos.z, z= -pos.y}
|
||||||
|
end
|
||||||
|
elseif axis == "y" then
|
||||||
|
if direction < 0 then
|
||||||
|
return {x= -pos.z, y= pos.y, z= pos.x}
|
||||||
|
else
|
||||||
|
return {x= pos.z, y= pos.y, z= -pos.x}
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if direction < 0 then
|
||||||
|
return {x= -pos.y, y= pos.x, z= pos.z}
|
||||||
|
else
|
||||||
|
return {x= pos.y, y= -pos.x, z= pos.z}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local rotate_pos_displaced = function(pos, origin, axis, direction)
|
||||||
|
-- position in space relative to origin
|
||||||
|
local newpos = vector.subtract(pos, origin)
|
||||||
|
newpos = rotate_pos(axis, direction, newpos)
|
||||||
|
-- Move back to original reference frame
|
||||||
|
return vector.add(newpos, origin)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
local get_door_layout = function(pos, facedir, player)
|
local get_door_layout = function(pos, facedir, player)
|
||||||
-- This method does a flood-fill looking for all nodes that meet the following criteria:
|
-- This method does a flood-fill looking for all nodes that meet the following criteria:
|
||||||
-- belongs to a "castle_gate" group
|
-- belongs to a "castle_gate" group
|
||||||
@ -156,13 +212,32 @@ local get_door_layout = function(pos, facedir, player)
|
|||||||
door.can_slide.left = door.can_slide.left and can_slide_to:get_pos(vector.add(door_node.pos, door.directions.left))
|
door.can_slide.left = door.can_slide.left and can_slide_to:get_pos(vector.add(door_node.pos, door.directions.left))
|
||||||
door.can_slide.right = door.can_slide.right and can_slide_to:get_pos(vector.add(door_node.pos, door.directions.right))
|
door.can_slide.right = door.can_slide.right and can_slide_to:get_pos(vector.add(door_node.pos, door.directions.right))
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
--rotating door, evaluate which direction it can go
|
||||||
|
local origin = door.hinge.placement
|
||||||
|
local axis = door.hinge.axis
|
||||||
|
door.swings = {}
|
||||||
|
|
||||||
|
for _, direction in pairs({-1, 1}) do
|
||||||
|
door.swings[direction] = true
|
||||||
|
for _, door_node in pairs(door.all) do
|
||||||
|
origin[axis] = door_node.pos[axis]
|
||||||
|
if not vector.equals(door_node.pos, origin) then -- There's no obstruction if the node is literally located along the rotation axis
|
||||||
|
local newpos = rotate_pos_displaced(door_node.pos, origin, axis, direction)
|
||||||
|
local newnode = minetest.get_node(newpos)
|
||||||
|
local newdef = minetest.registered_nodes[newnode.name]
|
||||||
|
if not newdef.buildable_to then
|
||||||
|
door.swings[direction] = false
|
||||||
|
break
|
||||||
|
end
|
||||||
|
-- TODO: tast swing-through volume here
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return door
|
return door
|
||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
-- Sliding
|
|
||||||
|
|
||||||
local slide_gate = function(door, direction)
|
local slide_gate = function(door, direction)
|
||||||
for _, door_node in pairs(door.all) do
|
for _, door_node in pairs(door.all) do
|
||||||
@ -171,75 +246,14 @@ local slide_gate = function(door, direction)
|
|||||||
door.previous_move = direction
|
door.previous_move = direction
|
||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
-- Rotation (slightly more complex than sliding)
|
|
||||||
|
|
||||||
local facedir_rotate = {
|
|
||||||
['x'] = {
|
|
||||||
[-1] = {[0]=4, 5, 6, 7, 22, 23, 20, 21, 0, 1, 2, 3, 13, 14, 15, 12, 19, 16, 17, 18, 10, 11, 8, 9}, -- 270 degrees
|
|
||||||
[1] = {[0]=8, 9, 10, 11, 0, 1, 2, 3, 22, 23, 20, 21, 15, 12, 13, 14, 17, 18, 19, 16, 6, 7, 4, 5}, -- 90 degrees
|
|
||||||
},
|
|
||||||
['y'] = {
|
|
||||||
[-1] = {[0]=3, 0, 1, 2, 19, 16, 17, 18, 15, 12, 13, 14, 7, 4, 5, 6, 11, 8, 9, 10, 21, 22, 23, 20}, -- 270 degrees
|
|
||||||
[1] = {[0]=1, 2, 3, 0, 13, 14, 15, 12, 17, 18, 19, 16, 9, 10, 11, 8, 5, 6, 7, 4, 23, 20, 21, 22}, -- 90 degrees
|
|
||||||
},
|
|
||||||
['z'] = {
|
|
||||||
[-1] = {[0]=16, 17, 18, 19, 5, 6, 7, 4, 11, 8, 9, 10, 0, 1, 2, 3, 20, 21, 22, 23, 12, 13, 14, 15}, -- 270 degrees
|
|
||||||
[1] = {[0]=12, 13, 14, 15, 7, 4, 5, 6, 9, 10, 11, 8, 20, 21, 22, 23, 0, 1, 2, 3, 16, 17, 18, 19}, -- 90 degrees
|
|
||||||
}
|
|
||||||
}
|
|
||||||
--90 degrees CW about x-axis: (x, y, z) -> (x, -z, y)
|
|
||||||
--90 degrees CCW about x-axis: (x, y, z) -> (x, z, -y)
|
|
||||||
--90 degrees CW about y-axis: (x, y, z) -> (-z, y, x)
|
|
||||||
--90 degrees CCW about y-axis: (x, y, z) -> (z, y, -x)
|
|
||||||
--90 degrees CW about z-axis: (x, y, z) -> (y, -x, z)
|
|
||||||
--90 degrees CCW about z-axis: (x, y, z) -> (-y, x, z)
|
|
||||||
local rotate_pos = function(axis, direction, pos)
|
|
||||||
if axis == "x" then
|
|
||||||
if direction < 0 then
|
|
||||||
return {x= pos.x, y= -pos.z, z= pos.y}
|
|
||||||
else
|
|
||||||
return {x= pos.x, y= pos.z, z= -pos.y}
|
|
||||||
end
|
|
||||||
elseif axis == "y" then
|
|
||||||
if direction < 0 then
|
|
||||||
return {x= -pos.z, y= pos.y, z= pos.x}
|
|
||||||
else
|
|
||||||
return {x= pos.z, y= pos.y, z= -pos.x}
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if direction < 0 then
|
|
||||||
return {x= -pos.y, y= pos.x, z= pos.z}
|
|
||||||
else
|
|
||||||
return {x= pos.y, y= -pos.x, z= pos.z}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local rotate_pos_displaced = function(pos, origin, axis, direction)
|
|
||||||
-- position in space relative to origin
|
|
||||||
local newpos = vector.subtract(pos, origin)
|
|
||||||
newpos = rotate_pos(axis, direction, newpos)
|
|
||||||
-- Move back to original reference frame
|
|
||||||
return vector.add(newpos, origin)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- TODO: this doesn't yet test for obstructions during the swing (since it "teleports" the gate into its new orientation) which makes common drawbridge designs misbehave.
|
|
||||||
local rotate_door = function (door, direction)
|
local rotate_door = function (door, direction)
|
||||||
|
if not door.swings[direction] then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
local origin = door.hinge.placement
|
local origin = door.hinge.placement
|
||||||
local axis = door.hinge.axis
|
local axis = door.hinge.axis
|
||||||
|
|
||||||
for _, door_node in pairs(door.all) do
|
|
||||||
origin[axis] = door_node.pos[axis]
|
|
||||||
if not vector.equals(door_node.pos, origin) then -- There's no obstruction if the node is literally located along the rotation axis
|
|
||||||
local newpos = rotate_pos_displaced(door_node.pos, origin, axis, direction)
|
|
||||||
local newnode = minetest.get_node(newpos)
|
|
||||||
local newdef = minetest.registered_nodes[newnode.name]
|
|
||||||
if not newdef.buildable_to then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for _, door_node in pairs(door.all) do
|
for _, door_node in pairs(door.all) do
|
||||||
door_node.pos = rotate_pos_displaced(door_node.pos, origin, axis, direction)
|
door_node.pos = rotate_pos_displaced(door_node.pos, origin, axis, direction)
|
||||||
door_node.node.param2 = facedir_rotate[axis][direction][door_node.node.param2]
|
door_node.node.param2 = facedir_rotate[axis][direction][door_node.node.param2]
|
||||||
@ -247,6 +261,7 @@ local rotate_door = function (door, direction)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------
|
||||||
-- When creating new gate pieces use this as the "on_rightclick" method of their node definitions
|
-- When creating new gate pieces use this as the "on_rightclick" method of their node definitions
|
||||||
-- if you want the player to be able to trigger the gate by clicking on that particular node.
|
-- if you want the player to be able to trigger the gate by clicking on that particular node.
|
||||||
@ -297,14 +312,14 @@ castle_gates.trigger_gate = function(pos, node, player)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif door.hinge ~= nil then -- this is a hinged door
|
elseif door.hinge ~= nil then -- this is a hinged door
|
||||||
if door.previous_move == "deosil" or door.previous_move == "clockwise" then
|
if door.previous_move == "deosil" then
|
||||||
door_moved = rotate_door(door, 1)
|
door_moved = rotate_door(door, 1)
|
||||||
elseif door.previous_move == "widdershins" or door.previous_move == "counterclockwise" then
|
elseif door.previous_move == "widdershins" then
|
||||||
door_moved = rotate_door(door, -1)
|
door_moved = rotate_door(door, -1)
|
||||||
end
|
end
|
||||||
|
|
||||||
if not door_moved then
|
if not door_moved then
|
||||||
if door.previous_move == "deosil" or door.previous_move == "clockwise" then
|
if door.previous_move == "deosil" then
|
||||||
door.previous_move = "widdershins"
|
door.previous_move = "widdershins"
|
||||||
else
|
else
|
||||||
door.previous_move = "deosil"
|
door.previous_move = "deosil"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user