From 37e4dd55564d70c9a1d4b1089f9109410f90e118 Mon Sep 17 00:00:00 2001 From: ancientmarinerdev Date: Tue, 25 Oct 2022 20:24:37 +0100 Subject: [PATCH 1/3] Villagers will now path through doors. Villagers don't stand around whne not working. --- mods/ENTITIES/mcl_mobs/api.lua | 91 +++++++++++++++++++++++------- mods/ENTITIES/mobs_mc/villager.lua | 28 ++++++--- 2 files changed, 91 insertions(+), 28 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 45245622e..08e30e24e 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -2484,10 +2484,11 @@ local function check_doors(self) if n.name:find("_b_") then local def = minetest.registered_nodes[n.name] local closed = n.name:find("_b_1") - if t < 0.3 or t > 0.8 then - if not closed and def.on_rightclick then def.on_rightclick(d,n,self) end - else + if self.state == "gowp" then 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 @@ -2498,7 +2499,7 @@ local gowp_etime = 0 local function check_gowp(self,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 local p = self.object:get_pos() @@ -2509,7 +2510,7 @@ local function check_gowp(self,dtime) return end - -- arrived at location + -- arrived at location, finish gowp local distance_to_targ = vector.distance(p,self._target) mcl_log("Distance to targ: ".. tostring(distance_to_targ)) if distance_to_targ < 2 then @@ -2525,34 +2526,79 @@ local function check_gowp(self,dtime) return true 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 for i, j in pairs (self.waypoints) do - mcl_log("Way: ".. tostring(i)) mcl_log("Val: ".. tostring(j)) end - --mcl_log("nextwp:".. tostring(self.waypoints) ) end 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) ) go_to_pos(self,self.current_target) return 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) + -- 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 - 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 not self.waypoints then self.state = "walk" end --give up - self.current_target = nil + --if self.current_target and not minetest.line_of_sight(self.object:get_pos(),self.current_target) then + if self.current_target and (self.waypoints and #self.waypoints == 0) then + local updated_p = self.object:get_pos() + 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 end - if not self.current_target then - --mcl_log("no path") - self.state = "walk" - end + --if not self.current_target then + --mcl_log("no path. Give up") + --self.state = "walk" + --end end -- execute current state (stand, walk, run, attacks) @@ -2601,7 +2647,7 @@ local do_states = function(self, dtime) end -- 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 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"}) if d then --mcl_log("Found a door near") + local up_one = vector.new(0,1,0) for _,v in pairs(plane_adjacents) do local pos = vector.add(d,v) + local n = minetest.get_node(pos) if n.name == "air" then wp = minetest.find_path(p,pos,150,1,4) 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 else diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 7df4c6ea7..bd2d39002 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -577,9 +577,9 @@ function get_activity(tod) local lunch_start = 12000 - local lunch_end = 13500 - local work_start = 8500 - local work_end = 16300 + local lunch_end = 12500 + local work_start = 6500 + local work_end = 18000 local activity = nil @@ -817,7 +817,7 @@ local function look_for_job(self, requested_jobsites) local looking_for_type = jobsites 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 else mcl_log("Looking for any job type") @@ -863,7 +863,7 @@ local function get_a_job(self) local requested_jobsites = jobsites 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) -- Only pass in my jobsite to two functions here else @@ -1461,6 +1461,7 @@ local trade_inventory = { -- END OF SPECIAL HANDLING FOR COMPASS local trader = player_trading_with[name] local tradenum = player_tradenum[name] + local trades trader._traded = true if trader and trader._trades then @@ -1643,23 +1644,31 @@ mcl_mobs:register_mob("mobs_mc:villager", { return it end, 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 - 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. self.state = "stand" self.attack = nil end + -- Don't do at night. Go to bed? Maybe do_activity needs it's own method if validate_jobsite(self) then mcl_mobs:gopath(self,self._jobsite,function() --minetest.log("arrived at jobsite") end) else self.state = "stand" -- cancel gowp in case it has messed up + self.order = nil -- cancel work if working end - if self.child or self._profession == "unemployed" or self._profession == "nitwit" then - return - end -- Initiate trading init_trader_vars(self) local name = clicker:get_player_name() @@ -1733,6 +1742,7 @@ mcl_mobs:register_mob("mobs_mc:villager", { take_bed (self) end + -- Only check in day or during thunderstorm but wandered_too_far code won't work if check_bed (self) then --self.state ~= "go_home" local wandered_too_far = ( self.state ~= "gowp" ) and (vector.distance(self.object:get_pos(),self._bed) > 50 ) From eebea4a7a9fa92283eae7640556e08b6790cca4f Mon Sep 17 00:00:00 2001 From: ancientmarinerdev Date: Tue, 25 Oct 2022 23:53:55 +0100 Subject: [PATCH 2/3] Clean up and add pathfinding constant --- mods/ENTITIES/mcl_mobs/api.lua | 12 +++++++----- mods/ENTITIES/mobs_mc/villager.lua | 18 ++++++++++-------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 08e30e24e..422857de4 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -13,6 +13,8 @@ local FLOP_HOR_SPEED = 1.5 local ENTITY_CRAMMING_MAX = 24 local CRAMMING_DAMAGE = 3 +local PATHFINDING = "gowp" + -- Localize local S = minetest.get_translator("mcl_mobs") @@ -2484,7 +2486,7 @@ local function check_doors(self) if n.name:find("_b_") then local def = minetest.registered_nodes[n.name] local closed = n.name:find("_b_1") - if self.state == "gowp" then + if self.state == PATHFINDING then 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 @@ -2661,7 +2663,7 @@ local do_states = function(self, dtime) end end - elseif self.state == "gowp" then + elseif self.state == PATHFINDING then check_gowp(self,dtime) elseif self.state == "walk" then @@ -3178,7 +3180,7 @@ local plane_adjacents = { local gopath_last = os.time() function mcl_mobs:gopath(self,target,callback_arrived) - if self.state == "gowp" then mcl_log("Already set as gowp, don't set another path until done.") return end + if self.state == PATHFINDING then mcl_log("Already set as gowp, don't set another path until done.") return end if os.time() - gopath_last < 15 then mcl_log("Not ready to path yet") @@ -3232,7 +3234,7 @@ function mcl_mobs:gopath(self,target,callback_arrived) self.callback_arrived = callback_arrived table.remove(wp,1) self.waypoints = wp - self.state = "gowp" + self.state = PATHFINDING return true else self.state = "walk" @@ -4193,7 +4195,7 @@ local mob_step = function(self, dtime) -- attack timer self.timer = self.timer + dtime - if self.state ~= "attack" and self.state ~= "gowp" then + if self.state ~= "attack" and self.state ~= PATHFINDING then if self.timer < 1 then return end diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index bd2d39002..a6f21b83b 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -30,6 +30,8 @@ local DEFAULT_WALK_CHANCE = 33 -- chance to walk in percent, if no player nearby local PLAYER_SCAN_INTERVAL = 5 -- every X seconds, villager looks for players nearby local PLAYER_SCAN_RADIUS = 4 -- scan radius for looking for nearby players +local PATHFINDING = "gowp" + --[=======[ TRADING ]=======] -- LIST OF VILLAGER PROFESSIONS AND TRADES @@ -564,7 +566,7 @@ end local function set_textures(self) local badge_textures = get_badge_textures(self) - mcl_log("Setting textures: " .. tostring(badge_textures)) + --mcl_log("Setting textures: " .. tostring(badge_textures)) self.object:set_properties({textures=badge_textures}) end @@ -671,7 +673,7 @@ local function take_bed (entity) for _,n in pairs(nn) do local m=minetest.get_meta(n) --mcl_log("Bed owner: ".. m:get_string("villager")) - if m:get_string("villager") == "" and not (entity.state == "gowp") then + if m:get_string("villager") == "" and not (entity.state == PATHFINDING) then mcl_log("Can we path to bed: "..minetest.pos_to_string(n) ) local gp = mcl_mobs:gopath(entity,n,function(self) if self then @@ -884,7 +886,7 @@ local function get_a_job(self) if n and employ(self,n) then return true end - if self.state ~= "gowp" then + if self.state ~= PATHFINDING then mcl_log("Nothing near. Need to look for a job") look_for_job(self, requested_jobsites) end @@ -938,7 +940,7 @@ local function do_work (self) -- Don't try if looking_for_work, or gowp possibly if validate_jobsite(self) then - mcl_log("My jobsite is valid. Do i need to travel?") + --mcl_log("My jobsite is valid. Do i need to travel?") local jobsite2 = retrieve_my_jobsite (self) local jobsite = self._jobsite @@ -947,9 +949,9 @@ local function do_work (self) --mcl_log("Villager: ".. minetest.pos_to_string(self.object:get_pos()) .. ", jobsite: " .. minetest.pos_to_string(self._jobsite)) if vector.distance(self.object:get_pos(),self._jobsite) < 2 then - mcl_log("Made it to work ok!") + --mcl_log("Made it to work ok!") - if not (self.state == "gowp") then + if not (self.state == PATHFINDING) then --mcl_log("Setting order to work.") self.order = WORK else @@ -1649,7 +1651,7 @@ mcl_mobs:register_mob("mobs_mc:villager", { return end - if self.state == "gowp" then + if self.state == PATHFINDING then self.state = "stand" end -- Can we remove now we possibly have fixed root cause @@ -1745,7 +1747,7 @@ mcl_mobs:register_mob("mobs_mc:villager", { -- Only check in day or during thunderstorm but wandered_too_far code won't work if check_bed (self) then --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 ~= PATHFINDING ) and (vector.distance(self.object:get_pos(),self._bed) > 50 ) --if wandered_too_far then minetest.log("Wandered too far! Return home ") end if wandered_too_far then From f8ee473383afd1842fe486d1fd5d08c7181ec1ad Mon Sep 17 00:00:00 2001 From: ancientmarinerdev Date: Wed, 26 Oct 2022 00:17:29 +0100 Subject: [PATCH 3/3] Fix villager work times --- mods/ENTITIES/mcl_mobs/api.lua | 3 --- mods/ENTITIES/mobs_mc/villager.lua | 6 +++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 422857de4..8d385d040 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -3201,7 +3201,6 @@ function mcl_mobs:gopath(self,target,callback_arrived) local d = minetest.find_node_near(target,16,{"group:door"}) if d then --mcl_log("Found a door near") - local up_one = vector.new(0,1,0) for _,v in pairs(plane_adjacents) do local pos = vector.add(d,v) @@ -3212,8 +3211,6 @@ function mcl_mobs:gopath(self,target,callback_arrived) 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 diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index a6f21b83b..336221a17 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -579,9 +579,9 @@ function get_activity(tod) local lunch_start = 12000 - local lunch_end = 12500 - local work_start = 6500 - local work_end = 18000 + local lunch_end = 13500 + local work_start = 8500 + local work_end = 16500 local activity = nil