Actions: Enhance walking reliability by adding a moveto() at the end of every step and just before the next step.

Increase walking speed constants to more normal values.
This commit is contained in:
Hector Franqui 2017-05-05 09:13:30 -04:00
parent 55c6146e94
commit f4c374314a
3 changed files with 57 additions and 16 deletions

View File

@ -2,7 +2,7 @@
---------------------------------------------------------------------------------------
-- Action functionality
---------------------------------------------------------------------------------------
-- The NPCs will be able to perform five fundamental actions that will allow
-- The NPCs will be able to perform six fundamental actions that will allow
-- for them to perform any other kind of interaction in the world. These
-- fundamental actions are: place a node, dig a node, put items on an inventory,
-- take items from an inventory, find a node closeby (radius 3) and
@ -35,9 +35,12 @@ npc.actions.const = {
}
}
npc.actions.one_nps_speed = 0.98
npc.actions.one_half_nps_speed = 1.40
npc.actions.two_nps_speed = 1.90
--npc.actions.one_nps_speed = 0.98
--npc.actions.one_half_nps_speed = 1.40
--npc.actions.two_nps_speed = 1.90'
npc.actions.one_nps_speed = 1
npc.actions.one_half_nps_speed = 1.5
npc.actions.two_nps_speed = 2
---------------------------------------------------------------------------------------
-- Actions
@ -96,11 +99,20 @@ end
function npc.actions.walk_step(self, args)
local dir = args.dir
local speed = args.speed
local target_pos = args.target_pos
local vel = {}
-- Set default node per seconds
if speed == nil then
speed = npc.actions.one_nps_speed
end
-- If there is a target position to reach, set it
if target_pos ~= nil then
self.actions.walking.target_pos = target_pos
end
-- Set is_walking = true
self.actions.walking.is_walking = true
if dir == npc.direction.north then
vel = {x=0, y=0, z=speed}
elseif dir == npc.direction.east then
@ -125,6 +137,8 @@ end
function npc.actions.stand(self, args)
local pos = args.pos
local dir = args.dir
-- Set is_walking = true
self.actions.walking.is_walking = false
-- Stop NPC
self.object:setvelocity({x=0, y=0, z=0})
-- If position given, set to that position
@ -422,7 +436,7 @@ function npc.actions.use_furnace(self, args)
count = npc.get_item_count(item),
is_furnace = false
}
minetest.log("Taking item back: "..dump(pos))
minetest.log("Taking item back: "..minetest.pos_to_string(pos))
npc.add_action(self, npc.actions.take_item_from_external_inventory, args)
minetest.log("Inventory: "..dump(self.inventory))
@ -496,8 +510,10 @@ function npc.actions.use_sittable(self, args)
local node = minetest.get_node(pos)
if action == npc.actions.const.sittable.SIT then
-- minetest.log("On sittable: Node: "..dump(node))
-- minetest.log("On sittable: Sittable stuff: "..dump(npc.actions.nodes.sittable[node.name]))
-- minetest.log("On sittable: HAHA: "..dump(node))
-- Calculate position depending on bench
minetest.log("Got sit position: "..dump(sit_pos))
local sit_pos = npc.actions.nodes.sittable[node.name].get_sit_pos(pos, node.param2)
-- Sit down on bench/chair/stairs
npc.add_action(self, npc.actions.sit, {pos=sit_pos, dir=(node.param2 + 2) % 4})
@ -561,7 +577,9 @@ function npc.actions.walk_to_pos(self, args)
local path = pathfinder.find_path(start_pos, end_pos, 20, walkable_nodes)
if path ~= nil then
minetest.log("Found path to node: "..dump(end_pos))
minetest.log("[advanced_npc] Found path to node: "..minetest.pos_to_string(end_pos))
-- Store path
self.actions.walking.path = path
-- Local variables
local door_opened = false
@ -571,6 +589,9 @@ function npc.actions.walk_to_pos(self, args)
-- the increased speed when walking.
npc.add_action(self, npc.actions.set_interval, {interval=0.5, freeze=true})
-- Set the initial last and target positions
self.actions.walking.target_pos = path[1].pos
-- Add steps to path
for i = 1, #path do
-- Do not add an extra step if reached the goal node
@ -578,7 +599,7 @@ function npc.actions.walk_to_pos(self, args)
-- Add direction to last node
local dir = npc.actions.get_direction(path[i].pos, end_pos)
-- Add stand animation at end
npc.add_action(self, npc.actions.stand, { dir = dir})
npc.add_action(self, npc.actions.stand, {dir = dir})
break
end
-- Get direction to move from path[i] to path[i+1]
@ -597,8 +618,9 @@ function npc.actions.walk_to_pos(self, args)
door_opened = true
end
end
-- Add walk action to action queue
npc.add_action(self, npc.actions.walk_step, {dir = dir, speed = speed})
npc.add_action(self, npc.actions.walk_step, {dir = dir, speed = speed, target_pos = path[i+1].pos})
if door_opened then
-- Stop to close door, this avoids misplaced movements later on

31
npc.lua
View File

@ -240,7 +240,18 @@ function npc.initialize(entity, pos, is_lua_entity)
action_state = npc.action_state.none,
-- Action executed while on lock
interrupted_action = {}
}
},
-- Walking variables -- required for implementing accurate movement code
walking = {
-- Defines whether NPC is walking to specific position or not
is_walking = false,
-- Path that the NPC is following
path = {},
-- Target position the NPC is supposed to walk to in this step. NOTE:
-- This is NOT the end of the path, but the next position in the path
-- relative to the last position
target_pos = {}
}
}
-- This flag is checked on every step. If it is true, the rest of
@ -270,8 +281,7 @@ function npc.initialize(entity, pos, is_lua_entity)
-- Temporary initialization of actions for testing
local nodes = npc.places.find_node_nearby(ent.object:getpos(), {"cottages:bench"}, 20)
minetest.log("Self destination: "..minetest.pos_to_string(nodes[1]))
--minetest.log("Self destination: "..minetest.pos_to_string(nodes[1]))
--local path = pathfinder.find_path(ent.object:getpos(), nodes[1], 20, {})
--minetest.log("Path to node: "..dump(path))
@ -288,7 +298,7 @@ function npc.initialize(entity, pos, is_lua_entity)
-- --npc.actions.use_sittable(ent, nodes[1], npc.actions.const.sittable.GET_UP)
-- --npc.add_action(ent, npc.actions.set_interval, {self=ent, interval=10, freeze=true})
-- npc.add_action(ent, npc.actions.freeze, {freeze = false})
-- end
--end
-- Dedicated trade test
ent.trader_data.trade_list.both = {
@ -324,7 +334,8 @@ function npc.initialize(entity, pos, is_lua_entity)
[3] = {action = npc.actions.freeze, args = {freeze = true}}
}
npc.add_schedule_entry(ent, npc.schedule_types.generic, 0, 7, nil, morning_actions)
local afternoon_actions = { [1] = {action = npc.actions.stand, args = {}} }
--local afternoon_actions = { [1] = {action = npc.actions.stand, args = {}} }
local afternoon_actions = {[1] = {task = npc.actions.use_sittable, args = {pos=nodes[1], action=npc.actions.const.sittable.GET_UP} } }
npc.add_schedule_entry(ent, npc.schedule_types.generic, 0, 9, nil, afternoon_actions)
-- local night_actions = {action: npc.action, args: {}}
-- npc.add_schedule_entry(self, npc.schedule_type.generic, 0, 19, check, actions)
@ -535,10 +546,13 @@ function npc.execute_action(self)
return self.freeze
end
local action_obj = self.actions.queue[1]
if action_obj.action == nil then
return
end
-- If the entry is a task, then push all this new operations in
-- stack fashion
if action_obj.is_task == true then
minetest.log("Executing task")
minetest.log("Executing task: "..dump(action_obj))
-- Backup current queue
local backup_queue = self.actions.queue
-- Remove this "task" action from queue
@ -918,6 +932,11 @@ mobs:register_mob("advanced_npc:npc", {
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
local pos = self.actions.walking.target_pos
self.object:moveto({x=pos.x, y=pos.y + 1, z=pos.z})
end
-- Execute action
self.freeze = npc.execute_action(self)
-- Check if there are still remaining actions in the queue

View File

@ -141,7 +141,7 @@ function npc.spawner.spawn_npc(pos)
if spawned_npc_count < npc_count then
minetest.log("[advanced_npc] Spawning NPC at "..minetest.pos_to_string(pos))
-- Spawn a NPC
local ent = minetest.add_entity(pos, "advanced_npc:npc")
local ent = minetest.add_entity({x=pos.x, y=pos.y+1, z=pos.z}, "advanced_npc:npc")
if ent and ent:get_luaentity() then
ent:get_luaentity().initialized = false
npc.initialize(ent, pos)