Spawner: Large code refactor to remove dependency on plotmarkers.

Most spawner functions can now be called without giving a plotmarker.
Move scanning functions to places.lua.
Places: Cleanup and add more area-scanning functions.
Schedules: Bugfix where schedules weren't being executed due to wrong
"end" order in the do_custom() function.
Data: Moved random data to "data" folder.
Textures: Add 14 male textures and 10 female textures.
Occupations: Small tweaks to "default_basic" occupation.
This commit is contained in:
Hector Franqui
2017-08-25 09:31:45 -04:00
parent 698d247aba
commit 4c102a70a4
28 changed files with 816 additions and 741 deletions

View File

@ -102,7 +102,7 @@ function npc.places.add_owned_accessible_place(self, nodes, place_type)
-- Set owner to this NPC
nodes[i].owner = self.npc_id
-- Assign node to NPC
npc.places.add_owned(self, place_type, place_type,
npc.places.add_owned(self, place_type, place_type,
nodes[i].node_pos, empty_nodes[1].pos)
npc.log("DEBUG", "Added node at "..minetest.pos_to_string(nodes[i].node_pos)
.." to NPC "..dump(self.npc_name))
@ -126,7 +126,7 @@ function npc.places.add_shared_accessible_place(self, nodes, place_type, overrid
-- Check if node is accessible
if #empty_nodes > 0 then
-- Assign node to NPC
npc.places.add_shared(self, place_type..dump(i),
npc.places.add_shared(self, place_type..dump(i),
place_type, nodes[i].node_pos, empty_nodes[1].pos)
end
end
@ -139,7 +139,7 @@ function npc.places.add_shared_accessible_place(self, nodes, place_type, overrid
-- Check if node is accessible
if #empty_nodes > 0 then
-- Nodes is only one node
npc.places.add_shared(self, place_type, place_type,
npc.places.add_shared(self, place_type, place_type,
nodes.node_pos, empty_nodes[1].pos)
end
end
@ -155,6 +155,12 @@ function npc.places.get_by_type(self, place_type)
return result
end
---------------------------------------------------------------------------------------
-- Utility functions
---------------------------------------------------------------------------------------
-- The following are utility functions that are used to operate on nodes for
-- specific conditions
-- 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(pos, type, radius)
@ -169,7 +175,7 @@ end
-- TODO: This function can be improved to support a radius greater than 1.
function npc.places.find_node_orthogonally(pos, nodes, y_adjustment)
-- Calculate orthogonal points
-- Calculate orthogonal points
local points = {}
table.insert(points, {x=pos.x+1,y=pos.y+y_adjustment,z=pos.z})
table.insert(points, {x=pos.x-1,y=pos.y+y_adjustment,z=pos.z})
@ -188,11 +194,64 @@ function npc.places.find_node_orthogonally(pos, nodes, y_adjustment)
return result
end
-- Wrapper around minetest.find_nodes_in_area()
-- TODO: Verify if this wrapper is actually needed
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
-- Function used to filter all nodes in the first floor of a building
-- If floor height isn't given, it will assume 2
-- Notice that nodes is an array of entries {node_pos={}, type={}}
function npc.places.filter_first_floor_nodes(nodes, ground_pos, floor_height)
local height = floor_height or 2
local result = {}
for _,node in pairs(nodes) do
if node.node_pos.y <= ground_pos.y + height then
table.insert(result, node)
end
end
return result
end
-- Creates an array of {pos=<node_pos>, owner=''} for managing
-- which NPC owns what
function npc.places.get_nodes_by_type(start_pos, end_pos, type)
local result = {}
local nodes = npc.places.find_node_in_area(start_pos, end_pos, type)
--minetest.log("Found "..dump(#nodes).." nodes of type: "..dump(type))
for _,node_pos in pairs(nodes) do
local entry = {}
entry["node_pos"] = node_pos
entry["owner"] = ''
table.insert(result, entry)
end
return result
end
-- Scans an area for the supported nodes: beds, benches,
-- furnaces, storage (e.g. chests) and openable (e.g. doors).
-- Returns a table with these classifications
function npc.places.scan_area_for_usable_nodes(pos1, pos2)
local result = {
bed_type = {},
sittable_type = {},
furnace_type = {},
storage_type = {},
openable_type = {}
}
local start_pos, end_pos = vector.sort(pos1, pos2)
result.bed_type = npc.places.get_nodes_by_type(start_pos, end_pos, npc.places.nodes.BED_TYPE)
result.sittable_type = npc.places.get_nodes_by_type(start_pos, end_pos, npc.places.nodes.SITTABLE_TYPE)
result.furnace_type = npc.places.get_nodes_by_type(start_pos, end_pos, npc.places.nodes.FURNACE_TYPE)
result.storage_type = npc.places.get_nodes_by_type(start_pos, end_pos, npc.places.nodes.STORAGE_TYPE)
result.openable_type = npc.places.get_nodes_by_type(start_pos, end_pos, npc.places.nodes.OPENABLE_TYPE)
return result
end
-- Specialized function to find doors that are an entrance to a building.
-- The definition of an entrance is:
-- The openable node with the shortest path to the plotmarker node
@ -205,7 +264,7 @@ function npc.places.find_entrance_from_openable_nodes(all_openable_nodes, marker
-- Filter out all other openable nodes except MTG doors.
-- Why? For supported village types (which are: medieval, nore
-- and logcabin) all buildings use, as the main entrance,
-- and logcabin) all buildings use, as the main entrance,
-- a MTG door. Some medieval building have "half_doors" (like farms)
-- which NPCs love to confuse with the right building entrance.
for i = 1, #all_openable_nodes do
@ -231,18 +290,8 @@ function npc.places.find_entrance_from_openable_nodes(all_openable_nodes, marker
local start_pos = {x=open_pos.x, y=open_pos.y, z=open_pos.z}
local end_pos = {x=marker_pos.x, y=marker_pos.y, z=marker_pos.z}
-- Check if there's any difference in vertical position
-- minetest.log("Openable node pos: "..minetest.pos_to_string(open_pos))
-- minetest.log("Plotmarker node pos: "..minetest.pos_to_string(marker_pos))
-- NOTE: Commented out while testing MarkBu's pathfinder
--if start_pos.y ~= end_pos.y then
-- Adjust to make pathfinder find nodes one node above
-- end_pos.y = start_pos.y
--end
-- This adjustment allows the map to be created correctly
--start_pos.y = start_pos.y + 1
--end_pos.y = end_pos.y + 1
-- Find path from the openable node to the plotmarker
--local path = pathfinder.find_path(start_pos, end_pos, 20, {})
@ -258,7 +307,7 @@ function npc.places.find_entrance_from_openable_nodes(all_openable_nodes, marker
if #path < min then
-- Set min to path length and the result to the currently found node
min = #path
result = openable_nodes[i]
result = openable_nodes[i]
else
-- Specific check to prefer mtg's doors to cottages' doors.
-- The reason? Sometimes a cottages' door could be closer to the
@ -419,4 +468,4 @@ function npc.places.find_node_in_front_of_door(door_pos)
-- Looking west
return {x=door_pos.x + 1, y=door_pos.y, z=door_pos.z}
end
end
end