Merge pull request 'Pathfinding optimisations and villager has earlier bed time' (#3410) from villager_tweaks into master

Reviewed-on: https://git.minetest.land/MineClone2/MineClone2/pulls/3410
This commit is contained in:
ancientmarinerdev 2023-02-11 10:48:36 +00:00
commit 15a15158b8
2 changed files with 35 additions and 14 deletions

@ -3,6 +3,9 @@ local mob_class = mcl_mobs.mob_class
local PATHFINDING_FAIL_THRESHOLD = 100 -- no. of ticks to fail before giving up. 20p/s. 5s helps them get through door local PATHFINDING_FAIL_THRESHOLD = 100 -- no. of ticks to fail before giving up. 20p/s. 5s helps them get through door
local PATHFINDING_FAIL_WAIT = 30 -- how long to wait before trying to path again local PATHFINDING_FAIL_WAIT = 30 -- how long to wait before trying to path again
local PATHING_START_DELAY = 4 -- When doing non-prioritised pathing, how long to wait until last mob pathed
local PATHFINDING_SEARCH_DISTANCE = 50 -- How big the square is that pathfinding will look
local PATHFINDING = "gowp" local PATHFINDING = "gowp"
@ -107,14 +110,20 @@ local function generate_enriched_path(wp_in, door_open_pos, door_close_pos, cur_
return wp_out return wp_out
end end
function mob_class:ready_to_path() local last_pathing_time = os.time()
function mob_class:ready_to_path(prioritised)
mcl_log("Check ready to path") mcl_log("Check ready to path")
if self._pf_last_failed and (os.time() - self._pf_last_failed) < PATHFINDING_FAIL_WAIT then if self._pf_last_failed and (os.time() - self._pf_last_failed) < PATHFINDING_FAIL_WAIT then
mcl_log("Not ready to path as last fail is less than threshold: " .. (os.time() - self._pf_last_failed)) mcl_log("Not ready to path as last fail is less than threshold: " .. (os.time() - self._pf_last_failed))
return false return false
else else
mcl_log("We are ready to pathfind, no previous fail or we are past threshold") local time_since_path_start = os.time() - last_pathing_time
return true mcl_log("time_since_path_start: " .. tostring(time_since_path_start))
if prioritised or (time_since_path_start) > PATHING_START_DELAY then
mcl_log("We are ready to pathfind, no previous fail or we are past threshold")
return true
end
end end
end end
@ -144,7 +153,7 @@ local function calculate_path_through_door (p, cur_door_pos, t)
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)) mcl_log("We have air space next to door at: " .. minetest.pos_to_string(pos_closest_to_door))
prospective_wp = minetest.find_path(p,pos_closest_to_door,150,1,4) prospective_wp = minetest.find_path(p, pos_closest_to_door, PATHFINDING_SEARCH_DISTANCE, 1, 4)
if prospective_wp then if prospective_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))
@ -154,7 +163,7 @@ local function calculate_path_through_door (p, cur_door_pos, t)
if t then if t then
mcl_log("We have t, lets go from door to target") mcl_log("We have t, lets go from door to target")
local wp_otherside_door_to_target = minetest.find_path(other_side_of_door,t,150,1,4) local wp_otherside_door_to_target = minetest.find_path(other_side_of_door, t, PATHFINDING_SEARCH_DISTANCE, 1, 4)
if wp_otherside_door_to_target and #wp_otherside_door_to_target > 0 then if wp_otherside_door_to_target and #wp_otherside_door_to_target > 0 then
append_paths (prospective_wp, wp_otherside_door_to_target) append_paths (prospective_wp, wp_otherside_door_to_target)
@ -190,9 +199,13 @@ local function calculate_path_through_door (p, cur_door_pos, t)
return enriched_path return enriched_path
end end
function mob_class:gopath(target,callback_arrived)
function mob_class:gopath(target, callback_arrived, prioritised)
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
if not self:ready_to_path() then return end if not self:ready_to_path(prioritised) then return end
last_pathing_time = os.time()
self.order = nil self.order = nil
@ -200,7 +213,7 @@ function mob_class:gopath(target,callback_arrived)
local t = vector.offset(target,0,1,0) local t = vector.offset(target,0,1,0)
--Check direct route --Check direct route
local wp = minetest.find_path(p,t,150,1,4) local wp = minetest.find_path(p, t, PATHFINDING_SEARCH_DISTANCE, 1, 4)
if not wp then if not wp then
mcl_log("### No direct path. Path through door closest to target.") mcl_log("### No direct path. Path through door closest to target.")
@ -410,7 +423,7 @@ function mob_class:check_gowp(dtime)
mcl_log("No current target") mcl_log("No current target")
end end
local final_wp = minetest.find_path(p,self._target,150,1,4) local final_wp = minetest.find_path(p, self._target, PATHFINDING_SEARCH_DISTANCE, 1, 4)
if final_wp then if final_wp then
mcl_log("We can get to target here.") mcl_log("We can get to target here.")
-- self.waypoints = final_wp -- self.waypoints = final_wp

@ -617,6 +617,13 @@ local function set_textures(self)
self.object:set_properties({textures=badge_textures}) self.object:set_properties({textures=badge_textures})
end end
-- TODO Pass in self and if nitwit, go to bed later.
local function is_night()
local tod = minetest.get_timeofday()
tod = ( tod * 24000 ) % 24000
return tod > 17500 or tod < 6500
end
function get_activity(tod) function get_activity(tod)
-- night hours = tod > 18541 or tod < 5458 -- night hours = tod > 18541 or tod < 5458
if not tod then if not tod then
@ -626,8 +633,8 @@ function get_activity(tod)
local lunch_start = 11000 local lunch_start = 11000
local lunch_end = 13500 local lunch_end = 13500
local work_start = 7000 local work_start = 7500
local work_end = 16500 local work_end = 16000
local activity = nil local activity = nil
if weather_mod and mcl_weather.get_weather() == "thunder" then if weather_mod and mcl_weather.get_weather() == "thunder" then
@ -635,7 +642,7 @@ function get_activity(tod)
activity = SLEEP activity = SLEEP
elseif (tod > work_start and tod < lunch_start) or (tod > lunch_end and tod < work_end) then elseif (tod > work_start and tod < lunch_start) or (tod > lunch_end and tod < work_end) then
activity = WORK activity = WORK
elseif mcl_beds.is_night() then elseif is_night() then
activity = SLEEP activity = SLEEP
elseif tod > lunch_start and tod < lunch_end then elseif tod > lunch_start and tod < lunch_end then
activity = GATHERING activity = GATHERING
@ -829,7 +836,7 @@ local function go_home(entity, sleep)
else else
--minetest.log("Need to walk to home") --minetest.log("Need to walk to home")
end end
end) end, true)
end end
end end
@ -1166,6 +1173,7 @@ local function do_work (self)
self.order = nil self.order = nil
return return
end end
self:gopath(jobsite, function(self, jobsite) self:gopath(jobsite, function(self, jobsite)
if not self then if not self then
--mcl_log("missing self. not good") --mcl_log("missing self. not good")
@ -1309,7 +1317,7 @@ local function do_activity (self)
local jobsite_valid = false local jobsite_valid = false
if not mcl_beds.is_night() then if not is_night() then
if self.order == SLEEP then self.order = nil end if self.order == SLEEP then self.order = nil end
if not validate_jobsite(self) then if not validate_jobsite(self) then