mojira.dev
MC-248961

takenDamage for achievement criteria is calculated wrongly when the player has equipped a helmet

When a player takes damage from a DamageSource of ANVIL, FALLING_BLOCK, or FALLING_STALACTITE, if the player is wearing head gear, there will be a difference between the actual damage taken by the player and the damage seen in Advancement criteria.

 

*Code analysis*

net.minecraft.world.entity.LivingEntity

public abstract class LivingEntity extends Entity {
    ...

    public boolean hurt(DamageSource damageSource, float f) {
        ...

        if ((float)this.invulnerableTime > 10.0f) {
            ...

            this.actuallyHurt(damageSource, f - this.lastHurt);
            ...

        } else {
            ...

            this.actuallyHurt(damageSource, f);
            ...

        }
        if (damageSource.isDamageHelmet() && !this.getItemBySlot(EquipmentSlot.HEAD).isEmpty()) {
            ...

            f *= 0.75f;
        }
        ...

        if (this instanceof ServerPlayer) {
            CriteriaTriggers.ENTITY_HURT_PLAYER.trigger((ServerPlayer)this, damageSource, f2, f, bl2);
         ...

        }
    }
}

The difference occurs because the variable f is multiplied by 0.75f after LivingEntity#actuallyHurt.

Comments 1

Affects 1.20.1.

Seems related to MC-251027. Helmets use to block 25% of anvil damage, but now they don't. To me that seems like an accidental change, since the line of code to reduce damage by 25% is still there, it just gets calculated after the damage is applied to the player.

To reproduce:

Make a datapack with the following advancement JSON. This should give an advancement when 8 or more damage is taken from anvil.

{
  "display": {
    "icon": {
      "item": "minecraft:stone"
    },
    "title": "test",
    "description": ""
  },
  "criteria": {
    "requirement": {
      "trigger": "minecraft:entity_hurt_player",
      "conditions": {
        "damage": {
          "taken": {
            "min": 8
          },
          "type": {
            "direct_entity": {
              "type": "minecraft:falling_block"
            }
          }
        }
      }
    }
  }
}

Make a new world with datapack, then, in survival:

  • Without a helmet:

    • /setblock ~ ~6 ~ minecraft:anvil

      • This should deal 10 damage (5 hearts), triggering the advancement

  • With a leather helmet:

    • /advancement revoke @a everything 

    • /setblock ~ ~6 ~ minecraft:anvil

      • Deals about 9 damage (4.5 hearts), but does NOT trigger the advancement even though the threshold of 8 was exceeded.

    • /setblock ~ ~7 ~ minecraft:anvil

      • Deals about 11 damage (5.5 hearts), and WILL trigger the advancement.

 

Chen

etanaratsastaja

Confirmed

Platform

Low

Advancements

advancement, entity_hurt_player

1.18.2, 1.20.1, 1.20.2

23w51a

Retrieved