Make shields work with all mobs

NO411 2022-04-09 16:21:22 +02:00
parent 8e904e2ca9
commit e790bf90f4
2 changed files with 18 additions and 7 deletions

@ -2833,6 +2833,10 @@ local do_states = function(self, dtime)
end end
ent.switch = 1 ent.switch = 1
ent.owner_id = tostring(self.object) -- add unique owner id to arrow ent.owner_id = tostring(self.object) -- add unique owner id to arrow
-- important for mcl_shields
ent._shooter = self.object
ent._saved_shooter_pos = self.object:get_pos()
end end
local amount = (vec.x * vec.x + vec.y * vec.y + vec.z * vec.z) ^ 0.5 local amount = (vec.x * vec.x + vec.y * vec.y + vec.z * vec.z) ^ 0.5
@ -4078,7 +4082,6 @@ end
-- make explosion with protection and tnt mod check -- make explosion with protection and tnt mod check
function mobs:boom(self, pos, strength, fire) function mobs:boom(self, pos, strength, fire)
self.object:remove()
if mod_explosions then if mod_explosions then
if mobs_griefing and not minetest.is_protected(pos, "") then if mobs_griefing and not minetest.is_protected(pos, "") then
mcl_explosions.explode(pos, strength, { drop_chance = 1.0, fire = fire }, self.object) mcl_explosions.explode(pos, strength, { drop_chance = 1.0, fire = fire }, self.object)
@ -4088,6 +4091,9 @@ function mobs:boom(self, pos, strength, fire)
else else
mobs:safe_boom(self, pos, strength) mobs:safe_boom(self, pos, strength)
end end
-- delete the object after it punched the player to avoid nil entities in e.g. mcl_shields!!
self.object:remove()
end end

@ -8,7 +8,7 @@ mcl_shields = {
player = true, player = true,
arrow = true, arrow = true,
generic = true, generic = true,
explosion = true, -- ghasts don't work explosion = true,
dragon_breath = true, dragon_breath = true,
}, },
enchantments = {"mending", "unbreaking"}, enchantments = {"mending", "unbreaking"},
@ -128,20 +128,24 @@ mcl_damage.register_modifier(function(obj, damage, reason)
local type = reason.type local type = reason.type
local damager = reason.direct local damager = reason.direct
local blocking, shieldstack = mcl_shields.is_blocking(obj) local blocking, shieldstack = mcl_shields.is_blocking(obj)
if not (obj:is_player() and blocking and mcl_shields.types[type] and damager) then if not (obj:is_player() and blocking and mcl_shields.types[type] and damager) then
return return
end end
local entity = damager:get_luaentity() local entity = damager:get_luaentity()
if entity and (type == "arrow" or type == "generic") then if entity and entity._shooter then
damager = entity._shooter damager = entity._shooter
end end
if not damager then
return
end
local dpos = damager:get_pos() local dpos = damager:get_pos()
if dpos and vector.dot(obj:get_look_dir(), vector.subtract(dpos, obj:get_pos())) < 0 then
-- Used for removed / killed entities before the projectile hits the player
if entity and not entity._shooter and entity._saved_shooter_pos then
dpos = entity._saved_shooter_pos
end
if not dpos or vector.dot(obj:get_look_dir(), vector.subtract(dpos, obj:get_pos())) < 0 then
return return
end end
@ -150,6 +154,7 @@ mcl_damage.register_modifier(function(obj, damage, reason)
if unbreaking > 0 then if unbreaking > 0 then
durability = durability * (unbreaking + 1) durability = durability * (unbreaking + 1)
end end
if not minetest.is_creative_enabled(obj:get_player_name()) and damage >= 3 then if not minetest.is_creative_enabled(obj:get_player_name()) and damage >= 3 then
shieldstack:add_wear(65535 / durability) shieldstack:add_wear(65535 / durability)
if blocking == 2 then if blocking == 2 then