minecraft:blocks_attacks non-vanilla behaviour
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 12.7k
- Forks
- 3.5k
- Avg merge
- 3d 13h
- Merged PRs (30d)
- 11
Description
Expected behavior
If damage post block is above 0 :
- Take knockback
- setDeltaMovement of player accordingly to knockback
- Play block_sound
- Deal remaining damage to player
If damage post block is 0 :
- Deal knockback to attacker
- Play block_sound
Observed/Actual behavior
If damage post block is above 0 :
- setDeltaMovement of player accordingly to knockback
- Play block_sound
- Deal remaining damage to player
If damage post block is 0 :
- setDeltaMovement of player accordingly to knockback
- Deal knockback to attacker
- Play block_sound
Steps/models to reproduce
If damage post block is above 0 :
/give @s diamond_sword[blocks_attacks={disable_cooldown_scale:0,damage_reductions:[{types: [mob_attack,arrow,explosion],base:0,factor:0.5}],block_sound:block.anvil.place}]
Block with that sword, facing an enemy attacking you, you'll take damage but not knockback, this is not the case in Vanilla, in Vanilla you still take knockback if attacks deal over 0 damage
If damage post block is 0 :
Block with a shield, when blocking a hit, the server will still set your delta movement based off knockback the player received yet knockback was never sent to client, you shouldn't do setDeltaMovement from knockback function in LivingEntity.java if no damage was dealt, it's useless and could cause desync between client and server, server's delta movement is used for arrow speed calculation for example, it wouldn't make sense to make your arrows go faster after blocking a hit
Plugin and Datapack List
None
Paper version
1.21.10-129
Other
Note 1 : The main issue would be caused by this in LivingEntity.java
if (!damageSource.is(DamageTypeTags.NO_IMPACT) && !flag) { // CraftBukkit - Prevent marking hurt if the damage is blocked
this.markHurt();
}
flag is if damageBlocked is above 0 instead of if damage - damageBlocked is above 0, this.markHurt() sets this.hurtMarked to true which causes knockback to be sent to the client at the end of the tick, knockback equivalent to current deltaMovement value (which is properly set in this case by this.knockback function that is after that in note 2 but shouldn't be set if damage received is 0 or less)
Note 2 : The 2nd issue where it sets knockback even if damage is 0 is also there in LivingEntity.java
if (!damageSource.is(DamageTypeTags.NO_KNOCKBACK)) {
double d = 0.0;
double d1 = 0.0;
if (damageSource.getDirectEntity() instanceof Projectile projectile) {
DoubleDoubleImmutablePair doubleDoubleImmutablePair = projectile.calculateHorizontalHurtKnockbackDirection(this, damageSource);
d = -doubleDoubleImmutablePair.leftDouble();
d1 = -doubleDoubleImmutablePair.rightDouble();
} else if (damageSource.getSourcePosition() != null) {
d = damageSource.getSourcePosition().x() - this.getX();
d1 = damageSource.getSourcePosition().z() - this.getZ();
}
// Paper start - Check distance in entity interactions; see for loop in knockback method
if (Math.abs(d) > 200) {
d = Math.random() - Math.random();
}
if (Math.abs(d1) > 200) {
d1 = Math.random() - Math.random();
}
// Paper end - Check distance in entity interactions
this.knockback(0.4F, d, d1, damageSource.getDirectEntity(), damageSource.getDirectEntity() == null ? io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.DAMAGE : io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_ATTACK); // CraftBukkit // Paper - knockback events
if (!flag) {
this.indicateDamage(d, d1);
}
}
This sets player's serveride speed to knockback even though knockback isn't dealt, also, once again
if (!flag) {
this.indicateDamage(d, d1);
}
It is not indicatingDamage is flag is false and flag is false if blockedDamage is above 0 instead of checking if damage - damageBlocked is above 0
Note : If possible, add an option not to play shield sound if damage after block is above 0 and play the normal hurt sound normally
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in LivingEntity.java at the damage-blocking and knockback logic shown in the report, then reproduce both cases with the provided sword command and shield blocking scenario. Compare the results with the stated vanilla behavior: apply knockback and hurt indication based on post-block damage, avoid movement changes when no damage is dealt, and preserve the expected block sound behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- game-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 70/100