From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: BillyGalbreath <Blake.Galbreath@GMail.com>
Date: Fri, 24 Aug 2018 08:18:42 -0500
Subject: [PATCH] Slime Pathfinder Events


diff --git a/src/main/java/net/minecraft/server/EntitySlime.java b/src/main/java/net/minecraft/server/EntitySlime.java
index 3ecf732192f7f1bd20b9d766bedef08e64434fda..2efc18df945bcaa6eba59f561733b9fd6b217d6d 100644
--- a/src/main/java/net/minecraft/server/EntitySlime.java
+++ b/src/main/java/net/minecraft/server/EntitySlime.java
@@ -3,6 +3,14 @@ package net.minecraft.server;
 import java.util.EnumSet;
 import java.util.Random;
 import javax.annotation.Nullable;
+// Paper start
+import com.destroystokyo.paper.event.entity.SlimeChangeDirectionEvent;
+import com.destroystokyo.paper.event.entity.SlimeSwimEvent;
+import com.destroystokyo.paper.event.entity.SlimeTargetLivingEntityEvent;
+import com.destroystokyo.paper.event.entity.SlimeWanderEvent;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Slime;
+// Paper end
 // CraftBukkit start
 import java.util.ArrayList;
 import java.util.List;
@@ -71,6 +79,7 @@ public class EntitySlime extends EntityInsentient implements IMonster {
         super.b(nbttagcompound);
         nbttagcompound.setInt("Size", this.getSize() - 1);
         nbttagcompound.setBoolean("wasOnGround", this.bx);
+        nbttagcompound.setBoolean("Paper.canWander", this.canWander); // Paper
     }
 
     @Override
@@ -84,6 +93,11 @@ public class EntitySlime extends EntityInsentient implements IMonster {
         this.setSize(i + 1, false);
         super.a(nbttagcompound);
         this.bx = nbttagcompound.getBoolean("wasOnGround");
+        // Paper start - check exists before loading or this will be loaded as false
+        if (nbttagcompound.hasKey("Paper.canWander")) {
+            this.canWander = nbttagcompound.getBoolean("Paper.canWander");
+        }
+        // Paper end
     }
 
     public boolean ev() {
@@ -357,7 +371,7 @@ public class EntitySlime extends EntityInsentient implements IMonster {
 
         @Override
         public boolean a() {
-            return !this.a.isPassenger();
+            return !this.a.isPassenger() && this.a.canWander && new SlimeWanderEvent((Slime) this.a.getBukkitEntity()).callEvent(); // Paper
         }
 
         @Override
@@ -378,7 +392,7 @@ public class EntitySlime extends EntityInsentient implements IMonster {
 
         @Override
         public boolean a() {
-            return (this.a.isInWater() || this.a.aH()) && this.a.getControllerMove() instanceof EntitySlime.ControllerMoveSlime;
+            return (this.a.isInWater() || this.a.aH()) && this.a.getControllerMove() instanceof EntitySlime.ControllerMoveSlime && this.a.canWander && new SlimeSwimEvent((Slime) this.a.getBukkitEntity()).callEvent(); // Paper
         }
 
         @Override
@@ -404,14 +418,18 @@ public class EntitySlime extends EntityInsentient implements IMonster {
 
         @Override
         public boolean a() {
-            return this.a.getGoalTarget() == null && (this.a.onGround || this.a.isInWater() || this.a.aH() || this.a.hasEffect(MobEffects.LEVITATION)) && this.a.getControllerMove() instanceof EntitySlime.ControllerMoveSlime;
+            return this.a.canWander && this.a.getGoalTarget() == null && (this.a.onGround || this.a.isInWater() || this.a.aH() || this.a.hasEffect(MobEffects.LEVITATION)) && this.a.getControllerMove() instanceof EntitySlime.ControllerMoveSlime;
         }
 
         @Override
         public void e() {
             if (--this.c <= 0) {
                 this.c = 40 + this.a.getRandom().nextInt(60);
-                this.b = (float) this.a.getRandom().nextInt(360);
+                // Paper start
+                SlimeChangeDirectionEvent event = new SlimeChangeDirectionEvent((Slime) this.a.getBukkitEntity(), (float) this.a.getRandom().nextInt(360));
+                if (!this.a.canWander || !event.callEvent()) return;
+                this.b = event.getNewYaw();
+                // Paper end
             }
 
             ((EntitySlime.ControllerMoveSlime) this.a.getControllerMove()).a(this.b, false);
@@ -432,7 +450,15 @@ public class EntitySlime extends EntityInsentient implements IMonster {
         public boolean a() {
             EntityLiving entityliving = this.a.getGoalTarget();
 
-            return entityliving == null ? false : (!entityliving.isAlive() ? false : (entityliving instanceof EntityHuman && ((EntityHuman) entityliving).abilities.isInvulnerable ? false : this.a.getControllerMove() instanceof EntitySlime.ControllerMoveSlime));
+            // Paper start
+            if (entityliving == null || !entityliving.isAlive()) {
+                return false;
+            }
+            if (entityliving instanceof EntityHuman && ((EntityHuman) entityliving).abilities.isInvulnerable) {
+                return false;
+            }
+            return this.a.getControllerMove() instanceof EntitySlime.ControllerMoveSlime && this.a.canWander && new SlimeTargetLivingEntityEvent((Slime) this.a.getBukkitEntity(), (LivingEntity) entityliving.getBukkitEntity()).callEvent();
+            // Paper end
         }
 
         @Override
@@ -445,7 +471,15 @@ public class EntitySlime extends EntityInsentient implements IMonster {
         public boolean b() {
             EntityLiving entityliving = this.a.getGoalTarget();
 
-            return entityliving == null ? false : (!entityliving.isAlive() ? false : (entityliving instanceof EntityHuman && ((EntityHuman) entityliving).abilities.isInvulnerable ? false : --this.b > 0));
+            // Paper start
+            if (entityliving == null || !entityliving.isAlive()) {
+                return false;
+            }
+            if (entityliving instanceof EntityHuman && ((EntityHuman) entityliving).abilities.isInvulnerable) {
+                return false;
+            }
+            return --this.b > 0 && this.a.canWander && new SlimeTargetLivingEntityEvent((Slime) this.a.getBukkitEntity(), (LivingEntity) entityliving.getBukkitEntity()).callEvent();
+            // Paper end
         }
 
         @Override
@@ -453,6 +487,13 @@ public class EntitySlime extends EntityInsentient implements IMonster {
             this.a.a((Entity) this.a.getGoalTarget(), 10.0F, 10.0F);
             ((EntitySlime.ControllerMoveSlime) this.a.getControllerMove()).a(this.a.yaw, this.a.eq());
         }
+
+        // Paper start - clear timer and target when goal resets
+        public void d() {
+            this.b = 0;
+            this.a.setGoalTarget(null);
+        }
+        // Paper end
     }
 
     static class ControllerMoveSlime extends ControllerMove {
@@ -511,4 +552,15 @@ public class EntitySlime extends EntityInsentient implements IMonster {
             }
         }
     }
+
+    // Paper start
+    private boolean canWander = true;
+    public boolean canWander() {
+        return canWander;
+    }
+
+    public void setWander(boolean canWander) {
+        this.canWander = canWander;
+    }
+    // Paper end
 }
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java
index ce6ed6e890795ff2840c800a8fd56fdc618b383a..6e9f1b66dfc12491c945f87c51e81aa02424e885 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java
@@ -35,4 +35,14 @@ public class CraftSlime extends CraftMob implements Slime {
     public EntityType getType() {
         return EntityType.SLIME;
     }
+
+    // Paper start
+    public boolean canWander() {
+        return getHandle().canWander();
+    }
+
+    public void setWander(boolean canWander) {
+        getHandle().setWander(canWander);
+    }
+    // Paper end
 }
