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

Shield doesn't knock back attacker

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • None
    • 1.20.4
    • None
    • Unconfirmed
    • (Unassigned)

      Shields have always been used only to offset damage. But the shield should be able to repel melee attackers.

      Here is the evidence:

      1. Unsual method calls:

       

      //代码占位符
      @Override
      public boolean hurt(DamageSource damagesource, float f) {
          if (this.isInvulnerableTo(damagesource)) {
              ...
          } else {
              if (this.isSleeping() && !this.level().isClientSide) {
                  this.stopSleeping();
              }
      
              this.noActionTime = 0;
              float f1 = f;
              boolean flag = false;
              float f2 = 0.0F;
      
              if (f > 0.0F && this.isDamageSourceBlocked(damagesource)) {
                  this.hurtCurrentlyUsedShield(f);
                  f2 = f;
                  f = 0.0F;
                  if (!damagesource.is(DamageTypeTags.IS_PROJECTILE)) {
                      Entity entity = damagesource.getDirectEntity();
      
                      if (entity instanceof EntityLiving) {
                          EntityLiving entityliving = (EntityLiving) entity;
      
                          this.blockUsingShield(entityliving); // <- this entityliving is the attacker
                      }
                  }
      
                  flag = true;
              } 
          ...
      }
      
      protected void blockUsingShield(EntityLiving entityliving) {
          entityliving.blockedByShield(this); // <- and then the attacker is blocked by shield
      }
      
      protected void blockedByShield(EntityLiving entityliving) { // this entityliving is the victim
          entityliving.knockback(0.5D, entityliving.getX() - this.getX(), entityliving.getZ() - this.getZ()); // <- and then the victim is knocked back.. what??
      }
      
      

      What this code means: when the LivingEntity (in this case the victim) raises its shield and is attacked, the victim is knocked back. The direction of the knock back is from where the victim is to where the victim is.
      There are two problems. The first is that the start and end of the knock back vector are at the same position, so the actual effect of adjustment within the knock back method is that the victim will receive an upward knock back of 0.4. The second is that the entity will update the invincible time when it is attacked, which causes the knock back to not be triggered.

       

      2. It's different from Bedrock Edition:

      In Bedrock Edition, an attacker attacking a shield-raising victim will be bounced by the victim's shield, similar to how shields bounce arrows.

       

      The way to solve:

      Change this:

      //代码占位符
      protected void blockedByShield(EntityLiving entityliving) {
          entityliving.knockback(0.5D, entityliving.getX() - this.getX(), entityliving.getZ() - this.getZ());
      } 

      To this:

      //代码占位符
      protected void blockedByShield(EntityLiving entityliving) {
          this.knockback(0.5D, entityliving.getX() - this.getX(), entityliving.getZ() - this.getZ());
      } 

      The correct result is that when an attacker attacks a shield-raising victim, the attacker bounces off the victim's shield

            Unassigned Unassigned
            LoliColleen LoliColleen
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: