--- a/net/minecraft/world/entity/monster/Ravager.java
+++ b/net/minecraft/world/entity/monster/Ravager.java
@@ -1,5 +1,7 @@
 package net.minecraft.world.entity.monster;
 
+import java.util.Iterator;
+import java.util.List;
 import java.util.function.Predicate;
 import javax.annotation.Nullable;
 import net.minecraft.core.BlockPos;
@@ -39,11 +41,17 @@
 import net.minecraft.world.level.pathfinder.PathType;
 import net.minecraft.world.phys.AABB;
 import net.minecraft.world.phys.Vec3;
+// CraftBukkit start
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+// CraftBukkit end
 
 public class Ravager extends Raider {
-    private static final Predicate<Entity> NO_RAVAGER_AND_ALIVE = entity -> entity.isAlive() && !(entity instanceof Ravager);
-    private static final double BASE_MOVEMENT_SPEED = 0.3;
-    private static final double ATTACK_MOVEMENT_SPEED = 0.35;
+
+    private static final Predicate<Entity> NO_RAVAGER_AND_ALIVE = (entity) -> {
+        return entity.isAlive() && !(entity instanceof Ravager);
+    };
+    private static final double BASE_MOVEMENT_SPEED = 0.3D;
+    private static final double ATTACK_MOVEMENT_SPEED = 0.35D;
     private static final int STUNNED_COLOR = 8356754;
     private static final float STUNNED_COLOR_BLUE = 0.57254905F;
     private static final float STUNNED_COLOR_GREEN = 0.5137255F;
@@ -64,35 +72,31 @@
     protected void registerGoals() {
         super.registerGoals();
         this.goalSelector.addGoal(0, new FloatGoal(this));
-        this.goalSelector.addGoal(4, new MeleeAttackGoal(this, 1.0, true));
-        this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 0.4));
+        this.goalSelector.addGoal(4, new MeleeAttackGoal(this, 1.0D, true));
+        this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 0.4D));
         this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 6.0F));
         this.goalSelector.addGoal(10, new LookAtPlayerGoal(this, Mob.class, 8.0F));
-        this.targetSelector.addGoal(2, new HurtByTargetGoal(this, Raider.class).setAlertOthers());
+        this.targetSelector.addGoal(2, (new HurtByTargetGoal(this, new Class[]{Raider.class})).setAlertOthers());
         this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Player.class, true));
-        this.targetSelector.addGoal(4, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, true, entity -> !entity.isBaby()));
+        this.targetSelector.addGoal(4, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, true, (entityliving) -> {
+            return !entityliving.isBaby();
+        }));
         this.targetSelector.addGoal(4, new NearestAttackableTargetGoal<>(this, IronGolem.class, true));
     }
 
     @Override
     protected void updateControlFlags() {
-        boolean bl = !(this.getControllingPassenger() instanceof Mob) || this.getControllingPassenger().getType().is(EntityTypeTags.RAIDERS);
-        boolean bl2 = !(this.getVehicle() instanceof Boat);
-        this.goalSelector.setControlFlag(Goal.Flag.MOVE, bl);
-        this.goalSelector.setControlFlag(Goal.Flag.JUMP, bl && bl2);
-        this.goalSelector.setControlFlag(Goal.Flag.LOOK, bl);
-        this.goalSelector.setControlFlag(Goal.Flag.TARGET, bl);
+        boolean flag = !(this.getControllingPassenger() instanceof Mob) || this.getControllingPassenger().getType().is(EntityTypeTags.RAIDERS);
+        boolean flag1 = !(this.getVehicle() instanceof Boat);
+
+        this.goalSelector.setControlFlag(Goal.Flag.MOVE, flag);
+        this.goalSelector.setControlFlag(Goal.Flag.JUMP, flag && flag1);
+        this.goalSelector.setControlFlag(Goal.Flag.LOOK, flag);
+        this.goalSelector.setControlFlag(Goal.Flag.TARGET, flag);
     }
 
     public static AttributeSupplier.Builder createAttributes() {
-        return Monster.createMonsterAttributes()
-            .add(Attributes.MAX_HEALTH, 100.0)
-            .add(Attributes.MOVEMENT_SPEED, 0.3)
-            .add(Attributes.KNOCKBACK_RESISTANCE, 0.75)
-            .add(Attributes.ATTACK_DAMAGE, 12.0)
-            .add(Attributes.ATTACK_KNOCKBACK, 1.5)
-            .add(Attributes.FOLLOW_RANGE, 32.0)
-            .add(Attributes.STEP_HEIGHT, 1.0);
+        return Monster.createMonsterAttributes().add(Attributes.MAX_HEALTH, 100.0D).add(Attributes.MOVEMENT_SPEED, 0.3D).add(Attributes.KNOCKBACK_RESISTANCE, 0.75D).add(Attributes.ATTACK_DAMAGE, 12.0D).add(Attributes.ATTACK_KNOCKBACK, 1.5D).add(Attributes.FOLLOW_RANGE, 32.0D).add(Attributes.STEP_HEIGHT, 1.0D);
     }
 
     @Override
@@ -126,65 +130,73 @@
         super.aiStep();
         if (this.isAlive()) {
             if (this.isImmobile()) {
-                this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.0);
+                this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.0D);
             } else {
-                double d = this.getTarget() != null ? 0.35 : 0.3;
-                double e = this.getAttribute(Attributes.MOVEMENT_SPEED).getBaseValue();
-                this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(Mth.lerp(0.1, e, d));
+                double d0 = this.getTarget() != null ? 0.35D : 0.3D;
+                double d1 = this.getAttribute(Attributes.MOVEMENT_SPEED).getBaseValue();
+
+                this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(Mth.lerp(0.1D, d1, d0));
             }
 
             if (this.horizontalCollision && this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
-                boolean bl = false;
-                AABB aABB = this.getBoundingBox().inflate(0.2);
+                boolean flag = false;
+                AABB axisalignedbb = this.getBoundingBox().inflate(0.2D);
+                Iterator iterator = BlockPos.betweenClosed(Mth.floor(axisalignedbb.minX), Mth.floor(axisalignedbb.minY), Mth.floor(axisalignedbb.minZ), Mth.floor(axisalignedbb.maxX), Mth.floor(axisalignedbb.maxY), Mth.floor(axisalignedbb.maxZ)).iterator();
+
+                while (iterator.hasNext()) {
+                    BlockPos blockposition = (BlockPos) iterator.next();
+                    BlockState iblockdata = this.level().getBlockState(blockposition);
+                    Block block = iblockdata.getBlock();
 
-                for (BlockPos blockPos : BlockPos.betweenClosed(
-                    Mth.floor(aABB.minX), Mth.floor(aABB.minY), Mth.floor(aABB.minZ), Mth.floor(aABB.maxX), Mth.floor(aABB.maxY), Mth.floor(aABB.maxZ)
-                )) {
-                    BlockState blockState = this.level().getBlockState(blockPos);
-                    Block block = blockState.getBlock();
                     if (block instanceof LeavesBlock) {
-                        bl = this.level().destroyBlock(blockPos, true, this) || bl;
+                        // CraftBukkit start
+                        if (!CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, iblockdata.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state
+                            continue;
+                        }
+                        // CraftBukkit end
+                        flag = this.level().destroyBlock(blockposition, true, this) || flag;
                     }
                 }
 
-                if (!bl && this.onGround()) {
+                if (!flag && this.onGround()) {
+                    if (new com.destroystokyo.paper.event.entity.EntityJumpEvent(getBukkitLivingEntity()).callEvent()) { // Paper - Entity Jump API
                     this.jumpFromGround();
+                    } else { this.setJumping(false); } // Paper - Entity Jump API; setJumping(false) stops a potential loop
                 }
             }
 
             if (this.roarTick > 0) {
-                this.roarTick--;
+                --this.roarTick;
                 if (this.roarTick == 10) {
                     this.roar();
                 }
             }
 
             if (this.attackTick > 0) {
-                this.attackTick--;
+                --this.attackTick;
             }
 
             if (this.stunnedTick > 0) {
-                this.stunnedTick--;
+                --this.stunnedTick;
                 this.stunEffect();
                 if (this.stunnedTick == 0) {
                     this.playSound(SoundEvents.RAVAGER_ROAR, 1.0F, 1.0F);
                     this.roarTick = 20;
                 }
             }
+
         }
     }
 
     private void stunEffect() {
         if (this.random.nextInt(6) == 0) {
-            double d = this.getX()
-                - (double)this.getBbWidth() * Math.sin((double)(this.yBodyRot * (float) (Math.PI / 180.0)))
-                + (this.random.nextDouble() * 0.6 - 0.3);
-            double e = this.getY() + (double)this.getBbHeight() - 0.3;
-            double f = this.getZ()
-                + (double)this.getBbWidth() * Math.cos((double)(this.yBodyRot * (float) (Math.PI / 180.0)))
-                + (this.random.nextDouble() * 0.6 - 0.3);
-            this.level().addParticle(ColorParticleOption.create(ParticleTypes.ENTITY_EFFECT, 0.49803922F, 0.5137255F, 0.57254905F), d, e, f, 0.0, 0.0, 0.0);
+            double d0 = this.getX() - (double) this.getBbWidth() * Math.sin((double) (this.yBodyRot * 0.017453292F)) + (this.random.nextDouble() * 0.6D - 0.3D);
+            double d1 = this.getY() + (double) this.getBbHeight() - 0.3D;
+            double d2 = this.getZ() + (double) this.getBbWidth() * Math.cos((double) (this.yBodyRot * 0.017453292F)) + (this.random.nextDouble() * 0.6D - 0.3D);
+
+            this.level().addParticle(ColorParticleOption.create(ParticleTypes.ENTITY_EFFECT, 0.49803922F, 0.5137255F, 0.57254905F), d0, d1, d2, 0.0D, 0.0D, 0.0D);
         }
+
     }
 
     @Override
@@ -194,16 +206,16 @@
 
     @Override
     public boolean hasLineOfSight(Entity entity) {
-        return this.stunnedTick <= 0 && this.roarTick <= 0 && super.hasLineOfSight(entity);
+        return this.stunnedTick <= 0 && this.roarTick <= 0 ? super.hasLineOfSight(entity) : false;
     }
 
     @Override
     protected void blockedByShield(LivingEntity target) {
         if (this.roarTick == 0) {
-            if (this.random.nextDouble() < 0.5) {
+            if (this.random.nextDouble() < 0.5D) {
                 this.stunnedTick = 40;
                 this.playSound(SoundEvents.RAVAGER_STUNNED, 1.0F, 1.0F);
-                this.level().broadcastEntityEvent(this, (byte)39);
+                this.level().broadcastEntityEvent(this, (byte) 39);
                 target.push(this);
             } else {
                 this.strongKnockback(target);
@@ -211,36 +223,43 @@
 
             target.hurtMarked = true;
         }
+
     }
 
     private void roar() {
         if (this.isAlive()) {
-            for (LivingEntity livingEntity : this.level().getEntitiesOfClass(LivingEntity.class, this.getBoundingBox().inflate(4.0), NO_RAVAGER_AND_ALIVE)) {
-                if (!(livingEntity instanceof AbstractIllager)) {
-                    livingEntity.hurt(this.damageSources().mobAttack(this), 6.0F);
-                }
+            List<? extends LivingEntity> list = this.level().getEntitiesOfClass(LivingEntity.class, this.getBoundingBox().inflate(4.0D), Ravager.NO_RAVAGER_AND_ALIVE);
 
-                this.strongKnockback(livingEntity);
+            LivingEntity entityliving;
+
+            for (Iterator iterator = list.iterator(); iterator.hasNext(); this.strongKnockback(entityliving)) {
+                entityliving = (LivingEntity) iterator.next();
+                if (!(entityliving instanceof AbstractIllager)) {
+                    entityliving.hurt(this.damageSources().mobAttack(this), 6.0F);
+                }
             }
 
-            Vec3 vec3 = this.getBoundingBox().getCenter();
+            Vec3 vec3d = this.getBoundingBox().getCenter();
 
-            for (int i = 0; i < 40; i++) {
-                double d = this.random.nextGaussian() * 0.2;
-                double e = this.random.nextGaussian() * 0.2;
-                double f = this.random.nextGaussian() * 0.2;
-                this.level().addParticle(ParticleTypes.POOF, vec3.x, vec3.y, vec3.z, d, e, f);
+            for (int i = 0; i < 40; ++i) {
+                double d0 = this.random.nextGaussian() * 0.2D;
+                double d1 = this.random.nextGaussian() * 0.2D;
+                double d2 = this.random.nextGaussian() * 0.2D;
+
+                this.level().addParticle(ParticleTypes.POOF, vec3d.x, vec3d.y, vec3d.z, d0, d1, d2);
             }
 
             this.gameEvent(GameEvent.ENTITY_ACTION);
         }
+
     }
 
     private void strongKnockback(Entity entity) {
-        double d = entity.getX() - this.getX();
-        double e = entity.getZ() - this.getZ();
-        double f = Math.max(d * d + e * e, 0.001);
-        entity.push(d / f * 4.0, 0.2, e / f * 4.0);
+        double d0 = entity.getX() - this.getX();
+        double d1 = entity.getZ() - this.getZ();
+        double d2 = Math.max(d0 * d0 + d1 * d1, 0.001D);
+
+        entity.push(d0 / d2 * 4.0D, 0.2D, d1 / d2 * 4.0D, this); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
     }
 
     @Override
@@ -270,7 +289,7 @@
     @Override
     public boolean doHurtTarget(Entity target) {
         this.attackTick = 10;
-        this.level().broadcastEntityEvent(this, (byte)4);
+        this.level().broadcastEntityEvent(this, (byte) 4);
         this.playSound(SoundEvents.RAVAGER_ATTACK, 1.0F, 1.0F);
         return super.doHurtTarget(target);
     }
@@ -302,8 +321,7 @@
     }
 
     @Override
-    public void applyRaidBuffs(int wave, boolean unused) {
-    }
+    public void applyRaidBuffs(int wave, boolean unused) {}
 
     @Override
     public boolean canBeLeader() {
@@ -312,7 +330,8 @@
 
     @Override
     protected AABB getAttackBoundingBox() {
-        AABB aABB = super.getAttackBoundingBox();
-        return aABB.deflate(0.05, 0.0, 0.05);
+        AABB axisalignedbb = super.getAttackBoundingBox();
+
+        return axisalignedbb.deflate(0.05D, 0.0D, 0.05D);
     }
 }
