mojira.dev
MC-248272

Enchantment::doPostHurt and Enchantment::doPostAttack are called twice for players

The Enchantment::doPostHurt and Enchantment::doPostAttack functions are called twice for the player causing some bugs.

  • The Bane of Arthropods enchantment gives the Slowness effect twice

  • The Thorns enchantment deals damage to the attacker and the durability of the item with this enchantment twice.

The problem is that the EnchantmentHelper::doPostHurtEffects and EnchantmentHelper::doPostDamageEffects actually call these functions twice:

Vanilla code 1.18.1-1.20.1

public static void doPostHurtEffects(LivingEntity defender, Entity attacker) {
    EnchantmentVisitor consumer = (enchantment, lvl) -> enchantment.doPostHurt(defender, attacker, lvl);

    if (defender != null) {
        EnchantmentHelper.runIterationOnInventory(consumer, defender.getAllSlots());
    }
    if (attacker instanceof Player) {
        EnchantmentHelper.runIterationOnItem(consumer, defender.getMainHandItem());
    }
}
public static void doPostDamageEffects(LivingEntity attacker, Entity target) {
    EnchantmentVisitor consumer = (enchantment, lvl) -> enchantment.doPostAttack(attacker, target, lvl);

    if (attacker != null) {
        EnchantmentHelper.runIterationOnInventory(consumer, attacker.getAllSlots());
    }
    if (attacker instanceof Player) {
        EnchantmentHelper.runIterationOnItem(consumer, attacker.getMainHandItem());
    }
}

Fix suggestion

public static void doPostHurtEffects(LivingEntity defender, Entity attacker) {
    EnchantmentVisitor consumer = (enchantment, lvl) -> enchantment.doPostHurt(defender, attacker, lvl);

    if (defender != null) {
        EnchantmentHelper.runIterationOnInventory(consumer, defender.getAllSlots());
    } else if (attacker instanceof Player) {
        EnchantmentHelper.runIterationOnItem(consumer, defender.getMainHandItem());
    }
}
public static void doPostDamageEffects(LivingEntity attacker, Entity target) {
    EnchantmentVisitor consumer = (enchantment, lvl) -> enchantment.doPostAttack(attacker, target, lvl);

    if (attacker != null) {
        EnchantmentHelper.runIterationOnInventory(consumer, attacker.getAllSlots());
    } else if (attacker instanceof Player) {
        EnchantmentHelper.runIterationOnItem(consumer, attacker.getMainHandItem());
    }
}

Linked issues

Attachments

Comments 3

⚠️ Please do not mark Unreleased Versions as affected. You don't have access to them yet.

-- I am a bot. This action was performed automatically! If you think it was incorrect, please notify us on Discord or Reddit

Can confirm in 1.18.2.

[media]

Maity

slicedlime

Confirmed

Platform

Normal

Enchantments

1.18.1, 22w03a, 22w05a, 1.18.2, 1.19.2, 1.19.4 Pre-release 3, 1.20.1, 1.20.2

24w18a

Retrieved