Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-211708

Client spawns attack particles when attacking another player even though that player can't be harmed

XMLWordPrintable

    • Icon: Bug 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

      1. Start a server and join (or open a local world on your network) alongside another player.
      2. Make sure you have OP permissions for the /effect command
      3. Give yourself weakness level 255 (/effect give @s minecraft:weakness 1000000 255)
      4. Try to hit the other player while falling to trigger critical hit particles. -> Particles appear
      5. 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.

        1. image-2021-01-17-18-24-26-745.png
          image-2021-01-17-18-24-26-745.png
          881 kB
        2. image-2021-01-17-18-24-34-672.png
          image-2021-01-17-18-24-34-672.png
          691 kB
        3. MC-211708.mp4
          6.87 MB
        4. MC-211708.png
          MC-211708.png
          554 kB

            Unassigned Unassigned
            thecookieplays Jonas Mittnacht
            Votes:
            8 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              CHK: