Locations API: Improve building entrance algorithm.

Rename and refactor constants.
Spawner: Improve building scanning logic for mg_villages
master
Hector Franqui 2018-04-19 15:10:48 -04:00
parent 8f159a9478
commit b79525833e
11 changed files with 228 additions and 253 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.idea/
backup/

View File

@ -901,7 +901,7 @@ local function get_pos_argument(self, pos, use_access_node)
end
npc.locations.add_shared_accessible_place(
self, {owner="", node_pos=place.pos}, npc.locations.PLACE_TYPE.CALCULATED.TARGET, true, {})
self, {owner="", node_pos=place.pos}, npc.locations.data.CALCULATED.TARGET, true, {})
end
-- Check if access node is desired
if use_access_node == true then

View File

@ -233,7 +233,7 @@ function npc.programs.helper.get_pos_argument(self, pos, use_access_node)
end
npc.locations.add_shared_accessible_place(
self, {owner="", node_pos=place.pos}, npc.locations.PLACE_TYPE.CALCULATED.TARGET, true, {})
self, {owner="", node_pos=place.pos}, npc.locations.data.calculated.target, true, {})
else
return nil
end

View File

@ -10,89 +10,56 @@
-- many sitting nodes, many beds, many tables, chests, etc. For now, by default,
-- support for default MTG games and cottages mod is going to be provided.
-- Public API
npc.locations = {}
local _locations = {
categories = {
workplace = {
location = "location",
tool = "tool"
},
home_entrance = {
door = "door",
inside = "inside",
outside = "outside"
},
room_entrance = {
door = "door",
inside = "inside",
outside = "outside"
}
},
register = {}
}
function npc.locations.register_node(node_name, category)
if _locations.register[category] == nil then
_locations.register[category] = {}
-- Function to register nodes
-- Categories are utilized to categorize nodes by type, example beds,
-- furnaces, etc. Sub-categories give more particular categorization to
-- beds in terms of how the NPC uses them
function npc.locations.register_node(node_name, category, sub_category)
-- Check category, if it doesn't exists, create it
if npc.locations.data.categories[category] == nil then
-- Create category name
npc.locations.data.categories[category] = category
npc.locations.data[category] = {}
end
_locations.register[category][#_locations.register[category] + 1] = node_name
-- Check sub-category and create it if necessary
if npc.locations.data[category][sub_category] == nil then
-- Create sub category
npc.locations.data[category][sub_category] = sub_category
end
-- Add node
npc.locations.nodes[category][#npc.locations.nodes[category] + 1] = node_name
end
function npc.locations.register_category(category_name)
if _locations.categories[category_name] == nil then
_locations.categories[category_name] = {}
else
npc.log("WARNING", "Attempt to register location category "..dump(category_name)..": already exists.")
end
end
function npc.locations.register_sub_category(category_name, sub_category_name)
if _locations.categories[category_name] == nil then
npc.log("WARNING", "Attempt to register sub-category "..dump(sub_category_name).." in non-existing category "
..dump(category_name))
else
if _locations.categories[category_name][sub_category_name] ~= nil then
npc.log("WARNING", "Attempt to register sub-category "..dump(sub_category_name).." on category "
..dump(category_name))
else
_locations.categories[category_name][sub_category_name] = sub_category_name
end
end
end
--
--
--npc.locations.register_node("beds:fancy_bed_bottom", npc.locations.PLACE_TYPE.CATEGORIES.BED)
--npc.locations.register_node("cottages:bed_foot", npc.locations.PLACE_TYPE.CATEGORIES.BED)
--npc.locations.register_node("cottages:straw_mat", npc.locations.PLACE_TYPE.CATEGORIES.BED)
--npc.locations.register_node("cottages:sleeping_mat", npc.locations.PLACE_TYPE.CATEGORIES.BED)
-- Default set of registered nodes
npc.locations.nodes = {
BED_TYPE = {
bed = {
"beds:bed_bottom",
"beds:fancy_bed_bottom",
"cottages:bed_foot",
"cottages:straw_mat",
"cottages:sleeping_mat"
},
SITTABLE_TYPE = {
sittable = {
"cottages:bench",
-- Currently commented out since some NPCs
-- currently commented out since some npcs
-- were sitting at stairs that are actually staircases
-- TODO: Register other stair types
-- TODO: register other stair types
--"stairs:stair_wood"
},
STORAGE_TYPE = {
storage = {
"default:chest",
"default:chest_locked",
"cottages:shelf"
},
FURNACE_TYPE = {
furnace = {
"default:furnace",
"default:furnace_active"
},
OPENABLE_TYPE = {
-- TODO: Register fences
openable = {
-- TODO: register fences
"doors:door_glass_a",
"doors:door_glass_b",
"doors:door_obsidian_a",
@ -105,77 +72,66 @@ npc.locations.nodes = {
"cottages:gate_closed",
"cottages:half_door"
},
PLOTMARKER_TYPE = {
plotmarker = {
"mg_villages:plotmarker",
"advanced_npc:plotmarker"
},
WORKPLACE_TYPE = {
-- TODO: Do we have an advanced_npc workplace?
workplace = {
-- TODO: do we have an advanced_npc workplace?
"mg_villages:mob_workplace_marker",
"advanced_npc:workplace_marker"
}
}
-- Plan for replacement:
-- npc.locations.nodes can be changed to _locations.register
-- The scan_area_for_usable_nodes() function can search for all categories
-- registered in npc.locations.categories. Then return a generic result.
-- Some categories are hardcoded: workplace, room and building entrance. However
-- things as sittable, furnace, etc. are generic. While bed could be part of this,
-- it is not, as bed is needed as well and it is important.
-- Spawner function assign_places can also take a generic categories, and specially
-- process the hardcoded ones.
npc.locations.PLACE_TYPE = {
CATEGORIES = {
BED = "BED",
SITTABLE = "SITTABLE",
FURNACE = "FURNACE",
STORAGE = "STORAGE",
OPENABLE = "OPENABLE",
SCHEDULE = "SCHEDULE",
CALCULATED = "CALCULATED",
WORKPLACE = "WORKPLACE",
ROOM = "ROOM",
OTHER = "OTHER"
npc.locations.data = {
categories = {
bed = "bed",
sittable = "sittable",
furnace = "furnace",
storage = "storage",
openable = "openable",
schedule = "schedule",
calculated = "calculated",
workplace = "workplace",
other = "other"
},
BED = {
PRIMARY = "bed_primary"
bed = {
primary = "bed_primary"
},
SITTABLE = {
PRIMARY = "sit_primary",
SHARED = "sit_shared"
sittable = {
primary = "sit_primary",
shared = "sit_shared"
},
FURNACE = {
PRIMARY = "furnace_primary",
SHARED = "furnace_shared"
furnace = {
primary = "furnace_primary",
shared = "furnace_shared"
},
STORAGE = {
PRIMARY = "storage_primary",
SHARED = "storage_shared"
storage = {
primary = "storage_primary",
shared = "storage_shared"
},
OPENABLE = {
HOME_ENTRANCE_DOOR = "home_entrance_door"
openable = {
home_entrance_door = "home_entrance_door",
room_entrance_door = "room_entrance_door"
},
SCHEDULE = {
TARGET = "schedule_target_pos"
schedule = {
target = "schedule_target_pos"
},
CALCULATED = {
TARGET = "calculated_target_pos"
calculated = {
target = "calculated_target_pos"
},
WORKPLACE = {
PRIMARY = "workplace_primary",
TOOL = "workplace_tool"
workplace = {
primary = "workplace_primary",
tool = "workplace_tool"
},
ROOM = {
ROOM_DOOR = "room_door",
ROOM_INSIDE = "room_inside",
ROOM_OUTSIDE = "room_outside"
},
OTHER = {
HOME_PLOTMARKER = "home_plotmarker",
HOME_INSIDE = "home_inside",
HOME_OUTSIDE = "home_outside"
other = {
home_plotmarker = "home_plotmarker",
home_inside = "home_inside",
home_outside = "home_outside",
room_inside = "room_inside",
room_outside = "room_outside"
},
is_primary = function(place_type)
local p1,p2 = string.find(place_type, "primary")
@ -184,19 +140,19 @@ npc.locations.PLACE_TYPE = {
-- Only works for place types where there is a "primary" and a "shared"
get_alternative = function(place_category, place_type)
local result = {}
local place_types = npc.locations.PLACE_TYPE[place_category]
local place_types = npc.locations.data[place_category]
-- Determine search type
local search_shared = false
if npc.locations.PLACE_TYPE.is_primary(place_type) then
if npc.locations.data.is_primary(place_type) then
search_shared = true
end
for key,place_type in pairs(place_types) do
if search_shared == true then
if npc.locations.PLACE_TYPE.is_primary(place_type) == false then
if npc.locations.data.is_primary(place_type) == false then
return place_type
end
else
if npc.locations.PLACE_TYPE.is_primary(place_type) == true then
if npc.locations.data.is_primary(place_type) == true then
return place_type
end
end
@ -318,7 +274,7 @@ function npc.locations.find_unused_place(self, place_category, place_type, origi
local used = meta:get_string("advanced_npc:used")
if used == npc.locations.USE_STATE.USED then
-- Node is being used, try to find alternative
local alternative_place_type = npc.locations.PLACE_TYPE.get_alternative(place_category, place_type)
local alternative_place_type = npc.locations.data.get_alternative(place_category, place_type)
--minetest.log("Alternative place type: "..dump(alternative_place_type))
local alternative_places = npc.locations.get_by_type(self, alternative_place_type)
--minetest.log("Alternatives: "..dump(alternative_places))
@ -539,7 +495,7 @@ function npc.locations.find_plotmarkers(pos, radius, exclude_current_pos)
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}
local nodes = minetest.find_nodes_in_area(start_pos, end_pos,
npc.locations.nodes.PLOTMARKER_TYPE)
npc.locations.nodes.PLOTMARKER)
-- Scan nodes
for i = 1, #nodes do
-- Check if current plotmarker is to be excluded from the list
@ -578,6 +534,7 @@ end
-- furnaces, storage (e.g. chests) and openable (e.g. doors).
-- Returns a table with these classifications
function npc.locations.scan_area_for_usable_nodes(pos1, pos2)
minetest.log("Bed Nodes: "..dump(npc.locations.nodes.bed))
local result = {
bed_type = {},
sittable_type = {},
@ -588,11 +545,11 @@ function npc.locations.scan_area_for_usable_nodes(pos1, pos2)
}
local start_pos, end_pos = vector.sort(pos1, pos2)
result.bed_type = npc.locations.get_nodes_by_type(start_pos, end_pos, npc.locations.nodes.BED_TYPE)
result.sittable_type = npc.locations.get_nodes_by_type(start_pos, end_pos, npc.locations.nodes.SITTABLE_TYPE)
result.furnace_type = npc.locations.get_nodes_by_type(start_pos, end_pos, npc.locations.nodes.FURNACE_TYPE)
result.storage_type = npc.locations.get_nodes_by_type(start_pos, end_pos, npc.locations.nodes.STORAGE_TYPE)
result.openable_type = npc.locations.get_nodes_by_type(start_pos, end_pos, npc.locations.nodes.OPENABLE_TYPE)
result.bed_type = npc.locations.get_nodes_by_type(start_pos, end_pos, npc.locations.nodes.bed)
result.sittable_type = npc.locations.get_nodes_by_type(start_pos, end_pos, npc.locations.nodes.sittable)
result.furnace_type = npc.locations.get_nodes_by_type(start_pos, end_pos, npc.locations.nodes.furnace)
result.storage_type = npc.locations.get_nodes_by_type(start_pos, end_pos, npc.locations.nodes.storage)
result.openable_type = npc.locations.get_nodes_by_type(start_pos, end_pos, npc.locations.nodes.openable)
-- Find workplace nodes: if mg_villages:plotmarker is given as start pos, take it from there.
-- If not, search for them.
@ -607,7 +564,7 @@ function npc.locations.scan_area_for_usable_nodes(pos1, pos2)
result.workplace_type = npc.locations.get_nodes_by_type(
{x=start_pos.x-20, y=start_pos.y, z=start_pos.z-20},
{x=end_pos.x+20, y=end_pos.y, z=end_pos.z+20},
npc.locations.nodes.WORKPLACE_TYPE)
npc.locations.nodes.WORKPLACE)
-- Find out building type and add it to the result
for i = 1, #result.workplace_type do
local meta = minetest.get_meta(result.workplace_type[i].node_pos)
@ -682,9 +639,9 @@ function npc.locations.find_building_entrance(bed_nodes, marker_pos)
if decorated_path[i].type == npc.pathfinder.node_types.openable then
minetest.log("Hello there!!"..dump(decorated_path[i]))
local result = {
door = decorated_path[i].pos,
inside = decorated_path[i-1].pos,
outside = decorated_path[i+1].pos
door = vector.round(decorated_path[i].pos),
inside = vector.round(decorated_path[i-1].pos),
outside = vector.round(decorated_path[i+1].pos)
}
minetest.log("Returning: "..dump(result))
return result
@ -697,11 +654,15 @@ function npc.locations.find_bedroom_entrance(bed_node, marker_pos)
local end_pos = {x=marker_pos.x, y=marker_pos.y, z=marker_pos.z }
-- Find path from the bed node to the plotmarker
local decorated_path = get_decorated_path(start_pos, end_pos)
minetest.log("Decorated path: "..dump(decorated_path))
--minetest.log("Decorated path: "..dump(decorated_path))
-- Find building entrance, traverse path forward and return first node that is openable
for i = 1, #decorated_path do
if decorated_path[i].type == npc.pathfinder.node_types.openable then
return {door = decorated_path[i].pos, inside = decorated_path[i-1].pos, outside = decorated_path[i+1].pos}
return {
door = vector.floor(decorated_path[i].pos),
inside = vector.floor(decorated_path[i-1].pos),
outside = vector.floor(decorated_path[i+1].pos)
}
end
end
end

0
backup/.gitignore vendored
View File

View File

@ -66,14 +66,14 @@ local basic_def = {
},
-- Initialize schedule
schedules_entries = {
-- Schedule entry for 7 in the morning
-- schedule entry for 7 in the morning
[7] = {
[1] = {
program_name = "advanced_npc:internal_property_change",
arguments = {
property = npc.programs.internal_properties.change_trader_status,
args = {
status = npc.trade.NONE
status = npc.trade.none
}
},
interrupt_options = {}
@ -83,11 +83,11 @@ local basic_def = {
arguments = {},
interrupt_options = {}
},
-- Walk to home inside
-- walk to home inside
[3] = {
program_name = "advanced_npc:walk_to_pos",
arguments = {
end_pos = npc.locations.PLACE_TYPE.OTHER.HOME_INSIDE,
end_pos = npc.locations.data.other.home_inside,
walkable = {}
},
interrupt_options = {},
@ -102,28 +102,28 @@ local basic_def = {
is_state_program = true
}
},
-- Schedule entry for 10 in the morning
-- schedule entry for 10 in the morning
[10] = {
-- Walk to outside of home
-- walk to outside of home
[1] = {
program_name = "advanced_npc:walk_to_pos",
arguments = {
end_pos = npc.locations.PLACE_TYPE.OTHER.HOME_OUTSIDE,
end_pos = npc.locations.data.other.home_outside,
walkable = {}
},
interrupt_options = {},
chance = 75
}
},
-- Schedule entry for 12 midday
-- schedule entry for 12 midday
[12] = {
-- Walk to a sittable node
-- walk to a sittable node
[1] = {
program_name = "advanced_npc:walk_to_pos",
arguments = {
end_pos = {
place_category = npc.locations.PLACE_TYPE.CATEGORIES.SITTABLE,
place_type = npc.locations.PLACE_TYPE.SITTABLE.PRIMARY,
place_category = npc.locations.data.categories.sittable,
place_type = npc.locations.data.sittable.primary,
use_access_node = true,
try_alternative_if_used = true,
mark_target_as_used = true
@ -133,17 +133,17 @@ local basic_def = {
chance = 75,
interrupt_options = {},
},
-- Sit on the node
-- sit on the node
[2] = {
program_name = "advanced_npc:use_sittable",
arguments = {
pos = npc.locations.PLACE_TYPE.CALCULATED.TARGET,
action = npc.programs.const.node_ops.sittable.SIT
pos = npc.locations.data.calculated.target,
action = npc.programs.const.node_ops.sittable.sit
},
depends = {1},
interrupt_options = {}
},
-- Stay put
-- stay put
[3] = {
program_name = "advanced_npc:idle",
arguments = {
@ -154,18 +154,18 @@ local basic_def = {
is_state_program = true
}
},
-- Schedule entry for 1 in the afternoon
-- schedule entry for 1 in the afternoon
[13] = {
-- Get up from sit
-- get up from sit
[1] = {
program_name = "advanced_npc:use_sittable",
arguments = {
pos = npc.locations.PLACE_TYPE.CALCULATED.TARGET,
action = npc.programs.const.node_ops.sittable.GET_UP
pos = npc.locations.data.calculated.target,
action = npc.programs.const.node_ops.sittable.get_up
},
interrupt_options = {}
},
-- Give NPC money to buy from player
-- give npc money to buy from player
[2] = {
program_name = "advanced_npc:internal_property_change",
arguments = {
@ -179,13 +179,13 @@ local basic_def = {
interrupt_options = {},
chance = 75
},
-- Change trader status to "casual trader"
-- change trader status to "casual trader"
[3] = {
program_name = "advanced_npc:internal_property_change",
arguments = {
property = npc.schedule_properties.change_trader_status,
args = {
status = npc.trade.CASUAL
status = npc.trade.casual
},
},
interrupt_options = {},
@ -203,16 +203,16 @@ local basic_def = {
depends = {3}
},
},
-- Schedule entry for 6 in the evening
-- schedule entry for 6 in the evening
[18] = {
-- Change trader status to "none"
-- change trader status to "none"
[1] = {
program_name = "advanced_npc:internal_property_change",
arguments = {
{
property = npc.schedule_properties.change_trader_status,
args = {
status = npc.trade.NONE
status = npc.trade.none
},
},
{
@ -225,11 +225,11 @@ local basic_def = {
},
interrupt_options = {},
},
-- Get inside home
-- get inside home
[2] = {
program_name = "advanced_npc:walk_to_pos",
arguments = {
end_pos = npc.locations.PLACE_TYPE.OTHER.HOME_INSIDE,
end_pos = npc.locations.data.other.home_inside,
walkable = {}
},
interrupt_options = {},
@ -239,18 +239,18 @@ local basic_def = {
[1] = {
program_name = "advanced_npc:walk_to_pos",
arguments = {
end_pos = npc.locations.PLACE_TYPE.ROOM.ROOM_INSIDE,
end_pos = npc.locations.data.other.room_inside,
walkable = {}
},
interrupt_options = {}
}
},
-- Schedule entry for 10 in the evening
-- schedule entry for 10 in the evening
[22] = {
[1] = {
program_name = "advanced_npc:walk_to_pos",
arguments = {
end_pos = {place_type=npc.locations.PLACE_TYPE.BED.PRIMARY, use_access_node=true},
end_pos = {place_type=npc.locations.data.bed.primary, use_access_node=true},
walkable = {}
},
interrupt_options = {}
@ -258,8 +258,8 @@ local basic_def = {
[2] = {
program_name = "advanced_npc:use_bed",
arguments = {
pos = npc.locations.PLACE_TYPE.BED.PRIMARY,
action = npc.programs.const.node_ops.beds.LAY
pos = npc.locations.data.bed.primary,
action = npc.programs.const.node_ops.beds.lay
},
interrupt_options = {
allow_rightclick = false
@ -286,7 +286,7 @@ local basic_def = {
-- npc.exec.proc.enqueue(self, "advanced_npc:interrupt", {
-- new_program = "advanced_npc:walk_to_pos",
-- new_args = {
-- end_pos = {place_type=npc.locations.PLACE_TYPE.BED.PRIMARY, use_access_node=true},
-- end_pos = {place_type=npc.locations.data.bed.primary, use_access_node=true},
-- walkable = {}
-- },
-- interrupt_options = {}
@ -295,7 +295,7 @@ local basic_def = {
-- npc.exec.proc.enqueue(self, "advanced_npc:interrupt", {
-- new_program = "advanced_npc:use_bed",
-- new_args = {
-- pos = npc.locations.PLACE_TYPE.BED.PRIMARY,
-- pos = npc.locations.data.bed.primary,
-- action = npc.programs.const.node_ops.beds.LAY
-- },
-- interrupt_options = {
@ -309,7 +309,7 @@ npc.programs.register("schedules:default:wake_up", function(self, args)
npc.exec.proc.enqueue(self, "advanced_npc:interrupt", {
new_program = "advanced_npc:use_bed",
new_args = {
pos = npc.locations.PLACE_TYPE.BED.PRIMARY,
pos = npc.locations.data.bed.primary,
action = npc.programs.const.node_ops.beds.GET_UP
},
interrupt_options = {

View File

@ -44,14 +44,14 @@
-- -- Get out of bed
-- [1] = {
-- task = npc.commands.cmd.USE_BED, args = {
-- pos = npc.locations.PLACE_TYPE.BED.PRIMARY,
-- pos = npc.locations.data.bed.primary,
-- action = npc.commands.const.beds.GET_UP
-- }
-- },
-- -- Walk to home inside
-- [2] = {
-- task = npc.commands.cmd.WALK_TO_POS, args = {
-- end_pos = npc.locations.PLACE_TYPE.OTHER.HOME_INSIDE,
-- end_pos = npc.locations.data.OTHER.HOME_INSIDE,
-- walkable = {}
-- },
-- chance = 75
@ -64,7 +64,7 @@
-- {
-- task = npc.commands.cmd.WALK_TO_POS,
-- args = {
-- end_pos = npc.locations.PLACE_TYPE.WORKPLACE.PRIMARY,
-- end_pos = npc.locations.data.WORKPLACE.PRIMARY,
-- walkable = {}
-- }
-- },
@ -87,7 +87,7 @@
-- {
-- task = npc.commands.cmd.WALK_TO_POS,
-- args = {
-- end_pos = npc.locations.PLACE_TYPE.SCHEDULE.TARGET,
-- end_pos = npc.locations.data.SCHEDULE.TARGET,
-- walkable = farming_plants
-- }
-- },
@ -124,7 +124,7 @@
-- {
-- task = npc.commands.cmd.WALK_TO_POS,
-- args = {
-- end_pos = npc.locations.PLACE_TYPE.SCHEDULE.TARGET,
-- end_pos = npc.locations.data.SCHEDULE.TARGET,
-- walkable = farming_plants
-- }
-- },
@ -161,7 +161,7 @@
-- {
-- task = npc.commands.cmd.WALK_TO_POS,
-- args = {
-- end_pos = npc.locations.PLACE_TYPE.SCHEDULE.TARGET,
-- end_pos = npc.locations.data.SCHEDULE.TARGET,
-- walkable = farming_plants
-- }
-- },
@ -198,7 +198,7 @@
-- {
-- task = npc.commands.cmd.WALK_TO_POS,
-- args = {
-- end_pos = npc.locations.PLACE_TYPE.SCHEDULE.TARGET,
-- end_pos = npc.locations.data.SCHEDULE.TARGET,
-- walkable = farming_plants
-- }
-- },
@ -235,7 +235,7 @@
-- {
-- task = npc.commands.cmd.WALK_TO_POS,
-- args = {
-- end_pos = npc.locations.PLACE_TYPE.SCHEDULE.TARGET,
-- end_pos = npc.locations.data.SCHEDULE.TARGET,
-- walkable = farming_plants
-- }
-- },
@ -272,7 +272,7 @@
-- {
-- task = npc.commands.cmd.WALK_TO_POS,
-- args = {
-- end_pos = npc.locations.PLACE_TYPE.SCHEDULE.TARGET,
-- end_pos = npc.locations.data.SCHEDULE.TARGET,
-- walkable = farming_plants
-- }
-- },
@ -309,7 +309,7 @@
-- {
-- task = npc.commands.cmd.WALK_TO_POS,
-- args = {
-- end_pos = npc.locations.PLACE_TYPE.SCHEDULE.TARGET,
-- end_pos = npc.locations.data.SCHEDULE.TARGET,
-- walkable = farming_plants
-- }
-- },
@ -346,7 +346,7 @@
-- {
-- task = npc.commands.cmd.WALK_TO_POS,
-- args = {
-- end_pos = npc.locations.PLACE_TYPE.SCHEDULE.TARGET,
-- end_pos = npc.locations.data.SCHEDULE.TARGET,
-- walkable = farming_plants
-- }
-- },
@ -383,7 +383,7 @@
-- {
-- task = npc.commands.cmd.WALK_TO_POS,
-- args = {
-- end_pos = npc.locations.PLACE_TYPE.SCHEDULE.TARGET,
-- end_pos = npc.locations.data.SCHEDULE.TARGET,
-- walkable = farming_plants
-- }
-- },
@ -436,7 +436,7 @@
-- -- Walk to a sittable node
-- [1] = {
-- task = npc.commands.cmd.WALK_TO_POS, args = {
-- end_pos = {place_type=npc.locations.PLACE_TYPE.SITTABLE.PRIMARY, use_access_node=true},
-- end_pos = {place_type=npc.locations.data.SITTABLE.PRIMARY, use_access_node=true},
-- walkable = {"cottages:bench"}
-- },
-- chance = 75
@ -444,7 +444,7 @@
-- -- Sit on the node
-- [2] = {
-- task = npc.commands.cmd.USE_SITTABLE, args = {
-- pos = npc.locations.PLACE_TYPE.SITTABLE.PRIMARY,
-- pos = npc.locations.data.SITTABLE.PRIMARY,
-- action = npc.commands.const.sittable.SIT
-- },
-- depends = {1}
@ -467,7 +467,7 @@
-- -- Get up from sit
-- [5] = {
-- action = npc.commands.cmd.USE_SITTABLE, args = {
-- pos = npc.locations.PLACE_TYPE.SITTABLE.PRIMARY,
-- pos = npc.locations.data.SITTABLE.PRIMARY,
-- action = npc.commands.const.sittable.GET_UP
-- },
-- depends = {4}
@ -527,7 +527,7 @@
-- -- Get inside home
-- [3] = {
-- task = npc.commands.cmd.WALK_TO_POS, args = {
-- end_pos = npc.locations.PLACE_TYPE.BED.PRIMARY,
-- end_pos = npc.locations.data.bed.primary,
-- walkable = {}
-- }
-- },
@ -537,14 +537,14 @@
-- [22] = {
-- [1] = {
-- task = npc.commands.cmd.WALK_TO_POS, args = {
-- end_pos = {place_type=npc.locations.PLACE_TYPE.BED.PRIMARY, use_access_node=true},
-- end_pos = {place_type=npc.locations.data.bed.primary, use_access_node=true},
-- walkable = {}
-- }
-- },
-- -- Use bed
-- [2] = {
-- task = npc.commands.cmd.USE_BED, args = {
-- pos = npc.locations.PLACE_TYPE.BED.PRIMARY,
-- pos = npc.locations.data.bed.primary,
-- action = npc.commands.const.beds.LAY
-- }
-- },

View File

@ -12,7 +12,7 @@
-- [1] = {
-- task = npc.commands.cmd.WALK_TO_POS,
-- args = {
-- end_pos = npc.locations.PLACE_TYPE.OTHER.HOME_OUTSIDE,
-- end_pos = npc.locations.data.OTHER.HOME_OUTSIDE,
-- walkable = {}
-- }
-- },

View File

@ -133,7 +133,7 @@
-- [1] = {
-- task = npc.commands.cmd.USE_BED,
-- args = {
-- pos = npc.locations.PLACE_TYPE.BED.PRIMARY,
-- pos = npc.locations.data.bed.primary,
-- action = npc.commands.const.beds.GET_UP
-- }
-- },
@ -142,7 +142,7 @@
-- task = npc.commands.cmd.WALK_TO_POS,
-- chance = 95,
-- args = {
-- end_pos = npc.locations.PLACE_TYPE.OTHER.HOME_INSIDE,
-- end_pos = npc.locations.data.OTHER.HOME_INSIDE,
-- walkable = {}
-- }
-- },
@ -155,7 +155,7 @@
-- {
-- task = npc.commands.cmd.WALK_TO_POS,
-- args = {
-- end_pos = npc.locations.PLACE_TYPE.WORKPLACE.PRIMARY,
-- end_pos = npc.locations.data.WORKPLACE.PRIMARY,
-- walkable = {},
-- use_access_node = true
-- }
@ -184,7 +184,7 @@
-- {
-- task = npc.commands.cmd.WALK_TO_POS,
-- args = {
-- end_pos = npc.locations.PLACE_TYPE.OTHER.HOME_INSIDE,
-- end_pos = npc.locations.data.OTHER.HOME_INSIDE,
-- walkable = {}
-- }
-- }
@ -193,7 +193,7 @@
-- [1] = {
-- task = npc.commands.cmd.WALK_TO_POS,
-- args = {
-- end_pos = {place_type=npc.locations.PLACE_TYPE.BED.PRIMARY, use_access_node=true},
-- end_pos = {place_type=npc.locations.data.bed.primary, use_access_node=true},
-- walkable = {}
-- }
-- },
@ -201,7 +201,7 @@
-- [2] = {
-- task = npc.commands.cmd.USE_BED,
-- args = {
-- pos = npc.locations.PLACE_TYPE.BED.PRIMARY,
-- pos = npc.locations.data.bed.primary,
-- action = npc.commands.const.beds.LAY
-- }
-- },

View File

@ -119,13 +119,13 @@ npc.occupations.basic_def = {
-- [7] = {
-- -- Get out of bed
-- [1] = {task = npc.commands.cmd.USE_BED, args = {
-- pos = npc.locations.PLACE_TYPE.BED.PRIMARY,
-- pos = npc.locations.data.bed.primary,
-- action = npc.commands.const.beds.GET_UP
-- }
-- },
-- -- Walk to home inside
-- [2] = {task = npc.commands.cmd.WALK_TO_POS, args = {
-- end_pos = npc.locations.PLACE_TYPE.OTHER.HOME_INSIDE,
-- end_pos = npc.locations.data.OTHER.HOME_INSIDE,
-- walkable = {}
-- },
-- chance = 75
@ -137,7 +137,7 @@ npc.occupations.basic_def = {
-- [8] = {
-- -- Walk to outside of home
-- [1] = {task = npc.commands.cmd.WALK_TO_POS, args = {
-- end_pos = npc.locations.PLACE_TYPE.OTHER.HOME_OUTSIDE,
-- end_pos = npc.locations.data.OTHER.HOME_OUTSIDE,
-- walkable = {}
-- },
-- chance = 75
@ -149,14 +149,14 @@ npc.occupations.basic_def = {
-- [12] = {
-- -- Walk to a sittable node
-- [1] = {task = npc.commands.cmd.WALK_TO_POS, args = {
-- end_pos = {place_type=npc.locations.PLACE_TYPE.SITTABLE.PRIMARY, use_access_node=true},
-- end_pos = {place_type=npc.locations.data.SITTABLE.PRIMARY, use_access_node=true},
-- walkable = {"cottages:bench"}
-- },
-- chance = 75
-- },
-- -- Sit on the node
-- [2] = {task = npc.commands.cmd.USE_SITTABLE, args = {
-- pos = npc.locations.PLACE_TYPE.SITTABLE.PRIMARY,
-- pos = npc.locations.data.SITTABLE.PRIMARY,
-- action = npc.commands.const.sittable.SIT
-- },
-- depends = {1}
@ -176,7 +176,7 @@ npc.occupations.basic_def = {
-- },
-- -- Get up from sit
-- [5] = {action = npc.commands.cmd.USE_SITTABLE, args = {
-- pos = npc.locations.PLACE_TYPE.SITTABLE.PRIMARY,
-- pos = npc.locations.data.SITTABLE.PRIMARY,
-- action = npc.commands.const.sittable.GET_UP
-- },
-- depends = {4}
@ -220,7 +220,7 @@ npc.occupations.basic_def = {
-- },
-- -- Get inside home
-- [3] = {task = npc.commands.cmd.WALK_TO_POS, args = {
-- end_pos = npc.locations.PLACE_TYPE.OTHER.HOME_INSIDE,
-- end_pos = npc.locations.data.OTHER.HOME_INSIDE,
-- walkable = {}
-- }
-- },
@ -230,13 +230,13 @@ npc.occupations.basic_def = {
-- -- Schedule entry for 10 in the evening
-- [22] = {
-- [1] = {task = npc.commands.cmd.WALK_TO_POS, args = {
-- end_pos = {place_type=npc.locations.PLACE_TYPE.BED.PRIMARY, use_access_node=true},
-- end_pos = {place_type=npc.locations.data.bed.primary, use_access_node=true},
-- walkable = {}
-- }
-- },
-- -- Use bed
-- [2] = {task = npc.commands.cmd.USE_BED, args = {
-- pos = npc.locations.PLACE_TYPE.BED.PRIMARY,
-- pos = npc.locations.data.bed.primary,
-- action = npc.commands.const.beds.LAY
-- }
-- },

View File

@ -491,16 +491,16 @@ end
function npc.spawner.assign_places(self, entrance, node_data, pos)
-- Assign plotmarker if position given
if pos then
npc.locations.add_shared(self, npc.locations.PLACE_TYPE.OTHER.HOME_PLOTMARKER,
npc.locations.PLACE_TYPE.OTHER.HOME_PLOTMARKER, pos)
npc.locations.add_shared(self, npc.locations.data.other.home_plotmarker,
npc.locations.data.other.home_plotmarker, pos)
end
-- Assign building entrance door
if entrance ~= nil and entrance.door ~= nil and entrance.inside ~= nil and entrance.outside ~= nil then
npc.locations.add_shared(self, npc.locations.PLACE_TYPE.OPENABLE.HOME_ENTRANCE_DOOR, npc.locations.PLACE_TYPE.OPENABLE.HOME_ENTRANCE_DOOR, entrance.door)
-- Assign these places to NPC
npc.locations.add_shared(self, npc.locations.PLACE_TYPE.OTHER.HOME_INSIDE, npc.locations.PLACE_TYPE.OTHER.HOME_INSIDE, entrance.inside)
npc.locations.add_shared(self, npc.locations.PLACE_TYPE.OTHER.HOME_OUTSIDE, npc.locations.PLACE_TYPE.OTHER.HOME_OUTSIDE, entrance.outside)
npc.locations.add_shared(self, npc.locations.data.openable.home_entrance_door, npc.locations.data.openable.home_entrance_door, entrance.door)
-- Assign these places to npc
npc.locations.add_shared(self, npc.locations.data.other.home_inside, npc.locations.data.other.home_inside, entrance.inside)
npc.locations.add_shared(self, npc.locations.data.other.home_outside, npc.locations.data.other.home_outside, entrance.outside)
end
-- Assign beds
@ -508,7 +508,7 @@ function npc.spawner.assign_places(self, entrance, node_data, pos)
if #node_data.bed_type > 0 then
-- Assign a specific bed node to a NPC.
assigned_bed = npc.locations.add_owned_accessible_place(self, node_data.bed_type,
npc.locations.PLACE_TYPE.BED.PRIMARY)
npc.locations.data.bed.primary)
end
-- Assign rooms
@ -519,10 +519,10 @@ function npc.spawner.assign_places(self, entrance, node_data, pos)
and bedroom_entrance.door ~= nil
and bedroom_entrance.inside ~= nil
and bedroom_entrance.outside ~= nil then
npc.locations.add_shared(self, npc.locations.PLACE_TYPE.ROOM.ROOM_DOOR, npc.locations.PLACE_TYPE.ROOM.ROOM_DOOR, bedroom_entrance.door)
-- Assign these places to NPC
npc.locations.add_shared(self, npc.locations.PLACE_TYPE.ROOM.ROOM_INSIDE, npc.locations.PLACE_TYPE.ROOM.ROOM_INSIDE, bedroom_entrance.inside)
npc.locations.add_shared(self, npc.locations.PLACE_TYPE.ROOM.ROOM_OUTSIDE, npc.locations.PLACE_TYPE.ROOM.ROOM_OUTSIDE, bedroom_entrance.outside)
npc.locations.add_shared(self, npc.locations.data.openable.room_entrance_door, npc.locations.data.openable.room_entrance_door, bedroom_entrance.door)
-- Assign these places to npc
npc.locations.add_shared(self, npc.locations.data.other.room_inside, npc.locations.data.other.room_inside, bedroom_entrance.inside)
npc.locations.add_shared(self, npc.locations.data.other.room_outside, npc.locations.data.other.room_outside, bedroom_entrance.outside)
end
end
@ -532,14 +532,14 @@ function npc.spawner.assign_places(self, entrance, node_data, pos)
if #node_data.sittable_type >= #node_data.bed_type then
-- Assign a specific sittable node to a NPC.
npc.locations.add_owned_accessible_place(self, node_data.sittable_type,
npc.locations.PLACE_TYPE.SITTABLE.PRIMARY)
npc.locations.data.sittable.primary)
-- Store changes to node_data
--meta:set_string("node_data", minetest.serialize(node_data))
end
-- Add all sits to places as shared since NPC should be able to sit
-- at any accessible sit
npc.locations.add_shared_accessible_place(self, node_data.sittable_type,
npc.locations.PLACE_TYPE.SITTABLE.SHARED)
npc.locations.data.sittable.shared)
end
-- Assign furnaces
@ -548,14 +548,14 @@ function npc.spawner.assign_places(self, entrance, node_data, pos)
if #node_data.furnace_type >= #node_data.bed_type then
-- Assign a specific furnace node to a NPC.
npc.locations.add_owned_accessible_place(self, node_data.furnace_type,
npc.locations.PLACE_TYPE.FURNACE.PRIMARY)
npc.locations.data.furnace.primary)
-- Store changes to node_data
--meta:set_string("node_data", minetest.serialize(node_data))
end
-- Add all furnaces to places as shared since NPC should be able to use
-- any accessible furnace
npc.locations.add_shared_accessible_place(self, node_data.furnace_type,
npc.locations.PLACE_TYPE.FURNACE.SHARED)
npc.locations.data.furnace.shared)
end
-- Assign storage nodes
@ -564,14 +564,14 @@ function npc.spawner.assign_places(self, entrance, node_data, pos)
if #node_data.storage_type >= #node_data.bed_type then
-- Assign a specific storage node to a NPC.
npc.locations.add_owned_accessible_place(self, node_data.storage_type,
npc.locations.PLACE_TYPE.STORAGE.PRIMARY)
npc.locations.data.storage.primary)
-- Store changes to node_data
--meta:set_string("node_data", minetest.serialize(node_data))
end
-- Add all storage-types to places as shared since NPC should be able
-- to use other storaage nodes as well.
npc.locations.add_shared_accessible_place(self, node_data.storage_type,
npc.locations.PLACE_TYPE.STORAGE.SHARED)
npc.locations.data.storage.shared)
end
-- Assign workplace nodes
@ -588,7 +588,7 @@ function npc.spawner.assign_places(self, entrance, node_data, pos)
local walkables = npc.occupations.registered_occupations[self.occupation_name].walkable_nodes
-- Found the node. Assign only this node to the NPC.
npc.locations.add_shared_accessible_place(self, {node_data.workplace_type[i]},
npc.locations.PLACE_TYPE.WORKPLACE.PRIMARY, false, walkables)
npc.locations.data.WORKPLACE.PRIMARY, false, walkables)
-- Edit metadata of this workplace node to not allow it for other NPCs
local meta = minetest.get_meta(node_data.workplace_type[i].node_pos)
local work_data = {
@ -610,7 +610,7 @@ function npc.spawner.assign_places(self, entrance, node_data, pos)
if entrance then
-- npc.enqueue_script(self,
-- npc.commands.cmd.WALK_TO_POS,
-- {end_pos=npc.locations.PLACE_TYPE.OTHER.HOME_INSIDE,
-- {end_pos=npc.locations.data.OTHER.HOME_INSIDE,
-- walkable={}})
-- npc.enqueue_command(self, npc.commands.cmd.FREEZE, {freeze = false})
end
@ -847,6 +847,7 @@ if minetest.get_modpath("mg_villages") ~= nil then
-- point and the building_data to get the x, y and z-coordinate size
-- of the building schematic
function spawner.scan_mg_villages_building(pos, building_data)
local result = {}
-- Get area of the building
local x_size = building_data.bsizex
local y_size = building_data.ysize
@ -861,19 +862,47 @@ if minetest.get_modpath("mg_villages") ~= nil then
-- 1 - facing North, +Z
-- 2 - facing East, +X
-- 3 - facing South -Z
if brotate == 0 then
x_sign, z_sign = 1, -1
elseif brotate == 1 then
x_sign, z_sign = -1, -1
local temp = z_size
z_size = x_size
x_size = temp
elseif brotate == 2 then
x_sign, z_sign = -1, 1
elseif brotate == 3 then
x_sign, z_sign = 1, 1
end
-- Attempt rotating the search area if no data is found
for i = 1, 4 do
if brotate == 0 then
x_sign, z_sign = 1, -1
elseif brotate == 1 then
x_sign, z_sign = -1, -1
local temp = z_size
z_size = x_size
x_size = temp
elseif brotate == 2 then
x_sign, z_sign = -1, 1
elseif brotate == 3 then
x_sign, z_sign = 1, 1
end
npc.log("DEBUG", "Start pos: "..minetest.pos_to_string(start_pos))
npc.log("DEBUG", "Plot: "..dump(minetest.get_meta(start_pos):get_string("infotext")))
npc.log("DEBUG", "Brotate: "..dump(brotate))
npc.log("DEBUG", "X_sign: "..dump(x_sign))
npc.log("DEBUG", "X_adj: "..dump(x_sign*x_size))
npc.log("DEBUG", "Z_sign: "..dump(z_sign))
npc.log("DEBUG", "Z_adj: "..dump(z_sign*z_size))
local end_pos = {x=pos.x + (x_sign * x_size), y=pos.y + y_size, z=pos.z + (z_sign * z_size)}
-- For debug:
--minetest.set_node(start_pos, {name="default:mese_block"})
--minetest.set_node(end_pos, {name="default:mese_block"})
--minetest.get_meta(end_pos):set_string("infotext", minetest.get_meta(start_pos):get_string("infotext"))
npc.log("DEBUG", "Calculated end pos: "..minetest.pos_to_string(end_pos))
result = npc.locations.scan_area_for_usable_nodes(start_pos, end_pos)
if result and result.bed_type and #result.bed_type > 0 then
return result
else
npc.log("WARNING", "Failed attempt "..dump(i).." in finding usable nodes. "..dump(4-i).." attempts left.")
-- Rotate search area and try again
brotate = (brotate + 1) % 4
end
end
------------------------
-- For debug:
------------------------
@ -883,26 +912,6 @@ if minetest.get_modpath("mg_villages") ~= nil then
-- Blue is z marker
--minetest.set_node({x=pos.x,y=pos.y,z=pos.z + (z_sign * z_size)}, {name = "wool:blue"})
--minetest.get_meta({x=pos.x,y=pos.y,z=pos.z + (z_sign * z_size)}):set_string("infotext", minetest.get_meta(pos):get_string("infotext")..", Axis: z, Sign: "..dump(z_sign))
npc.log("DEBUG", "Start pos: "..minetest.pos_to_string(start_pos))
npc.log("DEBUG", "Plot: "..dump(minetest.get_meta(start_pos):get_string("infotext")))
npc.log("DEBUG", "Brotate: "..dump(brotate))
npc.log("DEBUG", "X_sign: "..dump(x_sign))
npc.log("DEBUG", "X_adj: "..dump(x_sign*x_size))
npc.log("DEBUG", "Z_sign: "..dump(z_sign))
npc.log("DEBUG", "Z_adj: "..dump(z_sign*z_size))
local end_pos = {x=pos.x + (x_sign * x_size), y=pos.y + y_size, z=pos.z + (z_sign * z_size)}
-- For debug:
--minetest.set_node(start_pos, {name="default:mese_block"})
--minetest.set_node(end_pos, {name="default:mese_block"})
--minetest.get_meta(end_pos):set_string("infotext", minetest.get_meta(start_pos):get_string("infotext"))
npc.log("DEBUG", "Calculated end pos: "..minetest.pos_to_string(end_pos))
return npc.locations.scan_area_for_usable_nodes(start_pos, end_pos)
end
-- This function "adapts" an existent mg_villages:plotmarker for NPC spawning.
@ -927,6 +936,9 @@ if minetest.get_modpath("mg_villages") ~= nil then
local building_type = all_data.building_type
local building_pos_data = all_data.building_pos_dataS
--minetest.log("bldng data: "..dump(building_data))
--minetest.log("bldng type: "..dump(building_type))
--minetest.log("Pos data: "..dump(building_pos_data))
--minetest.log("Found building data: "..dump(building_data))
-- Check if the building is of the support types
@ -945,14 +957,14 @@ if minetest.get_modpath("mg_villages") ~= nil then
-- Store plot information
local plot_info = mg_villages.all_villages[village_id].to_add_data.bpos[plot_nr]
plot_info["ysize"] = building_data.ysize
-- minetest.log("Plot info at replacement time: "..dump(plot_info))
minetest.log("Plot info at replacement time: "..dump(plot_info))
meta:set_string("plot_info", minetest.serialize(plot_info))
-- Scan building for nodes
local nodedata = spawner.scan_mg_villages_building(pos, plot_info)
-- Find building entrance
local doors = nodedata.openable_type
--minetest.log("Found "..dump(#doors).." openable nodes")
--minetest.log("Nodedata: "..dump(nodedata))
minetest.log("Nodedata: "..dump(nodedata))
local entrance = npc.locations.find_building_entrance(nodedata.bed_type, pos)
--minetest.log("Found good entrance: "..dump(entrance1))
--local entrance = npc.locations.find_entrance_from_openable_nodes(doors, pos)