From e4102e612448b79a3512b01ca4e3dddf190d7ef6 Mon Sep 17 00:00:00 2001 From: the-real-herowl Date: Wed, 13 Sep 2023 09:27:40 +0200 Subject: [PATCH] Implemented wither defensive measures Added block breaking when hit, or a safe_boom when hit and mobs_griefing is disabled. Removed dubious anti-troll measures. --- mods/ENTITIES/mobs_mc/wither.lua | 66 ++++++++++++++++------------ mods/ITEMS/mcl_potions/functions.lua | 24 ++++++++++ mods/ITEMS/mcl_potions/splash.lua | 2 +- 3 files changed, 64 insertions(+), 28 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/wither.lua b/mods/ENTITIES/mobs_mc/wither.lua index ea8dbd0c5..5f88c18ad 100644 --- a/mods/ENTITIES/mobs_mc/wither.lua +++ b/mods/ENTITIES/mobs_mc/wither.lua @@ -21,6 +21,35 @@ end --################### WITHER --################### +local function wither_unstuck(self) + local pos = self.object:get_pos() + if mobs_griefing then + local col = self.collisionbox + local pos1 = vector.offset(pos, col[1], col[2], col[3]) + local pos2 = vector.offset(pos, col[4], col[5], col[6]) + for z = pos1.z, pos2.z do for y = pos1.y, pos2.y do for x = pos1.x, pos2.x do + local npos = vector.new(x,y,z) + local name = minetest.get_node(npos).name + if name ~= "air" then + local ndef = minetest.registered_nodes[name] + if ndef and ndef._mcl_hardness and ndef._mcl_hardness >= 0 then + local drops = minetest.get_node_drops(name, "") + if minetest.dig_node(npos) then + for _, item in ipairs(drops) do + if type(item) ~= "string" then + item = item:get_name() .. item:get_count() + end + minetest.add_item(npos, item) + end + end + end + end + end end end + else + mcl_mobs.mob_class.safe_boom(self, pos, 2) + end +end + mobs_mc.wither_count_overworld = 0 mobs_mc.wither_count_nether = 0 mobs_mc.wither_count_end = 0 @@ -137,12 +166,12 @@ mcl_mobs.register_mob("mobs_mc:wither", { if anti_troll and self._spawner then local spawner = minetest.get_player_by_name(self._spawner) - if spawner then + if follow_spawner and spawner then self._death_timer = 0 local pos = self.object:get_pos() local spw = spawner:get_pos() local dist = vector.distance(pos, spw) - if dist > 60 and follow_spawner then -- teleport to the player who spawned the wither + if dist > 60 then -- teleport to the player who spawned the wither local R = 10 pos.x = spw.x + math.random(-R, R) pos.y = spw.y + math.random(-R, R) @@ -165,26 +194,6 @@ mcl_mobs.register_mob("mobs_mc:wither", { elseif dim == "nether" then mobs_mc.wither_count_nether = mobs_mc.wither_count_nether + 1 elseif dim == "end" then mobs_mc.wither_count_end = mobs_mc.wither_count_end + 1 end - if anti_troll then - local INDESTRUCT_BLASTRES = 1000000 - local head_pos = vector.offset(self.object:get_pos(),0,self.collisionbox[5],0) - local subh_pos = vector.offset(head_pos,0,-1,0) - local head_node = minetest.get_node(head_pos).name - local subh_node = minetest.get_node(subh_pos).name - local hnodef = minetest.registered_nodes[head_node] - local subhnodef = minetest.registered_nodes[subh_node] - if hnodef and subhnodef and (hnodef.walkable or subhnodef.walkable) and not self._xplded_lately then - if mobs_griefing and not minetest.is_protected(head_pos, "") and hnodef._mcl_blast_resistance < INDESTRUCT_BLASTRES then - local hp = self.health - mcl_explosions.explode(head_pos, 5, { drop_chance = 1.0, max_blast_resistance = 0, }, self.object) - self._xplded_lately = true - self.health = hp - else - self.object:set_pos(vector.offset(head_pos,0,10,0)) - end - end - end - local rand_factor if self.health < (self.hp_max / 2) then self.base_texture = "mobs_mc_wither_half_health.png" @@ -337,14 +346,16 @@ mcl_mobs.register_mob("mobs_mc:wither", { end, do_punch = function(self, hitter, tflp, tool_capabilities, dir) - if self._spawning then return false end + if self._spawning or hitter == self.object then return false end local ent = hitter:get_luaentity() if ent and self._arrow_resistant and (string.find(ent.name, "arrow") or string.find(ent.name, "rocket")) then return false end + wither_unstuck(self) return true end, deal_damage = function(self, damage, mcl_reason) if self._spawning then return end if self._arrow_resistant and mcl_reason.type == "magic" then return end + wither_unstuck(self) self.health = self.health - damage end, @@ -390,7 +401,7 @@ mcl_mobs.register_arrow("mobs_mc:wither_skull", { -- direct hit hit_player = function(self, player) - local pos = self.object:get_pos() + local pos = vector.new(self.object:get_pos()) mcl_mobs.effect_functions["withering"](player, 0.5, 10) player:punch(self.object, 1.0, { full_punch_interval = 0.5, @@ -405,7 +416,7 @@ mcl_mobs.register_arrow("mobs_mc:wither_skull", { end, hit_mob = function(self, mob) - local pos = self.object:get_pos() + local pos = vector.new(self.object:get_pos()) mcl_mobs.effect_functions["withering"](mob, 0.5, 10) mob:punch(self.object, 1.0, { full_punch_interval = 0.5, @@ -443,7 +454,7 @@ mcl_mobs.register_arrow("mobs_mc:wither_skull_strong", { -- direct hit hit_player = function(self, player) - local pos = self.object:get_pos() + local pos = vector.new(self.object:get_pos()) mcl_mobs.effect_functions["withering"](player, 0.5, 10) player:punch(self.object, 1.0, { full_punch_interval = 0.5, @@ -462,7 +473,7 @@ mcl_mobs.register_arrow("mobs_mc:wither_skull_strong", { end, hit_mob = function(self, mob) - local pos = self.object:get_pos() + local pos = vector.new(self.object:get_pos()) mcl_mobs.effect_functions["withering"](mob, 0.5, 10) mob:punch(self.object, 1.0, { full_punch_interval = 0.5, @@ -496,3 +507,4 @@ mcl_mobs.register_egg("mobs_mc:wither", S("Wither"), "#4f4f4f", "#4f4f4f", 0, tr mcl_wip.register_wip_item("mobs_mc:wither") mcl_mobs:non_spawn_specific("mobs_mc:wither","overworld",0,minetest.LIGHT_MAX+1) + diff --git a/mods/ITEMS/mcl_potions/functions.lua b/mods/ITEMS/mcl_potions/functions.lua index cb0c60a5c..b2bc3fc96 100644 --- a/mods/ITEMS/mcl_potions/functions.lua +++ b/mods/ITEMS/mcl_potions/functions.lua @@ -730,6 +730,8 @@ end function mcl_potions.healing_func(player, hp) + if player:get_hp() <= 0 then return false end + local obj = player:get_luaentity() if player:get_hp() == 0 then @@ -762,6 +764,8 @@ end function mcl_potions.swiftness_func(player, factor, duration) + if player:get_hp() <= 0 then return false end + local entity = player:get_luaentity() if entity and entity.is_boss then return false end @@ -793,6 +797,8 @@ end function mcl_potions.leaping_func(player, factor, duration) + if player:get_hp() <= 0 then return false end + local entity = player:get_luaentity() if entity and entity.is_boss then return false end @@ -824,6 +830,8 @@ end function mcl_potions.weakness_func(player, factor, duration) + if player:get_hp() <= 0 then return false end + local entity = player:get_luaentity() if entity and entity.is_boss then return false end @@ -850,6 +858,8 @@ end function mcl_potions.strength_func(player, factor, duration) + if player:get_hp() <= 0 then return false end + local entity = player:get_luaentity() if entity and entity.is_boss then return false end @@ -876,6 +886,8 @@ end function mcl_potions.withering_func(player, factor, duration) + if player:get_hp() <= 0 then return false end + local entity = player:get_luaentity() if entity and (entity.is_boss or string.find(entity.name, "wither")) then return false end @@ -902,6 +914,8 @@ end function mcl_potions.poison_func(player, factor, duration) + if player:get_hp() <= 0 then return false end + local entity = player:get_luaentity() if entity and (entity.is_boss or entity.harmed_by_heal or string.find(entity.name, "spider")) then return false end @@ -928,6 +942,8 @@ end function mcl_potions.regeneration_func(player, factor, duration) + if player:get_hp() <= 0 then return false end + local entity = player:get_luaentity() if entity and (entity.is_boss or entity.harmed_by_heal) then return false end @@ -954,6 +970,8 @@ end function mcl_potions.invisiblility_func(player, null, duration) + if player:get_hp() <= 0 then return false end + local entity = player:get_luaentity() if entity and entity.is_boss then return false end @@ -979,6 +997,8 @@ end function mcl_potions.water_breathing_func(player, null, duration) + if player:get_hp() <= 0 then return false end + local entity = player:get_luaentity() if entity and entity.is_boss then return false end @@ -1004,6 +1024,8 @@ end function mcl_potions.fire_resistance_func(player, null, duration) + if player:get_hp() <= 0 then return false end + local entity = player:get_luaentity() if entity and entity.is_boss then return false end @@ -1028,6 +1050,8 @@ end function mcl_potions.night_vision_func(player, null, duration) + if player:get_hp() <= 0 then return false end + local entity = player:get_luaentity() if entity and entity.is_boss then return false end diff --git a/mods/ITEMS/mcl_potions/splash.lua b/mods/ITEMS/mcl_potions/splash.lua index 730796952..6b6238dbf 100644 --- a/mods/ITEMS/mcl_potions/splash.lua +++ b/mods/ITEMS/mcl_potions/splash.lua @@ -110,7 +110,7 @@ function mcl_potions.register_splash(name, descr, color, def) for _,obj in pairs(minetest.get_objects_inside_radius(pos, 4)) do local entity = obj:get_luaentity() - if obj:is_player() or entity.is_mob then + if obj:is_player() or entity and entity.is_mob then local pos2 = obj:get_pos() local rad = math.floor(math.sqrt((pos2.x-pos.x)^2 + (pos2.y-pos.y)^2 + (pos2.z-pos.z)^2))