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.hollow_logs_ref_recovery
parent
17c8f220e6
commit
e4102e6124
|
@ -21,6 +21,35 @@ end
|
||||||
--################### WITHER
|
--################### 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_overworld = 0
|
||||||
mobs_mc.wither_count_nether = 0
|
mobs_mc.wither_count_nether = 0
|
||||||
mobs_mc.wither_count_end = 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
|
if anti_troll and self._spawner then
|
||||||
local spawner = minetest.get_player_by_name(self._spawner)
|
local spawner = minetest.get_player_by_name(self._spawner)
|
||||||
if spawner then
|
if follow_spawner and spawner then
|
||||||
self._death_timer = 0
|
self._death_timer = 0
|
||||||
local pos = self.object:get_pos()
|
local pos = self.object:get_pos()
|
||||||
local spw = spawner:get_pos()
|
local spw = spawner:get_pos()
|
||||||
local dist = vector.distance(pos, spw)
|
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
|
local R = 10
|
||||||
pos.x = spw.x + math.random(-R, R)
|
pos.x = spw.x + math.random(-R, R)
|
||||||
pos.y = spw.y + 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 == "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
|
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
|
local rand_factor
|
||||||
if self.health < (self.hp_max / 2) then
|
if self.health < (self.hp_max / 2) then
|
||||||
self.base_texture = "mobs_mc_wither_half_health.png"
|
self.base_texture = "mobs_mc_wither_half_health.png"
|
||||||
|
@ -337,14 +346,16 @@ mcl_mobs.register_mob("mobs_mc:wither", {
|
||||||
end,
|
end,
|
||||||
|
|
||||||
do_punch = function(self, hitter, tflp, tool_capabilities, dir)
|
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()
|
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
|
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
|
return true
|
||||||
end,
|
end,
|
||||||
deal_damage = function(self, damage, mcl_reason)
|
deal_damage = function(self, damage, mcl_reason)
|
||||||
if self._spawning then return end
|
if self._spawning then return end
|
||||||
if self._arrow_resistant and mcl_reason.type == "magic" then return end
|
if self._arrow_resistant and mcl_reason.type == "magic" then return end
|
||||||
|
wither_unstuck(self)
|
||||||
self.health = self.health - damage
|
self.health = self.health - damage
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
@ -390,7 +401,7 @@ mcl_mobs.register_arrow("mobs_mc:wither_skull", {
|
||||||
|
|
||||||
-- direct hit
|
-- direct hit
|
||||||
hit_player = function(self, player)
|
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)
|
mcl_mobs.effect_functions["withering"](player, 0.5, 10)
|
||||||
player:punch(self.object, 1.0, {
|
player:punch(self.object, 1.0, {
|
||||||
full_punch_interval = 0.5,
|
full_punch_interval = 0.5,
|
||||||
|
@ -405,7 +416,7 @@ mcl_mobs.register_arrow("mobs_mc:wither_skull", {
|
||||||
end,
|
end,
|
||||||
|
|
||||||
hit_mob = function(self, mob)
|
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)
|
mcl_mobs.effect_functions["withering"](mob, 0.5, 10)
|
||||||
mob:punch(self.object, 1.0, {
|
mob:punch(self.object, 1.0, {
|
||||||
full_punch_interval = 0.5,
|
full_punch_interval = 0.5,
|
||||||
|
@ -443,7 +454,7 @@ mcl_mobs.register_arrow("mobs_mc:wither_skull_strong", {
|
||||||
|
|
||||||
-- direct hit
|
-- direct hit
|
||||||
hit_player = function(self, player)
|
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)
|
mcl_mobs.effect_functions["withering"](player, 0.5, 10)
|
||||||
player:punch(self.object, 1.0, {
|
player:punch(self.object, 1.0, {
|
||||||
full_punch_interval = 0.5,
|
full_punch_interval = 0.5,
|
||||||
|
@ -462,7 +473,7 @@ mcl_mobs.register_arrow("mobs_mc:wither_skull_strong", {
|
||||||
end,
|
end,
|
||||||
|
|
||||||
hit_mob = function(self, mob)
|
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)
|
mcl_mobs.effect_functions["withering"](mob, 0.5, 10)
|
||||||
mob:punch(self.object, 1.0, {
|
mob:punch(self.object, 1.0, {
|
||||||
full_punch_interval = 0.5,
|
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_wip.register_wip_item("mobs_mc:wither")
|
||||||
mcl_mobs:non_spawn_specific("mobs_mc:wither","overworld",0,minetest.LIGHT_MAX+1)
|
mcl_mobs:non_spawn_specific("mobs_mc:wither","overworld",0,minetest.LIGHT_MAX+1)
|
||||||
|
|
||||||
|
|
|
@ -730,6 +730,8 @@ end
|
||||||
|
|
||||||
function mcl_potions.healing_func(player, hp)
|
function mcl_potions.healing_func(player, hp)
|
||||||
|
|
||||||
|
if player:get_hp() <= 0 then return false end
|
||||||
|
|
||||||
local obj = player:get_luaentity()
|
local obj = player:get_luaentity()
|
||||||
|
|
||||||
if player:get_hp() == 0 then
|
if player:get_hp() == 0 then
|
||||||
|
@ -762,6 +764,8 @@ end
|
||||||
|
|
||||||
function mcl_potions.swiftness_func(player, factor, duration)
|
function mcl_potions.swiftness_func(player, factor, duration)
|
||||||
|
|
||||||
|
if player:get_hp() <= 0 then return false end
|
||||||
|
|
||||||
local entity = player:get_luaentity()
|
local entity = player:get_luaentity()
|
||||||
if entity and entity.is_boss then return false end
|
if entity and entity.is_boss then return false end
|
||||||
|
|
||||||
|
@ -793,6 +797,8 @@ end
|
||||||
|
|
||||||
function mcl_potions.leaping_func(player, factor, duration)
|
function mcl_potions.leaping_func(player, factor, duration)
|
||||||
|
|
||||||
|
if player:get_hp() <= 0 then return false end
|
||||||
|
|
||||||
local entity = player:get_luaentity()
|
local entity = player:get_luaentity()
|
||||||
if entity and entity.is_boss then return false end
|
if entity and entity.is_boss then return false end
|
||||||
|
|
||||||
|
@ -824,6 +830,8 @@ end
|
||||||
|
|
||||||
function mcl_potions.weakness_func(player, factor, duration)
|
function mcl_potions.weakness_func(player, factor, duration)
|
||||||
|
|
||||||
|
if player:get_hp() <= 0 then return false end
|
||||||
|
|
||||||
local entity = player:get_luaentity()
|
local entity = player:get_luaentity()
|
||||||
if entity and entity.is_boss then return false end
|
if entity and entity.is_boss then return false end
|
||||||
|
|
||||||
|
@ -850,6 +858,8 @@ end
|
||||||
|
|
||||||
function mcl_potions.strength_func(player, factor, duration)
|
function mcl_potions.strength_func(player, factor, duration)
|
||||||
|
|
||||||
|
if player:get_hp() <= 0 then return false end
|
||||||
|
|
||||||
local entity = player:get_luaentity()
|
local entity = player:get_luaentity()
|
||||||
if entity and entity.is_boss then return false end
|
if entity and entity.is_boss then return false end
|
||||||
|
|
||||||
|
@ -876,6 +886,8 @@ end
|
||||||
|
|
||||||
function mcl_potions.withering_func(player, factor, duration)
|
function mcl_potions.withering_func(player, factor, duration)
|
||||||
|
|
||||||
|
if player:get_hp() <= 0 then return false end
|
||||||
|
|
||||||
local entity = player:get_luaentity()
|
local entity = player:get_luaentity()
|
||||||
if entity and (entity.is_boss or string.find(entity.name, "wither")) then return false end
|
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)
|
function mcl_potions.poison_func(player, factor, duration)
|
||||||
|
|
||||||
|
if player:get_hp() <= 0 then return false end
|
||||||
|
|
||||||
local entity = player:get_luaentity()
|
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
|
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)
|
function mcl_potions.regeneration_func(player, factor, duration)
|
||||||
|
|
||||||
|
if player:get_hp() <= 0 then return false end
|
||||||
|
|
||||||
local entity = player:get_luaentity()
|
local entity = player:get_luaentity()
|
||||||
if entity and (entity.is_boss or entity.harmed_by_heal) then return false end
|
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)
|
function mcl_potions.invisiblility_func(player, null, duration)
|
||||||
|
|
||||||
|
if player:get_hp() <= 0 then return false end
|
||||||
|
|
||||||
local entity = player:get_luaentity()
|
local entity = player:get_luaentity()
|
||||||
if entity and entity.is_boss then return false end
|
if entity and entity.is_boss then return false end
|
||||||
|
|
||||||
|
@ -979,6 +997,8 @@ end
|
||||||
|
|
||||||
function mcl_potions.water_breathing_func(player, null, duration)
|
function mcl_potions.water_breathing_func(player, null, duration)
|
||||||
|
|
||||||
|
if player:get_hp() <= 0 then return false end
|
||||||
|
|
||||||
local entity = player:get_luaentity()
|
local entity = player:get_luaentity()
|
||||||
if entity and entity.is_boss then return false end
|
if entity and entity.is_boss then return false end
|
||||||
|
|
||||||
|
@ -1004,6 +1024,8 @@ end
|
||||||
|
|
||||||
function mcl_potions.fire_resistance_func(player, null, duration)
|
function mcl_potions.fire_resistance_func(player, null, duration)
|
||||||
|
|
||||||
|
if player:get_hp() <= 0 then return false end
|
||||||
|
|
||||||
local entity = player:get_luaentity()
|
local entity = player:get_luaentity()
|
||||||
if entity and entity.is_boss then return false end
|
if entity and entity.is_boss then return false end
|
||||||
|
|
||||||
|
@ -1028,6 +1050,8 @@ end
|
||||||
|
|
||||||
function mcl_potions.night_vision_func(player, null, duration)
|
function mcl_potions.night_vision_func(player, null, duration)
|
||||||
|
|
||||||
|
if player:get_hp() <= 0 then return false end
|
||||||
|
|
||||||
local entity = player:get_luaentity()
|
local entity = player:get_luaentity()
|
||||||
if entity and entity.is_boss then return false end
|
if entity and entity.is_boss then return false end
|
||||||
|
|
||||||
|
|
|
@ -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
|
for _,obj in pairs(minetest.get_objects_inside_radius(pos, 4)) do
|
||||||
|
|
||||||
local entity = obj:get_luaentity()
|
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 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))
|
local rad = math.floor(math.sqrt((pos2.x-pos.x)^2 + (pos2.y-pos.y)^2 + (pos2.z-pos.z)^2))
|
||||||
|
|
Loading…
Reference in New Issue