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
Linked issues
Comments


Thank you for your report!
We're actually already tracking this issue in MC-147694, so this ticket is being resolved and linked as a duplicate.
If you would like to add a vote or any additional information to the main ticket it would be appreciated.
Please be sure to use the search feature before creating a ticket to see if the issue has already been reported.
Quick Links:
📗 Tracker Guidelines – 🛠 Community Support – 📧 Mojang Support – 🔑 Account Support – ✍️ Feedback Discord – 💬 Mojira Discord
I've annotated the code block for understanding, so check it out