mojira.dev
MC-44280

Entities don't receive knockback from projectiles fired from dispensers

Fireworks, eggs, snowballs, and splash potions of harming fired from dispensers don't knock back mobs, but they do when thrown by the player or a mob such as a snow golem or witch.

Steps to Reproduce:

  • Build the setup as shown in the attachment below.

[media]
  • Place some snowballs inside of the dispenser.

  • Summon a husk on the diamond block.

  • Use the lever to activate the dispenser and watch the husk closely.

Observed Behavior:
Projectiles fired from dispensers don't deal any knockback to entities.

Expected Behavior:
Projectiles fired from dispensers would deal knockback to entities.

Note

Arrows are not affected by this bug, as they knock back mobs when fired either from a bow or a dispenser.

Code analysis

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

Linked issues

Attachments

Comments 43

Confirmed in 1.8. Also affects Splash Potions of Harming.

confirmed for 1.9 pre2. snowballs fly through mobs now. It's worse than before.

Please link to this comment in the description

The following is based on decompiled version of Minecraft 1.9 using MCP 9.24 beta. All method and class names are the names used in the decompiled version.

The reason why for this bug is that the net.minecraft.entity.EntityLivingBase.attackEntityFrom(DamageSource, float) method only knockbacks mobs if the indirect damage has an entity as owner. This is not the case for projectiles fired from a dispenser. The problem is that currently the coordinates of the thrower are used to determine the knockback.
This allows "exploits" like [[Tutorial] Guided & Regular Rocket Launcher in Vanilla Minecraft Using Fireballs! [MC 1.8]|https://www.youtube.com/watch?v=548wxRDL1U8].

A possible solution would be to use the motion of the projectile. This means however that the distance does not determine the strength completely anymore.
The following shows how this could be done, but the motion values very likely need to be adjusted.

// Added this
if (source instanceof net.minecraft.util.EntityDamageSourceIndirect && source.getSourceOfDamage() != null) {
    Entity damagingEntity = source.getSourceOfDamage();
    double d1 = -damagingEntity.motionX;
    double d0;

    for (d0 = -damagingEntity.motionZ; d1 * d1 + d0 * d0 < 1.0E-4D; d0 = (Math.random() - Math.random()) * 0.01D)
    {
        d1 = (Math.random() - Math.random()) * 0.01D;
    }

    this.attackedAtYaw = (float)(MathHelper.atan2(d0, d1) * (180D / Math.PI) - (double)this.rotationYaw);
    this.knockBack(entity, 0.4F, d1, d0);
    
}
// Replaced this
//if (entity != null)
else if (entity != null)
{
    double d1 = entity.posX - this.posX;
    double d0;

    for (d0 = entity.posZ - this.posZ; d1 * d1 + d0 * d0 < 1.0E-4D; d0 = (Math.random() - Math.random()) * 0.01D)
    {
        d1 = (Math.random() - Math.random()) * 0.01D;
    }

    this.attackedAtYaw = (float)(MathHelper.atan2(d0, d1) * (180D / Math.PI) - (double)this.rotationYaw);
    this.knockBack(entity, 0.4F, d1, d0);
}
else
{
    this.attackedAtYaw = (float)((int)(Math.random() * 2.0D) * 180);
}
Balázs Slemmer

Still present in 1.9.3-pre2.

33 more comments

Can confirm in 22w17a.

Can confirm in 1.19.

Can confirm in 1.19.2.

Can Confirm 1.19.3 Release Candidate 3

@unknown, 1.19.3 Release Candidate 3 is already marked as affected. 🙂

Nick Bambridge

Shugoh

Confirmed

Gameplay

Low

Entities, Projectiles

dispenser, egg, knockback, snowball

Minecraft 1.7.4, Minecraft 1.7.9, Minecraft 1.8, Minecraft 1.8.3, Minecraft 15w47c, ..., 1.19.3, 1.20, 1.20.1, 1.20.2, 1.20.4

Minecraft 16w02a, 24w18a

Retrieved