diff --git a/server/entity/projectile.go b/server/entity/projectile.go index 0ade0d531..31955bef6 100644 --- a/server/entity/projectile.go +++ b/server/entity/projectile.go @@ -297,19 +297,22 @@ func (lt *ProjectileBehaviour) tickMovement(e *Ent, tx *world.Tx) (*Movement, tr if !mgl64.FloatEqual(end.Sub(pos).LenSqr(), 0) { if hit, ok = trace.Perform(pos, end, tx, e.H().Type().BBox(e).Grow(1.0), lt.ignores(e)); ok { if r, ok := hit.(trace.BlockResult); ok { - // Undo the gravity because the velocity as a result of gravity - // at the point of collision should be 0. - vel[1] = (vel[1] + lt.mc.Gravity) / (1 - lt.mc.Drag) - x, y, z := vel.Mul(lt.conf.BlockCollisionVelocityMultiplier).Elem() - // Calculate multipliers for all coordinates: 1 for the ones that - // weren't on the same axis as the one collided with, -1 for the one - // that was on that axis to deflect the projectile. - mx, my, mz := hit.Face().Axis().Vec3().Mul(-2).Add(mgl64.Vec3{1, 1, 1}).Elem() - - vel = mgl64.Vec3{x * mx, y * my, z * mz} + resultPos := r.BlockPosition() + if h, ok := tx.Block(resultPos).(block.ProjectileHitter); ok { + h.ProjectileHit(resultPos, tx, e, r.Face()) + } + // Check that the block hit was not set to air by a block.ProjectileHitter. + if _, ok := tx.Block(resultPos).(block.Air); !ok { + // Undo the gravity because the velocity as a result of gravity + // at the point of collision should be 0. + vel[1] = (vel[1] + lt.mc.Gravity) / (1 - lt.mc.Drag) + x, y, z := vel.Mul(lt.conf.BlockCollisionVelocityMultiplier).Elem() + // Calculate multipliers for all coordinates: 1 for the ones that + // weren't on the same axis as the one collided with, -1 for the one + // that was on that axis to deflect the projectile. + mx, my, mz := hit.Face().Axis().Vec3().Mul(-2).Add(mgl64.Vec3{1, 1, 1}).Elem() - if h, ok := tx.Block(r.BlockPosition()).(block.ProjectileHitter); ok { - h.ProjectileHit(r.BlockPosition(), tx, e, r.Face()) + vel = mgl64.Vec3{x * mx, y * my, z * mz} } } else { vel = zeroVec3