Farmer walks around a little at worksite
This commit is contained in:
parent
fe3b7b28dc
commit
00eac7010f
@ -388,13 +388,74 @@ local find_closest_horizontal_dir = function(pos)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local find_free_horizontal_neighbor = function(pos, precise, prefer_front)
|
local find_random_crop = function(pos)
|
||||||
|
local neighbors = {
|
||||||
|
vector.new(0,0,0),
|
||||||
|
vector.new(-1,0,0),
|
||||||
|
vector.new(1,0,0),
|
||||||
|
vector.new(0,0,-1),
|
||||||
|
vector.new(0,0,1),
|
||||||
|
vector.new(-1,0,-1),
|
||||||
|
vector.new(-1,0,1),
|
||||||
|
vector.new(1,0,-1),
|
||||||
|
vector.new(1,0,1),
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Check if node at npos is a crop, has enough space to stand on
|
||||||
|
-- and is on a safe on walkable node
|
||||||
|
local is_crop = function(npos)
|
||||||
|
local nnode = minetest.get_node(npos)
|
||||||
|
local ndef = minetest.registered_nodes[nnode.name]
|
||||||
|
local bpos = vector.offset(npos, 0, -1, 0)
|
||||||
|
local bnode = minetest.get_node(bpos)
|
||||||
|
local bdef = minetest.registered_nodes[bnode.name]
|
||||||
|
local apos = vector.offset(npos, 0, 1, 0)
|
||||||
|
local anode = minetest.get_node(apos)
|
||||||
|
local adef = minetest.registered_nodes[anode.name]
|
||||||
|
if ndef and minetest.get_item_group(nnode.name, "farming_plant") ~= 0 and
|
||||||
|
not ndef.walkable and ndef.drowning == 0 and ndef.damage_per_second <= 0 and
|
||||||
|
adef and not adef.walkable and adef.drowning == 0 and adef.damage_per_second <= 0 and
|
||||||
|
bdef and bdef.walkable and minetest.get_item_group(bnode.name, "fence") == 0 then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check which neighbors are valid crops
|
||||||
|
local possible = {}
|
||||||
|
for n=1,#neighbors do
|
||||||
|
local npos = vector.add(pos, neighbors[n])
|
||||||
|
if is_crop(npos) then
|
||||||
|
table.insert(possible, neighbors[n])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if #possible == 0 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Pick random possible neighbor
|
||||||
|
local r = math.random(1, #possible)
|
||||||
|
local offset = possible[r]
|
||||||
|
return vector.add(pos, offset)
|
||||||
|
end
|
||||||
|
|
||||||
|
local find_free_horizontal_neighbor = function(pos, precise, prefer_front, add_corners, add_self)
|
||||||
local neighbors = {
|
local neighbors = {
|
||||||
{ vector.new(-1,0,0), "-x" },
|
{ vector.new(-1,0,0), "-x" },
|
||||||
{ vector.new(1,0,0), "+x" },
|
{ vector.new(1,0,0), "+x" },
|
||||||
{ vector.new(0,0,-1), "-z" },
|
{ vector.new(0,0,-1), "-z" },
|
||||||
{ vector.new(0,0,1), "+z" },
|
{ vector.new(0,0,1), "+z" },
|
||||||
}
|
}
|
||||||
|
if add_self then
|
||||||
|
table.insert(neighbors, { vector.new(0,0,0), "" })
|
||||||
|
end
|
||||||
|
if add_corners then
|
||||||
|
table.insert(neighbors, { vector.new(-1,0,-1), "" })
|
||||||
|
table.insert(neighbors, { vector.new(-1,0,1), "" })
|
||||||
|
table.insert(neighbors, { vector.new(1,0,-1), "" })
|
||||||
|
table.insert(neighbors, { vector.new(1,0,1), "" })
|
||||||
|
end
|
||||||
|
|
||||||
-- Check if node at npos is 'free'
|
-- Check if node at npos is 'free'
|
||||||
-- (not blocking, not dangerous, not on air or fence;
|
-- (not blocking, not dangerous, not on air or fence;
|
||||||
@ -452,7 +513,7 @@ local find_free_horizontal_neighbor = function(pos, precise, prefer_front)
|
|||||||
for p=1, #possible do
|
for p=1, #possible do
|
||||||
local offset = possible[p][1]
|
local offset = possible[p][1]
|
||||||
local dir = possible[p][2]
|
local dir = possible[p][2]
|
||||||
if closest_dir == dir then
|
if dir ~= "" and closest_dir == dir then
|
||||||
return vector.round(vector.add(pos, offset))
|
return vector.round(vector.add(pos, offset))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1342,8 +1403,8 @@ local movement_decider_empty = function(task_queue, mob)
|
|||||||
if mob._custom_state.worksite then
|
if mob._custom_state.worksite then
|
||||||
target_block = mob._custom_state.worksite
|
target_block = mob._custom_state.worksite
|
||||||
if profession == "farmer" then
|
if profession == "farmer" then
|
||||||
-- Farmer's worksite is crops, so we can stand directly on top
|
-- Farmer's worksite is crops, so find a crop at or near the worksite
|
||||||
target = mob._custom_state.worksite
|
target = find_random_crop(mob._custom_state.worksite)
|
||||||
else
|
else
|
||||||
-- Butcher and blacksmith want to stand in front of worksite
|
-- Butcher and blacksmith want to stand in front of worksite
|
||||||
local prefer_front = profession == "butcher" or profession == "blacksmith"
|
local prefer_front = profession == "butcher" or profession == "blacksmith"
|
||||||
@ -1373,9 +1434,9 @@ local movement_decider_empty = function(task_queue, mob)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if target and target_block then
|
if target and target_block then
|
||||||
-- Check if we are already close to the target block.
|
-- Check if we are already close to the target.
|
||||||
-- If yes, no need to pathfind again.
|
-- If yes, no need to pathfind again.
|
||||||
local dist = vector.distance(mobpos, target_block)
|
local dist = vector.distance(mobpos, target)
|
||||||
local ydist = math.abs(target_block.y - mobpos.y)
|
local ydist = math.abs(target_block.y - mobpos.y)
|
||||||
if dist >= 1.42 or ydist >= 1 then
|
if dist >= 1.42 or ydist >= 1 then
|
||||||
-- First find the path asynchronously ...
|
-- First find the path asynchronously ...
|
||||||
|
Loading…
x
Reference in New Issue
Block a user