Places: Allow finding alternative nodes when nodes are being used.
Add owned and used properties to each owned/shared node. Actions: Allow to find alternative sittable/bed/furnace node if currently being used. Default occupation: Add alternative sitting finding. NPC: Log cleanup.
This commit is contained in:
parent
d92b729e19
commit
8a5e80e2cb
@ -664,19 +664,42 @@ local function get_pos_argument(self, pos, use_access_node)
|
|||||||
return pos
|
return pos
|
||||||
elseif pos.place_type ~= nil then
|
elseif pos.place_type ~= nil then
|
||||||
-- Received table in the following format:
|
-- Received table in the following format:
|
||||||
-- {place_type = "", index = 1, use_access_node = false}
|
-- {
|
||||||
|
-- place_category = "",
|
||||||
|
-- place_type = "",
|
||||||
|
-- index = 1,
|
||||||
|
-- use_access_node = false|true,
|
||||||
|
-- try_alternative_if_used = true|false
|
||||||
|
-- }
|
||||||
local index = pos.index or 1
|
local index = pos.index or 1
|
||||||
local use_access_node = pos.use_access_node or false
|
local use_access_node = pos.use_access_node or false
|
||||||
|
local try_alternative_if_used = pos.try_alternative_if_used or false
|
||||||
local places = npc.places.get_by_type(self, pos.place_type)
|
local places = npc.places.get_by_type(self, pos.place_type)
|
||||||
|
--minetest.log("Place type: "..dump(pos.place_type))
|
||||||
|
--minetest.log("Places: "..dump(places))
|
||||||
-- Check index is valid on the places map
|
-- Check index is valid on the places map
|
||||||
if #places >= index then
|
if #places >= index then
|
||||||
|
local place = places[index]
|
||||||
|
-- Check if place is used, and if it is, find alternative if required
|
||||||
|
if try_alternative_if_used == true then
|
||||||
|
place = npc.places.find_unused_place(self, pos.place_category, pos.place_type, place)
|
||||||
|
|
||||||
|
--minetest.log("Mark as used? "..dump(pos.mark_target_as_used))
|
||||||
|
if pos.mark_target_as_used == true then
|
||||||
|
--minetest.log("Marking as used: "..minetest.pos_to_string(place.pos))
|
||||||
|
npc.places.mark_place_used(place.pos, npc.places.USE_STATE.USED)
|
||||||
|
end
|
||||||
|
|
||||||
|
npc.places.add_shared_accessible_place(
|
||||||
|
self, {owner="", node_pos=place.pos}, npc.places.PLACE_TYPE.CALCULATED.TARGET, true, {})
|
||||||
|
end
|
||||||
-- Check if access node is desired
|
-- Check if access node is desired
|
||||||
if use_access_node == true then
|
if use_access_node == true then
|
||||||
-- Return actual node pos
|
-- Return actual node pos
|
||||||
return places[index].access_node, places[index].pos
|
return place.access_node, place.pos
|
||||||
else
|
else
|
||||||
-- Return node pos that allows access to node
|
-- Return node pos that allows access to node
|
||||||
return places[index].pos
|
return place.pos
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -722,6 +745,7 @@ function npc.actions.use_furnace(self, args)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local enable_usage_marking = args.enable_usage_marking or true
|
||||||
local item = args.item
|
local item = args.item
|
||||||
local freeze = args.freeze
|
local freeze = args.freeze
|
||||||
-- Define which items are usable as fuels. The NPC
|
-- Define which items are usable as fuels. The NPC
|
||||||
@ -775,6 +799,12 @@ function npc.actions.use_furnace(self, args)
|
|||||||
return cook_result.time - fuel_time
|
return cook_result.time - fuel_time
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Set furnace as used if flag is enabled
|
||||||
|
if enable_usage_marking then
|
||||||
|
-- Set place as used
|
||||||
|
npc.places.mark_place_used(pos, npc.places.USE_STATE.USED)
|
||||||
|
end
|
||||||
|
|
||||||
-- Calculate how much fuel is needed
|
-- Calculate how much fuel is needed
|
||||||
local fuel_amount = total_cook_time / fuel_time
|
local fuel_amount = total_cook_time / fuel_time
|
||||||
if fuel_amount < 1 then
|
if fuel_amount < 1 then
|
||||||
@ -832,6 +862,12 @@ function npc.actions.use_furnace(self, args)
|
|||||||
|
|
||||||
npc.log("DEBUG", "Inventory: "..dump(self.inventory))
|
npc.log("DEBUG", "Inventory: "..dump(self.inventory))
|
||||||
|
|
||||||
|
-- Set furnace as unused if flag is enabled
|
||||||
|
if enable_usage_marking then
|
||||||
|
-- Set place as used
|
||||||
|
npc.places.mark_place_used(pos, npc.places.USE_STATE.NOT_USED)
|
||||||
|
end
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -848,6 +884,7 @@ function npc.actions.use_bed(self, args)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
local action = args.action
|
local action = args.action
|
||||||
|
local enable_usage_marking = args.enable_usage_marking or true
|
||||||
local node = minetest.get_node(pos)
|
local node = minetest.get_node(pos)
|
||||||
--minetest.log(dump(node))
|
--minetest.log(dump(node))
|
||||||
local dir = minetest.facedir_to_dir(node.param2)
|
local dir = minetest.facedir_to_dir(node.param2)
|
||||||
@ -863,6 +900,10 @@ function npc.actions.use_bed(self, args)
|
|||||||
npc.add_action(self, npc.actions.cmd.SIT, {pos=bed_pos, dir=(node.param2 + 2) % 4})
|
npc.add_action(self, npc.actions.cmd.SIT, {pos=bed_pos, dir=(node.param2 + 2) % 4})
|
||||||
-- Lay down
|
-- Lay down
|
||||||
npc.add_action(self, npc.actions.cmd.LAY, {})
|
npc.add_action(self, npc.actions.cmd.LAY, {})
|
||||||
|
if enable_usage_marking then
|
||||||
|
-- Set place as used
|
||||||
|
npc.places.mark_place_used(pos, npc.places.USE_STATE.USED)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
-- Calculate position to get up
|
-- Calculate position to get up
|
||||||
-- Error here due to ignore. Need to come up with better solution
|
-- Error here due to ignore. Need to come up with better solution
|
||||||
@ -906,9 +947,12 @@ function npc.actions.use_bed(self, args)
|
|||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Stand out of bed
|
-- Stand out of bed
|
||||||
npc.add_action(self, npc.actions.cmd.STAND, {pos=pos_out_of_bed, dir=dir})
|
npc.add_action(self, npc.actions.cmd.STAND, {pos=pos_out_of_bed, dir=dir})
|
||||||
|
if enable_usage_marking then
|
||||||
|
-- Set place as unused
|
||||||
|
npc.places.mark_place_used(pos, npc.places.USE_STATE.NOT_USED)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -921,6 +965,7 @@ function npc.actions.use_sittable(self, args)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
local action = args.action
|
local action = args.action
|
||||||
|
local enable_usage_marking = args.enable_usage_marking or true
|
||||||
local node = minetest.get_node(pos)
|
local node = minetest.get_node(pos)
|
||||||
|
|
||||||
if action == npc.actions.const.sittable.SIT then
|
if action == npc.actions.const.sittable.SIT then
|
||||||
@ -932,6 +977,10 @@ function npc.actions.use_sittable(self, args)
|
|||||||
local sit_pos = npc.actions.nodes.sittable[node.name].get_sit_pos(pos, node.param2)
|
local sit_pos = npc.actions.nodes.sittable[node.name].get_sit_pos(pos, node.param2)
|
||||||
-- Sit down on bench/chair/stairs
|
-- Sit down on bench/chair/stairs
|
||||||
npc.add_action(self, npc.actions.cmd.SIT, {pos=sit_pos, dir=(node.param2 + 2) % 4})
|
npc.add_action(self, npc.actions.cmd.SIT, {pos=sit_pos, dir=(node.param2 + 2) % 4})
|
||||||
|
if enable_usage_marking then
|
||||||
|
-- Set place as used
|
||||||
|
npc.places.mark_place_used(pos, npc.places.USE_STATE.USED)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
-- Find empty areas around chair
|
-- Find empty areas around chair
|
||||||
local dir = node.param2 + 2 % 4
|
local dir = node.param2 + 2 % 4
|
||||||
@ -951,6 +1000,11 @@ function npc.actions.use_sittable(self, args)
|
|||||||
end
|
end
|
||||||
-- Stand
|
-- Stand
|
||||||
npc.add_action(self, npc.actions.cmd.STAND, {pos=pos_out_of_sittable, dir=dir})
|
npc.add_action(self, npc.actions.cmd.STAND, {pos=pos_out_of_sittable, dir=dir})
|
||||||
|
minetest.log("Setting sittable at "..minetest.pos_to_string(pos).." as not used")
|
||||||
|
if enable_usage_marking then
|
||||||
|
-- Set place as unused
|
||||||
|
npc.places.mark_place_used(pos, npc.places.USE_STATE.NOT_USED)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -63,6 +63,17 @@ npc.places.nodes = {
|
|||||||
|
|
||||||
|
|
||||||
npc.places.PLACE_TYPE = {
|
npc.places.PLACE_TYPE = {
|
||||||
|
CATEGORIES = {
|
||||||
|
BED = "BED",
|
||||||
|
SITTABLE = "SITTABLE",
|
||||||
|
FURNACE = "FURNACE",
|
||||||
|
STORAGE = "STORAGE",
|
||||||
|
OPENABLE = "OPENABLE",
|
||||||
|
SCHEDULE = "SCHEDULE",
|
||||||
|
CALCULATED = "CALCULATED",
|
||||||
|
WORKPLACE = "WORKPLACE",
|
||||||
|
OTHER = "OTHER"
|
||||||
|
},
|
||||||
BED = {
|
BED = {
|
||||||
PRIMARY = "bed_primary"
|
PRIMARY = "bed_primary"
|
||||||
},
|
},
|
||||||
@ -84,6 +95,9 @@ npc.places.PLACE_TYPE = {
|
|||||||
SCHEDULE = {
|
SCHEDULE = {
|
||||||
TARGET = "schedule_target_pos"
|
TARGET = "schedule_target_pos"
|
||||||
},
|
},
|
||||||
|
CALCULATED = {
|
||||||
|
TARGET = "calculated_target_pos"
|
||||||
|
},
|
||||||
WORKPLACE = {
|
WORKPLACE = {
|
||||||
PRIMARY = "workplace_primary",
|
PRIMARY = "workplace_primary",
|
||||||
TOOL = "workplace_tool"
|
TOOL = "workplace_tool"
|
||||||
@ -92,14 +106,60 @@ npc.places.PLACE_TYPE = {
|
|||||||
HOME_PLOTMARKER = "home_plotmarker",
|
HOME_PLOTMARKER = "home_plotmarker",
|
||||||
HOME_INSIDE = "home_inside",
|
HOME_INSIDE = "home_inside",
|
||||||
HOME_OUTSIDE = "home_outside"
|
HOME_OUTSIDE = "home_outside"
|
||||||
|
},
|
||||||
|
is_primary = function(place_type)
|
||||||
|
local p1,p2 = string.find(place_type, "primary")
|
||||||
|
return p1 ~= nil
|
||||||
|
end,
|
||||||
|
-- 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.places.PLACE_TYPE[place_category]
|
||||||
|
-- Determine search type
|
||||||
|
local search_shared = false
|
||||||
|
if npc.places.PLACE_TYPE.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.places.PLACE_TYPE.is_primary(place_type) == false then
|
||||||
|
return place_type
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if npc.places.PLACE_TYPE.is_primary(place_type) == true then
|
||||||
|
return place_type
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
npc.places.USE_STATE = {
|
||||||
|
USED = "true",
|
||||||
|
NOT_USED = "false"
|
||||||
}
|
}
|
||||||
|
|
||||||
function npc.places.add_shared(self, place_name, place_type, pos, access_node)
|
function npc.places.add_shared(self, place_name, place_type, pos, access_node)
|
||||||
|
-- Set metadata of node
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
if not meta:get_string("advanced_npc:used") then
|
||||||
|
meta:set_string("advanced_npc:used", npc.places.USE_STATE.NOT_USED)
|
||||||
|
end
|
||||||
|
meta:set_string("advanced_npc:owner", "")
|
||||||
|
-- This avoid lags
|
||||||
|
meta:mark_as_private({"advanced_npc:used", "advanced_npc:owner"})
|
||||||
self.places_map[place_name] = {type=place_type, pos=pos, access_node=access_node or pos, status="shared"}
|
self.places_map[place_name] = {type=place_type, pos=pos, access_node=access_node or pos, status="shared"}
|
||||||
end
|
end
|
||||||
|
|
||||||
function npc.places.add_owned(self, place_name, place_type, pos, access_node)
|
function npc.places.add_owned(self, place_name, place_type, pos, access_node)
|
||||||
|
-- Set metadata of node
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
if not meta:get_string("advanced_npc:used") then
|
||||||
|
meta:set_string("advanced_npc:used", npc.places.USE_STATE.NOT_USED)
|
||||||
|
end
|
||||||
|
meta:set_string("advanced_npc:owner", self.npc_id)
|
||||||
|
-- This avoid lags
|
||||||
|
meta:mark_as_private({"advanced_npc:used", "advanced_npc:owner"})
|
||||||
self.places_map[place_name] = {type=place_type, pos=pos, access_node=access_node or pos, status="owned"}
|
self.places_map[place_name] = {type=place_type, pos=pos, access_node=access_node or pos, status="owned"}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -161,6 +221,48 @@ function npc.places.add_shared_accessible_place(self, nodes, place_type, overrid
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function npc.places.mark_place_used(pos, value)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local used = meta:get_string("advanced_npc:used")
|
||||||
|
if value == used then
|
||||||
|
npc.log("WARNING", "Attempted to set 'used' property of node at "
|
||||||
|
..minetest.pos_to_string(pos).." to the same value: '"..dump(value).."'")
|
||||||
|
return false
|
||||||
|
else
|
||||||
|
meta:set_string("advanced_npc:used", value)
|
||||||
|
npc.log("DEBUG", "'Used' value at pos "..minetest.pos_to_string(pos)..": "..dump(meta:get_string("advanced_npc:used")))
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- This function is to find an alternative place if the original is
|
||||||
|
-- not usable. If the original place is a "primary" place, it will
|
||||||
|
-- try to find a "shared" place. If it is a "shared" place, it will try
|
||||||
|
-- to find a "primary" place. If none is found, it retuns the given type.
|
||||||
|
function npc.places.find_unused_place(self, place_category, place_type, original_place)
|
||||||
|
local result = {}
|
||||||
|
-- Check if node is being used
|
||||||
|
local meta = minetest.get_meta(original_place.pos)
|
||||||
|
local used = meta:get_string("advanced_npc:used")
|
||||||
|
if used == npc.places.USE_STATE.USED then
|
||||||
|
-- Node is being used, try to find alternative
|
||||||
|
local alternative_place_type = npc.places.PLACE_TYPE.get_alternative(place_category, place_type)
|
||||||
|
--minetest.log("Alternative place type: "..dump(alternative_place_type))
|
||||||
|
local alternative_places = npc.places.get_by_type(self, alternative_place_type)
|
||||||
|
--minetest.log("Alternatives: "..dump(alternative_places))
|
||||||
|
for i = 1, #alternative_places do
|
||||||
|
meta = minetest.get_meta(alternative_places[i].pos)
|
||||||
|
local used = meta:get_string("advanced_npc:used")
|
||||||
|
if used == npc.places.USE_STATE.NOT_USED then
|
||||||
|
return alternative_places[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
result = original_place
|
||||||
|
end
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
function npc.places.get_by_type(self, place_type, exact_match)
|
function npc.places.get_by_type(self, place_type, exact_match)
|
||||||
local result = {}
|
local result = {}
|
||||||
for _, place_entry in pairs(self.places_map) do
|
for _, place_entry in pairs(self.places_map) do
|
||||||
|
@ -55,15 +55,23 @@ local basic_def = {
|
|||||||
-- Schedule entry for 12 midday
|
-- Schedule entry for 12 midday
|
||||||
[12] = {
|
[12] = {
|
||||||
-- Walk to a sittable node
|
-- Walk to a sittable node
|
||||||
[1] = {task = npc.actions.cmd.WALK_TO_POS, args = {
|
[1] = {task = npc.actions.cmd.WALK_TO_POS,
|
||||||
end_pos = {place_type=npc.places.PLACE_TYPE.SITTABLE.PRIMARY, use_access_node=true},
|
args = {
|
||||||
|
end_pos = {
|
||||||
|
place_category=npc.places.PLACE_TYPE.CATEGORIES.SITTABLE,
|
||||||
|
place_type=npc.places.PLACE_TYPE.SITTABLE.PRIMARY,
|
||||||
|
use_access_node=true,
|
||||||
|
try_alternative_if_used=true,
|
||||||
|
mark_target_as_used = true
|
||||||
|
},
|
||||||
walkable = {"cottages:bench"}
|
walkable = {"cottages:bench"}
|
||||||
},
|
},
|
||||||
chance = 75
|
chance = 75
|
||||||
},
|
},
|
||||||
-- Sit on the node
|
-- Sit on the node
|
||||||
[2] = {task = npc.actions.cmd.USE_SITTABLE, args = {
|
[2] = {task = npc.actions.cmd.USE_SITTABLE,
|
||||||
pos = npc.places.PLACE_TYPE.SITTABLE.PRIMARY,
|
args = {
|
||||||
|
pos = npc.places.PLACE_TYPE.CALCULATED.TARGET,
|
||||||
action = npc.actions.const.sittable.SIT
|
action = npc.actions.const.sittable.SIT
|
||||||
},
|
},
|
||||||
depends = {1}
|
depends = {1}
|
||||||
@ -83,10 +91,10 @@ local basic_def = {
|
|||||||
},
|
},
|
||||||
-- Get up from sit
|
-- Get up from sit
|
||||||
[5] = {action = npc.actions.cmd.USE_SITTABLE, args = {
|
[5] = {action = npc.actions.cmd.USE_SITTABLE, args = {
|
||||||
pos = npc.places.PLACE_TYPE.SITTABLE.PRIMARY,
|
pos = npc.places.PLACE_TYPE.CALCULATED.TARGET,
|
||||||
action = npc.actions.const.sittable.GET_UP
|
action = npc.actions.const.sittable.GET_UP
|
||||||
},
|
},
|
||||||
depends = {4}
|
--depends = {4}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
-- Schedule entry for 1 in the afternoon
|
-- Schedule entry for 1 in the afternoon
|
||||||
@ -142,7 +150,8 @@ local basic_def = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
-- Use bed
|
-- Use bed
|
||||||
[2] = {task = npc.actions.cmd.USE_BED, args = {
|
[2] = {task = npc.actions.cmd.USE_BED,
|
||||||
|
args = {
|
||||||
pos = npc.places.PLACE_TYPE.BED.PRIMARY,
|
pos = npc.places.PLACE_TYPE.BED.PRIMARY,
|
||||||
action = npc.actions.const.beds.LAY
|
action = npc.actions.const.beds.LAY
|
||||||
}
|
}
|
||||||
|
2
npc.lua
2
npc.lua
@ -564,7 +564,7 @@ function npc.generate_trade_list_from_inventory(self)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function npc.set_trading_status(self, status)
|
function npc.set_trading_status(self, status)
|
||||||
minetest.log("Trader_data: "..dump(self.trader_data))
|
--minetest.log("Trader_data: "..dump(self.trader_data))
|
||||||
-- Set status
|
-- Set status
|
||||||
self.trader_data.trader_status = status
|
self.trader_data.trader_status = status
|
||||||
-- Re-generate trade offers
|
-- Re-generate trade offers
|
||||||
|
Loading…
Reference in New Issue
Block a user