Closed BrunoMine closed 6 years ago
I think your NPC has to be initialized.
When spawning your NPC, do npc.initialize()
. You can also do it from the do_custom()
. This is an example:
if self.initialized == nil then
npc.initialize(self, self.object:getpos(), true)
self.tamed = false
self.owner = nil
end
Okay, but he not lay.
do_custom = function(self, dtime)
-- Inicializar NPC
if self.initialized == nil then
npc.initialize(self, self.object:getpos(), true)
self.tamed = false
self.owner = nil
end
if not self.tested and minetest.find_node_near(self.object:getpos(), 3, {"beds:bed_bottom"}) then
self.tested = true
npc.add_task(self, npc.actions.cmd.USE_BED, {
pos = minetest.find_node_near(self.object:getpos(), 3, {"beds:bed_bottom"}),
action = npc.actions.cmd.LAY,
})
end
end,
The action is not correct. Task arguments should be:
args = {
pos = npc.places.PLACE_TYPE.BED.PRIMARY,
action = npc.actions.const.beds.LAY
}
You can refer to data/occupations/default.lua
for example actions and tasks
The code still does not work, but I'm a bit confused by it.
do_custom = function(self, dtime)
-- Inicialize NPC
if self.initialized == nil then
npc.initialize(self, self.object:getpos(), true)
self.tamed = false
self.owner = nil
end
-- Lay in the bed
if not self.tested then
self.tested = true
npc.add_task(self, npc.actions.cmd.USE_BED, {
pos = npc.places.PLACE_TYPE.BED.PRIMARY,
action = npc.actions.const.beds.LAY,
})
end
end,
pos
should be a position of bed to be used (wiki), but it's a string. So where the coordinate is set?
It can receive a string (this is set when NPC is spawned using the spawn egg or the auto spawn), a position table, or a table with other data. Your previous code was good, you only needed this:
action = npc.actions.const.beds.LAY
instead of:
action = npc.actions.cmd.LAY
Are you referring to this? Not work. I had tried that too. Maybe it's some API error. No error message is displayed.
do_custom = function(self, dtime)
-- Inicialize NPC
if self.initialized == nil then
npc.initialize(self, self.object:getpos(), true)
self.tamed = false
self.owner = nil
end
-- Lay in the bed
if not self.tested and minetest.find_node_near(self.object:getpos(), 3, {"beds:bed_bottom"}) then
self.tested = true
npc.add_task(self, npc.actions.cmd.USE_BED, {
pos = minetest.find_node_near(self.object:getpos(), 3, {"beds:bed_bottom"}),
action = npc.actions.const.beds.LAY,
})
end
end,
What does minetest.find_node_near(self.object:getpos(), 3, {"beds:bed_bottom"})
returns? Is it a single node?
Yes, or nil if not find. EDIT: It is a position/coordinate {x,y,z}
I got it! I have missed all the time that you are not using the normal do_custom()
that the NPC has defined in npc.lua
.
At the very least you need to add this to your do_custom()
:
-- Action queue timer
-- Check if actions and timers aren't locked
if self.actions.action_timer_lock == false then
-- Increment action timer
self.actions.action_timer = self.actions.action_timer + dtime
if self.actions.action_timer >= self.actions.action_interval then
-- Reset action timer
self.actions.action_timer = 0
-- Check if NPC is walking
if self.actions.walking.is_walking == true then
-- Move NPC to expected position to ensure not getting lost
local pos = self.actions.walking.target_pos
self.object:moveto({x=pos.x, y=pos.y, z=pos.z})
end
-- Execute action
self.freeze = npc.execute_action(self)
-- Check if there are still remaining actions in the queue
if self.freeze == nil and table.getn(self.actions.queue) > 0 then
self.freeze = false
end
end
end
All of those variables should be defined after initialization.
Now it works fine, I'm beginning to understand API mechanics , but it still needs a lot of documentation. I will discuss issues related to documentation in the future.
Agreed, documentation is very lacking. I truly need to work on it. Thanks for your patience!
I do not know if I'm doing this correctly, I just tried to follow what the documentation says.
My npc do_custom:
This is what happens when I put a bed next to it.