From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Tue, 5 Jan 2021 22:21:56 -0500
Subject: [PATCH] Add mobGriefing bypass to everything affected

This adds the "bypass-mob-griefing" world config option to everything that is affected by the gamerule.

diff --git a/src/main/java/net/minecraft/world/entity/EntityLiving.java b/src/main/java/net/minecraft/world/entity/EntityLiving.java
index c957122f8463fc1eae632730a64bec7f8b0d1055..52bd6b4a3bcd44166bd4c897756fe06b19120907 100644
--- a/src/main/java/net/minecraft/world/entity/EntityLiving.java
+++ b/src/main/java/net/minecraft/world/entity/EntityLiving.java
@@ -1571,7 +1571,7 @@ public abstract class EntityLiving extends Entity {
             boolean flag = false;
 
             if (this.killed && entityliving instanceof EntityWither) { // Paper
-                if (this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) {
+                if (this.world.purpurConfig.witherBypassMobGriefing || this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) { // Purpur
                     BlockPosition blockposition = this.getChunkCoordinates();
                     IBlockData iblockdata = Blocks.WITHER_ROSE.getBlockData();
 
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalBreakDoor.java b/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalBreakDoor.java
index d785066e2a52699c18315f7244d80db6cab0c736..6c40b070c674f2b120b860b78a63d0a6635d2f5b 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalBreakDoor.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalBreakDoor.java
@@ -34,7 +34,7 @@ public class PathfinderGoalBreakDoor extends PathfinderGoalDoorInteract {
 
     @Override
     public boolean a() {
-        return !super.a() ? false : (!this.entity.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) ? false : this.a(this.entity.world.getDifficulty()) && !this.g());
+        return !super.a() ? false : ((!this.entity.world.purpurConfig.zombieBypassMobGriefing && !this.entity.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) ? false : this.a(this.entity.world.getDifficulty()) && !this.g()); // Purpur
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalEatTile.java b/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalEatTile.java
index 6737dd77c8f46edf353f951b5adb4399142a1753..06dbce54602d02382e9d47b7e6925cfc686d26f6 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalEatTile.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalEatTile.java
@@ -19,7 +19,7 @@ public class PathfinderGoalEatTile extends PathfinderGoal {
 
     private static final Predicate<IBlockData> a = BlockStatePredicate.a(Blocks.GRASS);
     private final EntityInsentient b;
-    private final World c;
+    private final World c; private final World getWorld() { return c; } // Purpur - OBFHELPER
     private int d;
 
     public PathfinderGoalEatTile(EntityInsentient entityinsentient) {
@@ -68,7 +68,7 @@ public class PathfinderGoalEatTile extends PathfinderGoal {
 
             if (PathfinderGoalEatTile.a.test(this.c.getType(blockposition))) {
                 // CraftBukkit
-                if (!CraftEventFactory.callEntityChangeBlockEvent(this.b, blockposition, Blocks.AIR.getBlockData(), !this.c.getGameRules().getBoolean(GameRules.MOB_GRIEFING)).isCancelled()) {
+                if (!CraftEventFactory.callEntityChangeBlockEvent(this.b, blockposition, Blocks.AIR.getBlockData(), !this.getWorld().purpurConfig.sheepBypassMobGriefing && !this.c.getGameRules().getBoolean(GameRules.MOB_GRIEFING)).isCancelled()) { // Purpur
                     this.c.b(blockposition, false);
                 }
 
@@ -78,7 +78,7 @@ public class PathfinderGoalEatTile extends PathfinderGoal {
 
                 if (this.c.getType(blockposition1).a(Blocks.GRASS_BLOCK)) {
                     // CraftBukkit
-                    if (!CraftEventFactory.callEntityChangeBlockEvent(this.b, blockposition, Blocks.AIR.getBlockData(), !this.c.getGameRules().getBoolean(GameRules.MOB_GRIEFING)).isCancelled()) {
+                    if (!CraftEventFactory.callEntityChangeBlockEvent(this.b, blockposition, Blocks.AIR.getBlockData(), !this.getWorld().purpurConfig.sheepBypassMobGriefing && !this.c.getGameRules().getBoolean(GameRules.MOB_GRIEFING)).isCancelled()) { // Purpur
                         this.c.triggerEffect(2001, blockposition1, Block.getCombinedId(Blocks.GRASS_BLOCK.getBlockData()));
                         this.c.setTypeAndData(blockposition1, Blocks.DIRT.getBlockData(), 2);
                     }
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalRemoveBlock.java b/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalRemoveBlock.java
index 61a62c093b24c43064f116630d85096159e082d3..2519a78f7e5dd759680a1f47a1047885d4ad32f1 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalRemoveBlock.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalRemoveBlock.java
@@ -41,7 +41,7 @@ public class PathfinderGoalRemoveBlock extends PathfinderGoalGotoTarget {
 
     @Override
     public boolean a() {
-        if (!this.entity.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) {
+        if (!this.entity.world.purpurConfig.zombieBypassMobGriefing && !this.entity.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) { // Purpur
             return false;
         } else if (this.c > 0) {
             --this.c;
diff --git a/src/main/java/net/minecraft/world/entity/animal/EntityFox.java b/src/main/java/net/minecraft/world/entity/animal/EntityFox.java
index b8b0ee65798dc94d707fa64bd53fdda5506331d9..355735c2efbba62481d059b8e733c9c70e834be1 100644
--- a/src/main/java/net/minecraft/world/entity/animal/EntityFox.java
+++ b/src/main/java/net/minecraft/world/entity/animal/EntityFox.java
@@ -1075,7 +1075,7 @@ public class EntityFox extends EntityAnimal {
         }
 
         protected void n() {
-            if (EntityFox.this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) {
+            if (EntityFox.this.world.purpurConfig.foxBypassMobGriefing || EntityFox.this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) { // Purpur
                 IBlockData iblockdata = EntityFox.this.world.getType(this.e);
 
                 if (iblockdata.a(Blocks.SWEET_BERRY_BUSH)) {
diff --git a/src/main/java/net/minecraft/world/entity/animal/EntityRabbit.java b/src/main/java/net/minecraft/world/entity/animal/EntityRabbit.java
index 284c52276b2fd816990c23b7b8a9ee50e70ab005..acb4c79b23fada090c5605cd352a573bdb0667bf 100644
--- a/src/main/java/net/minecraft/world/entity/animal/EntityRabbit.java
+++ b/src/main/java/net/minecraft/world/entity/animal/EntityRabbit.java
@@ -518,7 +518,7 @@ public class EntityRabbit extends EntityAnimal {
         @Override
         public boolean a() {
             if (this.c <= 0) {
-                if (!this.entity.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) {
+                if (!this.entity.world.purpurConfig.rabbitBypassMobGriefing && !this.entity.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) { // Purpur
                     return false;
                 }
 
diff --git a/src/main/java/net/minecraft/world/entity/animal/EntitySnowman.java b/src/main/java/net/minecraft/world/entity/animal/EntitySnowman.java
index 88db8ff8cb415b84ab98cc0550c705d5a472230c..17f27d2bf5be746a0fa0e1e0fecab8158b2b3587 100644
--- a/src/main/java/net/minecraft/world/entity/animal/EntitySnowman.java
+++ b/src/main/java/net/minecraft/world/entity/animal/EntitySnowman.java
@@ -123,7 +123,7 @@ public class EntitySnowman extends EntityGolem implements IShearable, IRangedEnt
                 this.damageEntity(CraftEventFactory.MELTING, 1.0F); // CraftBukkit - DamageSource.BURN -> CraftEventFactory.MELTING
             }
 
-            if (!this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) {
+            if (!this.world.purpurConfig.snowGolemBypassMobGriefing && !this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) { // Purpur
                 return;
             }
 
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EntityEnderDragon.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EntityEnderDragon.java
index 999a6d17eccd6305c0063e1558abfe70d72c39fe..a81d782877ff6116477792fa4cec0846e56ed384 100644
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EntityEnderDragon.java
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EntityEnderDragon.java
@@ -539,7 +539,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {
                     Block block = iblockdata.getBlock();
 
                     if (!iblockdata.isAir() && iblockdata.getMaterial() != Material.FIRE) {
-                        if (this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) && !TagsBlock.DRAGON_IMMUNE.isTagged(block)) {
+                        if ((this.world.purpurConfig.enderDragonBypassMobGriefing || this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) && !TagsBlock.DRAGON_IMMUNE.isTagged(block)) { // Purpur
                             // CraftBukkit start - Add blocks to list rather than destroying them
                             // flag1 = this.world.a(blockposition, false) || flag1;
                             flag1 = true;
diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/EntityWither.java b/src/main/java/net/minecraft/world/entity/boss/wither/EntityWither.java
index beb4d59faf4bd7501468b2eaa0e866613625e963..fa6b72c7a12b20f8ccffa360a3895e4d8f4277e4 100644
--- a/src/main/java/net/minecraft/world/entity/boss/wither/EntityWither.java
+++ b/src/main/java/net/minecraft/world/entity/boss/wither/EntityWither.java
@@ -380,7 +380,7 @@ public class EntityWither extends EntityMonster implements IRangedEntity {
         if (this.getInvul() > 0) {
             i = this.getInvul() - 1;
             if (i <= 0) {
-                Explosion.Effect explosion_effect = this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) ? Explosion.Effect.DESTROY : Explosion.Effect.NONE;
+                Explosion.Effect explosion_effect = (this.world.purpurConfig.witherBypassMobGriefing || this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) ? Explosion.Effect.DESTROY : Explosion.Effect.NONE; // Purpur
                 // CraftBukkit start
                 // this.world.createExplosion(this, this.locX(), this.getHeadY(), this.locZ(), 7.0F, false, explosion_effect);
                 ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), 7.0F, false);
@@ -492,7 +492,7 @@ public class EntityWither extends EntityMonster implements IRangedEntity {
 
             if (this.bw > 0) {
                 --this.bw;
-                if (this.bw == 0 && this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) {
+                if (this.bw == 0 && (this.world.purpurConfig.witherBypassMobGriefing || this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING))) { // Purpur
                     i = MathHelper.floor(this.locY());
                     j = MathHelper.floor(this.locX());
                     int j1 = MathHelper.floor(this.locZ());
diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityEnderman.java b/src/main/java/net/minecraft/world/entity/monster/EntityEnderman.java
index 478ac5bfdc69b5c3e24906bb5e0ea1dff81cea98..ea500a6080f73dcc35d83a3b5a170f57dedaa431 100644
--- a/src/main/java/net/minecraft/world/entity/monster/EntityEnderman.java
+++ b/src/main/java/net/minecraft/world/entity/monster/EntityEnderman.java
@@ -455,7 +455,7 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable {
         @Override
         public boolean a() {
             if (!enderman.world.purpurConfig.endermanAllowGriefing) return false; // Purpur
-            return this.enderman.getCarried() != null ? false : (!this.enderman.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) ? false : this.enderman.getRandom().nextInt(20) == 0);
+            return this.enderman.getCarried() != null ? false : (!this.enderman.world.purpurConfig.endermanBypassMobGriefing && !this.enderman.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) ? false : this.enderman.getRandom().nextInt(20) == 0); // Purpur
         }
 
         @Override
@@ -498,7 +498,7 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable {
         @Override
         public boolean a() {
             if (!getEnderman().world.purpurConfig.endermanAllowGriefing) return false; // Purpur
-            return this.a.getCarried() == null ? false : (!this.a.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) ? false : this.a.getRandom().nextInt(2000) == 0);
+            return this.a.getCarried() == null ? false : (!this.a.world.purpurConfig.endermanBypassMobGriefing && !this.a.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) ? false : this.a.getRandom().nextInt(2000) == 0); // Purpur
         }
 
         @Override
diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityEvoker.java b/src/main/java/net/minecraft/world/entity/monster/EntityEvoker.java
index 8d7b8d2ac9a7340e2cfd0d1b8963e4e4d97e8bc8..8a219ac18307c715913f5c2a80b1ff35a2ea8b93 100644
--- a/src/main/java/net/minecraft/world/entity/monster/EntityEvoker.java
+++ b/src/main/java/net/minecraft/world/entity/monster/EntityEvoker.java
@@ -171,7 +171,7 @@ public class EntityEvoker extends EntityIllagerWizard {
                 return false;
             } else if (EntityEvoker.this.ticksLived < this.c) {
                 return false;
-            } else if (!EntityEvoker.this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) {
+            } else if (!EntityEvoker.this.world.purpurConfig.evokerBypassMobGriefing && !EntityEvoker.this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) { // Purpur
                 return false;
             } else {
                 List<EntitySheep> list = EntityEvoker.this.world.a(EntitySheep.class, this.e, EntityEvoker.this, EntityEvoker.this.getBoundingBox().grow(16.0D, 4.0D, 16.0D));
diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityRavager.java b/src/main/java/net/minecraft/world/entity/monster/EntityRavager.java
index 80c3cd540a46e249e85586e8d7a2f0f6226091fc..6809c93fe435d183a27204fb4460fd68a86aa04f 100644
--- a/src/main/java/net/minecraft/world/entity/monster/EntityRavager.java
+++ b/src/main/java/net/minecraft/world/entity/monster/EntityRavager.java
@@ -179,7 +179,7 @@ public class EntityRavager extends EntityRaider {
                 this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(MathHelper.d(0.1D, d1, d0));
             }
 
-            if (this.positionChanged && this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) {
+            if (this.positionChanged && (this.world.purpurConfig.ravagerBypassMobGriefing || this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING))) { // Purpur
                 boolean flag = false;
                 AxisAlignedBB axisalignedbb = this.getBoundingBox().g(0.2D);
                 Iterator iterator = BlockPosition.b(MathHelper.floor(axisalignedbb.minX), MathHelper.floor(axisalignedbb.minY), MathHelper.floor(axisalignedbb.minZ), MathHelper.floor(axisalignedbb.maxX), MathHelper.floor(axisalignedbb.maxY), MathHelper.floor(axisalignedbb.maxZ)).iterator();
diff --git a/src/main/java/net/minecraft/world/entity/monster/EntitySilverfish.java b/src/main/java/net/minecraft/world/entity/monster/EntitySilverfish.java
index a0a1e5977a3cbc8e9befd827dd1e15352a2c0c39..cbdb512c924ac54e925f8c52558d24d3286d31ce 100644
--- a/src/main/java/net/minecraft/world/entity/monster/EntitySilverfish.java
+++ b/src/main/java/net/minecraft/world/entity/monster/EntitySilverfish.java
@@ -172,7 +172,7 @@ public class EntitySilverfish extends EntityMonster {
             } else {
                 Random random = this.a.getRandom();
 
-                if (this.a.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) && random.nextInt(10) == 0) {
+                if ((this.a.world.purpurConfig.silverfishBypassMobGriefing || this.a.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) && random.nextInt(10) == 0) { // Purpur
                     this.h = EnumDirection.a(random);
                     BlockPosition blockposition = (new BlockPosition(this.a.locX(), this.a.locY() + 0.5D, this.a.locZ())).shift(this.h);
                     IBlockData iblockdata = this.a.world.getType(blockposition);
@@ -260,7 +260,7 @@ public class EntitySilverfish extends EntityMonster {
                                     continue;
                                 }
                                 // CraftBukkit end
-                                if (world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) {
+                                if (world.purpurConfig.silverfishBypassMobGriefing || world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) { // Purpur
                                     world.a(blockposition1, true, this.silverfish);
                                 } else {
                                     world.setTypeAndData(blockposition1, ((BlockMonsterEggs) block).c().getBlockData(), 3);
diff --git a/src/main/java/net/minecraft/world/entity/projectile/EntityLargeFireball.java b/src/main/java/net/minecraft/world/entity/projectile/EntityLargeFireball.java
index e860737bacfea0a1d728dbaaf41d62165658ad89..61f06eacb4ea4ef869b60c9014cc23b25583eead 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/EntityLargeFireball.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/EntityLargeFireball.java
@@ -19,19 +19,19 @@ public class EntityLargeFireball extends EntityFireballFireball {
 
     public EntityLargeFireball(EntityTypes<? extends EntityLargeFireball> entitytypes, World world) {
         super(entitytypes, world);
-        isIncendiary = this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING); // CraftBukkit
+        isIncendiary = this.world.purpurConfig.fireballsBypassMobGriefing || this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING); // CraftBukkit // Purpur
     }
 
     public EntityLargeFireball(World world, EntityLiving entityliving, double d0, double d1, double d2) {
         super(EntityTypes.FIREBALL, entityliving, d0, d1, d2, world);
-        isIncendiary = this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING); // CraftBukkit
+        isIncendiary = this.world.purpurConfig.fireballsBypassMobGriefing || this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING); // CraftBukkit // Purpur
     }
 
     @Override
     protected void a(MovingObjectPosition movingobjectposition) {
         super.a(movingobjectposition);
         if (!this.world.isClientSide) {
-            boolean flag = this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING);
+            boolean flag = this.world.purpurConfig.fireballsBypassMobGriefing || this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING); // Purpur
 
             // CraftBukkit start - fire ExplosionPrimeEvent
             ExplosionPrimeEvent event = new ExplosionPrimeEvent((org.bukkit.entity.Explosive) this.getBukkitEntity());
diff --git a/src/main/java/net/minecraft/world/entity/projectile/EntitySmallFireball.java b/src/main/java/net/minecraft/world/entity/projectile/EntitySmallFireball.java
index bf747cbf6e1ef9ea9d1d41d0441b29a46ce874c0..53e02e512b8bcebac105e421991b3554a7ad699a 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/EntitySmallFireball.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/EntitySmallFireball.java
@@ -26,7 +26,7 @@ public class EntitySmallFireball extends EntityFireballFireball {
         super(EntityTypes.SMALL_FIREBALL, entityliving, d0, d1, d2, world);
         // CraftBukkit start
         if (this.getShooter() != null && this.getShooter() instanceof EntityInsentient) {
-            isIncendiary = this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING);
+            isIncendiary = this.world.purpurConfig.fireballsBypassMobGriefing || this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING); // Purpur
         }
         // CraftBukkit end
     }
diff --git a/src/main/java/net/minecraft/world/entity/projectile/EntityWitherSkull.java b/src/main/java/net/minecraft/world/entity/projectile/EntityWitherSkull.java
index 2fe0e32a1158cccb3060f5a986c9fc41a0237aa8..616b5267d1d94b2be37ec48983b45e4478502fb5 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/EntityWitherSkull.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/EntityWitherSkull.java
@@ -94,7 +94,7 @@ public class EntityWitherSkull extends EntityFireball {
     protected void a(MovingObjectPosition movingobjectposition) {
         super.a(movingobjectposition);
         if (!this.world.isClientSide) {
-            Explosion.Effect explosion_effect = this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) ? Explosion.Effect.DESTROY : Explosion.Effect.NONE;
+            Explosion.Effect explosion_effect = (this.world.purpurConfig.witherBypassMobGriefing || this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) ? Explosion.Effect.DESTROY : Explosion.Effect.NONE; // Purpur
 
             // CraftBukkit start
             // this.world.createExplosion(this, this.locX(), this.locY(), this.locZ(), 1.0F, false, explosion_effect);
diff --git a/src/main/java/net/minecraft/world/entity/raid/EntityRaider.java b/src/main/java/net/minecraft/world/entity/raid/EntityRaider.java
index ff41ee884e3e46af1b1e9fb550f0abc6998fd031..8eec32af12c69e1963dcd304a25ec4811b2f1f5a 100644
--- a/src/main/java/net/minecraft/world/entity/raid/EntityRaider.java
+++ b/src/main/java/net/minecraft/world/entity/raid/EntityRaider.java
@@ -532,7 +532,7 @@ public abstract class EntityRaider extends EntityMonsterPatrolling {
 
         @Override
         public boolean a() {
-            if (!getRaider().world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) || !getRaider().canPickupLoot()) return false; // Paper - respect game and entity rules for picking up items
+            if ((!getRaider().world.purpurConfig.pillagerBypassMobGriefing && !getRaider().world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) || !getRaider().canPickupLoot()) return false; // Paper - respect game and entity rules for picking up items // Purpur
             Raid raid = this.b.fa();
 
             if (this.b.fb() && !this.b.fa().a() && this.b.eN() && !ItemStack.matches(this.b.getEquipment(EnumItemSlot.HEAD), Raid.s())) {
diff --git a/src/main/java/net/minecraft/world/level/block/BlockCampfire.java b/src/main/java/net/minecraft/world/level/block/BlockCampfire.java
index 21baa8fb99b0587da503e14e2b04abf3134d03bc..3f816358758165bf5e346eaffcb3edc46c48dd40 100644
--- a/src/main/java/net/minecraft/world/level/block/BlockCampfire.java
+++ b/src/main/java/net/minecraft/world/level/block/BlockCampfire.java
@@ -181,7 +181,7 @@ public class BlockCampfire extends BlockTileEntity implements IBlockWaterlogged
     public void a(World world, IBlockData iblockdata, MovingObjectPositionBlock movingobjectpositionblock, IProjectile iprojectile) {
         if (!world.isClientSide && iprojectile.isBurning()) {
             Entity entity = iprojectile.getShooter();
-            boolean flag = entity == null || entity instanceof EntityHuman || world.getGameRules().getBoolean(GameRules.MOB_GRIEFING);
+            boolean flag = entity == null || entity instanceof EntityHuman || world.purpurConfig.fireballsBypassMobGriefing || world.getGameRules().getBoolean(GameRules.MOB_GRIEFING); // Purpur
 
             if (flag && !(Boolean) iblockdata.get(BlockCampfire.LIT) && !(Boolean) iblockdata.get(BlockCampfire.d)) {
                 BlockPosition blockposition = movingobjectpositionblock.getBlockPosition();
diff --git a/src/main/java/net/minecraft/world/level/block/BlockCrops.java b/src/main/java/net/minecraft/world/level/block/BlockCrops.java
index 09f15d9087f1c40e5d50cb56f8c764ddaa992e41..5f8366beeaac7153a0421554f9bf91fbf265edca 100644
--- a/src/main/java/net/minecraft/world/level/block/BlockCrops.java
+++ b/src/main/java/net/minecraft/world/level/block/BlockCrops.java
@@ -160,7 +160,7 @@ public class BlockCrops extends BlockPlant implements IBlockFragilePlantElement
 
     @Override
     public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Entity entity) {
-        if (entity instanceof EntityRavager && !CraftEventFactory.callEntityChangeBlockEvent(entity, blockposition, Blocks.AIR.getBlockData(), !world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)).isCancelled()) { // CraftBukkit
+        if (entity instanceof EntityRavager && !CraftEventFactory.callEntityChangeBlockEvent(entity, blockposition, Blocks.AIR.getBlockData(), (!world.purpurConfig.ravagerBypassMobGriefing && !world.getGameRules().getBoolean(GameRules.MOB_GRIEFING))).isCancelled()) { // CraftBukkit // Purpur
             world.a(blockposition, true, entity);
         }
 
diff --git a/src/main/java/net/minecraft/world/level/block/BlockSoil.java b/src/main/java/net/minecraft/world/level/block/BlockSoil.java
index 3e8893bf76b8ffda4c595c81086556ea929beaa4..d3fd0b418b9088b621e44f5da452db74b433efe8 100644
--- a/src/main/java/net/minecraft/world/level/block/BlockSoil.java
+++ b/src/main/java/net/minecraft/world/level/block/BlockSoil.java
@@ -99,7 +99,7 @@ public class BlockSoil extends Block {
     @Override
     public void fallOn(World world, BlockPosition blockposition, Entity entity, float f) {
         super.fallOn(world, blockposition, entity, f); // CraftBukkit - moved here as game rules / events shouldn't affect fall damage.
-        if (!world.isClientSide && world.random.nextFloat() < f - 0.5F && entity instanceof EntityLiving && (entity instanceof EntityHuman || world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) && entity.getWidth() * entity.getWidth() * entity.getHeight() > 0.512F) {
+        if (!world.isClientSide && world.random.nextFloat() < f - 0.5F && entity instanceof EntityLiving && (entity instanceof EntityHuman || world.purpurConfig.farmlandBypassMobGriefing || world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) && entity.getWidth() * entity.getWidth() * entity.getHeight() > 0.512F) { // Purpur
             // CraftBukkit start - Interact soil
             org.bukkit.event.Cancellable cancellable;
             if (entity instanceof EntityHuman) {
diff --git a/src/main/java/net/minecraft/world/level/block/BlockTurtleEgg.java b/src/main/java/net/minecraft/world/level/block/BlockTurtleEgg.java
index 04504901b1933ed760b34b8abb994de8ec340a4e..e18be05c9a9230105ec54395d4391c86132e7930 100644
--- a/src/main/java/net/minecraft/world/level/block/BlockTurtleEgg.java
+++ b/src/main/java/net/minecraft/world/level/block/BlockTurtleEgg.java
@@ -206,7 +206,7 @@ public class BlockTurtleEgg extends Block {
             return false;
         }
         if (entity instanceof EntityLiving && !(entity instanceof EntityHuman)) {
-            return world.getGameRules().getBoolean(GameRules.MOB_GRIEFING);
+            return world.purpurConfig.turtleEggsBypassMobGriefing || world.getGameRules().getBoolean(GameRules.MOB_GRIEFING); // Purpur
         }
         return true;
         // Purpur end
diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
index b8c9c8e5ed7f3ffea4dc2cbe29d308afe0069773..a5086549c5cb034b47989141efabeaf9980ad2ff 100644
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
@@ -252,6 +252,7 @@ public class PurpurWorldConfig {
     public boolean disableDropsOnCrammingDeath = false;
     public boolean entitiesPickUpLootBypassMobGriefing = false;
     public boolean entitiesCanUsePortals = true;
+    public boolean fireballsBypassMobGriefing = false;
     public boolean milkCuresBadOmen = true;
     public boolean persistentTileEntityDisplayNames = false;
     public boolean persistentDroppableEntityDisplayNames = false;
@@ -266,6 +267,7 @@ public class PurpurWorldConfig {
         disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath);
         entitiesPickUpLootBypassMobGriefing = getBoolean("gameplay-mechanics.entities-pick-up-loot-bypass-mob-griefing", entitiesPickUpLootBypassMobGriefing);
         entitiesCanUsePortals = getBoolean("gameplay-mechanics.entities-can-use-portals", entitiesCanUsePortals);
+        fireballsBypassMobGriefing = getBoolean("gameplay-mechanics.fireballs-bypass-mob-griefing", fireballsBypassMobGriefing);
         milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen);
         persistentTileEntityDisplayNames = getBoolean("gameplay-mechanics.persistent-tileentity-display-names-and-lore", persistentTileEntityDisplayNames);
         persistentDroppableEntityDisplayNames = getBoolean("gameplay-mechanics.persistent-droppable-entity-display-names", persistentDroppableEntityDisplayNames);
@@ -418,9 +420,11 @@ public class PurpurWorldConfig {
         dispenserPlaceAnvils = getBoolean("blocks.dispenser.place-anvils", dispenserPlaceAnvils);
     }
 
+    public boolean farmlandBypassMobGriefing = false;
     public boolean farmlandGetsMoistFromBelow = false;
     public boolean farmlandAlpha = false;
     private void farmlandSettings() {
+        farmlandBypassMobGriefing = getBoolean("blocks.farmland.bypass-mob-griefing", farmlandBypassMobGriefing);
         farmlandGetsMoistFromBelow = getBoolean("blocks.farmland.gets-moist-from-below", farmlandGetsMoistFromBelow);
         farmlandAlpha = getBoolean("blocks.farmland.use-alpha-farmland", farmlandAlpha);
     }
@@ -479,10 +483,12 @@ public class PurpurWorldConfig {
         stonecutterDamage = (float) getDouble("blocks.stonecutter.damage", stonecutterDamage);
     }
 
+    public boolean turtleEggsBypassMobGriefing = false;
     public boolean turtleEggsBreakFromExpOrbs = true;
     public boolean turtleEggsBreakFromItems = true;
     public boolean turtleEggsBreakFromMinecarts = true;
     private void turtleEggSettings() {
+        turtleEggsBypassMobGriefing = getBoolean("blocks.turtle_egg.bypass-mob-griefing", turtleEggsBypassMobGriefing);
         turtleEggsBreakFromExpOrbs = getBoolean("blocks.turtle_egg.break-from-exp-orbs", turtleEggsBreakFromExpOrbs);
         turtleEggsBreakFromItems = getBoolean("blocks.turtle_egg.break-from-items", turtleEggsBreakFromItems);
         turtleEggsBreakFromMinecarts = getBoolean("blocks.turtle_egg.break-from-minecarts", turtleEggsBreakFromMinecarts);
@@ -754,12 +760,14 @@ public class PurpurWorldConfig {
     public boolean enderDragonRidableInWater = false;
     public double enderDragonMaxY = 256D;
     public boolean enderDragonAlwaysDropsFullExp = false;
+    public boolean enderDragonBypassMobGriefing = false;
     public double enderDragonMaxHealth = 200.0D;
     private void enderDragonSettings() {
         enderDragonRidable = getBoolean("mobs.ender_dragon.ridable", enderDragonRidable);
         enderDragonRidableInWater = getBoolean("mobs.ender_dragon.ridable-in-water", enderDragonRidableInWater);
         enderDragonMaxY = getDouble("mobs.ender_dragon.ridable-max-y", enderDragonMaxY);
         enderDragonAlwaysDropsFullExp = getBoolean("mobs.ender_dragon.always-drop-full-exp", enderDragonAlwaysDropsFullExp);
+        enderDragonBypassMobGriefing = getBoolean("mobs.ender_dragon.bypass-mob-griefing", enderDragonBypassMobGriefing);
         if (PurpurConfig.version < 8) {
             double oldValue = getDouble("mobs.ender_dragon.max-health", enderDragonMaxHealth);
             set("mobs.ender_dragon.max-health", null);
@@ -775,12 +783,14 @@ public class PurpurWorldConfig {
     public boolean endermanRidable = false;
     public boolean endermanRidableInWater = false;
     public boolean endermanAllowGriefing = true;
+    public boolean endermanBypassMobGriefing = false;
     public boolean endermanDespawnEvenWithBlock = false;
     public double endermanMaxHealth = 40.0D;
     private void endermanSettings() {
         endermanRidable = getBoolean("mobs.enderman.ridable", endermanRidable);
         endermanRidableInWater = getBoolean("mobs.enderman.ridable-in-water", endermanRidableInWater);
         endermanAllowGriefing = getBoolean("mobs.enderman.allow-griefing", endermanAllowGriefing);
+        endermanBypassMobGriefing = getBoolean("mobs.enderman.bypass-mob-griefing", endermanBypassMobGriefing);
         endermanDespawnEvenWithBlock = getBoolean("mobs.enderman.can-despawn-with-held-block", endermanDespawnEvenWithBlock);
         if (PurpurConfig.version < 10) {
             double oldValue = getDouble("mobs.enderman.attributes.max-health", endermanMaxHealth);
@@ -806,10 +816,12 @@ public class PurpurWorldConfig {
 
     public boolean evokerRidable = false;
     public boolean evokerRidableInWater = false;
+    public boolean evokerBypassMobGriefing = false;
     public double evokerMaxHealth = 24.0D;
     private void evokerSettings() {
         evokerRidable = getBoolean("mobs.evoker.ridable", evokerRidable);
         evokerRidableInWater = getBoolean("mobs.evoker.ridable-in-water", evokerRidableInWater);
+        evokerBypassMobGriefing = getBoolean("mobs.evoker.bypass-mob-griefing", evokerBypassMobGriefing);
         if (PurpurConfig.version < 10) {
             double oldValue = getDouble("mobs.evoker.attributes.max-health", evokerMaxHealth);
             set("mobs.evoker.attributes.max-health", null);
@@ -820,12 +832,14 @@ public class PurpurWorldConfig {
 
     public boolean foxRidable = false;
     public boolean foxRidableInWater = false;
+    public boolean foxBypassMobGriefing = false;
     public boolean foxTypeChangesWithTulips = false;
     public int foxBreedingTicks = 6000;
     public double foxMaxHealth = 10.0D;
     private void foxSettings() {
         foxRidable = getBoolean("mobs.fox.ridable", foxRidable);
         foxRidableInWater = getBoolean("mobs.fox.ridable-in-water", foxRidableInWater);
+        foxBypassMobGriefing = getBoolean("mobs.fox.bypass-mob-griefing", foxBypassMobGriefing);
         foxTypeChangesWithTulips = getBoolean("mobs.fox.tulips-change-type", foxTypeChangesWithTulips);
         foxBreedingTicks = getInt("mobs.fox.breeding-delay-ticks", foxBreedingTicks);
         if (PurpurConfig.version < 10) {
@@ -1262,10 +1276,12 @@ public class PurpurWorldConfig {
 
     public boolean pillagerRidable = false;
     public boolean pillagerRidableInWater = false;
+    public boolean pillagerBypassMobGriefing = false;
     public double pillagerMaxHealth = 24.0D;
     private void pillagerSettings() {
         pillagerRidable = getBoolean("mobs.pillager.ridable", pillagerRidable);
         pillagerRidableInWater = getBoolean("mobs.pillager.ridable-in-water", pillagerRidableInWater);
+        pillagerBypassMobGriefing = getBoolean("mobs.pillager.bypass-mob-griefing", pillagerBypassMobGriefing);
         if (PurpurConfig.version < 10) {
             double oldValue = getDouble("mobs.pillager.attributes.max-health", pillagerMaxHealth);
             set("mobs.pillager.attributes.max-health", null);
@@ -1309,6 +1325,7 @@ public class PurpurWorldConfig {
 
     public boolean rabbitRidable = false;
     public boolean rabbitRidableInWater = false;
+    public boolean rabbitBypassMobGriefing = false;
     public double rabbitNaturalToast = 0.0D;
     public double rabbitNaturalKiller = 0.0D;
     public int rabbitBreedingTicks = 6000;
@@ -1316,6 +1333,7 @@ public class PurpurWorldConfig {
     private void rabbitSettings() {
         rabbitRidable = getBoolean("mobs.rabbit.ridable", rabbitRidable);
         rabbitRidableInWater = getBoolean("mobs.rabbit.ridable-in-water", rabbitRidableInWater);
+        rabbitBypassMobGriefing = getBoolean("mobs.rabbit.bypass-mob-griefing", rabbitBypassMobGriefing);
         rabbitNaturalToast = getDouble("mobs.rabbit.spawn-toast-chance", rabbitNaturalToast);
         rabbitNaturalKiller = getDouble("mobs.rabbit.spawn-killer-rabbit-chance", rabbitNaturalKiller);
         rabbitBreedingTicks = getInt("mobs.rabbit.breeding-delay-ticks", rabbitBreedingTicks);
@@ -1329,10 +1347,12 @@ public class PurpurWorldConfig {
 
     public boolean ravagerRidable = false;
     public boolean ravagerRidableInWater = false;
+    public boolean ravagerBypassMobGriefing = false;
     public double ravagerMaxHealth = 100.0D;
     private void ravagerSettings() {
         ravagerRidable = getBoolean("mobs.ravager.ridable", ravagerRidable);
         ravagerRidableInWater = getBoolean("mobs.ravager.ridable-in-water", ravagerRidableInWater);
+        ravagerBypassMobGriefing = getBoolean("mobs.ravager.bypass-mob-griefing", ravagerBypassMobGriefing);
         if (PurpurConfig.version < 10) {
             double oldValue = getDouble("mobs.ravager.attributes.max-health", ravagerMaxHealth);
             set("mobs.ravager.attributes.max-health", null);
@@ -1356,11 +1376,13 @@ public class PurpurWorldConfig {
     public boolean sheepRidable = false;
     public boolean sheepRidableInWater = false;
     public int sheepBreedingTicks = 6000;
+    public boolean sheepBypassMobGriefing = false;
     public double sheepMaxHealth = 8.0D;
     private void sheepSettings() {
         sheepRidable = getBoolean("mobs.sheep.ridable", sheepRidable);
         sheepRidableInWater = getBoolean("mobs.sheep.ridable-in-water", sheepRidableInWater);
         sheepBreedingTicks = getInt("mobs.sheep.breeding-delay-ticks", sheepBreedingTicks);
+        sheepBypassMobGriefing = getBoolean("mobs.sheep.bypass-mob-griefing", sheepBypassMobGriefing);
         if (PurpurConfig.version < 10) {
             double oldValue = getDouble("mobs.sheep.attributes.max-health", sheepMaxHealth);
             set("mobs.sheep.attributes.max-health", null);
@@ -1385,10 +1407,12 @@ public class PurpurWorldConfig {
 
     public boolean silverfishRidable = false;
     public boolean silverfishRidableInWater = false;
+    public boolean silverfishBypassMobGriefing = false;
     public double silverfishMaxHealth = 8.0D;
     private void silverfishSettings() {
         silverfishRidable = getBoolean("mobs.silverfish.ridable", silverfishRidable);
         silverfishRidableInWater = getBoolean("mobs.silverfish.ridable-in-water", silverfishRidableInWater);
+        silverfishBypassMobGriefing = getBoolean("mobs.silverfish.bypass-mob-griefing", silverfishBypassMobGriefing);
         if (PurpurConfig.version < 10) {
             double oldValue = getDouble("mobs.silverfish.attributes.max-health", silverfishMaxHealth);
             set("mobs.silverfish.attributes.max-health", null);
@@ -1455,6 +1479,7 @@ public class PurpurWorldConfig {
     public boolean snowGolemRidable = false;
     public boolean snowGolemRidableInWater = false;
     public boolean snowGolemLeaveTrailWhenRidden = false;
+    public boolean snowGolemBypassMobGriefing = false;
     public boolean snowGolemDropsPumpkin = true;
     public boolean snowGolemPutPumpkinBack = false;
     public int snowGolemSnowBallMin = 20;
@@ -1466,6 +1491,7 @@ public class PurpurWorldConfig {
         snowGolemRidable = getBoolean("mobs.snow_golem.ridable", snowGolemRidable);
         snowGolemRidableInWater = getBoolean("mobs.snow_golem.ridable-in-water", snowGolemRidableInWater);
         snowGolemLeaveTrailWhenRidden = getBoolean("mobs.snow_golem.leave-trail-when-ridden", snowGolemLeaveTrailWhenRidden);
+        snowGolemBypassMobGriefing = getBoolean("mobs.snow_golem.bypass-mob-griefing", snowGolemBypassMobGriefing);
         snowGolemDropsPumpkin = getBoolean("mobs.snow_golem.drop-pumpkin-when-sheared", snowGolemDropsPumpkin);
         snowGolemPutPumpkinBack = getBoolean("mobs.snow_golem.pumpkin-can-be-added-back", snowGolemPutPumpkinBack);
         snowGolemSnowBallMin = getInt("mobs.snow_golem.min-shoot-interval-ticks", snowGolemSnowBallMin);
@@ -1684,6 +1710,7 @@ public class PurpurWorldConfig {
     public boolean witherRidable = false;
     public boolean witherRidableInWater = false;
     public double witherMaxY = 256D;
+    public boolean witherBypassMobGriefing = false;
     public float witherHealthRegenAmount = 1.0f;
     public int witherHealthRegenDelay = 20;
     public double witherMaxHealth = 300.0D;
@@ -1691,6 +1718,7 @@ public class PurpurWorldConfig {
         witherRidable = getBoolean("mobs.wither.ridable", witherRidable);
         witherRidableInWater = getBoolean("mobs.wither.ridable-in-water", witherRidableInWater);
         witherMaxY = getDouble("mobs.wither.ridable-max-y", witherMaxY);
+        witherBypassMobGriefing = getBoolean("mobs.wither.bypass-mob-griefing", witherBypassMobGriefing);
         witherHealthRegenAmount = (float) getDouble("mobs.wither.health-regen-amount", witherHealthRegenAmount);
         witherHealthRegenDelay = getInt("mobs.wither.health-regen-delay", witherHealthRegenDelay);
         if (PurpurConfig.version < 8) {
@@ -1763,6 +1791,7 @@ public class PurpurWorldConfig {
 
     public boolean zombieRidable = false;
     public boolean zombieRidableInWater = false;
+    public boolean zombieBypassMobGriefing = false;
     public boolean zombieJockeyOnlyBaby = true;
     public double zombieJockeyChance = 0.05D;
     public boolean zombieJockeyTryExistingChickens = true;
@@ -1773,6 +1802,7 @@ public class PurpurWorldConfig {
     private void zombieSettings() {
         zombieRidable = getBoolean("mobs.zombie.ridable", zombieRidable);
         zombieRidableInWater = getBoolean("mobs.zombie.ridable-in-water", zombieRidableInWater);
+        zombieBypassMobGriefing = getBoolean("mobs.zombie.bypass-mob-griefing", zombieBypassMobGriefing);
         zombieJockeyOnlyBaby = getBoolean("mobs.zombie.jockey.only-babies", zombieJockeyOnlyBaby);
         zombieJockeyChance = getDouble("mobs.zombie.jockey.chance", zombieJockeyChance);
         zombieJockeyTryExistingChickens = getBoolean("mobs.zombie.jockey.try-existing-chickens", zombieJockeyTryExistingChickens);
