Villagers will now path through doors. Villagers don't stand around whne not working.

This commit is contained in:
ancientmarinerdev 2022-10-25 20:24:37 +01:00
parent 6a512139c9
commit 37e4dd5556
2 changed files with 91 additions and 28 deletions

View File

@ -2484,10 +2484,11 @@ local function check_doors(self)
if n.name:find("_b_") then if n.name:find("_b_") then
local def = minetest.registered_nodes[n.name] local def = minetest.registered_nodes[n.name]
local closed = n.name:find("_b_1") local closed = n.name:find("_b_1")
if t < 0.3 or t > 0.8 then if self.state == "gowp" then
if not closed and def.on_rightclick then def.on_rightclick(d,n,self) end
else
if closed and def.on_rightclick then def.on_rightclick(d,n,self) end if closed and def.on_rightclick then def.on_rightclick(d,n,self) end
--if not closed and def.on_rightclick then def.on_rightclick(d,n,self) end
else
end end
end end
@ -2498,7 +2499,7 @@ local gowp_etime = 0
local function check_gowp(self,dtime) local function check_gowp(self,dtime)
gowp_etime = gowp_etime + dtime gowp_etime = gowp_etime + dtime
if gowp_etime < 0.2 then return end if gowp_etime < 0.1 then return end
gowp_etime = 0 gowp_etime = 0
local p = self.object:get_pos() local p = self.object:get_pos()
@ -2509,7 +2510,7 @@ local function check_gowp(self,dtime)
return return
end end
-- arrived at location -- arrived at location, finish gowp
local distance_to_targ = vector.distance(p,self._target) local distance_to_targ = vector.distance(p,self._target)
mcl_log("Distance to targ: ".. tostring(distance_to_targ)) mcl_log("Distance to targ: ".. tostring(distance_to_targ))
if distance_to_targ < 2 then if distance_to_targ < 2 then
@ -2525,34 +2526,79 @@ local function check_gowp(self,dtime)
return true return true
end end
if self.waypoints and ( not self.current_target or vector.distance(p,self.current_target) < 2 ) then -- More pathing to be done
if self.waypoints and #self.waypoints > 0 and ( not self.current_target or vector.distance(p,self.current_target) < 2 ) then
-- We have waypoints, and no current target, or we're at it. We need a new current_target.
if not self.current_target then if not self.current_target then
for i, j in pairs (self.waypoints) do for i, j in pairs (self.waypoints) do
mcl_log("Way: ".. tostring(i))
mcl_log("Val: ".. tostring(j)) mcl_log("Val: ".. tostring(j))
end end
--mcl_log("nextwp:".. tostring(self.waypoints) )
end end
self.current_target = table.remove(self.waypoints, 1) self.current_target = table.remove(self.waypoints, 1)
mcl_log("current target:".. tostring(self.current_target) ) mcl_log("current target:".. minetest.pos_to_string(self.current_target) )
--mcl_log("type:".. type(self.current_target) ) --mcl_log("type:".. type(self.current_target) )
go_to_pos(self,self.current_target) go_to_pos(self,self.current_target)
return return
elseif self.current_target then elseif self.current_target then
-- No waypoints left, but have current target. Potentially last waypoint to go to.
mcl_log("self.current_target: ".. minetest.pos_to_string(self.current_target))
mcl_log("pos: ".. minetest.pos_to_string(p))
go_to_pos(self,self.current_target) go_to_pos(self,self.current_target)
-- Do i just delete current_target, and return so we can find final path.
else
-- Not at target, no current waypoints or current_target. Through the door and should be able to path to target.
-- Is a little sensitive and could take 1 - 7 times. A 10 fail count might be a good exit condition.
mcl_log("We don't have waypoints or a current target. Let's try to path to target")
local final_wp = minetest.find_path(p,self._target,150,1,4)
if final_wp then
mcl_log("We might be able to get to target here.")
self.waypoints = final_wp
--go_to_pos(self,self._target)
else
mcl_log("Cannot plot final route to target")
end
end end
if self.current_target and not minetest.line_of_sight(self.object:get_pos(),self.current_target) then --if self.current_target and not minetest.line_of_sight(self.object:get_pos(),self.current_target) then
self.waypoints=minetest.find_path(p,self._target,150,1,4) if self.current_target and (self.waypoints and #self.waypoints == 0) then
if not self.waypoints then self.state = "walk" end --give up local updated_p = self.object:get_pos()
self.current_target = nil local distance_to_cur_targ = vector.distance(updated_p,self.current_target)
mcl_log("Distance to current target: ".. tostring(distance_to_cur_targ))
mcl_log("Current p: ".. minetest.pos_to_string(updated_p))
--if not minetest.line_of_sight(self.object:get_pos(),self._target) then
-- 1.6 is good. is 1.9 better? It could fail less, but will it path to door when it isn't after door
if distance_to_cur_targ > 1.9 then
mcl_log("no LOS to target: ".. minetest.pos_to_string(self.current_target))
go_to_pos(self,self._current_target)
else
mcl_log("Let's go to target: ".. minetest.pos_to_string(self.current_target))
self.current_target = nil
--go_to_pos(self,self._target)
self.waypoints=minetest.find_path(updated_p,self._target,150,1,4)
--if not self.waypoints then
--mcl_log("Give up ")
--self.state = "walk"
--end --give up
end
--self.waypoints=minetest.find_path(p,self._target,150,1,4)
--if not self.waypoints then
--mcl_log("Give up ")
--self.state = "walk"
--end --give up
--self.current_target = nil
return return
end end
if not self.current_target then --if not self.current_target then
--mcl_log("no path") --mcl_log("no path. Give up")
self.state = "walk" --self.state = "walk"
end --end
end end
-- execute current state (stand, walk, run, attacks) -- execute current state (stand, walk, run, attacks)
@ -2601,7 +2647,7 @@ local do_states = function(self, dtime)
end end
-- npc's ordered to stand stay standing -- npc's ordered to stand stay standing
if self.type == "npc" or (self.order == "stand" or self.order == "sleep" or self.order == "work") then if self.order == "stand" or self.order == "sleep" or self.order == "work" then
else else
if self.walk_chance ~= 0 if self.walk_chance ~= 0
@ -3153,13 +3199,20 @@ function mcl_mobs:gopath(self,target,callback_arrived)
local d = minetest.find_node_near(target,16,{"group:door"}) local d = minetest.find_node_near(target,16,{"group:door"})
if d then if d then
--mcl_log("Found a door near") --mcl_log("Found a door near")
local up_one = vector.new(0,1,0)
for _,v in pairs(plane_adjacents) do for _,v in pairs(plane_adjacents) do
local pos = vector.add(d,v) local pos = vector.add(d,v)
local n = minetest.get_node(pos) local n = minetest.get_node(pos)
if n.name == "air" then if n.name == "air" then
wp = minetest.find_path(p,pos,150,1,4) wp = minetest.find_path(p,pos,150,1,4)
if wp then if wp then
--mcl_log("Found a path to next to door".. minetest.pos_to_string(pos)) mcl_log("Found a path to next to door".. minetest.pos_to_string(pos))
local other_side_of_door = vector.add(d,-v)
mcl_log("Opposite is: ".. minetest.pos_to_string(other_side_of_door))
--other_side_of_door = vector.add(other_side_of_door, up_one)
--mcl_log("Opposite 2 is: ".. minetest.pos_to_string(other_side_of_door))
table.insert(wp, other_side_of_door)
break break
else else

View File

@ -577,9 +577,9 @@ function get_activity(tod)
local lunch_start = 12000 local lunch_start = 12000
local lunch_end = 13500 local lunch_end = 12500
local work_start = 8500 local work_start = 6500
local work_end = 16300 local work_end = 18000
local activity = nil local activity = nil
@ -817,7 +817,7 @@ local function look_for_job(self, requested_jobsites)
local looking_for_type = jobsites local looking_for_type = jobsites
if requested_jobsites then if requested_jobsites then
mcl_log("Looking for jobs of my type: " .. tostring(requested_jobsites)) --mcl_log("Looking for jobs of my type: " .. tostring(requested_jobsites))
looking_for_type = requested_jobsites looking_for_type = requested_jobsites
else else
mcl_log("Looking for any job type") mcl_log("Looking for any job type")
@ -863,7 +863,7 @@ local function get_a_job(self)
local requested_jobsites = jobsites local requested_jobsites = jobsites
if has_traded (self) then if has_traded (self) then
--mcl_log("Has traded") mcl_log("Has traded so look for job of my type")
requested_jobsites = populate_jobsites(self._profession) requested_jobsites = populate_jobsites(self._profession)
-- Only pass in my jobsite to two functions here -- Only pass in my jobsite to two functions here
else else
@ -1461,6 +1461,7 @@ local trade_inventory = {
-- END OF SPECIAL HANDLING FOR COMPASS -- END OF SPECIAL HANDLING FOR COMPASS
local trader = player_trading_with[name] local trader = player_trading_with[name]
local tradenum = player_tradenum[name] local tradenum = player_tradenum[name]
local trades local trades
trader._traded = true trader._traded = true
if trader and trader._trades then if trader and trader._trades then
@ -1643,23 +1644,31 @@ mcl_mobs:register_mob("mobs_mc:villager", {
return it return it
end, end,
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
if self.child or self._profession == "unemployed" or self._profession == "nitwit" then
self.order = nil
return
end
if self.state == "gowp" then
self.state = "stand"
end
-- Can we remove now we possibly have fixed root cause
if self.state == "attack" then if self.state == "attack" then
mcl_log("Somehow villager got into an invalid attack state. Removed.") mcl_log("Somehow villager got into an invalid attack state. Removed attack state.")
-- Need to stop villager getting in attack state. This is a workaround to allow players to fix broken villager. -- Need to stop villager getting in attack state. This is a workaround to allow players to fix broken villager.
self.state = "stand" self.state = "stand"
self.attack = nil self.attack = nil
end end
-- Don't do at night. Go to bed? Maybe do_activity needs it's own method
if validate_jobsite(self) then if validate_jobsite(self) then
mcl_mobs:gopath(self,self._jobsite,function() mcl_mobs:gopath(self,self._jobsite,function()
--minetest.log("arrived at jobsite") --minetest.log("arrived at jobsite")
end) end)
else else
self.state = "stand" -- cancel gowp in case it has messed up self.state = "stand" -- cancel gowp in case it has messed up
self.order = nil -- cancel work if working
end end
if self.child or self._profession == "unemployed" or self._profession == "nitwit" then
return
end
-- Initiate trading -- Initiate trading
init_trader_vars(self) init_trader_vars(self)
local name = clicker:get_player_name() local name = clicker:get_player_name()
@ -1733,6 +1742,7 @@ mcl_mobs:register_mob("mobs_mc:villager", {
take_bed (self) take_bed (self)
end end
-- Only check in day or during thunderstorm but wandered_too_far code won't work
if check_bed (self) then if check_bed (self) then
--self.state ~= "go_home" --self.state ~= "go_home"
local wandered_too_far = ( self.state ~= "gowp" ) and (vector.distance(self.object:get_pos(),self._bed) > 50 ) local wandered_too_far = ( self.state ~= "gowp" ) and (vector.distance(self.object:get_pos(),self._bed) > 50 )