diff --git a/actions/places.lua b/actions/places.lua index 296aec5..251d662 100644 --- a/actions/places.lua +++ b/actions/places.lua @@ -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) @@ -105,4 +106,101 @@ end 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 \ No newline at end of file diff --git a/npc.lua b/npc.lua index 8a839bc..4018c7c 100755 --- a/npc.lua +++ b/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,15 +358,16 @@ 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}) -- npc.add_action(ent, npc.action.walk_step, {self = ent, dir = npc.direction.east})