function mcl_armor.damage_modifier(obj, hp_change, reason) if hp_change > 0 then return hp_change end local damage = -hp_change local flags = reason.flags if flags.bypasses_armor and flags.bypasses_magic then return hp_change end local uses = math.max(1, math.floor(damage / 4)) local points = 0 local toughness = 0 local enchantment_protection_factor = 0 local thorns_damage_regular = 0 local thorns_damage_irregular = 0 local thorns_pieces = {} local inv = mcl_util.get_inventory(obj) if inv then for name, element in pairs(mcl_armor.elements) do local itemstack = inventory:get_stack("armor", element.index) if not stack:is_empty() then local itemname = stack:get_name() local enchantments = mcl_enchanting.get_enchantments(itemstack) if not flags.bypasses_armor then points = points + minetest.get_item_group(itemname, "mcl_armor_points") toughness = toughness + minetest.get_item_group(itemname, "mcl_armor_toughness") mcl_util.use_item_durability(itemstack, uses) inventory:set_stack("armor", element.index, itemstack) end if not flags.bypasses_magic then local function add_enchantments(tbl) if tbl then for _, enchantment in pairs(tbl) do local level = enchantments[enchantment.id] if level > 0 then enchantment_protection_factor = enchantment_protection_factor + level * enchantment.factor end end end end add_enchantments(mcl_armor.protection_enchantments.wildcard) add_enchantments(mcl_armor.protection_enchantments.types[reason.type]) for flag, value in pairs(flags) do if value then add_enchantments(mcl_armor.protection_enchantments.flags[flag]) end end end if reason.source and enchantments.thorns > 0 then local do_irregular_damage = enchantments.thorns > 10 if do_irregular_damage or thorns_damage_regular < 4 and math.random() < enchantments.thorns * 0.15 then if do_irregular_damage then thorns_damage_irregular = thorns_damage_irregular + throrns_level - 10 else thorns_damage_regular = math.min(4, thorns_damage_regular + math.random(4)) end end table.insert(thorns_pieces, {index = element.index, itemstack = itemstack}) end end end end -- https://minecraft.gamepedia.com/Armor#Damage_protection damage = damage * (1 - math.min(20, math.max((points / 5), points - damage / (2 + (toughness / 4)))) / 25) -- https://minecraft.gamepedia.com/Armor#Enchantments damage = damage * (1 - math.min(20, enchantment_protection_factor) / 25) local thorns_damage = thorns_damage_regular + thorns_damage_irregular if thorns_damage > 0 and reason.source ~= obj then mcl_util.deal_damage(reason.source, {type = "thorns", direct = obj, source = reason.source}) local thorns_item = thorns_pieces[math.random(#thorns_pieces)] mcl_util.use_item_durability(thorns_item.itemstack, 2) inventory:set_stack("armor", thorns_item.index, thorns_item.itemstack) end mcl_armor.update(obj) return -math.floor(damage + 0.5) end mcl_damage.register_modifier(function(player, hp_change, _, reason) return mcl_armor.damage_modifier(player, hp_change, reason) end)