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/world/entity/monster/Slime.java b/src/main/java/net/minecraft/world/entity/monster/Slime.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Slime.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java
@@ -0,0 +0,0 @@ import net.minecraft.world.level.biome.Biomes;
 import net.minecraft.world.level.levelgen.WorldgenRandom;
 import net.minecraft.world.level.storage.loot.BuiltInLootTables;
 import net.minecraft.world.phys.Vec3;
+// 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;
+// Paper end
 // CraftBukkit start
 import java.util.ArrayList;
 import java.util.List;
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
     @Override
     public void addAdditionalSaveData(CompoundTag nbt) {
         super.addAdditionalSaveData(nbt);
+        nbt.putBoolean("Paper.canWander", this.canWander); // Paper
         nbt.putInt("Size", this.getSize() - 1);
         nbt.putBoolean("wasOnGround", this.wasOnGround);
     }
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
     public void readAdditionalSaveData(CompoundTag nbt) {
         this.setSize(nbt.getInt("Size") + 1, false);
         super.readAdditionalSaveData(nbt);
+        // Paper start - check exists before loading or this will be loaded as false
+        if (nbt.contains("Paper.canWander")) {
+            this.canWander = nbt.getBoolean("Paper.canWander");
+        }
+        // Paper end
         this.wasOnGround = nbt.getBoolean("wasOnGround");
     }
 
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
 
         @Override
         public boolean canUse() {
-            return (this.slime.isInWater() || this.slime.isInLava()) && this.slime.getMoveControl() instanceof Slime.SlimeMoveControl;
+            return (this.slime.isInWater() || this.slime.isInLava()) && this.slime.getMoveControl() instanceof Slime.SlimeMoveControl && this.slime.canWander && new SlimeSwimEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity()).callEvent(); // Paper
         }
 
         @Override
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
         public boolean canUse() {
             LivingEntity entityliving = this.slime.getTarget();
 
-            return entityliving == null ? false : (!this.slime.canAttack(entityliving) ? false : this.slime.getMoveControl() instanceof Slime.SlimeMoveControl);
+            // Paper start
+            if (entityliving == null || !entityliving.isAlive()) {
+                return false;
+            }
+            if (!this.slime.canAttack(entityliving)) {
+                return false;
+            }
+            return this.slime.getMoveControl() instanceof Slime.SlimeMoveControl && this.slime.canWander && new SlimeTargetLivingEntityEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), (org.bukkit.entity.LivingEntity) entityliving.getBukkitEntity()).callEvent();
+            // Paper end
         }
 
         @Override
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
         public boolean canContinueToUse() {
             LivingEntity entityliving = this.slime.getTarget();
 
-            return entityliving == null ? false : (!this.slime.canAttack(entityliving) ? false : --this.growTiredTimer > 0);
+            // Paper start
+            if (entityliving == null || !entityliving.isAlive()) {
+                return false;
+            }
+            if (!this.slime.canAttack(entityliving)) {
+                return false;
+            }
+            return --this.growTiredTimer > 0 && this.slime.canWander && new SlimeTargetLivingEntityEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), (org.bukkit.entity.LivingEntity) entityliving.getBukkitEntity()).callEvent();
+            // Paper end
         }
 
         @Override
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
 
             ((Slime.SlimeMoveControl) this.slime.getMoveControl()).setDirection(this.slime.getYRot(), this.slime.isDealsDamage());
         }
+
+        // Paper start - clear timer and target when goal resets
+        public void stop() {
+            this.growTiredTimer = 0;
+            this.slime.setTarget(null);
+        }
+        // Paper end
     }
 
     private static class SlimeRandomDirectionGoal extends Goal {
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
 
         @Override
         public boolean canUse() {
-            return this.slime.getTarget() == null && (this.slime.onGround || this.slime.isInWater() || this.slime.isInLava() || this.slime.hasEffect(MobEffects.LEVITATION)) && this.slime.getMoveControl() instanceof Slime.SlimeMoveControl;
+            return this.slime.getTarget() == null && (this.slime.onGround || this.slime.isInWater() || this.slime.isInLava() || this.slime.hasEffect(MobEffects.LEVITATION)) && this.slime.getMoveControl() instanceof Slime.SlimeMoveControl && this.slime.canWander; // Paper - add canWander
         }
 
         @Override
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
             if (--this.nextRandomizeTime <= 0) {
                 this.nextRandomizeTime = this.adjustedTickDelay(40 + this.slime.getRandom().nextInt(60));
                 this.chosenDegrees = (float) this.slime.getRandom().nextInt(360);
+                // Paper start
+                SlimeChangeDirectionEvent event = new SlimeChangeDirectionEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), this.chosenDegrees);
+                if (!this.slime.canWander || !event.callEvent()) return;
+                this.chosenDegrees = event.getNewYaw();
+                // Paper end
             }
 
             ((Slime.SlimeMoveControl) this.slime.getMoveControl()).setDirection(this.chosenDegrees, false);
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
 
         @Override
         public boolean canUse() {
-            return !this.slime.isPassenger();
+            return !this.slime.isPassenger() && this.slime.canWander && new SlimeWanderEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity()).callEvent(); // Paper
         }
 
         @Override
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
             ((Slime.SlimeMoveControl) this.slime.getMoveControl()).setWantedMovement(1.0D);
         }
     }
+
+    // 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java
@@ -0,0 +0,0 @@ public class CraftSlime extends CraftMob implements Slime {
     public EntityType getType() {
         return EntityType.SLIME;
     }
+
+    // Paper start
+    @Override
+    public boolean canWander() {
+        return getHandle().canWander();
+    }
+
+    @Override
+    public void setWander(boolean canWander) {
+        getHandle().setWander(canWander);
+    }
+    // Paper end
 }