Spawner: Avoid multiple spawning by not replacing the mg_villages:plotmarker, but just override its definition.
NPC: (WIP) Support change properties on schedules.
This commit is contained in:
parent
fd4cec0d63
commit
7110c49b42
46
npc.lua
46
npc.lua
@ -455,6 +455,24 @@ function npc.initialize(entity, pos, is_lua_entity, npc_stats)
|
||||
ent.object:set_properties(ent)
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------------------------
|
||||
-- Trading functions
|
||||
---------------------------------------------------------------------------------------
|
||||
function npc.generate_trade_list_from_inventory(self)
|
||||
local list = {}
|
||||
for i = 1, #self.inventory do
|
||||
list[npc.get_item_name(self.inventory[i])] = {}
|
||||
end
|
||||
self.trader_data.trade_list.both = list
|
||||
end
|
||||
|
||||
function npc.set_trading_status(self, status)
|
||||
-- Set status
|
||||
self.trader_data.trader_status = status
|
||||
-- Re-generate trade offers
|
||||
npc.trade.generate_trade_offers_by_status(self)
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------------------------
|
||||
-- Inventory functions
|
||||
---------------------------------------------------------------------------------------
|
||||
@ -743,6 +761,12 @@ npc.schedule_types = {
|
||||
["date_based"] = "date_based"
|
||||
}
|
||||
|
||||
npc.schedule_properties = {
|
||||
put_item = "put_item",
|
||||
take_item = "take_item",
|
||||
trader_status = "trader_status"
|
||||
}
|
||||
|
||||
local function get_time_in_hours()
|
||||
return minetest.get_timeofday() * 24
|
||||
end
|
||||
@ -861,6 +885,19 @@ function npc.delete_schedule_entry(self, schedule_type, date, time)
|
||||
end
|
||||
end
|
||||
|
||||
function npc.schedule_change_property(self, property, args)
|
||||
if property == npc.schedule_properties.trader_status then
|
||||
-- Get status from args
|
||||
local status = args.status
|
||||
-- Set status to NPC
|
||||
npc.set_trading_status(self, status)
|
||||
elseif property == npc.schedule_properties.put_item then
|
||||
|
||||
elseif property == npc.schedule_properties.take_item then
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------------------------
|
||||
-- NPC Definition
|
||||
---------------------------------------------------------------------------------------
|
||||
@ -996,6 +1033,7 @@ mobs:register_mob("advanced_npc:npc", {
|
||||
-- Set correct textures
|
||||
self.texture = {self.selected_texture}
|
||||
self.base_texture = {self.selected_texture}
|
||||
self.object:set_properties(self)
|
||||
-- Set interval to large interval so this code isn't called frequently
|
||||
npc.texture_check.interval = 60
|
||||
end
|
||||
@ -1095,12 +1133,16 @@ mobs:register_mob("advanced_npc:npc", {
|
||||
npc.log("DEBUG", "Adding actions to action queue")
|
||||
-- Add to action queue all actions on schedule
|
||||
for i = 1, #schedule[time] do
|
||||
if schedule[time][i].action == nil then
|
||||
--minetest.log("schedule[time]: "..dump(schedule[time]))
|
||||
if schedule[time][i].task ~= nil then
|
||||
-- Add task
|
||||
npc.add_task(self, schedule[time][i].task, schedule[time][i].args)
|
||||
else
|
||||
elseif schedule[time][i].action ~= nil then
|
||||
-- Add action
|
||||
npc.add_action(self, schedule[time][i].action, schedule[time][i].args)
|
||||
elseif schedule[time][i].property ~= nil then
|
||||
-- Change NPC property
|
||||
npc.schedule_change_property(self, schedule[time][i].property, schedule[time][i].args)
|
||||
end
|
||||
end
|
||||
npc.log("DEBUG", "New action queue: "..dump(self.actions))
|
||||
|
92
spawner.lua
92
spawner.lua
@ -114,19 +114,29 @@ local function get_basic_schedule()
|
||||
action = npc.actions.const.sittable.GET_UP
|
||||
}
|
||||
},
|
||||
-- Change trader status to "trader"
|
||||
[2] = {property = npc.schedule_properties.trader_status, args = {
|
||||
status = npc.trade.TRADER
|
||||
}
|
||||
},
|
||||
-- Allow mobs_redo wandering
|
||||
[2] = {action = npc.actions.cmd.FREEZE, args = {freeze = false}}
|
||||
[3] = {action = npc.actions.cmd.FREEZE, args = {freeze = false}}
|
||||
},
|
||||
-- Afternoon actions: go inside the house
|
||||
-- This will be executed around 6 PM MTG time
|
||||
late_afternoon_actions = {
|
||||
-- Change trader status to "none"
|
||||
[1] = {property = npc.schedule_properties.trader_status, args = {
|
||||
status = npc.trade.NONE
|
||||
}
|
||||
},
|
||||
-- Get inside home
|
||||
[1] = {task = npc.actions.cmd.WALK_TO_POS, args = {
|
||||
[2] = {task = npc.actions.cmd.WALK_TO_POS, args = {
|
||||
end_pos = npc.places.PLACE_TYPE.OTHER.HOME_INSIDE,
|
||||
walkable = {}}
|
||||
},
|
||||
-- Allow mobs_redo wandering
|
||||
[2] = {action = npc.actions.cmd.FREEZE, args = {freeze = false}}
|
||||
[3] = {action = npc.actions.cmd.FREEZE, args = {freeze = false}}
|
||||
},
|
||||
-- Evening actions: walk to bed and use it.
|
||||
-- This will be executed around 10 PM MTG time
|
||||
@ -412,17 +422,15 @@ end
|
||||
|
||||
-- This function takes care of calculating how many NPCs will be spawn
|
||||
function spawner.calculate_npc_spawning(pos)
|
||||
-- Check node
|
||||
local node = minetest.get_node(pos)
|
||||
if node.name ~= "advanced_npc:plotmarker_auto_spawner" then
|
||||
return
|
||||
end
|
||||
-- Check node metadata
|
||||
local meta = minetest.get_meta(pos)
|
||||
if meta:get_string("replaced") ~= "true" then
|
||||
return
|
||||
end
|
||||
-- Get nodes for this building
|
||||
local node_data = minetest.deserialize(meta:get_string("node_data"))
|
||||
if node_data == nil then
|
||||
npc.log("ERROR", "Mis-configured advanced_npc:plotmarker_auto_spawner at position: "..minetest.pos_to_string(pos))
|
||||
npc.log("ERROR", "Mis-configured mg_villages:plotmarker at position: "..minetest.pos_to_string(pos))
|
||||
return
|
||||
end
|
||||
-- Check number of beds
|
||||
@ -527,10 +535,6 @@ end
|
||||
-- Also, the building is scanned for NPC-usable nodes and the amount
|
||||
-- of NPCs to spawn and the interval is calculated.
|
||||
function spawner.replace_mg_villages_plotmarker(pos)
|
||||
-- Check if it is already replaced
|
||||
-- if minetest.get_node(pos).name == "advanced_npc:plotmarker_auto_spawner" then
|
||||
-- return
|
||||
-- end
|
||||
-- Get the meta at the current position
|
||||
local meta = minetest.get_meta(pos)
|
||||
local village_id = meta:get_string("village_id")
|
||||
@ -547,7 +551,7 @@ function spawner.replace_mg_villages_plotmarker(pos)
|
||||
|
||||
npc.log("INFO", "Replacing mg_villages:plotmarker at "..minetest.pos_to_string(pos))
|
||||
-- Replace the plotmarker for auto-spawner
|
||||
minetest.set_node(pos, {name="advanced_npc:plotmarker_auto_spawner"})
|
||||
--minetest.set_node(pos, {name="advanced_npc:plotmarker_auto_spawner"})
|
||||
-- Store old plotmarker metadata again
|
||||
meta:set_string("village_id", village_id)
|
||||
meta:set_int("plot_nr", plot_nr)
|
||||
@ -595,9 +599,10 @@ function spawner.replace_mg_villages_plotmarker(pos)
|
||||
meta:set_string("npc_stats", minetest.serialize(npc_stats))
|
||||
-- Set replaced
|
||||
meta:set_string("replaced", "true")
|
||||
-- Calculate how many NPCs will spawn
|
||||
spawner.calculate_npc_spawning(pos)
|
||||
-- Stop searching for building type
|
||||
break
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -609,19 +614,19 @@ if minetest.get_modpath("mg_villages") ~= nil then
|
||||
-- Node registration
|
||||
-- This node is currently a slightly modified mg_villages:plotmarker
|
||||
-- TODO: Change formspec to a more detailed one.
|
||||
minetest.register_node("advanced_npc:plotmarker_auto_spawner", {
|
||||
description = "Automatic NPC Spawner",
|
||||
drawtype = "nodebox",
|
||||
tiles = {"default_stone.png"},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5+2/16, -0.5, -0.5+2/16, 0.5-2/16, -0.5+2/16, 0.5-2/16},
|
||||
--{-0.5+0/16, -0.5, -0.5+0/16, 0.5-0/16, -0.5+0/16, 0.5-0/16},
|
||||
}
|
||||
},
|
||||
minetest.override_item("mg_villages:plotmarker", {
|
||||
-- description = "Automatic NPC Spawner",
|
||||
-- drawtype = "nodebox",
|
||||
-- tiles = {"default_stone.png"},
|
||||
-- paramtype = "light",
|
||||
-- paramtype2 = "facedir",
|
||||
-- node_box = {
|
||||
-- type = "fixed",
|
||||
-- fixed = {
|
||||
-- {-0.5+2/16, -0.5, -0.5+2/16, 0.5-2/16, -0.5+2/16, 0.5-2/16},
|
||||
-- --{-0.5+0/16, -0.5, -0.5+0/16, 0.5-0/16, -0.5+0/16, 0.5-0/16},
|
||||
-- }
|
||||
-- },
|
||||
walkable = false,
|
||||
groups = {cracky=3,stone=2},
|
||||
|
||||
@ -633,7 +638,7 @@ if minetest.get_modpath("mg_villages") ~= nil then
|
||||
--minetest.log("First-floor beds: "..dump(spawner.filter_first_floor_nodes(nodedata.bed_type, pos)))
|
||||
--local entrance = npc.places.find_entrance_from_openable_nodes(nodedata.openable_type, pos)
|
||||
--minetest.log("Found entrance: "..dump(entrance))
|
||||
|
||||
minetest.log("Replaced: "..dump(minetest.get_meta(pos):get_string("replaced")))
|
||||
-- for i = 1, #nodedata.bed_type do
|
||||
-- nodedata.bed_type[i].owner = ""
|
||||
-- end
|
||||
@ -644,22 +649,22 @@ if minetest.get_modpath("mg_villages") ~= nil then
|
||||
return mg_villages.plotmarker_formspec( pos, nil, {}, clicker )
|
||||
end,
|
||||
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
return mg_villages.plotmarker_formspec( pos, formname, fields, sender );
|
||||
end,
|
||||
-- on_receive_fields = function(pos, formname, fields, sender)
|
||||
-- return mg_villages.plotmarker_formspec( pos, formname, fields, sender );
|
||||
-- end,
|
||||
|
||||
on_timer = function(pos, elapsed)
|
||||
npc.spawner.spawn_npc(pos)
|
||||
end,
|
||||
|
||||
-- protect against digging
|
||||
can_dig = function(pos, player)
|
||||
local meta = minetest.get_meta(pos);
|
||||
if (meta and meta:get_string("village_id") ~= "" and meta:get_int("plot_nr") and meta:get_int("plot_nr") > 0 ) then
|
||||
return false;
|
||||
end
|
||||
return true;
|
||||
end
|
||||
-- can_dig = function(pos, player)
|
||||
-- local meta = minetest.get_meta(pos);
|
||||
-- if (meta and meta:get_string("village_id") ~= "" and meta:get_int("plot_nr") and meta:get_int("plot_nr") > 0 ) then
|
||||
-- return false;
|
||||
-- end
|
||||
-- return true;
|
||||
-- end
|
||||
})
|
||||
|
||||
-- LBM Registration
|
||||
@ -696,14 +701,14 @@ if minetest.get_modpath("mg_villages") ~= nil then
|
||||
if npc.spawner.replace_activated then
|
||||
-- Replace mg_villages:plotmarker
|
||||
spawner.replace_mg_villages_plotmarker(pos)
|
||||
-- Set NPCs to spawn
|
||||
spawner.calculate_npc_spawning(pos)
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
end
|
||||
|
||||
--minetest.register_alias_force("mg_villages:plotmarker", )
|
||||
|
||||
-- Chat commands to manage spawners
|
||||
minetest.register_chatcommand("restore_plotmarkers", {
|
||||
description = "Replaces all advanced_npc:plotmarker_auto_spawner with mg_villages:plotmarker in the specified radius.",
|
||||
@ -726,7 +731,7 @@ minetest.register_chatcommand("restore_plotmarkers", {
|
||||
local start_pos = {x=pos.x - radius, y=pos.y - radius, z=pos.z - radius}
|
||||
local end_pos = {x=pos.x + radius, y=pos.y + radius, z=pos.z + radius}
|
||||
local nodes = minetest.find_nodes_in_area_under_air(start_pos, end_pos,
|
||||
{"advanced_npc:plotmarker_auto_spawner"})
|
||||
{"mg_villages:plotmarker"})
|
||||
-- Check if we have nodes to replace
|
||||
minetest.chat_send_player(name, "Found "..dump(#nodes).." nodes to replace...")
|
||||
if #nodes == 0 then
|
||||
@ -734,13 +739,10 @@ minetest.register_chatcommand("restore_plotmarkers", {
|
||||
end
|
||||
-- Replace all nodes
|
||||
for i = 1, #nodes do
|
||||
--minetest.log(dump(nodes[i]))
|
||||
local meta = minetest.get_meta(nodes[i])
|
||||
local village_id = meta:get_string("village_id")
|
||||
local plot_nr = meta:get_int("plot_nr")
|
||||
local infotext = meta:get_string("infotext")
|
||||
-- Replace node
|
||||
minetest.set_node(nodes[i], {name="mg_villages:plotmarker"})
|
||||
-- Set metadata
|
||||
meta = minetest.get_meta(nodes[i])
|
||||
meta:set_string("village_id", village_id)
|
||||
|
Loading…
Reference in New Issue
Block a user