The bug
When doing damage to a player with absorption, the score, with criteria of minecraft.custom:minecraft.damage_dealt_absorbed, is supposed to increase but it is not. The same behaviour also occurs with the criteria minecraft.custom:minecraft.damage_dealt_resisted.
How to reproduce
Get two players on a LAN world and make sure they are in survival
Run the commands
/scoreboard objectives add damage_dealt minecraft.custom:minecraft.damage_dealt_absorbed /effect give @a minecraft:absorption 100000 14 true /scoreboard objectives setdisplay sidebar damage_dealt
Hit a player with a sword and notice the score doesn't increase
Linked issues
is duplicated by 1
Attachments
Comments 40
Confirmed for 19w14b. Also could it be added to the bug report that this also occurs with the minecraft.custom:minecraft.damage_dealt_resisted objective?
Code Analysis (Mojang Mappings, 1.20.6):
For minecraft.custom:minecraft.damage_dealt_absorbed
:
This happens because the Player
class overrides the *actuallyHurt*
with similar behaviour but doesn't include the code for awarding the minecraft.custom:minecraft.damage_dealt_absorbed
stat.
Suggested fix:
public abstract class Player extends LivingEntity {
// ...
@Override
protected void actuallyHurt(DamageSource source, float totalDamageAmount) {
// ...
float damageAmount = Math.max(damageAmount - this.getAbsorptionAmount(), 0.0F);
// ...
float damageAbsorbed = totalDamageAmount - damageAmount;
if (damageAbsorbed > 0.0F && damageAbsorbed < 3.4028235E37F) {
this.awardStat(Stats.DAMAGE_ABSORBED, Math.round(damageAbsorbed * 10.0F));
// Fix start
if (source.getEntity() instanceof ServerPlayer sourcePlayer) {
sourcePlayer.awardStat(Stats.DAMAGE_DEALT_ABSORBED, Math.round(damageAbsorbed * 10.0F));
}
// Fix end
}
// ...
}
}
For minecraft.custom:minecraft.damage_dealt_resisted
the stat is only not awarded when attacking player entities, because of an incorrect use of an *else if*
in *LivingEntity#getDamageAfterMagicAbsorb*
.
Suggested fix:
public abstract class LivingEntity extends Entity implements Attackable {
protected float getDamageAfterMagicAbsorb(DamageSource source, float damageAmount) {
// ...
if (this.hasEffect(MobEffects.DAMAGE_RESISTANCE) && !source.is(DamageTypeTags.BYPASSES_RESISTANCE)) {
int reducedDamageScale = 25 - (this.getEffect(MobEffects.DAMAGE_RESISTANCE).getAmplifier() + 1) * 5;
float reducedDamage = damageAmount * reducedDamageScale;
float originalDamageAmount = damageAmount;
damageAmount = Math.max(reducedDamage / 25.0F, 0.0F);
float damageResisted = originalDamageAmount - damageAmount;
if (damageResisted > 0.0F && damageResisted < 3.4028235E37F) {
if (this instanceof ServerPlayer) {
((ServerPlayer) this).awardStat(Stats.DAMAGE_RESISTED, Math.round(damageResisted * 10.0F));
}
// Suggested fix: removed the 'else if' and converted into 'if':
if (source.getEntity() instanceof ServerPlayer) {
((ServerPlayer) source.getEntity()).awardStat(Stats.DAMAGE_DEALT_RESISTED, Math.round(damageResisted * 10.0F));
}
}
}
}
}
The same issue occurs with the minecraft.custom:minecraft.damage_dealt_resisted objective.
Also this is confirmed for 19w11b.