From 1a670bc41b9c7ce66fe9ccb995442c92a5e8aa3b Mon Sep 17 00:00:00 2001 From: ancientmarinerdev Date: Tue, 15 Nov 2022 22:32:09 +0000 Subject: [PATCH 1/2] Allow villagers to resettle and not run back to job and and old bed --- mods/ENTITIES/mobs_mc/villager.lua | 52 +++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index a7b7d9852..f19ada233 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 RESETTLE_DISTANCE = 100 -- If a mob is transported this far from home, it gives up bed and job and resettles + local PATHFINDING = "gowp" --[=======[ TRADING ]=======] @@ -1089,25 +1091,38 @@ local function retrieve_my_jobsite (self) return end +local function remove_job (self) + self._jobsite = nil + if not has_traded(self) then + mcl_log("Cannot retrieve my jobsite. I am now unemployed.") + self._profession = "unemployed" + self._trades = nil + set_textures(self) + else + mcl_log("Cannot retrieve my jobsite but I've traded so only remove jobsite.") + end +end + local function validate_jobsite(self) if self._profession == "unemployed" then return false end - if not retrieve_my_jobsite (self) then - self._jobsite = nil + local job_block = retrieve_my_jobsite (self) + if not job_block then if self.order == WORK then self.order = nil end - if not has_traded(self) then - mcl_log("Cannot retrieve my jobsite. I am now unemployed.") - self._profession = "unemployed" - self._trades = nil - set_textures(self) - else - mcl_log("Cannot retrieve my jobsite but I've traded so only remove jobsite.") - end + remove_job (self) return false else + local resettle = vector.distance(self.object:get_pos(),self._jobsite) > RESETTLE_DISTANCE + mcl_log("Jobsite far, so resettle: " .. tostring(resettle)) + if resettle then + local m = minetest.get_meta(self._jobsite) + m:set_string("villager", nil) + remove_job (self) + return false + end return true end end @@ -1222,6 +1237,17 @@ local function validate_bed(self) local bed_valid = true local m = minetest.get_meta(self._bed) + + local resettle = vector.distance(self.object:get_pos(),self._bed) > RESETTLE_DISTANCE + mcl_log("Bed far, so resettle: " .. tostring(resettle)) + if resettle then + mcl_log("Resettled. Ditch bed.") + m:set_string("villager", nil) + self._bed = nil + bed_valid = false + return false + end + local owned_by_player = m:get_string("player") mcl_log("Player owner: " .. owned_by_player) if owned_by_player ~= "" then @@ -1229,7 +1255,7 @@ local function validate_bed(self) m:set_string("villager", nil) self._bed = nil bed_valid = false - return + return false end if m:get_string("villager") ~= self._id then @@ -1245,6 +1271,10 @@ end local function do_activity (self) -- Maybe just check we're pathfinding first? + if self.following then + mcl_log("Following, so do not do activity.") + return + end if not validate_bed(self) and self.state ~= PATHFINDING then if self.order == SLEEP then self.order = nil end From a28f667b20aaa112e3a87c798d5e998f61c0d88b Mon Sep 17 00:00:00 2001 From: cora Date: Wed, 16 Nov 2022 00:00:10 +0100 Subject: [PATCH 2/2] Villagers only summon golems when monsters are near --- mods/ENTITIES/mobs_mc/villager.lua | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index f19ada233..9c10c703d 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -887,11 +887,18 @@ local function has_golem(pos) end end +local function monsters_near(self) + for _,o in pairs(minetest.get_objects_inside_radius(self.object:get_pos(),10)) do + local l = o:get_luaentity() + if l and l.type =="monster" then return true end + end +end + local function has_summon_participants(self) local r = 0 for _,o in pairs(minetest.get_objects_inside_radius(self.object:get_pos(),10)) do local l = o:get_luaentity() - --TODO check for panicking or gossiping + --TODO check for gossiping if l and l.name == "mobs_mc:villager" then r = r + 1 end end return r > 2 @@ -915,7 +922,8 @@ local function check_summon(self,dtime) if self._summon_timer and self._summon_timer > 30 then local pos = self.object:get_pos() self._summon_timer = 0 - if has_golem(pos) then return false end + if has_golem(pos) then return end + if not monsters_near(self) then return end if not has_summon_participants(self) then return end summon_golem(self) elseif self._summon_timer == nil then