Pathfinding through door should also check door closest to position so villager can leave current house

This commit is contained in:
ancientmarinerdev 2022-12-30 04:15:59 +00:00 committed by Gitea
parent 5c0a763b83
commit 29cd73cb84
1 changed files with 81 additions and 73 deletions

View File

@ -35,11 +35,11 @@ function append_paths (wp1, wp2)
end end
local function output_enriched (wp_out) local function output_enriched (wp_out)
--mcl_log("Output enriched path") mcl_log("Output enriched path")
local i = 0 local i = 0
for _,outy in pairs (wp_out) do for _,outy in pairs (wp_out) do
i = i + 1 i = i + 1
--mcl_log("Pos ".. i ..":" .. minetest.pos_to_string(outy["pos"])) mcl_log("Pos ".. i ..":" .. minetest.pos_to_string(outy["pos"]))
local action = outy["action"] local action = outy["action"]
if action then if action then
@ -109,38 +109,43 @@ local plane_adjacents = {
vector.new(0,0,-1), vector.new(0,0,-1),
} }
--local gopath_last = os.time()
function mob_class:ready_to_path()
mcl_log("Check ready to path")
if self._pf_last_failed and (os.time() - self._pf_last_failed) < 30 then
return false
else
mcl_log("We are ready to pathfind, no previous fail or we are past threshold")
return true
end
end
-- This function is used to see if we can path. We could use to check a route, rather than making people move. -- This function is used to see if we can path. We could use to check a route, rather than making people move.
local function calculate_path_through_door (p, t, target) local function calculate_path_through_door (p, t, cur_door_pos)
-- target is the same as t, just 1 square difference. Maybe we don't need target -- target is the same as t, just 1 square difference. Maybe we don't need target
mcl_log("Plot route from mob: " .. minetest.pos_to_string(p) .. ", to target: " .. minetest.pos_to_string(t)) mcl_log("Plot route from mob: " .. minetest.pos_to_string(p) .. ", to target: " .. minetest.pos_to_string(t))
local enriched_path = nil local enriched_path = nil
local cur_door_pos = nil --local cur_door_pos = nil
local pos_closest_to_door = nil local pos_closest_to_door = nil
local other_side_of_door = nil local other_side_of_door = nil
--Check direct route local wp
local wp = minetest.find_path(p,t,150,1,4)
--Path to door first
if not wp then
mcl_log("No direct path. Path through door")
-- This could improve. There could be multiple doors. Check you can path from door to target first.
-- target could be pos
local cur_door_pos = minetest.find_node_near(target,16,{"group:door"})
if cur_door_pos then if cur_door_pos then
mcl_log("Found a door near: " .. minetest.pos_to_string(cur_door_pos)) mcl_log("Found a door near: " .. minetest.pos_to_string(cur_door_pos))
for _,v in pairs(plane_adjacents) do for _,v in pairs(plane_adjacents) do
pos_closest_to_door = vector.add(cur_door_pos,v) pos_closest_to_door = vector.add(cur_door_pos,v)
local n = minetest.get_node(pos_closest_to_door) local n = minetest.get_node(pos_closest_to_door)
if n.name == "air" then if n.name == "air" then
mcl_log("We have air space next to door at: " .. minetest.pos_to_string(pos_closest_to_door))
wp = minetest.find_path(p,pos_closest_to_door,150,1,4) wp = minetest.find_path(p,pos_closest_to_door,150,1,4)
if wp then
if wp then
mcl_log("Found a path to next to door".. minetest.pos_to_string(pos_closest_to_door)) mcl_log("Found a path to next to door".. minetest.pos_to_string(pos_closest_to_door))
other_side_of_door = vector.add(cur_door_pos,-v) other_side_of_door = vector.add(cur_door_pos,-v)
mcl_log("Opposite is: ".. minetest.pos_to_string(other_side_of_door)) mcl_log("Opposite is: ".. minetest.pos_to_string(other_side_of_door))
@ -158,38 +163,20 @@ local function calculate_path_through_door (p, t, target)
else else
mcl_log("This block next to door doesn't work.") mcl_log("This block next to door doesn't work.")
end end
else
--mcl_log("Block is not air, it is: ".. n.name)
end end
end end
else else
mcl_log("No door found") mcl_log("No door found")
end end
else
mcl_log("We have a direct route")
end
-- If not, get door near pos
--path from pos to door, path from otherside to target
if wp and not enriched_path then if wp and not enriched_path then
mcl_log("Wp but not enriched")
enriched_path = generate_enriched_path(wp) enriched_path = generate_enriched_path(wp)
end end
return enriched_path return enriched_path
end end
--local gopath_last = os.time()
function mob_class:ready_to_path()
mcl_log("Check ready to path")
if self._pf_last_failed and (os.time() - self._pf_last_failed) < 30 then
return false
else
mcl_log("We are ready to pathfind, no previous fail or we are past threshold")
return true
end
end
function mob_class:gopath(target,callback_arrived) function mob_class:gopath(target,callback_arrived)
if self.state == PATHFINDING then mcl_log("Already pathfinding, don't set another until done.") return end if self.state == PATHFINDING then mcl_log("Already pathfinding, don't set another until done.") return end
@ -210,7 +197,28 @@ function mob_class:gopath(target,callback_arrived)
local p = self.object:get_pos() local p = self.object:get_pos()
local t = vector.offset(target,0,1,0) local t = vector.offset(target,0,1,0)
local wp = calculate_path_through_door(p, t, target) --Check direct route
local wp = minetest.find_path(p,t,150,1,4)
if not wp then
mcl_log("No direct path. Path through door")
-- target could be pos
local cur_door_pos = minetest.find_node_near(target, 16, {"group:door"})
wp = calculate_path_through_door(p, t, cur_door_pos)
if not wp then
mcl_log("No path though door closest to target. Try door closest to origin.")
cur_door_pos = minetest.find_node_near(p, 16, {"group:door"})
wp = calculate_path_through_door(p, t, cur_door_pos)
end
else
wp = generate_enriched_path(wp)
mcl_log("We have a direct route")
end
--path from pos to door, path from otherside to target
if not wp then if not wp then
mcl_log("Could not calculate path") mcl_log("Could not calculate path")
self._pf_last_failed = os.time() self._pf_last_failed = os.time()