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
.
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.
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.