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:
		@@ -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
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								npc.lua
									
									
									
									
									
								
							@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user