-
Bug
-
Resolution: Fixed
-
Minecraft 1.12.2, Minecraft 1.13.2, 1.15.2, 20w09a, 20w10a, 20w11a, 20w12a, 20w14a, 20w15a, 20w16a, 20w17a, 20w21a, 1.16 Pre-release 2, 1.16 Pre-release 3, 1.16 Pre-release 4, 1.16 Pre-release 7, 1.16 Pre-release 8, 1.16 Release Candidate 1, 1.16, 1.16.1, 20w27a, 20w30a, 1.16.2, 1.16.3, 20w51a, 21w14a, 21w18a, 1.17 Release Candidate 1, 1.17, 1.17.1 Pre-release 1, 1.17.1, 21w37a, 21w42a, 21w43a, 1.18 Pre-release 4, 1.18.1, 1.18.2, 22w12a, 22w14a, 22w15a, 22w17a, 1.19 Pre-release 2, 1.19, 1.19.1 Pre-release 4, 1.19.1 Pre-release 6, 1.19.1, 1.19.2, 22w42a, 22w43a, 22w44a, 22w46a, 1.19.3 Pre-release 1, 1.19.3
-
None
-
Confirmed
-
Combat
-
Important
-
Platform
Code analysis below uses 1.19's code, deobfuscated manually using the official obfuscation mappings for 1.19.
Living entities have a CombatTracker, which tracks the details of recent hits. When such an entity is damaged, the combat tracker's recordDamage method is called to record it.
recordDamage first calls recheckStatus, which resets the tracked data if certain conditions are met. It then adds the data for the damage currently being taken.
The issue here is that, when recordDamage is called for the killing blow, recheckStatus will clear the tracker due to the condition !this.mob.isAlive() being met. This is because isAlive checks that the entity's health is above 0.
Looking at the method LivingEntity#actuallyHurt shows the problem:
protected void actuallyHurt(DamageSource damageSrc, float amount) { if (!this.isInvulnerableTo(damageSrc)) { amount = this.getDamageAfterArmorAbsorb(damageSrc, amount); amount = this.getDamageAfterMagicAbsorb(damageSrc, amount); float f2 = amount; amount = Math.max(amount - this.getAbsorptionAmount(), 0.0F); this.setAbsorptionAmount(this.getAbsorptionAmount() - f2 - amount); float f = f2 - amount; if (f > 0.0F && f < 3.4028235E37F && damageSrc.getEntity() instanceof ServerPlayer) { ((ServerPlayer)damageSrc.getEntity()).awardStat(Stats.DAMAGE_DEALT_ABSORBED, Math.round(f * 10.0F)); } if (f2 != 0.0F) { float f1 = this.getHealth(); this.setHealth(f1 - f2); this.getCombatTracker().recordDamage(damageSrc, f1, f2); this.setAbsorptionAmount(this.getAbsorptionAmount() - amount); this.gameEvent(GameEvent.ENTITY_DAMAGE); } } }
The health is updated before recordDamage is called, which makes the entity show up as dead and causes the combat data to be cleared.
Then, shortly afterwards, die is called for the just-killed entity. This checks getKillCredit to determine who to credit with the kill.
getKillCredit will first consult CombatTracker#getKiller which contains logic to go through the combat history and pick out the "best" attacker.
However this logic is currently irrelevant, as due to the above issue, the tracker will only contain an entry for the killing blow and nothing else.
The solution here is to change LivingEntity#actuallyHurt to call recordDamage first, followed by setHealth.
Fixing this bug will allow for the "doomed to fall" death messages to appear.
- is duplicated by
-
MC-173511 Death messages relating to specific kinds of fall damage ("doomed to fall") do not work
- Resolved
-
MC-173646 Some death messages won't show
- Resolved
-
MC-237248 When the player was fall from knocked by a mob/player, the death message do not mention the attacker
- Resolved
- relates to
-
MC-84595 "Roasted in dragon's breath" death message does not appear when player is killed by dragon's breath
- Open
-
MC-260761 Taking any damage before fatal fall damage removes the attacker credited for kill
- Reopened
-
MC-260437 Death message when falling from a high place whilst on fire is different from 1.19.3
- Resolved
-
MC-176385 "<Player 1> went off with a bang whilst fighting <Player 2>" death message never shows
- Open
-
MC-7424 Fall damage death messages don't show block player fall from correctly (ladders, vines, water)
- Resolved
-
MC-189692 Dying by other means than mobs when knocked back by a bee sting does not mention the bee in the death message
- Resolved
-
MC-197466 Some unused Death messages
- Resolved
- links to