Places: Add correct detection of sittable nodes, including stairs used as benches.
Add staircase detection method, for basic staircases. Ability to detect the bottom, middle and top nodes. Useful for future implementation of being able to use 2nd floors.
This commit is contained in:
parent
7e41e328e8
commit
e3fc7be783
@ -18,7 +18,10 @@ npc.places.nodes = {
|
||||
"beds:fancy_bed_bottom"
|
||||
},
|
||||
SITTABLE = {
|
||||
"cottages:bench"
|
||||
"cottages:bench",
|
||||
-- TODO: Register all stairs node that are supported for sitting
|
||||
-- Hint: wood
|
||||
"stairs:stair_wood"
|
||||
},
|
||||
CHESTS = {
|
||||
"default:chest",
|
||||
@ -69,12 +72,10 @@ end
|
||||
|
||||
-- This function searches on a squared are of the given radius
|
||||
-- for nodes of the given type. The type should be npc.places.nodes
|
||||
function npc.places.find_node_nearby(self, type, radius)
|
||||
-- Get current pos
|
||||
local current_pos = self.object:getpos()
|
||||
function npc.places.find_node_nearby(pos, type, radius)
|
||||
-- Determine area points
|
||||
local start_pos = {x=current_pos.x - radius, y=current_pos.y - 1, z=current_pos.z - radius}
|
||||
local end_pos = {x=current_pos.x + radius, y=current_pos.y + 1, z=current_pos.z + radius}
|
||||
local start_pos = {x=pos.x - radius, y=pos.y - 1, z=pos.z - radius}
|
||||
local end_pos = {x=pos.x + radius, y=pos.y + 1, z=pos.z + radius}
|
||||
-- Get nodes
|
||||
local nodes = minetest.find_nodes_in_area(start_pos, end_pos, type)
|
||||
|
||||
@ -106,3 +107,100 @@ function npc.places.find_node_in_area(start_pos, end_pos, type)
|
||||
local nodes = minetest.find_nodes_in_area(start_pos, end_pos, type)
|
||||
return nodes
|
||||
end
|
||||
|
||||
-- Specialized function to find all sittable nodes supported by the
|
||||
-- mod, namely default stairs and cottages' benches. Since not all
|
||||
-- stairs nodes placed aren't meant to simulate benches, this function
|
||||
-- is necessary in order to find stairs that are meant to be benches.
|
||||
function npc.places.find_sittable_nodes_nearby(pos, radius)
|
||||
local result = {}
|
||||
-- Try to find sittable nodes
|
||||
local nodes = npc.places.find_node_nearby(pos, npc.places.nodes.SITTABLE, radius)
|
||||
-- Highly unorthodox check for emptinnes
|
||||
if nodes[1] ~= nil then
|
||||
for i = 1, #nodes do
|
||||
-- Get node name, try to avoid using the staircase check if not a stair node
|
||||
local node = minetest.get_node(nodes[i])
|
||||
local i1, i2 = string.find(node.name, "stairs:")
|
||||
if i1 ~= nil then
|
||||
if npc.places.is_in_staircase(nodes[i]) < 1 then
|
||||
table.insert(result, nodes[i])
|
||||
end
|
||||
else
|
||||
-- Add node as it is sittable
|
||||
table.insert(result, nodes[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Return sittable nodes
|
||||
return result
|
||||
end
|
||||
|
||||
-- Specialized function to find sittable stairs: stairs that don't
|
||||
-- have any other stair above them. Only stairs using the default
|
||||
-- stairs mod are supported for now.
|
||||
-- Receives a position of a stair node.
|
||||
|
||||
npc.places.staircase = {
|
||||
none = 0,
|
||||
bottom = 1,
|
||||
middle = 2,
|
||||
top = 3
|
||||
}
|
||||
|
||||
function npc.places.is_in_staircase(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
-- Verify node is actually from default stairs mod
|
||||
local p1, p2 = string.find(node.name, "stairs:")
|
||||
if p1 ~= nil then
|
||||
-- Calculate the logical position to the lower and upper stairs node location
|
||||
local up_x_adj, up_z_adj = 0, 0
|
||||
local lo_x_adj, lo_z_adj = 0, 0
|
||||
if node.param2 == 1 then
|
||||
up_z_adj = -1
|
||||
lo_z_adj = 1
|
||||
elseif node.param2 == 2 then
|
||||
up_z_adj = 1
|
||||
lo_z_adj = -1
|
||||
elseif node.param2 == 3 then
|
||||
up_x_adj = -1
|
||||
lo_x_adj = 1
|
||||
elseif node.param2 == 4 then
|
||||
up_x_adj = 1
|
||||
lo_x_adj = -1
|
||||
else
|
||||
-- This is not a staircase
|
||||
return false
|
||||
end
|
||||
|
||||
-- Calculate upper and lower position
|
||||
local upper_pos = {x=pos.x + up_x_adj, y=pos.y + 1, z=pos.z + up_z_adj}
|
||||
local lower_pos = {x=pos.x + lo_x_adj, y=pos.y - 1, z=pos.z + lo_z_adj}
|
||||
-- Get next node
|
||||
local upper_node = minetest.get_node(upper_pos)
|
||||
local lower_node = minetest.get_node(lower_pos)
|
||||
minetest.log("Next node: "..dump(upper_pos))
|
||||
-- Check if next node is also a stairs node
|
||||
local up_p1, up_p2 = string.find(upper_node.name, "stairs:")
|
||||
local lo_p1, lo_p2 = string.find(lower_node.name, "stairs:")
|
||||
|
||||
if up_p1 ~= nil then
|
||||
-- By default, think this is bottom of staircase.
|
||||
local result = npc.places.staircase.bottom
|
||||
-- Try downwards now
|
||||
if lo_p1 ~= nil then
|
||||
result = npc.places.staircase.middle
|
||||
end
|
||||
return result
|
||||
else
|
||||
-- Check if there is a staircase downwards
|
||||
if lo_p1 ~= nil then
|
||||
return npc.places.staircase.top
|
||||
else
|
||||
return npc.places.staircase.none
|
||||
end
|
||||
end
|
||||
end
|
||||
-- This is not a stairs node
|
||||
return nil
|
||||
end
|
19
npc.lua
19
npc.lua
@ -350,7 +350,7 @@ local function npc_spawn(self, pos)
|
||||
ent.places_map = {}
|
||||
|
||||
-- Temporary initialization of actions for testing
|
||||
local nodes = npc.places.find_node_nearby(ent, {"cottages:bench"}, 30)
|
||||
local nodes = npc.places.find_sittable_nodes_nearby(ent.object:getpos(), 5)
|
||||
minetest.log("Found nodes: "..dump(nodes))
|
||||
|
||||
--local path = pathfinder.find_path(ent.object:getpos(), nodes[1], 20)
|
||||
@ -358,14 +358,15 @@ local function npc_spawn(self, pos)
|
||||
--npc.add_action(ent, npc.actions.use_door, {self = ent, pos = nodes[1], action = npc.actions.door_action.OPEN})
|
||||
--npc.add_action(ent, npc.actions.stand, {self = ent})
|
||||
--npc.add_action(ent, npc.actions.stand, {self = ent})
|
||||
npc.actions.walk_to_pos(ent, nodes[1], {})
|
||||
npc.actions.use_sittable(ent, nodes[1], npc.actions.const.sittable.SIT)
|
||||
npc.add_action(ent, npc.actions.sit, {self = ent})
|
||||
-- npc.add_action(ent, npc.actions.lay, {self = ent})
|
||||
-- npc.add_action(ent, npc.actions.lay, {self = ent})
|
||||
-- npc.add_action(ent, npc.actions.lay, {self = ent})
|
||||
npc.actions.use_sittable(ent, nodes[1], npc.actions.const.sittable.GET_UP)
|
||||
|
||||
if nodes[1] ~= nil then
|
||||
npc.actions.walk_to_pos(ent, nodes[1], {})
|
||||
npc.actions.use_sittable(ent, nodes[1], npc.actions.const.sittable.SIT)
|
||||
npc.add_action(ent, npc.actions.sit, {self = ent})
|
||||
-- npc.add_action(ent, npc.actions.lay, {self = ent})
|
||||
-- npc.add_action(ent, npc.actions.lay, {self = ent})
|
||||
-- npc.add_action(ent, npc.actions.lay, {self = ent})
|
||||
npc.actions.use_sittable(ent, nodes[1], npc.actions.const.sittable.GET_UP)
|
||||
end
|
||||
|
||||
-- npc.add_action(ent, npc.action.stand, {self = ent})
|
||||
-- npc.add_action(ent, npc.action.stand, {self = ent})
|
||||
|
Loading…
Reference in New Issue
Block a user