mojira.dev
MC-147694

Mobs no longer get repelled by shields

The bug

Ever since the beginning of 1.14 snapshots, mobs wouldn't get knocked back when a player is blocking with a shield.
Here are some screenshots from the current version (1.13.2) and current snapshot (19w14b)

1.13.2:

  • Vindicators

  • Piglin (New Mob in 1.16.x)

  • Zombie Pigman/Zombified Piglin (renamed in 1.16.x)

  • Zombie Villager

  • Zombie

  • Husk

  • Drowned

  • Wolf

  • Wither Skeleton

  • Enderman

  • Spider & Cave Spider

  • Silverfish

  • Slime and Magma Cube

These mobs do knockback when you're blocking.

19w14a & b and beyond of 1.14 - 1.16:
The mobs I said above don't do knockback in the current version(s).
However, this doesn't affect to Creeper/TNT explosions, as you still do knockback from it. And arrows from Skeletons/Strays will still bounce of the shield.

Code analysis

Code analysis by @unknown & @unknown can be found in this comment and this comment.

Related issues

Attachments

Comments

migrated
[media][media][media][media][media][media][media][media][media][media][media][media][media][media][media][media][media]
migrated

Still confirmed for 1.14 Pre-release 1

migrated

Still an issue for 1.14 Pre-Release 2

migrated

Confirmed for 1.14 Pre-Release 4

migrated

Confirmed for 1.14 Pre-Release 5

migrated

Still an issue in 1.14.2 

migrated

Still a bug confirmed in 1.15.1

Fusseel

Since I just stumbled across the code responsible for this bug anyways, here is a quick analysis. MCP mappings in use are 20200225-1.15.1.

This issue stems from introducing the ravager entity with its special behaviour towards shields into the game.

Where does this bug occur?

When a {{LivingEntity}} (defender) successfully blocks an attack by another {{LivingEntity}} (attacker) using a shield, {{LivingEntity::blockUsingShield}} is called for the defender, taking the attacker as a single argument for it to be knocked back.

Before Minecraft 1.14 {{LivingEntity::blockUsingShield}} would directly call {{LivingEntity::knockBack}} on the attacker, passing on the defender as the argument.

Now LivingEntity::blockUsingShield calls a new method, LivingEntity::constructKnockBackVector on the attacker, providing the defender as the argument. This method does exactly what {{LivingEntity::blockUsingShield}} did previously, so this is where the problem comes from: Defender and attacker are switched twice. In the end LivingEntity::knockBack is called on the defender when it should be called on the attacker.

(Why is the defender not knocked back in game now? Not relevant here, basically there's another call to LivingEntity::knockBack later and both cancel each other out. The second call won't be a problem when this bug is fixed, it's always been there.)

Why was this split made in the first place?

As mentioned ravager entities behave special when it comes to shields. This is achieved by overwriting the new LivingEntity::constructKnockBackVector method in RavagerEntity. The overwritten method expects both entities to be switched, therefor it behaves as intended.
 
How to fix?

Simply switch defender and attacker in LivingEntity::constructKnockBackVector, meaning

protected void constructKnockBackVector(LivingEntity entityIn) {
      entityIn.knockBack(this, 0.5F, entityIn.getPosX() - this.getPosX(), entityIn.getPosZ() - this.getPosZ());
   }

turns into

protected void constructKnockBackVector(LivingEntity entityIn) {
      this.knockBack(entityIn, 0.5F, this.getPosX() - entityIn.getPosX(), this.getPosZ() - entityIn.getPosZ());
   }

.

Note that LivingEntity::constructKnockBackVector is used nowhere else, so there won't be any side effects.

gaspoweredpick

Confirmed for slimes and magma cubes.

migrated

Affects 1.13-pre3

migrated

1.16.1? i knew it would also affect it, alongside 20w27a

Avoma

Can confirm in 21w03a.

Avoma

Can confirm in 21w05b.

Avoma

Can confirm in 21w06a.

Avoma

Can confirm in 21w11a.

Humiebees

Can confirm in 21wxxa and Pre-release 1

ampolive

Can confirm in 1.17.

syarumi

I'd say that since 1.16 this has become more critical, due to how mobs now attack more rapidly due to fixing MC-147516, making shields useless in some situations (MC-191642).

migrated

i dont think removing shields would work

Avoma

Can confirm in 1.17.1.

Avoma

Can confirm in 1.18.1 and 22w03a.

migrated

In 22w15a

Avoma

Can confirm in 1.19.

NBG-bootmgr

Can confirm in 1.19.2.

migrated

it seems noone cares

migrated

In 1.20

Maity

Actually, there is another issue: LivingEntity::blockedByShield, which should knockback the attacker (but knockback the defender as Fuzs already reported (but does not knockback because the modified motion packet is not sent)) is being overridden by some mobs without calling the super method. So those mobs will not be knocked back anyway. But this is pretty easy to fix: just move the knockback function that Fuzs suggested to LivingEntity::blockUsingShield

 

edit: I deleted my previous comment because it was wrong

migrated

In 23w32a

migrated

In 1.20.2 Release Candidate 1

migrated

In 1.20.2

LoliColleen

In 1.20.4

Libreh

Can confirm in 1.21.

Jukitsu

After testing, I have noticed that there's a slight error in Fuzs' fix: the vector constructed is flipped and would cause the mob to get knocked towards the blocker. The appropriate code should be:

(using 1.20.4 Mojmaps)

public void blockedByShield(LivingEntity livingEntity) {
    this.knockback(0.5, livingEntity.getX() - this.getX(), livingEntity.getZ() - this.getZ());
}
Jukitsu

As a side note, this causes virtually the blocker to be knocked towards the attacker. Therefore, this issue relates to MC-182638 as the report shows the inverted knockback is visible on the beam attack, which counts as magic, and thus does not trigger the knockback reduction of shields.

LoliColleen

Can confirm in 1.21.1

LoliColleen

Can confirm in 1.21.2 pre 2

LoliColleen

Can confirm in 24w45a

LoliColleen

Can confirm in 25w04a

Yuanzx6555

In 25w15a

migrated

(Unassigned)

Confirmed

Gameplay

Low

Player

Minecraft 19w12b, Minecraft 19w13b, Minecraft 19w14a, Minecraft 19w14b, Minecraft 1.14 Pre-Release 1, ..., 1.20.4, 1.21, 1.21.1, 1.21.2 Pre-Release 2, 24w45a

Retrieved