From 9b3d458872f0035a7e86294e1c22b5d28d90bc23 Mon Sep 17 00:00:00 2001 From: Hector Franqui Date: Fri, 5 May 2017 18:34:16 -0400 Subject: [PATCH] Spawner: Part 1: Add initial code to find doors front/behind position. Detect first floor nodes. --- actions/places.lua | 59 +++++++++++++++++++++++++++++++----- npc.lua | 75 ---------------------------------------------- spawner.lua | 16 +++++++--- 3 files changed, 63 insertions(+), 87 deletions(-) diff --git a/actions/places.lua b/actions/places.lua index a52467d..1f89f1c 100644 --- a/actions/places.lua +++ b/actions/places.lua @@ -50,18 +50,23 @@ npc.places.nodes = { } } + npc.places.PLACE_TYPE = { - NPC_HOUSE = { - "OWN_BED", - "OWN_ROOM_DOOR", - "OWN_STORAGE", - "SHARED_FURNACE", - "SHARED_SITTABLE", - "ENTRANCE_DOOR" + BED = { + "PRIMARY" + }, + SITTABLE = { + "PRIMARY" + }, + OPENABLE = { + "HOME_ENTRANCE_DOOR" + }, + OTHER = { + "HOME_INSIDE", + "HOME_OUTSIDE" } } - function npc.places.add_public(self, place_name, place_type, pos) self.places_map[place_name] = {type=place_type, pos=pos} end @@ -297,4 +302,42 @@ function npc.places.is_in_staircase(pos) end -- This is not a stairs node return nil +end + +-- Specialized function to find the node position right behind +-- a door. Used to make NPCs enter buildings. +function npc.places.find_node_behind_door(door_pos) + local door = minetest.get_node(door_pos) + if door.param2 == 0 then + -- Looking south + return {x=door_pos.x, y=door_pos.y, z=door_pos.z + 1} + elseif door.param2 == 1 then + -- Looking east + return {x=door_pos.x - 1, y=door_pos.y, z=door_pos.z} + elseif door.param2 == 2 then + -- Looking north + return {x=door_pos.x, y=door_pos.y, z=door_pos.z - 1} + -- Looking west + elseif door.param2 == 3 then + return {x=door_pos.x + 1, y=door_pos.y, z=door_pos.z} + end +end + +-- Specialized function to find the node position right in +-- front of a door. Used to make NPCs exit buildings. +function npc.places.find_node_in_front_of_door(door_pos) + local door = minetest.get_node(door_pos) + if door.param2 == 0 then + -- Looking south + return {x=door_pos.x, y=door_pos.y, z=door_pos.z - 1} + elseif door.param2 == 1 then + -- Looking east + return {x=door_pos.x + 1, y=door_pos.y, z=door_pos.z} + elseif door.param2 == 2 then + -- Looking north + return {x=door_pos.x, y=door_pos.y, z=door_pos.z + 1} + -- Looking west + elseif door.param2 == 3 then + return {x=door_pos.x - 1, y=door_pos.y, z=door_pos.z} + end end \ No newline at end of file diff --git a/npc.lua b/npc.lua index ff975ae..352fcde 100755 --- a/npc.lua +++ b/npc.lua @@ -994,81 +994,6 @@ mobs:register_mob("advanced_npc:npc", { end end end - - -- if self.follow_path then - -- self.home_timer = (self.home_timer or 0) + dtime - -- if self.home_timer < 1 then return end -- every 1 second - -- self.home_timer = 0 - - -- -- if self.time_of_day > 0.2 and self.time_of_day < 0.8 then - -- -- return -- return if not night time - -- -- end - - -- local h = self.destination - -- --local h = {x = 1, y = 8, z = 2} -- destination coords - -- local p = self.object:getpos() -- mob position - - -- -- lets try find a path, first take care of positions - -- -- since pathfinder is very sensitive - -- local pheight = self.collisionbox[5] - self.collisionbox[2] - - -- -- round position to center of node to avoid stuck in walls - -- -- also adjust height for player models! - -- p.x = math.floor(p.x + 0.5) - -- p.y = math.floor(p.y + 0.5) - pheight - -- p.z = math.floor(p.z + 0.5) - - -- local ssight, sground = minetest.line_of_sight(p, { - -- x = p.x, y = p.y - 4, z = p.z}, 1) - - -- -- determine node above ground - -- if not ssight then - -- p.y = sground.y + 1 - -- end - - -- h.x = math.floor(h.x + 0.5) - -- h.y = math.floor(h.y + 0.5) - -- h.z = math.floor(h.z + 0.5) - - - -- local x, y, z = p.x - h.x, p.y - h.y, p.z - h.z - -- local dist = math.floor(math.sqrt(x * x + y * y + z * z)) - - -- minetest.log("Self pos : "..minetest.pos_to_string(p)) - -- minetest.log("Self dest: "..minetest.pos_to_string(h)) - - -- if dist <= 1 then - -- print ("--- home!") - -- self.homepath = nil - -- self.state = "stand" - -- return - -- end - - -- if self.homepath == nil then - -- self.homepath = minetest.find_path(p, h, 50, 3, 6, "A*") - -- print ("--- finding route", self.homepath, dist) - -- end - - -- if self.homepath then - -- print ("--- following path", dist, #self.homepath) - - -- local np = self.homepath[1] ; if not np then return end - - -- if math.abs(np.x - p.x) + math.abs(np.z - p.z) < 0.6 then - -- table.remove(self.homepath, 1) ; print ("-- removed entry") - -- end - - -- np = {x = np.x, y = np.y, z = np.z} - - -- local vec = {x = np.x - p.x, z = np.z - p.z} - -- local yaw = (math.atan(vec.z / vec.x) + math.pi / 2) - self.rotate - - -- if np.x > p.x then yaw = yaw + math.pi end - - -- self.object:setyaw(yaw) - -- set_velocity(self, self.walk_velocity) - -- end - -- end return self.freeze end diff --git a/spawner.lua b/spawner.lua index 372ed30..448985f 100644 --- a/spawner.lua +++ b/spawner.lua @@ -67,9 +67,14 @@ npc.spawner.spawn_data = { -- Scanning functions --------------------------------------------------------------------------------------- -function spawner.filter_first_floor_nodes(nodes) +function spawner.filter_first_floor_nodes(nodes, ground_pos) local result = {} - + for _,node in pairs(nodes) do + if node.node_pos.y <= ground_pos.y + 3 then + table.insert(result, node) + end + end + return result end -- Creates an array of {pos=, owner=''} for managing @@ -123,7 +128,7 @@ end -- - If there are as many benches as beds, assign one to a NPC -- - Else, just let the NPC know one of the benches, but not own them -- - Let the NPC know all doors to the house. Identify the front one as the entrance -function spawner.assign_places(pos, self) +function spawner.assign_places(self, pos) end @@ -145,6 +150,8 @@ function npc.spawner.spawn_npc(pos) if ent and ent:get_luaentity() then ent:get_luaentity().initialized = false npc.initialize(ent, pos) + -- Assign nodes + spawner.assign_places(ent, pos) -- Increase NPC spawned count spawned_npc_count = spawned_npc_count + 1 -- Store count into node @@ -341,8 +348,9 @@ if minetest.get_modpath("mg_villages") ~= nil then }, groups = {cracky=3,stone=2}, - on_rightclick = function( pos, node, clicker, itemstack, pointed_thing) + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) -- Get all openable-type nodes for this building + -- NOTE: This is temporary code for testing... local meta = minetest.get_meta(pos) local doors = minetest.deserialize(meta:get_string("node_data")).openable_type minetest.log("Found "..dump(#doors).." openable nodes")