-
Bug
-
Resolution: Unresolved
-
None
-
1.16.5, 21w07a, 1.17.1, 1.18.1, 22w03a, 1.19, 1.20.1, 1.20.2
-
None
-
Confirmed
-
Particles
-
Low
-
Platform
The bug
When attacking another player, the client will always show particles for special attacks like critical hits or sharpness (these particles will not appear to other players since they appear on the client only) and will also stop sprinting even though the attack might not have registered (for example if pvp is disabled or if the player has weakness and can't deal enough damage).
This, however, only happens if the player attacks another player - hitting any other entity does not trigger any special particles or sprint cancellation.
How to reproduce
- Start a server and join (or open a local world on your network) alongside another player.
- Make sure you have OP permissions for the /effect command
- Give yourself weakness level 255 (/effect give @s minecraft:weakness 1000000 255)
- Try to hit the other player while falling to trigger critical hit particles. -> Particles appear
- Try to hit another mob (like a pig) in the same way. -> No Particles
Code analysis
(using the official Mojang mappings here)
Attacking an entity calls the attack(Entity entity) method in LocalPlayer. This method will, further down, call the hurt(DamageSource damageSource, float f) method for the entity it has attacked. Normally, that method will return false from all mobs as it's overridden in LivingEntity which includes the following check:
... } else if (this.level.isClientSide) { return false; } ...
This will result in the attack method effectively skipping most of the other code in that method on the client since the code stores the returned value of hurt(DamageSource damageSource, float f) and uses an if-statement checking if the value is true, only then executing the code regarding critical hit and sharpness particles as well as cancelling sprint.
... boolean bl6 = entity.hurt(DamageSource.playerAttack(this), f); if (bl6) { // Runs code regarding the particles and sprint cancellation. } else { // Irrelevant code }
However, to represent other players on the server, the client uses the RemotePlayer class, which overrides the method in the LivingEntity class.
public boolean hurt(DamageSource damageSource, float f) { return true; }
As you can see, this method always returns true, causing the client to run the previously mentioned code regarding the particles etc.
The fix
Simply making the hurt(DamageSource damageSource, float f) method in RemotePlayer always return false would fix the issue.