diff --git a/.gitignore b/.gitignore
index 10eb9dd..0bf3003 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,15 +1,15 @@
-# Don't track content of these folders
-.idea/*
-target/*
-
-# Compiled source #
-###################
-*.class
-
-# Packages #
-############
-# it's better to unpack these files and commit the raw source
-# git has its own built in compression methods
-#*.7z
-#*.dmg
+# Don't track content of these folders
+.idea/*
+target/*
+
+# Compiled source #
+###################
+*.class
+
+# Packages #
+# it's better to unpack these files and commit the raw source
+############
+# git has its own built in compression methods
+#*.7z
+#*.dmg
*.jar
\ No newline at end of file
diff --git a/.idea/$PRODUCT_WORKSPACE_FILE$ b/.idea/$PRODUCT_WORKSPACE_FILE$
new file mode 100644
index 0000000..3733e0d
--- /dev/null
+++ b/.idea/$PRODUCT_WORKSPACE_FILE$
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+ 1.8
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..2d833cc
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+tamableFoxes
\ No newline at end of file
diff --git a/.idea/artifacts/TamableFoxes_SNAPSHOT_jar.xml b/.idea/artifacts/TamableFoxes_SNAPSHOT_jar.xml
deleted file mode 100644
index 77d46d5..0000000
--- a/.idea/artifacts/TamableFoxes_SNAPSHOT_jar.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
- $USER_HOME$/OneDrive/Desktop/minecraftSpigotServer/plugins
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index e106ccb..419958f 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -6,11 +6,8 @@
-
+
-
-
-
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
index bee17f4..2da6745 100644
--- a/.idea/encodings.xml
+++ b/.idea/encodings.xml
@@ -2,7 +2,5 @@
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__net_wesjd_anvilgui_1_2_1_SNAPSHOT.xml b/.idea/libraries/Maven__net_wesjd_anvilgui_1_2_1_SNAPSHOT.xml
deleted file mode 100644
index 08ed1c0..0000000
--- a/.idea/libraries/Maven__net_wesjd_anvilgui_1_2_1_SNAPSHOT.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_spigotmc_spigot_1_14_4_R0_1_SNAPSHOT.xml b/.idea/libraries/Maven__org_spigotmc_spigot_1_14_4_R0_1_SNAPSHOT.xml
deleted file mode 100644
index ce394c9..0000000
--- a/.idea/libraries/Maven__org_spigotmc_spigot_1_14_4_R0_1_SNAPSHOT.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 6fb7c97..f10f358 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,10 +1,6 @@
-
-
-
-
-
+
@@ -12,7 +8,7 @@
-
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index 6b3344f..0000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
deleted file mode 100644
index b93ac08..0000000
--- a/.idea/uiDesigner.xml
+++ /dev/null
@@ -1,124 +0,0 @@
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
- -
-
-
- -
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 5a0ff9a..66b4bf5 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -1,262 +1,139 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1559787286537
-
-
- 1559787286537
-
-
-
-
-
-
-
-
- jar://$MAVEN_REPOSITORY$/org/spigotmc/spigot/1.14.2-R0.1-SNAPSHOT/spigot-1.14.2-R0.1-SNAPSHOT.jar!/net/minecraft/server/v1_14_R1/PathfinderGoalWrapped.class
- 17
-
-
-
-
-
-
-
-
-
-
-
-
- var1 == null
- JAVA
- EXPRESSION
-
-
- this.a == null
- JAVA
- EXPRESSION
-
-
- this.targetSelector.a == null
- JAVA
- EXPRESSION
-
-
- this.a
- JAVA
- EXPRESSION
-
-
- null
- JAVA
- EXPRESSION
-
-
-
-
-
-
-
-
- false
-
- TamableFoxes-SNAPSHOT:jar
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- TamableFoxes
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1579293785651
+
+
+ 1579293785651
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/1.14 TRANS.xlsx b/1.14 TRANS.xlsx
new file mode 100644
index 0000000..13163dd
Binary files /dev/null and b/1.14 TRANS.xlsx differ
diff --git a/TamableFoxes.iml b/TamableFoxes.iml
deleted file mode 100644
index 2718c32..0000000
--- a/TamableFoxes.iml
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-
- SPIGOT
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/lib/spigot-1.15.1.jar b/lib/spigot-1.15.1.jar
new file mode 100644
index 0000000..5b1bd75
Binary files /dev/null and b/lib/spigot-1.15.1.jar differ
diff --git a/pom.xml b/pom.xml
index fa38b7b..c9b3965 100644
--- a/pom.xml
+++ b/pom.xml
@@ -72,8 +72,8 @@
org.spigotmc
- spigot
- 1.14.4-R0.1-SNAPSHOT
+ spigot-api
+ 1.15.1-R0.1-SNAPSHOT
provided
@@ -81,5 +81,12 @@
anvilgui
1.2.1-SNAPSHOT
+
+
+ org.spigotmc
+ spigot
+ system
+ ${project.basedir}/lib/spigot-1.15.1.jar
+
diff --git a/src/main/java/net/seanomik/tamablefoxes/Commands/CommandSpawnTamableFox.java b/src/main/java/net/seanomik/tamablefoxes/Commands/CommandSpawnTamableFox.java
deleted file mode 100644
index 6386e6d..0000000
--- a/src/main/java/net/seanomik/tamablefoxes/Commands/CommandSpawnTamableFox.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package net.seanomik.tamablefoxes.Commands;
-
-import net.minecraft.server.v1_14_R1.EntityFox;
-import net.seanomik.tamablefoxes.Reference;
-import net.seanomik.tamablefoxes.TamableFoxes;
-import org.bukkit.ChatColor;
-import org.bukkit.Material;
-import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
-import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.meta.ItemMeta;
-
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
-
-public class CommandSpawnTamableFox implements CommandExecutor {
-
- private TamableFoxes plugin = TamableFoxes.getPlugin(TamableFoxes.class);
-
- @Override
- public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
- if (sender instanceof Player) {
- Player player = (Player) sender;
- TamableFoxes plugin = TamableFoxes.getPlugin(TamableFoxes.class);
-
- if (player.hasPermission("tamableFoxes.spawntamablefox")) {
- if (args.length != 0) {
- if (args[0].equals("snow")) {
- plugin.spawnTamableFox(player.getLocation(), EntityFox.Type.SNOW);
- player.sendMessage("Spawned snow fox.");
- } else if (args[0].equals("verbose")) {
- player.sendMessage(TamableFoxes.foxUUIDs.toString());
- } else if (args[0].equals("inspect")) {
- ItemStack itemStack = new ItemStack(Material.REDSTONE_TORCH, 1);
- ItemMeta itemMeta = itemStack.getItemMeta();
- List lore = new LinkedList<>(Arrays.asList(
- ChatColor.BLUE + "Tamable Fox Inspector"
- ));
-
- itemMeta.setLore(lore);
- itemStack.setItemMeta(itemMeta);
- if (player.getInventory().getItemInMainHand().getType() == Material.AIR) {
- player.getInventory().setItemInMainHand(itemStack);
- player.sendMessage(Reference.CHAT_PREFIX + ChatColor.GREEN + "Given item.");
- } else {
- if (player.getInventory().firstEmpty() == -1) {
- player.sendMessage(Reference.CHAT_PREFIX + ChatColor.RED + "Inventory is full!");
- } else {
- player.sendMessage(Reference.CHAT_PREFIX + ChatColor.GREEN + "Added item to inventory.");
- player.getInventory().addItem(itemStack);
- }
- }
-
- //player.sendMessage(TamableFoxes.foxUUIDs.toString());
- }
- } else {
- plugin.spawnTamableFox(player.getLocation(), EntityFox.Type.RED);
- player.sendMessage("Spawned red fox.");
- }
- } else {
- player.sendMessage(ChatColor.RED + "You do not have the permission for this command.");
- }
- }
-
- return true;
- }
-}
\ No newline at end of file
diff --git a/src/main/java/net/seanomik/tamablefoxes/ConfigManager.java b/src/main/java/net/seanomik/tamablefoxes/ConfigManager.java
deleted file mode 100644
index bf4589f..0000000
--- a/src/main/java/net/seanomik/tamablefoxes/ConfigManager.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package net.seanomik.tamablefoxes;
-
-import org.bukkit.Bukkit;
-import org.bukkit.ChatColor;
-import org.bukkit.configuration.file.FileConfiguration;
-import org.bukkit.configuration.file.YamlConfiguration;
-
-import java.io.File;
-import java.io.IOException;
-
-public class ConfigManager {
- private TamableFoxes plugin = TamableFoxes.getPlugin(TamableFoxes.class);
-
- //Files and File Configs Here
- public FileConfiguration foxesSave;
- public File foxesfile;
-
- public void setup() {
- if (!plugin.getDataFolder().exists()) {
- plugin.getDataFolder().mkdir();
- }
-
- foxesfile = new File(plugin.getDataFolder(), "Foxes.yml");
-
- if (!foxesfile.exists()) {
- try {
- foxesfile.createNewFile();
- } catch (IOException e) {
- Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.RED + "Could not create the Foxes.yml file!");
- }
- }
-
- foxesSave = YamlConfiguration.loadConfiguration(foxesfile);
- Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.GREEN + "The Foxes.yml file has been created successfully!");
- }
-
- public FileConfiguration getFoxes() {
- return foxesSave;
- }
-
- public void saveFoxes() {
- try {
- foxesSave.save(foxesfile);
- Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.AQUA + "The Foxes.yml file has been saved successfully!");
- } catch (IOException e) {
- Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.RED + "Could not save the Foxes.yml file!");
- }
- }
-
- public void reloadFoxes() {
- foxesSave = YamlConfiguration.loadConfiguration(foxesfile);
- Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.BLUE + "The Foxes.yml file has been reloaded successfully!");
- }
-}
diff --git a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalBeg.java b/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalBeg.java
deleted file mode 100644
index 9936f61..0000000
--- a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalBeg.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package net.seanomik.tamablefoxes.CustomPathfinding;
-
-import net.minecraft.server.v1_14_R1.*;
-import net.seanomik.tamablefoxes.TamableFox;
-
-import java.util.EnumSet;
-
-public class FoxPathfinderGoalBeg extends PathfinderGoal {
- private final EntityFox a;
- private final TamableFox z;
- private EntityHuman b;
- private final World c;
- private final float d;
- private int e;
- private final PathfinderTargetCondition f;
-
- public FoxPathfinderGoalBeg(TamableFox tamableFox, float var1) {
- this.a = tamableFox;
- this.c = tamableFox.world;
- this.d = var1;
- this.f = (new PathfinderTargetCondition()).a((double)var1).a().b().d();
- this.a(EnumSet.of(Type.LOOK));
- this.z = tamableFox;
- }
-
- public boolean a() {
- this.b = this.c.a(this.f, this.a);
- return this.b == null ? false : this.a(this.b);
- }
-
- public boolean b() {
- if (!this.b.isAlive()) {
- return false;
- } else if (this.a.h(this.b) > (double)(this.d * this.d)) {
- return false;
- } else {
- return this.e > 0 && this.a(this.b);
- }
- }
-
- /*public void c() {
- ((EntityFox)this.a).v(true);
- this.e = 40 + this.a.getRandom().nextInt(40);
- }
-
- public void d() {
- this.a.v(false);
- this.b = null;
- }*/
-
- public void e() {
- this.a.getControllerLook().a(this.b.locX, this.b.locY + (double)this.b.getHeadHeight(), this.b.locZ, 10.0F, (float)this.a.M());
- --this.e;
- }
-
- private boolean a(EntityHuman var0) {
- EnumHand[] var2 = EnumHand.values();
- int var3 = var2.length;
-
- for(int var4 = 0; var4 < var3; ++var4) {
- if (this.z.isTamed() && var0.getItemInMainHand().getItem() == Items.SWEET_BERRIES) { //var5.getItem() == Items.SWEET_BERRIES) {
- return true;
- }
-
- if (this.a.i(var0.getItemInMainHand())) {
- return true;
- }
- }
-
- return false;
- }
-}
diff --git a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalBreed.java b/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalBreed.java
deleted file mode 100644
index 8788698..0000000
--- a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalBreed.java
+++ /dev/null
@@ -1,132 +0,0 @@
-package net.seanomik.tamablefoxes.CustomPathfinding;
-
-import net.minecraft.server.v1_14_R1.*;
-import net.seanomik.tamablefoxes.TamableFox;
-import net.seanomik.tamablefoxes.TamableFoxes;
-import org.bukkit.Bukkit;
-import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer;
-import org.bukkit.craftbukkit.v1_14_R1.event.CraftEventFactory;
-import org.bukkit.event.entity.CreatureSpawnEvent;
-import org.bukkit.event.entity.EntityBreedEvent;
-
-import javax.annotation.Nullable;
-import java.util.EnumSet;
-import java.util.Iterator;
-import java.util.List;
-
-public class FoxPathfinderGoalBreed extends PathfinderGoal {
- private static final PathfinderTargetCondition d = (new PathfinderTargetCondition()).a(8.0D).a().b().c();
- protected final TamableFox animal;
- private final Class extends EntityAnimal> e;
- protected final World b;
- protected EntityAnimal partner;
- private int f;
- private final double g;
-
- public FoxPathfinderGoalBreed(TamableFox entityanimal, double d0) {
- this(entityanimal, d0, entityanimal.getClass());
- }
-
- public FoxPathfinderGoalBreed(TamableFox entityanimal, double d0, Class extends EntityAnimal> oclass) {
- this.animal = entityanimal;
- this.b = entityanimal.world;
- this.e = oclass;
- this.g = d0;
- this.a(EnumSet.of(Type.MOVE, Type.LOOK));
- }
-
- public boolean a() {
- if (!this.animal.isInLove()) {
- return false;
- } else {
- this.partner = this.h();
- return this.partner != null;
- }
- }
-
- public boolean b() {
- return this.partner.isAlive() && this.partner.isInLove() && this.f < 60;
- }
-
- public void d() {
- this.partner = null;
- this.f = 0;
- }
-
- public void e() {
- this.animal.getControllerLook().a(this.partner, 10.0F, (float)this.animal.M());
- this.animal.getNavigation().a(this.partner, this.g);
- ++this.f;
- if (this.f >= 60 && this.animal.h(this.partner) < 9.0D) {
- this.g();
- }
-
- }
-
- @Nullable
- private EntityAnimal h() {
- List list = this.b.a(this.e, d, this.animal, this.animal.getBoundingBox().g(8.0D));
- double d0 = 1.7976931348623157E308D;
- EntityAnimal entityanimal = null;
- Iterator iterator = list.iterator();
-
- while(iterator.hasNext()) {
- EntityAnimal entityanimal1 = (EntityAnimal)iterator.next();
- if (this.animal.mate(entityanimal1) && this.animal.h(entityanimal1) < d0) {
- entityanimal = entityanimal1;
- d0 = this.animal.h(entityanimal1);
- }
- }
-
- return entityanimal;
- }
-
- protected void g() {
- EntityAgeable entityageable = this.animal.createChild(animal);
- TamableFox tamableFoxAgeable = (TamableFox) entityageable.getBukkitEntity().getHandle();
-
- if (entityageable != null) {
- if (entityageable instanceof EntityTameableAnimal && ((EntityTameableAnimal)entityageable).isTamed()) {
- entityageable.persistent = true;
- }
-
- EntityPlayer entityplayer = this.animal.getBreedCause();
- if (entityplayer == null && this.partner.getBreedCause() != null) {
- entityplayer = this.partner.getBreedCause();
- }
-
- int experience = this.animal.getRandom().nextInt(7) + 1;
- EntityBreedEvent entityBreedEvent = CraftEventFactory.callEntityBreedEvent(entityageable, this.animal, this.partner, entityplayer, this.animal.breedItem, experience);
- if (entityBreedEvent.isCancelled()) {
- return;
- }
-
- experience = entityBreedEvent.getExperience();
- if (entityplayer != null) {
- entityplayer.a(StatisticList.ANIMALS_BRED);
- CriterionTriggers.o.a(entityplayer, this.animal, this.partner, entityageable);
- }
-
- this.animal.setAgeRaw(6000);
- this.partner.setAgeRaw(6000);
- this.animal.resetLove();
- this.partner.resetLove();
- entityageable.setAgeRaw(-24000);
- entityageable.setPositionRotation(this.animal.locX, this.animal.locY, this.animal.locZ, 0.0F, 0.0F);
- this.b.addEntity(entityageable, CreatureSpawnEvent.SpawnReason.BREEDING);
- this.b.broadcastEntityEffect(this.animal, (byte)18);
-
- TamableFox tamableFoxBaby = (TamableFox) entityageable;
- tamableFoxBaby.setTamed(true);
- tamableFoxBaby.setOwner(entityplayer);
-
- // Add fox to foxUUIDs to get their owner and other things
- TamableFoxes.foxUUIDs.replace(tamableFoxBaby.getUniqueID(), null, entityplayer.getUniqueID());
-
- if (this.b.getGameRules().getBoolean(GameRules.DO_MOB_LOOT) && experience > 0) {
- this.b.addEntity(new EntityExperienceOrb(this.b, this.animal.locX, this.animal.locY, this.animal.locZ, experience));
- }
- }
-
- }
-}
diff --git a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalFleeSun.java b/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalFleeSun.java
deleted file mode 100644
index c0dd4a5..0000000
--- a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalFleeSun.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package net.seanomik.tamablefoxes.CustomPathfinding;
-
-import net.minecraft.server.v1_14_R1.BlockPosition;
-import net.minecraft.server.v1_14_R1.PathfinderGoalFleeSun;
-import net.minecraft.server.v1_14_R1.WorldServer;
-import net.seanomik.tamablefoxes.TamableFox;
-import org.bukkit.Bukkit;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-public class FoxPathfinderGoalFleeSun extends PathfinderGoalFleeSun {
- private int c = 100;
- protected TamableFox tamableFox;
-
- public FoxPathfinderGoalFleeSun(TamableFox tamableFox, double d0) {
- super(tamableFox, d0);
- this.tamableFox = tamableFox;
- }
-
- public boolean a() {
- if (tamableFox.isTamed()) {
- return false;
- } else if (!tamableFox.isSleeping() && this.a.getGoalTarget() == null) {
- if (tamableFox.world.U()) {
- return true;
- } else if (this.c > 0) {
- --this.c;
- return false;
- } else {
- this.c = 100;
- BlockPosition blockposition = new BlockPosition(this.a);
- return tamableFox.world.J() && tamableFox.world.f(blockposition) && !((WorldServer)tamableFox.world).b_(blockposition) && this.g();
- }
- } else {
- return false;
- }
- }
-
- public void c() {
- try {
- Class> entityFoxClass = Class.forName("net.minecraft.server.v1_14_R1.EntityFox");
- Method method = entityFoxClass.getDeclaredMethod("en");
- method.setAccessible(true);
- method.invoke(tamableFox);
- method.setAccessible(false);
- } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | ClassNotFoundException e) {
- e.printStackTrace();
- }
- super.c();
- }
-}
diff --git a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalFloat.java b/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalFloat.java
deleted file mode 100644
index 5512bdf..0000000
--- a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalFloat.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package net.seanomik.tamablefoxes.CustomPathfinding;
-
-import net.minecraft.server.v1_14_R1.EntityFox;
-import net.minecraft.server.v1_14_R1.PathfinderGoalFloat;
-import net.seanomik.tamablefoxes.TamableFox;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-public class FoxPathfinderGoalFloat extends PathfinderGoalFloat {
- protected TamableFox tamableFox;
- public FoxPathfinderGoalFloat(TamableFox tamableFox) {
- super(tamableFox);
- this.tamableFox = tamableFox;
- }
-
- public void c() {
- try {
- super.c();
- Method method = tamableFox.getClass().getSuperclass().getDeclaredMethod("en");
- method.setAccessible(true);
- method.invoke(tamableFox);
- method.setAccessible(false);
- } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
- e.printStackTrace();
- }
- //tamableFox.en();
- }
-
- public boolean a() {
- return tamableFox.isInWater() && tamableFox.cf() > 0.25D || tamableFox.aD();
- }
-}
diff --git a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalLunge.java b/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalLunge.java
deleted file mode 100644
index 237e3f0..0000000
--- a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalLunge.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package net.seanomik.tamablefoxes.CustomPathfinding;
-
-import net.minecraft.server.v1_14_R1.*;
-import net.seanomik.tamablefoxes.TamableFox;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-public class FoxPathfinderGoalLunge extends PathfinderGoalWaterJumpAbstract {
- protected TamableFox tamableFox;
-
- public FoxPathfinderGoalLunge(TamableFox tamableFox) {
- this.tamableFox = tamableFox;
- }
-
- public boolean a() {
- if (!tamableFox.ee()) {
- return false;
- } else {
- EntityLiving entityliving = tamableFox.getGoalTarget();
- if (entityliving != null && entityliving.isAlive()) {
- if (entityliving.getAdjustedDirection() != entityliving.getDirection()) {
- return false;
- } else {
- boolean flag = EntityFox.a((EntityFox)tamableFox, (EntityLiving)entityliving);
- if (!flag) {
- tamableFox.getNavigation().a(entityliving, 0);
- tamableFox.setCrouching(false);
- tamableFox.u(false);
- }
-
- return flag;
- }
- } else {
- return false;
- }
- }
- }
-
- public boolean b() {
- EntityLiving entityliving = tamableFox.getGoalTarget();
- if (entityliving != null && entityliving.isAlive()) {
- double d0 = tamableFox.getMot().y;
- return (d0 * d0 >= 0.05000000074505806D || Math.abs(tamableFox.pitch) >= 15.0F || !tamableFox.onGround) && !tamableFox.dX();
- } else {
- return false;
- }
- }
-
- public boolean C_() {
- return false;
- }
-
- public void c() {
- tamableFox.setJumping(true);
- tamableFox.s(true);
- tamableFox.u(false);
- EntityLiving entityliving = tamableFox.getGoalTarget();
- tamableFox.getControllerLook().a(entityliving, 60.0F, 30.0F);
- Vec3D vec3d = (new Vec3D(entityliving.locX - tamableFox.locX, entityliving.locY - tamableFox.locY, entityliving.locZ - tamableFox.locZ)).d();
- tamableFox.setMot(tamableFox.getMot().add(vec3d.x * 0.8D, 0.9D, vec3d.z * 0.8D));
- tamableFox.getNavigation().o();
- }
-
- public void d() {
- tamableFox.setCrouching(false);
- try {
- Class> entityFoxClass = Class.forName("net.minecraft.server.v1_14_R1.EntityFox");
- Field field = entityFoxClass.getDeclaredField("bN");
- field.setAccessible(true);
- field.set(tamableFox, 0.0F);
- field.setAccessible(false);
-
- field = entityFoxClass.getDeclaredField("bO");
- field.setAccessible(true);
- field.set(tamableFox, 0);
- field.setAccessible(false);
- /*tamableFox.bN = 0.0F;
- tamableFox.bO = 0.0F;*/
- } catch (NoSuchFieldException | IllegalAccessException | ClassNotFoundException e) {
- e.printStackTrace();
- }
-
- tamableFox.u(false);
- tamableFox.s(false);
- }
-
- public void e() {
- EntityLiving entityliving = tamableFox.getGoalTarget();
- if (entityliving != null) {
- tamableFox.getControllerLook().a(entityliving, 60.0F, 30.0F);
- }
-
- if (!tamableFox.dX()) {
- Vec3D vec3d = tamableFox.getMot();
- if (vec3d.y * vec3d.y < 0.029999999329447746D && tamableFox.pitch != 0.0F) {
- tamableFox.pitch = this.a(tamableFox.pitch, 0.0F, 0.2F);
- } else {
- double d0 = Math.sqrt(Entity.b(vec3d));
- double d1 = Math.signum(-vec3d.y) * Math.acos(d0 / vec3d.f()) * 57.2957763671875D;
- tamableFox.pitch = (float)d1;
- }
- }
-
- if (entityliving != null && tamableFox.g(entityliving) <= 2.0F) {
- tamableFox.C(entityliving);
- } else if (tamableFox.pitch > 0.0F && tamableFox.onGround && (float)tamableFox.getMot().y != 0.0F && tamableFox.world.getType(new BlockPosition(tamableFox)).getBlock() == Blocks.SNOW) {
- tamableFox.pitch = 60.0F;
- tamableFox.setGoalTarget((EntityLiving)null);
-
- try {
- Class> entityFoxClass = Class.forName("net.minecraft.server.v1_14_R1.EntityFox");
- Method method = entityFoxClass.getDeclaredMethod("v");
- method.setAccessible(true);
- method.invoke(tamableFox, true);
- method.setAccessible(false);
- } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | ClassNotFoundException e) {
- e.printStackTrace();
- }
- //tamableFox.v(true);
- }
-
- }
-}
diff --git a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalLungeUNKNOWN_USE.java b/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalLungeUNKNOWN_USE.java
deleted file mode 100644
index ee84314..0000000
--- a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalLungeUNKNOWN_USE.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package net.seanomik.tamablefoxes.CustomPathfinding;
-
-import net.minecraft.server.v1_14_R1.*;
-import net.seanomik.tamablefoxes.TamableFox;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.EnumSet;
-import java.util.function.Predicate;
-
-public class FoxPathfinderGoalLungeUNKNOWN_USE extends PathfinderGoal {
- protected TamableFox tamableFox;
-
- public FoxPathfinderGoalLungeUNKNOWN_USE(TamableFox tamableFox) {
- this.a(EnumSet.of(net.minecraft.server.v1_14_R1.PathfinderGoal.Type.MOVE, net.minecraft.server.v1_14_R1.PathfinderGoal.Type.LOOK));
- this.tamableFox = tamableFox;
- }
-
- public boolean a() {
- if (tamableFox.isSleeping()) {
- return false;
- } else {
- EntityLiving entityliving = tamableFox.getGoalTarget();
-
- try {
- Class> entityFoxClass = Class.forName("net.minecraft.server.v1_14_R1.EntityFox");
- Field field = entityFoxClass.getDeclaredField("bG");
- field.setAccessible(true);
- Predicate bG = (Predicate) field.get(tamableFox);
- field.setAccessible(false);
-
- return entityliving != null && entityliving.isAlive() && bG.test(entityliving) && tamableFox.h(entityliving) > 36.0D && !tamableFox.isCrouching() && !tamableFox.eg() && !tamableFox.isJumping();
- } catch (IllegalAccessException | ClassNotFoundException | NoSuchFieldException e) {
- e.printStackTrace();
- }
-
- throw new NullPointerException();
- }
- }
-
- public void c() {
- tamableFox.setSitting(false);
- try {
- Method method = tamableFox.getClass().getSuperclass().getDeclaredMethod("v", boolean.class);
- method.setAccessible(true);
- method.invoke(tamableFox, false);
- method.setAccessible(false);
- } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
- e.printStackTrace();
- }
- }
-
- public void d() {
- EntityLiving entityliving = tamableFox.getGoalTarget();
- if (entityliving != null && EntityFox.a((EntityFox)tamableFox, (EntityLiving)entityliving)) {
- tamableFox.u(true);
- tamableFox.setCrouching(true);
- tamableFox.getNavigation().o();
- tamableFox.getControllerLook().a(entityliving, (float)tamableFox.dA(), (float)tamableFox.M());
- } else {
- tamableFox.u(false);
- tamableFox.setCrouching(false);
- }
-
- }
-
- public void e() {
- EntityLiving entityliving = tamableFox.getGoalTarget();
- tamableFox.getControllerLook().a(entityliving, (float)tamableFox.dA(), (float)tamableFox.M());
- if (tamableFox.h(entityliving) <= 36.0D) {
- tamableFox.u(true);
- tamableFox.setCrouching(true);
- tamableFox.getNavigation().o();
- } else {
- tamableFox.getNavigation().a(entityliving, 1.5D);
- }
-
- }
-}
diff --git a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalMeleeAttack.java b/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalMeleeAttack.java
deleted file mode 100644
index 86597fd..0000000
--- a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalMeleeAttack.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package net.seanomik.tamablefoxes.CustomPathfinding;
-
-import net.minecraft.server.v1_14_R1.EntityLiving;
-import net.minecraft.server.v1_14_R1.PathfinderGoalMeleeAttack;
-import net.minecraft.server.v1_14_R1.SoundEffects;
-import net.seanomik.tamablefoxes.TamableFox;
-
-public class FoxPathfinderGoalMeleeAttack extends PathfinderGoalMeleeAttack {
- protected TamableFox tamableFox;
- public FoxPathfinderGoalMeleeAttack(TamableFox tamableFox, double d0, boolean flag) {
- super(tamableFox, d0, flag);
- this.tamableFox = tamableFox;
- }
-
- protected void a(EntityLiving entityliving, double d0) {
- double d1 = this.a(entityliving);
- if (d0 <= d1 && this.b <= 0) {
- this.b = 20;
- this.a.C(entityliving);
- tamableFox.a(SoundEffects.ENTITY_FOX_BITE, 1.0F, 1.0F);
- }
-
- }
-
- public void c() {
- tamableFox.u(false);
- super.c();
- }
-
- public boolean a() {
- return !tamableFox.isSitting() && !tamableFox.isSleeping() && !tamableFox.isCrouching() && !tamableFox.dX() && super.a();
- }
-}
diff --git a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalOwnerHurtTarget.java b/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalOwnerHurtTarget.java
deleted file mode 100644
index a3ce86a..0000000
--- a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalOwnerHurtTarget.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package net.seanomik.tamablefoxes.CustomPathfinding;
-
-import net.minecraft.server.v1_14_R1.*;
-import net.seanomik.tamablefoxes.TamableFox;
-import org.bukkit.event.entity.EntityTargetEvent;
-
-import java.util.EnumSet;
-
-public class FoxPathfinderGoalOwnerHurtTarget extends PathfinderGoalTarget {
- private final TamableFox a;
- private EntityLiving b;
- private int c;
-
- public FoxPathfinderGoalOwnerHurtTarget(TamableFox tamableFox) {
- super(tamableFox, false);
- this.a = tamableFox;
- this.a(EnumSet.of(Type.TARGET));
- }
-
- public boolean a() {
- if (this.a.isTamed() && !this.a.isSitting()) {
- EntityLiving entityliving = this.a.getOwner();
- if (entityliving == null) {
- return false;
- } else {
- this.b = entityliving.cu();
- int i = entityliving.cv();
- return i != this.c && this.a(this.b, PathfinderTargetCondition.a);// && this.a.a(this.b, entityliving);
- }
- } else {
- return false;
- }
- }
-
- public void c() {
- this.e.setGoalTarget(this.b, EntityTargetEvent.TargetReason.OWNER_ATTACKED_TARGET, true);
- EntityLiving entityliving = this.a.getOwner();
- if (entityliving != null) {
- this.c = entityliving.cv();
- }
-
- super.c();
- }
-}
\ No newline at end of file
diff --git a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalPickBushes.java b/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalPickBushes.java
deleted file mode 100644
index 1ab4676..0000000
--- a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalPickBushes.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package net.seanomik.tamablefoxes.CustomPathfinding;
-
-import net.minecraft.server.v1_14_R1.*;
-import net.seanomik.tamablefoxes.TamableFox;
-import org.bukkit.craftbukkit.v1_14_R1.event.CraftEventFactory;
-
-import java.util.Random;
-
-public class FoxPathfinderGoalPickBushes extends PathfinderGoalGotoTarget {
- protected int g;
- protected TamableFox tamableFox;
-
- public FoxPathfinderGoalPickBushes(TamableFox tamableFox, double d0, int i, int j) {
- super(tamableFox, d0, i, j);
- this.tamableFox = tamableFox;
- }
-
- public double h() {
- return 2.0D;
- }
-
- public boolean j() {
- return this.d % 100 == 0;
- }
-
- protected boolean a(IWorldReader iworldreader, BlockPosition blockposition) {
- if (!tamableFox.isTamed()) {
- IBlockData iblockdata = iworldreader.getType(blockposition);
- return iblockdata.getBlock() == Blocks.SWEET_BERRY_BUSH && (Integer) iblockdata.get(BlockSweetBerryBush.a) >= 2;
- }
- return false;
- }
-
- public void e() {
- if (this.k()) {
- if (this.g >= 40) {
- this.m();
- } else {
- ++this.g;
- }
- //} else if (!this.k() && tamableFox.getRandom().nextFloat() < 0.05F && !tamableFox.isTamed()) {
- } else if (!this.k() && tamableFox.getRandom().nextFloat() < 0.05F && !tamableFox.isTamed()) {
- tamableFox.a(SoundEffects.ENTITY_FOX_SNIFF, 1.0F, 1.0F);
- }
-
- super.e();
- }
-
- protected void m() {
- if (tamableFox.world.getGameRules().getBoolean(GameRules.DO_MOB_LOOT) && !tamableFox.isTamed()) {
- IBlockData iblockdata = tamableFox.world.getType(this.e);
- if (iblockdata.getBlock() == Blocks.SWEET_BERRY_BUSH) {
- int i = (Integer)iblockdata.get(BlockSweetBerryBush.a);
- iblockdata.set(BlockSweetBerryBush.a, 1);
- if (CraftEventFactory.callEntityChangeBlockEvent(tamableFox, this.e, (IBlockData)iblockdata.set(BlockSweetBerryBush.a, 1)).isCancelled()) {
- return;
- }
-
- int j = 1 + tamableFox.world.random.nextInt(2) + (i == 3 ? 1 : 0);
- ItemStack itemstack = tamableFox.getEquipment(EnumItemSlot.MAINHAND);
- if (itemstack.isEmpty()) {
- tamableFox.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.SWEET_BERRIES));
- --j;
- }
-
- if (j > 0) {
- Block.a(tamableFox.world, this.e, new ItemStack(Items.SWEET_BERRIES, j));
- }
-
- tamableFox.a(SoundEffects.ITEM_SWEET_BERRIES_PICK_FROM_BUSH, 1.0F, 1.0F);
- tamableFox.world.setTypeAndData(this.e, (IBlockData)iblockdata.set(BlockSweetBerryBush.a, 1), 2);
- }
- }
-
- }
-
- public boolean a() {
- return !tamableFox.isSleeping() && super.a();
- }
-
- public void c() {
- this.g = 0;
- tamableFox.setSitting(false);
- super.c();
- }
-}
\ No newline at end of file
diff --git a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalRandomStrollLand.java b/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalRandomStrollLand.java
deleted file mode 100644
index 30a1b05..0000000
--- a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalRandomStrollLand.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package net.seanomik.tamablefoxes.CustomPathfinding;
-
-import net.minecraft.server.v1_14_R1.EntityCreature;
-import net.minecraft.server.v1_14_R1.PathfinderGoalRandomStroll;
-import net.minecraft.server.v1_14_R1.RandomPositionGenerator;
-import net.minecraft.server.v1_14_R1.Vec3D;
-import net.seanomik.tamablefoxes.TamableFox;
-import org.bukkit.Bukkit;
-
-import javax.annotation.Nullable;
-
-public class FoxPathfinderGoalRandomStrollLand extends PathfinderGoalRandomStroll {
- protected final float h;
- protected TamableFox tamableFox;
- protected Vec3D vec3D;
-
- public FoxPathfinderGoalRandomStrollLand(TamableFox var0, double var1) {
- this(var0, var1, 0.001F);
- this.tamableFox = var0;
- }
-
- public FoxPathfinderGoalRandomStrollLand(TamableFox var0, double var1, float var3) {
- super(var0, var1);
- this.h = var3;
- this.tamableFox = var0;
- }
-
- @Override
- public boolean a() {
- if (this.a.isVehicle()) {
- return false;
- } else {
- if (!this.g) {
- if (this.a.cw() >= 100) {
- return false;
- }
-
- if (this.a.getRandom().nextInt(this.f) != 0) {
- return false;
- }
- }
-
- if (!tamableFox.isSitting()) {
- vec3D = this.g();
- }
- if (vec3D == null) {
- return false;
- } else {
- this.b = vec3D.x;
- this.c = vec3D.y;
- this.d = vec3D.z;
- this.g = false;
- return true;
- }
- }
- }
-
- @Nullable
- protected Vec3D g() {
- if (this.a.av()) {
- Vec3D var0 = RandomPositionGenerator.b(this.a, 15, 7);
- return var0 == null ? super.g() : var0;
- } else {
- return this.a.getRandom().nextFloat() >= this.h ? RandomPositionGenerator.b(this.a, 10, 7) : super.g();
- }
- }
-
- @Override
- public boolean b() {
- /*Bukkit.broadcastMessage("B: " + !this.a.getNavigation().n());
- if (tamableFox.isSitting()) {
-
- }
-
- return false;*/
- return !this.a.getNavigation().n();
- }
-
- @Override
- public void c() {
- this.a.getNavigation().a(this.b, this.c, this.d, this.e);
- }
-
- @Override
- public void h() {
- this.g = true;
- }
-
- @Override
- public void setTimeBetweenMovement(int var0) {
- this.f = var0;
- }
-
- @Override
- public void e() {
- if (tamableFox.isSitting()) {
- vec3D = null;
- }
- }
-
- @Override
- public boolean C_() {
- if (tamableFox.isSitting()) {
- vec3D = null;
- return false;
- }
- return true;
- }
-}
diff --git a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalRandomTargetNonTamed.java b/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalRandomTargetNonTamed.java
deleted file mode 100644
index 591de82..0000000
--- a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalRandomTargetNonTamed.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package net.seanomik.tamablefoxes.CustomPathfinding;
-
-import net.minecraft.server.v1_14_R1.EntityLiving;
-import net.minecraft.server.v1_14_R1.PathfinderGoalNearestAttackableTarget;
-import net.seanomik.tamablefoxes.TamableFox;
-
-import javax.annotation.Nullable;
-import java.util.function.Predicate;
-
-public class FoxPathfinderGoalRandomTargetNonTamed extends PathfinderGoalNearestAttackableTarget {
- private final TamableFox tamableFox;
-
- public FoxPathfinderGoalRandomTargetNonTamed(TamableFox tamableFox, Class var1, boolean var2, @Nullable Predicate var3) {
- super(tamableFox, var1, 10, var2, false, var3);
- this.tamableFox = tamableFox;
- }
-
- public boolean a() {
- return !tamableFox.isTamed() && super.a();
- }
-
- public boolean b() {
- return this.d != null ? this.d.a(this.e, this.c) : super.b();
- }
-}
\ No newline at end of file
diff --git a/src/main/java/net/seanomik/tamablefoxes/NBTEditor.java b/src/main/java/net/seanomik/tamablefoxes/NBTEditor.java
deleted file mode 100644
index 8cf1aa7..0000000
--- a/src/main/java/net/seanomik/tamablefoxes/NBTEditor.java
+++ /dev/null
@@ -1,1111 +0,0 @@
-package net.seanomik.tamablefoxes;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.annotation.Nonnull;
-
-import org.bukkit.Bukkit;
-import org.bukkit.Location;
-import org.bukkit.Material;
-import org.bukkit.block.Block;
-import org.bukkit.craftbukkit.libs.org.apache.commons.codec.binary.Base64;
-import org.bukkit.entity.Entity;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.meta.ItemMeta;
-
-import com.mojang.authlib.GameProfile;
-import com.mojang.authlib.properties.Property;
-
-/**
- * Sets/Gets NBT tags from ItemStacks
- * Supports 1.8-1.14
- *
- * Github: https://github.com/BananaPuncher714/NBTEditor
- * Spigot: https://www.spigotmc.org/threads/single-class-nbt-editor-for-items-skulls-mobs-and-tile-entities-1-8-1-13.269621/
- *
- * @version 7.6
- * @author BananaPuncher714
- */
-public final class NBTEditor {
- private static final Map< String, Class> > classCache;
- private static final Map< String, Method > methodCache;
- private static final Map< Class< ? >, Constructor< ? > > constructorCache;
- private static final Map< Class< ? >, Class< ? > > NBTClasses;
- private static final Map< Class< ? >, Field > NBTTagFieldCache;
- private static Field NBTListData;
- private static Field NBTCompoundMap;
- private static final String VERSION;
-
- static {
- VERSION = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
-
- classCache = new HashMap< String, Class> >();
- try {
- classCache.put( "NBTBase", Class.forName( "net.minecraft.server." + VERSION + "." + "NBTBase" ) );
- classCache.put( "NBTTagCompound", Class.forName( "net.minecraft.server." + VERSION + "." + "NBTTagCompound" ) );
- classCache.put( "NBTTagList", Class.forName( "net.minecraft.server." + VERSION + "." + "NBTTagList" ) );
- classCache.put( "NBTBase", Class.forName( "net.minecraft.server." + VERSION + "." + "NBTBase" ) );
-
- classCache.put( "ItemStack", Class.forName( "net.minecraft.server." + VERSION + "." + "ItemStack" ) );
- classCache.put( "CraftItemStack", Class.forName( "org.bukkit.craftbukkit." + VERSION + ".inventory." + "CraftItemStack" ) );
-
- classCache.put( "Entity", Class.forName( "net.minecraft.server." + VERSION + "." + "Entity" ) );
- classCache.put( "CraftEntity", Class.forName( "org.bukkit.craftbukkit." + VERSION + ".entity." + "CraftEntity" ) );
- classCache.put( "EntityLiving", Class.forName( "net.minecraft.server." + VERSION + "." + "EntityLiving" ) );
-
- classCache.put( "CraftWorld", Class.forName( "org.bukkit.craftbukkit." + VERSION + "." + "CraftWorld" ) );
- classCache.put( "CraftBlockState", Class.forName( "org.bukkit.craftbukkit." + VERSION + ".block." + "CraftBlockState" ) );
- classCache.put( "BlockPosition", Class.forName( "net.minecraft.server." + VERSION + "." + "BlockPosition" ) );
- classCache.put( "TileEntity", Class.forName( "net.minecraft.server." + VERSION + "." + "TileEntity" ) );
- classCache.put( "World", Class.forName( "net.minecraft.server." + VERSION + "." + "World" ) );
-
- classCache.put( "TileEntitySkull", Class.forName( "net.minecraft.server." + VERSION + "." + "TileEntitySkull" ) );
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
-
- NBTClasses = new HashMap< Class< ? >, Class< ? > >();
- try {
- NBTClasses.put( Byte.class, Class.forName( "net.minecraft.server." + VERSION + "." + "NBTTagByte" ) );
- NBTClasses.put( String.class, Class.forName( "net.minecraft.server." + VERSION + "." + "NBTTagString" ) );
- NBTClasses.put( Double.class, Class.forName( "net.minecraft.server." + VERSION + "." + "NBTTagDouble" ) );
- NBTClasses.put( Integer.class, Class.forName( "net.minecraft.server." + VERSION + "." + "NBTTagInt" ) );
- NBTClasses.put( Long.class, Class.forName( "net.minecraft.server." + VERSION + "." + "NBTTagLong" ) );
- NBTClasses.put( Short.class, Class.forName( "net.minecraft.server." + VERSION + "." + "NBTTagShort" ) );
- NBTClasses.put( Float.class, Class.forName( "net.minecraft.server." + VERSION + "." + "NBTTagFloat" ) );
- NBTClasses.put( Class.forName( "[B" ), Class.forName( "net.minecraft.server." + VERSION + "." + "NBTTagByteArray" ) );
- NBTClasses.put( Class.forName( "[I" ), Class.forName( "net.minecraft.server." + VERSION + "." + "NBTTagIntArray" ) );
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
-
- methodCache = new HashMap< String, Method >();
- try {
- methodCache.put( "get", getNMSClass( "NBTTagCompound" ).getMethod( "get", String.class ) );
- methodCache.put( "set", getNMSClass( "NBTTagCompound" ).getMethod( "set", String.class, getNMSClass( "NBTBase" ) ) );
- methodCache.put( "hasKey", getNMSClass( "NBTTagCompound" ).getMethod( "hasKey", String.class ) );
- methodCache.put( "setIndex", getNMSClass( "NBTTagList" ).getMethod( "a", int.class, getNMSClass( "NBTBase" ) ) );
- if ( VERSION.contains( "1_14" ) ) {
- methodCache.put( "getTypeId", getNMSClass( "NBTBase" ).getMethod( "getTypeId" ) );
- methodCache.put( "add", getNMSClass( "NBTTagList" ).getMethod( "add", int.class, getNMSClass( "NBTBase" ) ) );
- } else {
- methodCache.put( "add", getNMSClass( "NBTTagList" ).getMethod( "add", getNMSClass( "NBTBase" ) ) );
- }
-
- if ( VERSION.contains( "1_8" ) ) {
- methodCache.put( "listRemove", getNMSClass( "NBTTagList" ).getMethod( "a", int.class ) );
- } else {
- methodCache.put( "listRemove", getNMSClass( "NBTTagList" ).getMethod( "remove", int.class ) );
- }
- methodCache.put( "remove", getNMSClass( "NBTTagCompound" ).getMethod( "remove", String.class ) );
-
- methodCache.put( "hasTag", getNMSClass( "ItemStack" ).getMethod( "hasTag" ) );
- methodCache.put( "getTag", getNMSClass( "ItemStack" ).getMethod( "getTag" ) );
- methodCache.put( "setTag", getNMSClass( "ItemStack" ).getMethod( "setTag", getNMSClass( "NBTTagCompound" ) ) );
- methodCache.put( "asNMSCopy", getNMSClass( "CraftItemStack" ).getMethod( "asNMSCopy", ItemStack.class ) );
- methodCache.put( "asBukkitCopy", getNMSClass( "CraftItemStack" ).getMethod( "asBukkitCopy", getNMSClass( "ItemStack" ) ) );
-
- methodCache.put( "getEntityHandle", getNMSClass( "CraftEntity" ).getMethod( "getHandle" ) );
- methodCache.put( "getEntityTag", getNMSClass( "Entity" ).getMethod( "c", getNMSClass( "NBTTagCompound" ) ) );
- methodCache.put( "setEntityTag", getNMSClass( "Entity" ).getMethod( "f", getNMSClass( "NBTTagCompound" ) ) );
-
- if ( VERSION.contains( "1_12" ) || VERSION.contains( "1_13" ) || VERSION.contains( "1_14" ) ) {
- methodCache.put( "setTileTag", getNMSClass( "TileEntity" ).getMethod( "load", getNMSClass( "NBTTagCompound" ) ) );
- } else {
- methodCache.put( "setTileTag", getNMSClass( "TileEntity" ).getMethod( "a", getNMSClass( "NBTTagCompound" ) ) );
- }
- methodCache.put( "getTileEntity", getNMSClass( "World" ).getMethod( "getTileEntity", getNMSClass( "BlockPosition" ) ) );
- methodCache.put( "getWorldHandle", getNMSClass( "CraftWorld" ).getMethod( "getHandle" ) );
-
- methodCache.put( "setGameProfile", getNMSClass( "TileEntitySkull" ).getMethod( "setGameProfile", GameProfile.class ) );
- } catch( Exception e ) {
- e.printStackTrace();
- }
-
- try {
- methodCache.put( "getTileTag", getNMSClass( "TileEntity" ).getMethod( "save", getNMSClass( "NBTTagCompound" ) ) );
- } catch( NoSuchMethodException exception ) {
- try {
- methodCache.put( "getTileTag", getNMSClass( "TileEntity" ).getMethod( "b", getNMSClass( "NBTTagCompound" ) ) );
- } catch ( Exception exception2 ) {
- exception2.printStackTrace();
- }
- } catch( Exception exception ) {
- exception.printStackTrace();
- }
-
- constructorCache = new HashMap< Class< ? >, Constructor< ? > >();
- try {
- constructorCache.put( getNBTTag( Byte.class ), getNBTTag( Byte.class ).getConstructor( byte.class ) );
- constructorCache.put( getNBTTag( String.class ), getNBTTag( String.class ).getConstructor( String.class ) );
- constructorCache.put( getNBTTag( Double.class ), getNBTTag( Double.class ).getConstructor( double.class ) );
- constructorCache.put( getNBTTag( Integer.class ), getNBTTag( Integer.class ).getConstructor( int.class ) );
- constructorCache.put( getNBTTag( Long.class ), getNBTTag( Long.class ).getConstructor( long.class ) );
- constructorCache.put( getNBTTag( Float.class ), getNBTTag( Float.class ).getConstructor( float.class ) );
- constructorCache.put( getNBTTag( Short.class ), getNBTTag( Short.class ).getConstructor( short.class ) );
- constructorCache.put( getNBTTag( Class.forName( "[B" ) ), getNBTTag( Class.forName( "[B" ) ).getConstructor( Class.forName( "[B" ) ) );
- constructorCache.put( getNBTTag( Class.forName( "[I" ) ), getNBTTag( Class.forName( "[I" ) ).getConstructor( Class.forName( "[I" ) ) );
-
- constructorCache.put( getNMSClass( "BlockPosition" ), getNMSClass( "BlockPosition" ).getConstructor( int.class, int.class, int.class ) );
- } catch( Exception e ) {
- e.printStackTrace();
- }
-
- NBTTagFieldCache = new HashMap< Class< ? >, Field >();
- try {
- for ( Class< ? > clazz : NBTClasses.values() ) {
- Field data = clazz.getDeclaredField( "data" );
- data.setAccessible( true );
- NBTTagFieldCache.put( clazz, data );
- }
- } catch( Exception e ) {
- e.printStackTrace();
- }
-
- try {
- NBTListData = getNMSClass( "NBTTagList" ).getDeclaredField( "list" );
- NBTListData.setAccessible( true );
- NBTCompoundMap = getNMSClass( "NBTTagCompound" ).getDeclaredField( "map" );
- NBTCompoundMap.setAccessible( true );
- } catch( Exception e ) {
- e.printStackTrace();
- }
- }
-
- private static Class< ? > getNBTTag( Class< ? > primitiveType ) {
- if ( NBTClasses.containsKey( primitiveType ) )
- return NBTClasses.get( primitiveType );
- return primitiveType;
- }
-
- private static Object getNBTVar( Object object ) {
- if ( object == null ) {
- return null;
- }
- Class< ? > clazz = object.getClass();
- try {
- if ( NBTTagFieldCache.containsKey( clazz ) ) {
- return NBTTagFieldCache.get( clazz ).get( object );
- }
- } catch ( Exception exception ) {
- exception.printStackTrace();
- }
- return null;
- }
-
- private static Method getMethod( String name ) {
- return methodCache.containsKey( name ) ? methodCache.get( name ) : null;
- }
-
- private static Constructor< ? > getConstructor( Class< ? > clazz ) {
- return constructorCache.containsKey( clazz ) ? constructorCache.get( clazz ) : null;
- }
-
- private static Class> getNMSClass(String name) {
- if ( classCache.containsKey( name ) ) {
- return classCache.get( name );
- }
-
- try {
- return Class.forName("net.minecraft.server." + VERSION + "." + name);
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- return null;
- }
- }
-
- private static String getMatch( String string, String regex ) {
- Pattern pattern = Pattern.compile( regex );
- Matcher matcher = pattern.matcher( string );
- if ( matcher.find() ) {
- return matcher.group( 1 );
- } else {
- return null;
- }
- }
-
- /**
- * Gets the Bukkit version
- *
- * @return
- * The Bukkit version in standard package format
- */
- public final static String getVersion() {
- return VERSION;
- }
-
- /**
- * Creates a skull with the given url as the skin
- *
- * @param skinURL
- * The URL of the skin, must be from mojang
- * @return
- * An item stack with count of 1
- */
- public final static ItemStack getHead( String skinURL ) {
- Material material = Material.getMaterial( "SKULL_ITEM" );
- if ( material == null ) {
- // Most likely 1.13 materials
- material = Material.getMaterial( "PLAYER_HEAD" );
- }
- ItemStack head = new ItemStack( material, 1, ( short ) 3 );
- if ( skinURL == null || skinURL.isEmpty() ) {
- return head;
- }
- ItemMeta headMeta = head.getItemMeta();
- GameProfile profile = new GameProfile( UUID.randomUUID(), null);
- byte[] encodedData = Base64.encodeBase64( String.format( "{textures:{SKIN:{\"url\":\"%s\"}}}", skinURL ).getBytes() );
- profile.getProperties().put("textures", new Property("textures", new String(encodedData)));
- Field profileField = null;
- try {
- profileField = headMeta.getClass().getDeclaredField("profile");
- } catch ( NoSuchFieldException | SecurityException e ) {
- e.printStackTrace();
- }
- profileField.setAccessible(true);
- try {
- profileField.set(headMeta, profile);
- } catch (IllegalArgumentException | IllegalAccessException e) {
- e.printStackTrace();
- }
- head.setItemMeta(headMeta);
- return head;
- }
-
- /**
- * Fetches the texture of a skull
- *
- * @param head
- * The item stack itself
- * @return
- * The URL of the texture
- */
- public final static String getTexture( ItemStack head ) {
- ItemMeta meta = head.getItemMeta();
- Field profileField = null;
- try {
- profileField = meta.getClass().getDeclaredField("profile");
- } catch ( NoSuchFieldException | SecurityException e ) {
- e.printStackTrace();
- throw new IllegalArgumentException( "Item is not a player skull!" );
- }
- profileField.setAccessible(true);
- try {
- GameProfile profile = ( GameProfile ) profileField.get( meta );
- if ( profile == null ) {
- return null;
- }
-
- for ( Property prop : profile.getProperties().values() ) {
- if ( prop.getName().equals( "textures" ) ) {
- String texture = new String( Base64.decodeBase64( prop.getValue() ) );
- return getMatch( texture, "\\{\"url\":\"(.*?)\"\\}" );
- }
- }
- return null;
- } catch ( IllegalArgumentException | IllegalAccessException | SecurityException e) {
- e.printStackTrace();
- return null;
- }
- }
-
- /**
- * @deprecated
- *
- * Gets an NBT tag in a given item with the specified keys
- *
- * @param item
- * The itemstack to get the keys from
- * @param keys
- * The keys to fetch; an integer after a key value indicates that it should get the nth place of
- * the previous compound because it is a list;
- * @return
- * The item represented by the keys, and an integer if it is showing how long a list is.
- */
- public final static Object getItemTag( ItemStack item, Object... keys ) {
- if ( item == null ) {
- return null;
- }
- try {
- Object stack = null;
- stack = getMethod( "asNMSCopy" ).invoke( null, item );
-
- Object tag = null;
-
- if ( getMethod( "hasTag" ).invoke( stack ).equals( true ) ) {
- tag = getMethod( "getTag" ).invoke( stack );
- } else {
- tag = getNMSClass( "NBTTagCompound" ).newInstance();
- }
-
- return getTag( tag, keys );
- } catch ( Exception exception ) {
- exception.printStackTrace();
- return null;
- }
- }
-
- /**
- * Gets an NBTCompound from the item provided
- *
- * @param item
- * Itemstack
- * @param keys
- * Keys in descending order
- * @return
- * An NBTCompound
- */
- public final static NBTCompound getItemNBTTag( ItemStack item, Object... keys ) {
- if ( item == null ) {
- return null;
- }
- try {
- Object stack = null;
- stack = getMethod( "asNMSCopy" ).invoke( null, item );
-
- Object tag = null;
-
- if ( getMethod( "hasTag" ).invoke( stack ).equals( true ) ) {
- tag = getMethod( "getTag" ).invoke( stack );
- } else {
- tag = getNMSClass( "NBTTagCompound" ).newInstance();
- Object count = getConstructor( getNBTTag( Integer.class ) ).newInstance( item.getAmount() );
- getMethod( "set" ).invoke( tag, "Count", count );
- Object id = getConstructor( getNBTTag( String.class ) ).newInstance( item.getType().name().toLowerCase() );
- getMethod( "set" ).invoke( tag, "id", id );
- }
-
- return getNBTTag( tag, keys );
- } catch ( Exception exception ) {
- exception.printStackTrace();
- return null;
- }
- }
-
- /**
- * @deprecated
- *
- * Sets an NBT tag in an item with the provided keys and value
- *
- * @param item
- * The itemstack to set
- * @param keys
- * The keys to set, String for NBTCompound, int or null for an NBTTagList
- * @param value
- * The value to set
- * @return
- * A new ItemStack with the updated NBT tags
- */
- public final static ItemStack setItemTag( ItemStack item, Object value, Object... keys ) {
- if ( item == null ) {
- return null;
- }
- try {
- Object stack = getMethod( "asNMSCopy" ).invoke( null, item );
-
- Object tag = null;
-
- if ( getMethod( "hasTag" ).invoke( stack ).equals( true ) ) {
- tag = getMethod( "getTag" ).invoke( stack );
- } else {
- tag = getNMSClass( "NBTTagCompound" ).newInstance();
- }
-
- setTag( tag, value, keys );
- getMethod( "setTag" ).invoke( stack, tag );
- return ( ItemStack ) getMethod( "asBukkitCopy" ).invoke( null, stack );
- } catch ( Exception exception ) {
- exception.printStackTrace();
- return null;
- }
- }
-
- /**
- * Constructs an ItemStack from a given NBTCompound
- *
- * @param compound
- * An NBTCompound following an ItemStack structure
- * @return
- * A new ItemStack
- */
- public final static ItemStack getItemFromTag( NBTCompound compound ) {
- if ( compound == null ) {
- return null;
- }
- try {
- Object tag = compound.tag;
- Object count = getTag( tag, "Count" );
- Object id = getTag( tag, "id" );
- if ( count == null || id == null ) {
- return null;
- }
- if ( count instanceof Byte && id instanceof String ) {
- int amount = ( byte ) count;
- String material = ( String ) id;
- Material type = Material.valueOf( material.substring( material.indexOf( ":" ) + 1 ).toUpperCase() );
- return NBTEditor.setItemTag( new ItemStack( type, amount ), tag );
- }
- return null;
- } catch ( Exception exception ) {
- exception.printStackTrace();
- return null;
- }
- }
-
- /**
- * @deprecated
- *
- * Gets an NBT tag in a given entity with the specified keys
- *
- * @param entity
- * The entity to get the keys from
- * @param keys
- * The keys to fetch; an integer after a key value indicates that it should get the nth place of
- * the previous compound because it is a list;
- * @return
- * The item represented by the keys, and an integer if it is showing how long a list is.
- */
- public final static Object getEntityTag( Entity entity, Object... keys ) {
- if ( entity == null ) {
- return entity;
- }
- try {
- Object NMSEntity = getMethod( "getEntityHandle" ).invoke( entity );
-
- Object tag = getNMSClass( "NBTTagCompound" ).newInstance();
-
- getMethod( "getEntityTag" ).invoke( NMSEntity, tag );
-
- return getTag( tag, keys );
- } catch ( Exception exception ) {
- exception.printStackTrace();
- return null;
- }
- }
-
- /**
- * Gets an NBTCompound from the entity provided
- *
- * @param entity
- * The Bukkit entity provided
- * @param keys
- * Keys in descending order
- * @return
- * An NBTCompound
- */
- public final static NBTCompound getEntityNBTTag( Entity entity, Object...keys ) {
- if ( entity == null ) {
- return null;
- }
- try {
- Object NMSEntity = getMethod( "getEntityHandle" ).invoke( entity );
-
- Object tag = getNMSClass( "NBTTagCompound" ).newInstance();
-
- getMethod( "getEntityTag" ).invoke( NMSEntity, tag );
-
- return getNBTTag( tag, keys );
- } catch ( Exception exception ) {
- exception.printStackTrace();
- return null;
- }
- }
-
- /**
- * @deprecated
- *
- * Sets an NBT tag in an entity with the provided keys and value
- *
- * @param entity
- * The entity to set
- * @param keys
- * The keys to set, String for NBTCompound, int or null for an NBTTagList
- * @param value
- * The value to set
- * @return
- * A new ItemStack with the updated NBT tags
- */
- public final static void setEntityTag( Entity entity, Object value, Object... keys ) {
- if ( entity == null ) {
- return;
- }
- try {
- Object NMSEntity = getMethod( "getEntityHandle" ).invoke( entity );
-
- Object tag = getNMSClass( "NBTTagCompound" ).newInstance() ;
-
- getMethod( "getEntityTag" ).invoke( NMSEntity, tag );
-
- setTag( tag, value, keys );
-
- getMethod( "setEntityTag" ).invoke( NMSEntity, tag );
- } catch ( Exception exception ) {
- exception.printStackTrace();
- return;
- }
- }
-
- /**
- * @deprecated
- *
- * Gets an NBT tag in a given block with the specified keys
- *
- * @param block
- * The block to get the keys from
- * @param keys
- * The keys to fetch; an integer after a key value indicates that it should get the nth place of
- * the previous compound because it is a list;
- * @return
- * The item represented by the keys, and an integer if it is showing how long a list is.
- */
- public final static Object getBlockTag( Block block, Object... keys ) {
- try {
- if ( block == null || !getNMSClass( "CraftBlockState" ).isInstance( block.getState() ) ) {
- return null;
- }
- Location location = block.getLocation();
-
- Object blockPosition = getConstructor( getNMSClass( "BlockPosition" ) ).newInstance( location.getBlockX(), location.getBlockY(), location.getBlockZ() );
-
- Object nmsWorld = getMethod( "getWorldHandle" ).invoke( location.getWorld() );
-
- Object tileEntity = getMethod( "getTileEntity" ).invoke( nmsWorld, blockPosition );
-
- Object tag = getNMSClass( "NBTTagCompound" ).newInstance();
-
- getMethod( "getTileTag" ).invoke( tileEntity, tag );
-
- return getTag( tag, keys );
- } catch( Exception exception ) {
- exception.printStackTrace();
- return null;
- }
- }
-
- /**
- * Gets an NBTCompound from the block provided
- *
- * @param block
- * The block provided
- * @param keys
- * Keys in descending order
- * @return
- * An NBTCompound
- */
- public final static Object getBlockNBTTag( Block block, Object... keys ) {
- try {
- if ( block == null || !getNMSClass( "CraftBlockState" ).isInstance( block.getState() ) ) {
- return null;
- }
- Location location = block.getLocation();
-
- Object blockPosition = getConstructor( getNMSClass( "BlockPosition" ) ).newInstance( location.getBlockX(), location.getBlockY(), location.getBlockZ() );
-
- Object nmsWorld = getMethod( "getWorldHandle" ).invoke( location.getWorld() );
-
- Object tileEntity = getMethod( "getTileEntity" ).invoke( nmsWorld, blockPosition );
-
- Object tag = getNMSClass( "NBTTagCompound" ).newInstance();
-
- getMethod( "getTileTag" ).invoke( tileEntity, tag );
-
- return getNBTTag( tag, keys );
- } catch( Exception exception ) {
- exception.printStackTrace();
- return null;
- }
- }
-
- /**
- * @deprecated
- *
- * Sets an NBT tag in an block with the provided keys and value
- *
- * @param block
- * The block to set
- * @param keys
- * The keys to set, String for NBTCompound, int or null for an NBTTagList
- * @param value
- * The value to set
- * @return
- * A new ItemStack with the updated NBT tags
- */
- public final static void setBlockTag( Block block, Object value, Object... keys ) {
- try {
- if ( block == null || !getNMSClass( "CraftBlockState" ).isInstance( block.getState() ) ) {
- return;
- }
- Location location = block.getLocation();
-
- Object blockPosition = getConstructor( getNMSClass( "BlockPosition" ) ).newInstance( location.getBlockX(), location.getBlockY(), location.getBlockZ() );
-
- Object nmsWorld = getMethod( "getWorldHandle" ).invoke( location.getWorld() );
-
- Object tileEntity = getMethod( "getTileEntity" ).invoke( nmsWorld, blockPosition );
-
- Object tag = getNMSClass( "NBTTagCompound" ).newInstance();
-
- getMethod( "getTileTag" ).invoke( tileEntity, tag );
-
- setTag( tag, value, keys );
-
- getMethod( "setTileTag" ).invoke( tileEntity, tag );
- } catch( Exception exception ) {
- exception.printStackTrace();
- return;
- }
- }
-
- /**
- * Sets the texture of a skull block
- *
- * @param block
- * The block, must be a skull
- * @param texture
- * The URL of the skin
- */
- public final static void setSkullTexture( Block block, String texture ) {
- GameProfile profile = new GameProfile( UUID.randomUUID(), null );
- profile.getProperties().put( "textures", new com.mojang.authlib.properties.Property( "textures", new String( Base64.encodeBase64( String.format( "{textures:{SKIN:{\"url\":\"%s\"}}}", texture ).getBytes() ) ) ) );
-
- try {
- Location location = block.getLocation();
-
- Object blockPosition = getConstructor( getNMSClass( "BlockPosition" ) ).newInstance( location.getBlockX(), location.getBlockY(), location.getBlockZ() );
-
- Object nmsWorld = getMethod( "getWorldHandle" ).invoke( location.getWorld() );
-
- Object tileEntity = getMethod( "getTileEntity" ).invoke( nmsWorld, blockPosition );
-
- getMethod( "setGameProfile" ).invoke( tileEntity, profile );
- } catch( Exception exception ) {
- exception.printStackTrace();
- }
- }
-
- /**
- * Gets a string from an object
- *
- * @param object
- * Must be an ItemStack, Entity, or Block
- * @param keys
- * Keys in descending order
- * @return
- * A string, or null if none is stored at the provided location
- */
- public final static String getString( Object object, Object... keys ) {
- Object result;
- if ( object instanceof ItemStack ) {
- result = getItemTag( ( ItemStack ) object, keys );
- } else if ( object instanceof Entity ) {
- result = getEntityTag( ( Entity ) object, keys );
- } else if ( object instanceof Block ) {
- result = getBlockTag( ( Block ) object, keys );
- } else {
- throw new IllegalArgumentException( "Object provided must be of type ItemStack, Entity, or Block!" );
- }
- return result instanceof String ? ( String ) result : null;
- }
-
- /**
- * Gets an int from an object
- *
- * @param object
- * Must be an ItemStack, Entity, or Block
- * @param keys
- * Keys in descending order
- * @return
- * An integer, or 0 if none is stored at the provided location
- */
- public final static int getInt( Object object, Object... keys ) {
- Object result;
- if ( object instanceof ItemStack ) {
- result = getItemTag( ( ItemStack ) object, keys );
- } else if ( object instanceof Entity ) {
- result = getEntityTag( ( Entity ) object, keys );
- } else if ( object instanceof Block ) {
- result = getBlockTag( ( Block ) object, keys );
- } else {
- throw new IllegalArgumentException( "Object provided must be of type ItemStack, Entity, or Block!" );
- }
- return result instanceof Integer ? ( int ) result : 0;
- }
-
- /**
- * Gets a long from an object
- *
- * @param object
- * Must be an ItemStack, Entity, or Block
- * @param keys
- * Keys in descending order
- * @return
- * A long, or 0 if none is stored at the provided location
- */
- public final static long getLong( Object object, Object... keys ) {
- Object result;
- if ( object instanceof ItemStack ) {
- result = getItemTag( ( ItemStack ) object, keys );
- } else if ( object instanceof Entity ) {
- result = getEntityTag( ( Entity ) object, keys );
- } else if ( object instanceof Block ) {
- result = getBlockTag( ( Block ) object, keys );
- } else {
- throw new IllegalArgumentException( "Object provided must be of type ItemStack, Entity, or Block!" );
- }
- return result instanceof Long ? ( long ) result : 0;
- }
-
- /**
- * Gets a float from an object
- *
- * @param object
- * Must be an ItemStack, Entity, or Block
- * @param keys
- * Keys in descending order
- * @return
- * A float, or 0 if none is stored at the provided location
- */
- public final static float getFloat( Object object, Object... keys ) {
- Object result;
- if ( object instanceof ItemStack ) {
- result = getItemTag( ( ItemStack ) object, keys );
- } else if ( object instanceof Entity ) {
- result = getEntityTag( ( Entity ) object, keys );
- } else if ( object instanceof Block ) {
- result = getBlockTag( ( Block ) object, keys );
- } else {
- throw new IllegalArgumentException( "Object provided must be of type ItemStack, Entity, or Block!" );
- }
- return result instanceof Float ? ( float ) result : 0;
- }
-
- /**
- * Gets a short from an object
- *
- * @param object
- * Must be an ItemStack, Entity, or Block
- * @param keys
- * Keys in descending order
- * @return
- * A short, or 0 if none is stored at the provided location
- */
- public final static short getShort( Object object, Object... keys ) {
- Object result;
- if ( object instanceof ItemStack ) {
- result = getItemTag( ( ItemStack ) object, keys );
- } else if ( object instanceof Entity ) {
- result = getEntityTag( ( Entity ) object, keys );
- } else if ( object instanceof Block ) {
- result = getBlockTag( ( Block ) object, keys );
- } else {
- throw new IllegalArgumentException( "Object provided must be of type ItemStack, Entity, or Block!" );
- }
- return result instanceof Short ? ( short ) result : 0;
- }
-
- /**
- * Gets a byte from an object
- *
- * @param object
- * Must be an ItemStack, Entity, or Block
- * @param keys
- * Keys in descending order
- * @return
- * A byte, or 0 if none is stored at the provided location
- */
- public final static byte getByte( Object object, Object... keys ) {
- Object result;
- if ( object instanceof ItemStack ) {
- result = getItemTag( ( ItemStack ) object, keys );
- } else if ( object instanceof Entity ) {
- result = getEntityTag( ( Entity ) object, keys );
- } else if ( object instanceof Block ) {
- result = getBlockTag( ( Block ) object, keys );
- } else {
- throw new IllegalArgumentException( "Object provided must be of type ItemStack, Entity, or Block!" );
- }
- return result instanceof Byte ? ( byte ) result : 0;
- }
-
- /**
- * Gets a byte array from an object
- *
- * @param object
- * Must be an ItemStack, Entity, or Block
- * @param keys
- * Keys in descending order
- * @return
- * A byte array, or null if none is stored at the provided location
- */
- public final static byte[] getByteArray( Object object, Object... keys ) {
- Object result;
- if ( object instanceof ItemStack ) {
- result = getItemTag( ( ItemStack ) object, keys );
- } else if ( object instanceof Entity ) {
- result = getEntityTag( ( Entity ) object, keys );
- } else if ( object instanceof Block ) {
- result = getBlockTag( ( Block ) object, keys );
- } else {
- throw new IllegalArgumentException( "Object provided must be of type ItemStack, Entity, or Block!" );
- }
- return result instanceof byte[] ? ( byte[] ) result : null;
- }
-
- /**
- * Gets an int array from an object
- *
- * @param object
- * Must be an ItemStack, Entity, or Block
- * @param keys
- * Keys in descending order
- * @return
- * An int array, or null if none is stored at the provided location
- */
- public final static int[] getIntArray( Object object, Object... keys ) {
- Object result;
- if ( object instanceof ItemStack ) {
- result = getItemTag( ( ItemStack ) object, keys );
- } else if ( object instanceof Entity ) {
- result = getEntityTag( ( Entity ) object, keys );
- } else if ( object instanceof Block ) {
- result = getBlockTag( ( Block ) object, keys );
- } else {
- throw new IllegalArgumentException( "Object provided must be of type ItemStack, Entity, or Block!" );
- }
- return result instanceof int[] ? ( int[] ) result : null;
- }
-
- /**
- * Checks if the object contains the given key
- *
- * @param object
- * Must be an ItemStack, Entity, or Block
- * @param keys
- * Keys in descending order
- * @return
- * Whether or not the particular tag exists, may not be a primitive
- */
- public final static boolean contains( Object object, Object... keys ) {
- Object result;
- if ( object instanceof ItemStack ) {
- result = getItemTag( ( ItemStack ) object, keys );
- } else if ( object instanceof Entity ) {
- result = getEntityTag( ( Entity ) object, keys );
- } else if ( object instanceof Block ) {
- result = getBlockTag( ( Block ) object, keys );
- } else {
- throw new IllegalArgumentException( "Object provided must be of type ItemStack, Entity, or Block!" );
- }
- return result != null;
- }
-
- /**
- * Sets the value in the object with the given keys
- *
- * @param object
- * Must be an ItemStack, Entity, or Block
- * @param value
- * The value to set, can be an NBTCompound
- * @param keys
- * The keys in descending order
- * @return
- * The new item stack if the object provided is an item, else original object
- */
- public final static < T > T set( T object, Object value, Object... keys ) {
- if ( object instanceof ItemStack ) {
- return ( T ) setItemTag( ( ItemStack ) object, value, keys );
- } else if ( object instanceof Entity ) {
- setEntityTag( ( Entity ) object, value, keys );
- } else if ( object instanceof Block ) {
- setBlockTag( ( Block ) object, value, keys );
- } else {
- throw new IllegalArgumentException( "Object provided must be of type ItemStack, Entity, or Block!" );
- }
- return object;
- }
-
- private static void setTag( Object tag, Object value, Object... keys ) throws Exception {
- Object notCompound;
- if ( value != null ) {
- if ( getNMSClass( "NBTTagList" ).isInstance( value ) || getNMSClass( "NBTTagCompound" ).isInstance( value ) ) {
- notCompound = value;
- } else {
- notCompound = getConstructor( getNBTTag( value.getClass() ) ).newInstance( value );
- }
- } else {
- notCompound = null;
- }
-
- Object compound = tag;
- for ( int index = 0; index < keys.length; index++ ) {
- Object key = keys[ index ];
- if ( index + 1 == keys.length ) {
- if ( key == null ) {
- if ( VERSION.contains( "1_14" ) ) {
- int type = ( int ) getMethod( "getTypeId" ).invoke( notCompound );
- getMethod( "add" ).invoke( compound, type, notCompound );
- } else {
- getMethod( "add" ).invoke( compound, notCompound );
- }
- } else if ( key instanceof Integer ) {
- if ( notCompound == null ) {
- getMethod( "listRemove" ).invoke( compound, ( int ) key );
- } else {
- getMethod( "setIndex" ).invoke( compound, ( int ) key, notCompound );
- }
- } else {
- if ( notCompound == null ) {
- getMethod( "remove" ).invoke( compound, ( String ) key );
- } else {
- getMethod( "set" ).invoke( compound, ( String ) key, notCompound );
- }
- }
- break;
- }
- Object oldCompound = compound;
- if ( key instanceof Integer ) {
- compound = ( ( List< ? > ) NBTListData.get( compound ) ).get( ( int ) key );
- } else if ( key != null ) {
- compound = getMethod( "get" ).invoke( compound, ( String ) key );
- }
- if ( compound == null || key == null ) {
- if ( keys[ index + 1 ] == null || keys[ index + 1 ] instanceof Integer ) {
- compound = getNMSClass( "NBTTagList" ).newInstance();
- } else {
- compound = getNMSClass( "NBTTagCompound" ).newInstance();
- }
- if ( oldCompound.getClass().getSimpleName().equals( "NBTTagList" ) ) {
- getMethod( "add" ).invoke( oldCompound, compound );
- } else {
- if ( notCompound == null ) {
- getMethod( "remove" ).invoke( oldCompound, ( String ) key );
- } else {
- getMethod( "set" ).invoke( oldCompound, ( String ) key, compound );
- }
- }
- }
- }
- }
-
- private static NBTCompound getNBTTag( Object tag, Object...keys ) throws Exception {
- Object compound = tag;
-
- for ( Object key : keys ) {
- if ( compound == null ) {
- return null;
- } else if ( getNMSClass( "NBTTagCompound" ).isInstance( compound ) ) {
- compound = getMethod( "get" ).invoke( compound, ( String ) key );
- } else if ( getNMSClass( "NBTTagList" ).isInstance( compound ) ) {
- compound = ( ( List< ? > ) NBTListData.get( compound ) ).get( ( int ) key );
- }
- }
- return new NBTCompound( compound );
- }
-
- private static Object getTag( Object tag, Object... keys ) throws Exception {
- if ( keys.length == 0 ) {
- return getTags( tag );
- }
-
- Object notCompound = tag;
-
- for ( Object key : keys ) {
- if ( notCompound == null ) {
- return null;
- } else if ( getNMSClass( "NBTTagCompound" ).isInstance( notCompound ) ) {
- notCompound = getMethod( "get" ).invoke( notCompound, ( String ) key );
- } else if ( getNMSClass( "NBTTagList" ).isInstance( notCompound ) ) {
- notCompound = ( ( List< ? > ) NBTListData.get( notCompound ) ).get( ( int ) key );
- } else {
- return getNBTVar( notCompound );
- }
- }
- if ( notCompound == null ) {
- return null;
- } else if ( getNMSClass( "NBTTagList" ).isInstance( notCompound ) ) {
- return getTags( notCompound );
- } else if ( getNMSClass( "NBTTagCompound" ).isInstance( notCompound ) ) {
- return getTags( notCompound );
- } else {
- return getNBTVar( notCompound );
- }
- }
-
- @SuppressWarnings( "unchecked" )
- private static Object getTags( Object tag ) {
- Map< Object, Object > tags = new HashMap< Object, Object >();
- try {
- if ( getNMSClass( "NBTTagCompound" ).isInstance( tag ) ) {
- Map< String, Object > tagCompound = ( Map< String, Object > ) NBTCompoundMap.get( tag );
- for ( String key : tagCompound.keySet() ) {
- Object value = tagCompound.get( key );
- if ( getNMSClass( "NBTTagEnd" ).isInstance( value ) ) {
- continue;
- }
- tags.put( key, getTag( value ) );
- }
- } else if ( getNMSClass( "NBTTagList" ).isInstance( tag ) ) {
- List< Object > tagList = ( List< Object > ) NBTListData.get( tag );
- for ( int index = 0; index < tagList.size(); index++ ) {
- Object value = tagList.get( index );
- if ( getNMSClass( "NBTTagEnd" ).isInstance( value ) ) {
- continue;
- }
- tags.put( index, getTag( value ) );
- }
- } else {
- return getNBTVar( tag );
- }
- return tags;
- } catch ( Exception e ) {
- e.printStackTrace();
- return tags;
- }
- }
-
- /**
- * A class for holding NBTTagCompounds
- */
- public static final class NBTCompound {
- protected final Object tag;
-
- protected NBTCompound( @Nonnull Object tag ) {
- this.tag = tag;
- }
-
- @Override
- public String toString() {
- return tag.toString();
- }
-
- @Override
- public int hashCode() {
- return tag.hashCode();
- }
-
- @Override
- public boolean equals( Object obj ) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- NBTCompound other = (NBTCompound) obj;
- if (tag == null) {
- if (other.tag != null)
- return false;
- } else if (!tag.equals(other.tag))
- return false;
- return true;
- }
- }
-}
diff --git a/src/main/java/net/seanomik/tamablefoxes/Reference.java b/src/main/java/net/seanomik/tamablefoxes/Reference.java
deleted file mode 100644
index 782900d..0000000
--- a/src/main/java/net/seanomik/tamablefoxes/Reference.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package net.seanomik.tamablefoxes;
-
-import org.bukkit.ChatColor;
-
-public class Reference {
- public static final String CHAT_PREFIX = ChatColor.RED + "[Tamable Foxes] ";
- public static final String CUSTOM_FOX_REGISTER_NAME = "tameablefox";
-}
-
diff --git a/src/main/java/net/seanomik/tamablefoxes/TamableFox.java b/src/main/java/net/seanomik/tamablefoxes/TamableFox.java
deleted file mode 100644
index a06ebdf..0000000
--- a/src/main/java/net/seanomik/tamablefoxes/TamableFox.java
+++ /dev/null
@@ -1,241 +0,0 @@
-package net.seanomik.tamablefoxes;
-
-import net.minecraft.server.v1_14_R1.*;
-import net.seanomik.tamablefoxes.CustomPathfinding.*;
-import org.bukkit.Bukkit;
-import org.bukkit.Location;
-import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
-import org.bukkit.craftbukkit.v1_14_R1.event.CraftEventFactory;
-import org.bukkit.entity.Fox;
-import org.bukkit.event.entity.EntityTargetEvent;
-import org.bukkit.plugin.java.JavaPlugin;
-import org.bukkit.scheduler.BukkitRunnable;
-import org.bukkit.scheduler.BukkitTask;
-import org.bukkit.util.Vector;
-
-import javax.annotation.Nullable;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.UUID;
-
-import static net.seanomik.tamablefoxes.TamableFoxes.plugin;
-import static net.seanomik.tamablefoxes.TamableFoxes.fileManager;
-
-public class TamableFox extends EntityFox {
- private boolean isTamed;
- private EntityLiving owner;
- private UUID ownerUUID;
- private boolean sit = false;
- private static Fox thisFox;
- private BukkitTask sittingRunnable;
-
- protected FoxPathfinderGoalSit goalSit;
-
- @Override
- protected void initPathfinder() {
- this.goalSit = new FoxPathfinderGoalSit(this);
-
- this.goalSelector.a(1, new FoxPathfinderGoalFloat(this));
-
- this.goalSelector.a(2, this.goalSit);
-
- this.goalSelector.a(3, new FoxPathfinderGoalMeleeAttack(this, 1.2000000476837158D, true)); // l | Lunging
- this.goalSelector.a(3, new PathfinderGoalAvoidTarget(this, EntityWolf.class, 8.0F, 1.6D, 1.4D, (entityliving) -> {
- return !((EntityWolf)entityliving).isTamed();
- }));
- this.goalSelector.a(4, new FoxPathfinderGoalFollowOwner(this, 1.35D, 10.0F, 2.0F));
-
- this.goalSelector.a(4, new FoxPathfinderGoalLungeUNKNOWN_USE(this)); // u | Lunging
- this.goalSelector.a(5, new FoxPathfinderGoalLunge(this)); // o | Lunging
-
- this.goalSelector.a(5, new FoxPathfinderGoalFleeSun(this, 1.25D));
- this.goalSelector.a(5, new FoxPathfinderGoalBreed(this, 1.0D));
-
- this.goalSelector.a(7, new PathfinderGoalFollowParent(this, 1.1D));
- this.goalSelector.a(7, new FoxPathfinderGoalBeg(this, 8.0F));
- this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
- this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this));
- this.goalSelector.a(9, new FoxPathfinderGoalPickBushes(this, 1.2000000476837158D, 12, 2));
- this.goalSelector.a(10, new FoxPathfinderGoalRandomStrollLand(this, 1D));
-
- this.targetSelector.a(1, new FoxPathfinderGoalOwnerHurtByTarget(this));
- this.targetSelector.a(2, new FoxPathfinderGoalOwnerHurtTarget(this));
-
- PathfinderGoal targetsGoal = new PathfinderGoalNearestAttackableTarget(this, EntityLiving.class, 10, false, false, (entityliving) -> {
- return entityliving instanceof EntityChicken || entityliving instanceof EntityRabbit;
- });
-
- this.targetSelector.a(4, targetsGoal);
- this.targetSelector.a(5, (new FoxPathfinderGoalHurtByTarget(this, new Class[0])).a(new Class[0]));
- }
-
- public TamableFox(EntityTypes entitytypes, World world) {
- super(EntityTypes.FOX, world);
-
- thisFox = (Fox) this.getBukkitEntity();
- TamableFoxes.foxUUIDs.put(this.getBukkitEntity().getUniqueId(), null);
- }
-
- //@Override
- //protected void a(DifficultyDamageScaler difficultydamagescaler) { } // Doesn't spawn with any items in its mouth
-
- @Override
- protected void initAttributes() {
- this.getAttributeMap().b(GenericAttributes.MAX_HEALTH);
- this.getAttributeMap().b(GenericAttributes.KNOCKBACK_RESISTANCE);
- this.getAttributeMap().b(GenericAttributes.MOVEMENT_SPEED);
- this.getAttributeMap().b(GenericAttributes.ARMOR);
- this.getAttributeMap().b(GenericAttributes.ARMOR_TOUGHNESS);
-
- this.getAttributeMap().b(GenericAttributes.FOLLOW_RANGE).setValue(2.0D);
- this.getAttributeMap().b(GenericAttributes.ATTACK_KNOCKBACK);
-
- this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D);
- this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(24.0D);
- this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(32.0D);
- this.getAttributeMap().b(GenericAttributes.ATTACK_DAMAGE).setValue(3.0D);
- }
-
- @Override
- public EntityFox createChild(EntityAgeable entityageable) {
- WorldServer world = ((CraftWorld) Bukkit.getWorlds().get(0)).getHandle();
- Location location = entityageable.getBukkitEntity().getLocation();
- net.minecraft.server.v1_14_R1.Entity b = TamableFoxes.customType.b(world,
- null,
- null,
- null,
- new BlockPosition(location.getX(), location.getY(), location.getZ()),
- null, false, false);
-
- EntityFox entityfox = (EntityFox) b;
- entityfox.setFoxType(this.random.nextBoolean() ? this.getFoxType() : ((EntityFox)entityageable).getFoxType());
-
- return entityfox;
- }
-
- // Pick up items
- @Override
- protected void a(EntityItem entityitem) {
- ItemStack itemstack = entityitem.getItemStack();
- if (!isTamed() && !CraftEventFactory.callEntityPickupItemEvent(this, entityitem, itemstack.getCount() - 1, !this.g(itemstack)).isCancelled()) {
- try {
- int i = itemstack.getCount();
- if (i > 1) {
- Method method = this.getClass().getSuperclass().getDeclaredMethod("l", ItemStack.class);
- method.setAccessible(true);
- method.invoke(this, itemstack.cloneAndSubtract(i - 1));
- method.setAccessible(false);
- }
- Method method = this.getClass().getSuperclass().getDeclaredMethod("k", ItemStack.class);
- method.setAccessible(true);
- method.invoke(this, this.getEquipment(EnumItemSlot.MAINHAND));
- method.setAccessible(false);
-
- this.setSlot(EnumItemSlot.MAINHAND, itemstack.cloneAndSubtract(1));
- this.dropChanceHand[EnumItemSlot.MAINHAND.b()] = 2.0F;
- this.receive(entityitem, itemstack.getCount());
- entityitem.die();
-
- Field field = this.getClass().getSuperclass().getDeclaredField("bO");
- field.setAccessible(true);
- field.set(this, 0);
- field.setAccessible(false);
- } catch (NoSuchMethodException | NoSuchFieldException | IllegalAccessException | InvocationTargetException e) {
- e.printStackTrace();
- }
- }
- }
-
- public boolean isTamed() {
- return isTamed;
- }
-
- public void setOwner(EntityLiving owner) {
- this.owner = owner;
- fileManager.getConfig("foxes.yml").set("Foxes." + thisFox.getUniqueId() + ".owner", owner.getUniqueIDString());
- fileManager.saveConfig("foxes.yml");
- sittingRunnable = new UpdateFoxRunnable(plugin).runTask(plugin);
- }
-
- public EntityLiving getOwner() {
- return owner;
- }
-
- public void setTamed(Boolean tamed) {
- this.isTamed = tamed;
- }
-
- public boolean toggleSitting() {
- sit = !sit;
- sittingRunnable = new UpdateFoxRunnable(plugin).runTask(plugin);
- return sit;
- }
-
- public void updateFox() {
- sittingRunnable = new UpdateFoxRunnable(plugin).runTask(plugin);
- }
-
- @Nullable
- @Override
- public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) {
- BiomeBase biomebase = generatoraccess.getBiome(new BlockPosition(this));
- EntityFox.Type entityfox_type = EntityFox.Type.a(biomebase);
- boolean flag = false;
- if (groupdataentity instanceof EntityFox.i) {
- entityfox_type = ((EntityFox.i)groupdataentity).a;
- if (((EntityFox.i)groupdataentity).b >= 2) {
- flag = true;
- } else {
- ++((EntityFox.i)groupdataentity).b;
- }
- } else {
- groupdataentity = new EntityFox.i(entityfox_type);
- ++((EntityFox.i)groupdataentity).b;
- }
-
- this.setFoxType(entityfox_type);
- if (flag) {
- this.setAgeRaw(-24000);
- }
-
- this.initPathfinder();
- this.a(difficultydamagescaler);
-
- // From EntityInsentient
- this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).addModifier(new AttributeModifier("Random spawn bonus", this.random.nextGaussian() * 0.05D, AttributeModifier.Operation.MULTIPLY_BASE));
- if (this.random.nextFloat() < 0.05F) {
- this.p(true);
- } else {
- this.p(false);
- }
-
- return groupdataentity;
- }
-
- private class UpdateFoxRunnable extends BukkitRunnable {
- private final JavaPlugin plugin;
-
- public UpdateFoxRunnable(JavaPlugin plugin) {
- this.plugin = plugin;
- }
-
- @Override
- public void run() {
- TamableFox.this.goalSit.setSitting(TamableFox.this.sit);
- TamableFox.thisFox.setVelocity(new Vector(0,0,0));
-
- TamableFox.this.setGoalTarget(null, EntityTargetEvent.TargetReason.CUSTOM, true);
-
- // Set custom name
- if (TamableFox.this.owner != null && fileManager.getConfig("config.yml").get().getBoolean("show-owner-in-fox-name")) {
- getBukkitEntity().setCustomName("Tamed by: " + TamableFox.this.owner.getName());
- getBukkitEntity().setCustomNameVisible(true);
- }
- }
- }
-
- public boolean isJumping() {
- return jumping;
- }
-}
diff --git a/src/main/java/net/seanomik/tamablefoxes/TamableFoxes.java b/src/main/java/net/seanomik/tamablefoxes/TamableFoxes.java
deleted file mode 100644
index 3a1aeb7..0000000
--- a/src/main/java/net/seanomik/tamablefoxes/TamableFoxes.java
+++ /dev/null
@@ -1,464 +0,0 @@
-package net.seanomik.tamablefoxes;
-
-import com.mojang.datafixers.DataFixUtils;
-import com.mojang.datafixers.types.Type;
-import com.sun.istack.internal.NotNull;
-import net.minecraft.server.v1_14_R1.*;
-import net.seanomik.tamablefoxes.Commands.CommandSpawnTamableFox;
-import net.seanomik.tamablefoxes.Utils.FileManager;
-import org.bukkit.*;
-import org.bukkit.Chunk;
-import org.bukkit.Material;
-import org.bukkit.Particle;
-import org.bukkit.World;
-import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
-import org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity;
-import org.bukkit.craftbukkit.v1_14_R1.entity.CraftFox;
-import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer;
-import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack;
-import org.bukkit.entity.*;
-import org.bukkit.entity.Entity;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.Listener;
-import org.bukkit.event.entity.CreatureSpawnEvent;
-import org.bukkit.event.entity.EntityDeathEvent;
-import org.bukkit.event.player.*;
-import org.bukkit.event.world.ChunkLoadEvent;
-import org.bukkit.inventory.EquipmentSlot;
-import org.bukkit.inventory.meta.ItemMeta;
-import org.bukkit.plugin.java.JavaPlugin;
-
-import java.io.*;
-import java.util.*;
-import java.util.logging.Level;
-
-public final class TamableFoxes extends JavaPlugin implements Listener {
-
- public static Map foxUUIDs = new HashMap<>(); // FoxUUID, OwnerUUID
- public static EntityTypes customType;
- public static JavaPlugin plugin;
- private boolean isOnLoad = true;
- private File dataFolder = null;
-
- public static FileManager fileManager;
-
- // TODO:
- // Fix the fox moving when you make it sit while it was moving.
-
- @Override
- public void onEnable() {
- if (!Bukkit.getVersion().contains("1.14.4")) {
- Bukkit.getConsoleSender().sendMessage(Reference.CHAT_PREFIX + ChatColor.RED + "THIS PLUGIN WILL ONLY RUN ON MC SPIGOT 1.14.4!");
- getServer().getPluginManager().disablePlugin(this);
- return;
- }
-
- fileManager = new FileManager(this);
- fileManager.getConfig("foxes.yml").copyDefaults(true).save();
- fileManager.getConfig("config.yml").copyDefaults(true).save();
-
- getServer().getPluginManager().registerEvents(this, this);
- getCommand("spawntamablefox").setExecutor(new CommandSpawnTamableFox());
-
- plugin = getPlugin(this.getClass());
- dataFolder = getDataFolder();
-
- // Registering Fox
- Map> types = (Map>) DataConverterRegistry.a().getSchema(DataFixUtils.makeKey(SharedConstants.a().getWorldVersion())).findChoiceType(DataConverterTypes.ENTITY).types();
- types.put("minecraft:" + Reference.CUSTOM_FOX_REGISTER_NAME, types.get("minecraft:fox"));
- EntityTypes.a a = EntityTypes.a.a(TamableFox::new, EnumCreatureType.AMBIENT);
- customType = IRegistry.a(IRegistry.ENTITY_TYPE, Reference.CUSTOM_FOX_REGISTER_NAME, a.a(Reference.CUSTOM_FOX_REGISTER_NAME));
-
- // Spawn all foxes
- replaceFoxesOnLoad();
- }
-
- private void replaceFoxesOnLoad() {
- int amountReplaced = 0;
- World world = Bukkit.getWorlds().get(0);
- for (Chunk chunk : world.getLoadedChunks()) {
- for (Entity entity : chunk.getEntities()) {
- if(entity instanceof Fox) {
- if (isTamableFox(entity)) {
- continue;
- }
- TamableFox tamableFox = (TamableFox) spawnTamableFox(entity.getLocation(), ((CraftFox) entity).getHandle().getFoxType());
-
- if (fileManager.getConfig("foxes.yml").get().getString("Foxes." + entity.getUniqueId()) != null) {
- Bukkit.broadcastMessage("NOT NULL");
- String owner = fileManager.getConfig("foxes.yml").get().getString("Foxes." + entity.getUniqueId() + ".owner");
-
- fileManager.getConfig("foxes.yml").get().set("Foxes." + entity.getUniqueId(), null);
- if (owner.equals("none")) {
- foxUUIDs.replace(tamableFox.getUniqueID(), null);
- fileManager.getConfig("foxes.yml").get().set("Foxes." + tamableFox.getUniqueID() + ".owner", "none");
- } else {
- foxUUIDs.replace(tamableFox.getUniqueID(), UUID.fromString(owner));
- tamableFox.setTamed(true);
- fileManager.getConfig("foxes.yml").get().set("Foxes." + tamableFox.getUniqueID() + ".owner", owner);
- }
-
- tamableFox.setSitting(((EntityFox) ((CraftEntity) entity).getHandle()).isSitting());
- tamableFox.updateFox();
-
- tamableFox.setAge(((CraftFox) entity).getAge());
-
- org.bukkit.inventory.ItemStack entityMouthItem = ((CraftFox) entity).getEquipment().getItemInMainHand();
- if (entityMouthItem.getType() != Material.AIR) {
- tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(entityMouthItem.getType(), 1)));
- } else {
- tamableFox.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.AIR));
- }
- } else {
- fileManager.getConfig("foxes.yml").get().set("Foxes." + tamableFox.getUniqueID() + ".owner", "none");
- tamableFox.setAge(((CraftFox) entity).getAge());
-
- org.bukkit.inventory.ItemStack entityMouthItem = ((CraftFox) entity).getEquipment().getItemInMainHand();
- if (entityMouthItem.getType() != Material.AIR) {
- tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(entityMouthItem.getType(), 1)));
- } else {
- tamableFox.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.AIR));
- }
- }
-
- entity.remove();
- amountReplaced++;
- }
- }
- }
-
- //Bukkit.getConsoleSender().sendMessage(Reference.CHAT_PREFIX + "Respawned " + amountReplaced + " foxes.");
- fileManager.saveConfig("foxes.yml");
- isOnLoad = false;
- }
-
- public static net.minecraft.server.v1_14_R1.Entity spawnTamableFox(Location location, EntityFox.Type type) {
- WorldServer world = ((CraftWorld) Bukkit.getWorlds().get(0)).getHandle();
-
- net.minecraft.server.v1_14_R1.Entity spawnedEntity = customType.b(world,
- null,
- null,
- null,
- new BlockPosition(location.getX(), location.getY(), location.getZ()),
- null, false, false);
- world.addEntity(spawnedEntity);
-
- EntityFox fox = (EntityFox) spawnedEntity;
- fox.setFoxType(type);
- fileManager.getConfig("foxes.yml").get().set("Foxes." + spawnedEntity.getUniqueID() + ".owner", "none");
- fileManager.saveConfig("foxes.yml");
- return fox;
- }
-
- @EventHandler
- public void onChunkLoad (ChunkLoadEvent event) {
- if (!isOnLoad) {
- Chunk chunk = event.getChunk();
- for (Entity entity : chunk.getEntities()) {
- if (entity instanceof Fox) {
- if (isTamableFox(entity)) {
- continue;
- }
- TamableFox tamableFox = (TamableFox) spawnTamableFox(entity.getLocation(), ((CraftFox) entity).getHandle().getFoxType());
-
- if (fileManager.getConfig("foxes.yml").get().getString("Foxes." + entity.getUniqueId()) != null) {
- String owner = fileManager.getConfig("foxes.yml").get().getString("Foxes." + entity.getUniqueId() + ".owner");
- if (!owner.equals("none")) {
- foxUUIDs.replace(tamableFox.getUniqueID(), UUID.fromString(owner));
- fileManager.getConfig("foxes.yml").get().set("Foxes." + tamableFox.getUniqueID() + ".owner", owner);
- fileManager.getConfig("foxes.yml").get().set("Foxes." + entity.getUniqueId(), null);
- tamableFox.setTamed(true);
- tamableFox.setSitting(((EntityFox) ((CraftEntity) entity).getHandle()).isSitting());
- tamableFox.updateFox();
-
- tamableFox.setAge(((CraftFox) entity).getAge());
-
- org.bukkit.inventory.ItemStack entityMouthItem = ((CraftFox) entity).getEquipment().getItemInMainHand();
- if (entityMouthItem.getType() != Material.AIR) {
- tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(entityMouthItem.getType(), 1)));
- } else {
- tamableFox.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.AIR));
- }
- }
- } else {
- fileManager.getConfig("foxes.yml").get().set("Foxes." + tamableFox.getUniqueID() + ".owner", "none");
- tamableFox.setAge(((CraftFox) entity).getAge());
-
- org.bukkit.inventory.ItemStack entityMouthItem = ((CraftFox) entity).getEquipment().getItemInMainHand();
- if (entityMouthItem.getType() != Material.AIR) {
- tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(entityMouthItem.getType(), 1)));
- } else {
- tamableFox.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.AIR));
- }
- }
-
- entity.remove();
- }
- }
- }
- }
-
- @EventHandler
- public void onPlayerJoin(PlayerJoinEvent event) {
- Player player = event.getPlayer();
- if (foxUUIDs.containsValue(player.getUniqueId())) {
- for (Map.Entry entry : foxUUIDs.entrySet()) {
- if (entry.getValue() != null && entry.getValue().equals(player.getUniqueId())) {
- TamableFox tamableFox = (TamableFox) ((CraftEntity) getEntityByUniqueId(entry.getKey())).getHandle();
- tamableFox.setOwner(((CraftPlayer) player).getHandle());
- tamableFox.setTamed(true);
- foxUUIDs.replace(tamableFox.getUniqueID(), player.getUniqueId());
- }
- }
- }
- }
-
- @EventHandler
- public void onPlayerInteractEntityEvent(PlayerInteractEntityEvent event) {
- Entity entity = event.getRightClicked();
- Player player = event.getPlayer();
-
- if (event.getHand().equals(EquipmentSlot.HAND)) {
- ItemMeta itemMeta = player.getInventory().getItemInMainHand().getItemMeta();
- if (player.getInventory().getItemInMainHand().getType() == Material.REDSTONE_TORCH && !isTamableFox(entity) && itemMeta.getLore().contains(ChatColor.BLUE + "Tamable Fox Inspector")) {
- org.bukkit.inventory.ItemStack item = player.getInventory().getItemInMainHand();
- ItemMeta itemMeta1 = item.getItemMeta();
- List lore = new LinkedList<>(Arrays.asList(
- ChatColor.BLUE + "Tamable Fox Inspector",
- "UUID: " + entity.getUniqueId(),
- "Entity ID: " + entity.getEntityId()
- ));
- itemMeta1.setLore(lore);
- item.setItemMeta(itemMeta1);
- player.sendMessage("Inspected Entity.");
- }
-
- if (isTamableFox(entity)) {
- TamableFox tamableFox = (TamableFox) ((CraftEntity)entity).getHandle();
- if (player.getInventory().getItemInMainHand().getType() == Material.REDSTONE_TORCH && itemMeta.getLore().contains(ChatColor.BLUE + "Tamable Fox Inspector")) {
- org.bukkit.inventory.ItemStack item = player.getInventory().getItemInMainHand();
- List lore = new LinkedList<>();
- if (tamableFox.getOwner() == null) {
- lore = new LinkedList<>(Arrays.asList(
- ChatColor.BLUE + "Tamable Fox Inspector",
- "UUID: " + entity.getUniqueId(),
- "Entity ID: " + entity.getEntityId(),
- "Tamable",
- "Owner: None"
- ));
- } else {
- lore = new LinkedList<>(Arrays.asList(
- ChatColor.BLUE + "Tamable Fox Inspector",
- "UUID: " + entity.getUniqueId(),
- "Entity ID: " + entity.getEntityId(),
- "Tamable",
- "Owner: " + tamableFox.getOwner().getName()
- ));
- }
-
- itemMeta.setLore(lore);
- item.setItemMeta(itemMeta);
-
- event.setCancelled(true);
- return;
- }
-
- if (tamableFox.isTamed() && tamableFox.getOwner() != null && player.getInventory().getItemInMainHand().getType() != Material.SWEET_BERRIES) {
- if (player.getUniqueId() == foxUUIDs.get(entity.getUniqueId())) {
- if (player.isSneaking()) { // Shift right click to add items
- ItemStack itemstack = tamableFox.getEquipment(EnumItemSlot.MAINHAND);
- if (itemstack.isEmpty()) {
- if (player.getInventory().getItemInMainHand().getType() == Material.AIR) {
- return;
- }
- net.minecraft.server.v1_14_R1.ItemStack playerItemInHandNMS = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand());
-
- playerItemInHandNMS.setCount(1);
-
- // Set foxes mouth
- tamableFox.setSlot(EnumItemSlot.MAINHAND, playerItemInHandNMS);
-
- // Take item from player
- org.bukkit.inventory.ItemStack playerItemInHand = player.getInventory().getItemInMainHand();
- playerItemInHand.setAmount(playerItemInHand.getAmount() - 1);
- player.getInventory().setItemInMainHand(playerItemInHand);
- } else {
- if (player.getInventory().getItemInMainHand().getType() == Material.AIR) { //
- // Drop the item in the foxes mouth on the floor
- World world = Bukkit.getWorlds().get(0);
- world.dropItem(tamableFox.getBukkitEntity().getLocation().add(0D, 0.2D, 0D), CraftItemStack.asBukkitCopy(itemstack));
-
- // Remove the item from mouth
- tamableFox.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.AIR));
- } else { // Replace items
- net.minecraft.server.v1_14_R1.ItemStack playerItemInHandNMS = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand());
-
- // Drop the item in the foxes mouth on the floor
- World world = Bukkit.getWorlds().get(0);
- world.dropItem(tamableFox.getBukkitEntity().getLocation().add(0D, 0.2D, 0D), CraftItemStack.asBukkitCopy(itemstack));
-
- playerItemInHandNMS.setCount(1);
-
- // Set foxes mouth
- tamableFox.setSlot(EnumItemSlot.MAINHAND, playerItemInHandNMS);
-
- // Take item from player
- org.bukkit.inventory.ItemStack playerItemInHand = player.getInventory().getItemInMainHand();
- playerItemInHand.setAmount(playerItemInHand.getAmount() - 1);
- player.getInventory().setItemInMainHand(playerItemInHand);
- }
- }
- } else {
- tamableFox.toggleSitting();
- }
- event.setCancelled(true);
- }
- } else if (player.getInventory().getItemInMainHand().getType() == Material.CHICKEN) {
- if (Math.random() < 0.33) {
- tamableFox.setTamed(true);
- tamableFox.setOwner(((CraftPlayer) player).getHandle());
-
- // Add fox to foxUUIDs to get their owner and other things
- TamableFoxes.foxUUIDs.replace(tamableFox.getUniqueID(), null, player.getUniqueId());
-
- // Indicate that it was tamed
- player.getWorld().spawnParticle(Particle.HEART, entity.getLocation(), 6, 0.5D, 0.5D, 0.5D);
- } else {
- player.getWorld().spawnParticle(Particle.SMOKE_NORMAL, entity.getLocation(), 10, 0.3D, 0.3D, 0.3D, 0.15D);
- }
-
- if (!player.getGameMode().equals(GameMode.CREATIVE)) { // Remove chicken from inventory unless in creative
- player.getInventory().getItemInMainHand().setAmount(player.getInventory().getItemInMainHand().getAmount() - 1);
- }
- event.setCancelled(true);
- }
- }
- }
- }
-
- // Make it so when player sleeps, fox does too
- @EventHandler
- public void onPlayerBedEnterEvent(PlayerBedEnterEvent event) {
- Player player = event.getPlayer();
- if (foxUUIDs.containsValue(player.getUniqueId())) {
- List listOfUUIDs = new ArrayList<>();
-
- for (Map.Entry entry : foxUUIDs.entrySet()) {
- if (entry.getValue().equals(player.getUniqueId())) {
- listOfUUIDs.add(entry.getKey());
- }
- }
-
- for (UUID uuid : listOfUUIDs) {
- TamableFox tamableFox = ((TamableFox)((CraftFox)getEntityByUniqueId(uuid)).getHandle());
- if (player.getWorld().getTime() > 12541 && player.getWorld().getTime() < 23460) {
- tamableFox.setSleeping(true);
- }
- }
- }
- }
-
- // Wake the fox up when the player wakes up
- @EventHandler
- public void onPlayerBedLeaveEvent(PlayerBedLeaveEvent event) {
- Player player = event.getPlayer();
- if (foxUUIDs.containsValue(player.getUniqueId())) {
- List listOfUUIDs = new ArrayList<>();
-
- for (Map.Entry entry : foxUUIDs.entrySet()) {
- if (entry.getValue().equals(event.getPlayer().getUniqueId())) {
- listOfUUIDs.add(entry.getKey());
- }
- }
-
- for (UUID uuid : listOfUUIDs) {
- TamableFox tamableFox = ((TamableFox)((CraftFox)getEntityByUniqueId(uuid)).getHandle());
- tamableFox.setSleeping(false);
- }
- }
- }
-
- // Replace all spawned foxes with the TamableFox
- @EventHandler
- public void onCreatureSpawnEvent(CreatureSpawnEvent event) {
- Entity entity = event.getEntity();
- if(entity instanceof Fox && !(isTamableFox(entity))) {
- EntityFox.Type foxType = ((EntityFox) ((CraftEntity)entity).getHandle()).getFoxType();
- spawnTamableFox(entity.getLocation(), foxType);
- //Bukkit.getConsoleSender().sendMessage(Reference.CHAT_PREFIX + "Replaced vanilla fox");
- event.setCancelled(true);
- }
- }
-
- public Entity getEntityByUniqueId(UUID uniqueId){
- for (org.bukkit.World world : Bukkit.getWorlds()) {
- for (org.bukkit.Chunk chunk : world.getLoadedChunks()) {
- for (Entity entity : chunk.getEntities()) {
- if (entity.getUniqueId().equals(uniqueId)) {
- return entity;
- }
- }
- }
- }
-
- return null;
- }
-
- @EventHandler
- public void onEntityDeathEvent (EntityDeathEvent event) {
- Entity entity = event.getEntity();
- if (isTamableFox(entity)) {
- foxUUIDs.remove(entity.getUniqueId());
- if (fileManager.getConfig("foxes.yml").get().getConfigurationSection("Foxes").contains(entity.getUniqueId() + "")) {
- fileManager.getConfig("foxes.yml").get().set("Foxes." + entity.getUniqueId(), null);
- fileManager.saveConfig("foxes.yml");
- }
- }
- }
-
- public boolean isTamableFox(Entity entity) {
- return ((CraftEntity)entity).getHandle().getClass().getName().contains("TamableFox") || ((CraftEntity)entity).getHandle() instanceof TamableFox;
- }
-
- @Override
- public void saveResource(@NotNull String resourcePath, boolean replace) {
- File file = getFile();
- if (resourcePath != null && !resourcePath.equals("")) {
- resourcePath = resourcePath.replace('\\', '/');
- InputStream in = this.getResource(resourcePath);
- if (in == null) {
- throw new IllegalArgumentException("The embedded resource '" + resourcePath + "' cannot be found in " + file);
- } else {
- File outFile = new File(this.dataFolder, resourcePath);
- int lastIndex = resourcePath.lastIndexOf(47);
- File outDir = new File(this.dataFolder, resourcePath.substring(0, lastIndex >= 0 ? lastIndex : 0));
- if (!outDir.exists()) {
- outDir.mkdirs();
- }
-
- try {
- //if (outFile.exists() && !replace) {
- if (!outFile.exists() && replace) {
- //this.logger.log(Level.WARNING, "Could not save " + outFile.getName() + " to " + outFile + " because " + outFile.getName() + " already exists.");
- OutputStream out = new FileOutputStream(outFile);
- byte[] buf = new byte[1024];
-
- int len;
- while((len = in.read(buf)) > 0) {
- out.write(buf, 0, len);
- }
-
- out.close();
- in.close();
- } /*else {
-
- }*/
- } catch (IOException var10) {
- Bukkit.getLogger().log(Level.SEVERE, "Could not save " + outFile.getName() + " to " + outFile, var10);
- }
- }
- } else {
- throw new IllegalArgumentException("ResourcePath cannot be null or empty");
- }
- }
-}
diff --git a/src/main/java/net/seanomik/tamablefoxes/Utils/FileManager.java b/src/main/java/net/seanomik/tamablefoxes/Utils/FileManager.java
deleted file mode 100644
index 2cceca5..0000000
--- a/src/main/java/net/seanomik/tamablefoxes/Utils/FileManager.java
+++ /dev/null
@@ -1,112 +0,0 @@
-package net.seanomik.tamablefoxes.Utils;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.UnsupportedEncodingException;
-import java.util.HashMap;
-
-import org.bukkit.configuration.file.YamlConfiguration;
-import org.bukkit.plugin.java.JavaPlugin;
-
-public class FileManager {
-
- private final JavaPlugin plugin;
- private HashMap configs = new HashMap();
-
- public FileManager(JavaPlugin plugin) {
- this.plugin = plugin;
- }
-
- public Config getConfig(String name) {
- if (!configs.containsKey(name))
- configs.put(name, new Config(name));
-
- return configs.get(name);
- }
-
- public Config saveConfig(String name) {
- return getConfig(name).save();
- }
-
- public Config reloadConfig(String name) {
- return getConfig(name).reload();
- }
-
- public class Config {
- private String name;
- private File file;
- private YamlConfiguration config;
-
- public Config(String name) {
- this.name = name;
- }
-
- public Config save() {
- if ((this.config == null) || (this.file == null))
- return this;
- try
- {
- if (config.getConfigurationSection("").getKeys(true).size() != 0)
- config.save(this.file);
- }
- catch (IOException ex)
- {
- ex.printStackTrace();
- }
- return this;
- }
-
- public YamlConfiguration get() {
- if (this.config == null)
- reload();
-
- return this.config;
- }
-
- public Config saveDefaultConfig() {
- file = new File(plugin.getDataFolder(), this.name);
-
- plugin.saveResource(this.name, false);
-
- return this;
- }
-
- public Config reload() {
- if (file == null)
- this.file = new File(plugin.getDataFolder(), this.name);
-
- this.config = YamlConfiguration.loadConfiguration(file);
-
- Reader defConfigStream;
- try {
- defConfigStream = new InputStreamReader(plugin.getResource(this.name), "UTF8");
-
- if (defConfigStream != null)
- {
- YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream);
- this.config.setDefaults(defConfig);
- }
- }
- catch (UnsupportedEncodingException | NullPointerException e) {
-
- }
- return this;
- }
-
- public Config copyDefaults(boolean force) {
- get().options().copyDefaults(force);
- return this;
- }
-
- public Config set(String key, Object value) {
- get().set(key, value);
- return this;
- }
-
- public Object get(String key) {
- return get().get(key);
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/java/net/seanomik/tamablefoxes/Utils/Utils.java b/src/main/java/net/seanomik/tamablefoxes/Utils/Utils.java
deleted file mode 100644
index 099305f..0000000
--- a/src/main/java/net/seanomik/tamablefoxes/Utils/Utils.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package net.seanomik.tamablefoxes.Utils;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-public class Utils {
- public static List getAllKeysForValue(Map mapOfWords, V value) {
- List listOfKeys = null;
-
- if(mapOfWords.containsValue(value)) {
- listOfKeys = new ArrayList<>();
-
- // Iterate over each entry of map using entrySet
- for (Map.Entry entry : mapOfWords.entrySet()) {
- // Check if value matches with given value
- if (entry.getValue().equals(value))
- {
- // Store the key from entry to the list
- listOfKeys.add(entry.getKey());
- }
- }
- }
- // Return the list of keys whose value matches with given value.
- return listOfKeys;
- }
-}
diff --git a/src/main/java/net/seanomilk/tamablefoxes/EntityTamableFox.java b/src/main/java/net/seanomilk/tamablefoxes/EntityTamableFox.java
new file mode 100644
index 0000000..f300762
--- /dev/null
+++ b/src/main/java/net/seanomilk/tamablefoxes/EntityTamableFox.java
@@ -0,0 +1,237 @@
+package net.seanomilk.tamablefoxes;
+
+import net.minecraft.server.v1_15_R1.*;
+import net.seanomilk.tamablefoxes.pathfinding.*;
+import org.bukkit.ChatColor;
+import org.bukkit.Location;
+import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
+import org.bukkit.craftbukkit.v1_15_R1.event.CraftEventFactory;
+import org.bukkit.entity.Fox;
+import org.bukkit.event.entity.EntityTargetEvent;
+import org.bukkit.scheduler.BukkitRunnable;
+import org.bukkit.scheduler.BukkitTask;
+import org.bukkit.util.Vector;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public class EntityTamableFox extends EntityFox {
+
+ private static Fox thisFox;
+ private final TamableFoxes plugin;
+
+ private boolean isTamed;
+ private EntityLiving owner;
+ private String chosenName;
+ private boolean sit = false;
+ private BukkitTask sittingRunnable;
+
+ private FoxPathfindGoalSit goalSit;
+ private PathfinderGoalNearestAttackableTarget goalAttack;
+
+
+ public EntityTamableFox(TamableFoxes plugin, EntityTypes entitytypes, World world) {
+ super(EntityTypes.FOX, world);
+ this.plugin = plugin;
+ thisFox = (Fox) this.getBukkitEntity();
+ plugin.getFoxUUIDs().put(this.getBukkitEntity().getUniqueId(), null);
+ }
+
+ protected void initPathfinder() {
+ this.goalSit = new FoxPathfindGoalSit(this);
+ this.goalSelector.a(1, new FoxPathfindGoalFloat(this));
+ this.goalSelector.a(2, this.goalSit);
+ this.goalSelector.a(3, new FoxPathfindGoalMeleeAttack(this, 1.2000000476837158D, true));
+ this.goalSelector.a(3, new PathfinderGoalAvoidTarget(this, EntityWolf.class, 8.0F, 1.6D, 1.4D,
+ entityliving -> !((EntityWolf) entityliving).isTamed()));
+ this.goalSelector.a(4, new FoxPathfindGoalFollowOwner(this, 1.35D, 10.0F, 2.0F));
+ this.goalSelector.a(4, new FoxPathfindGoalLungeUNKNOWN_USE(this));
+ this.goalSelector.a(5, new FoxPathfindGoalLunge(this));
+ this.goalSelector.a(5, new FoxPathfindGoalFleeSun(this, 1.25D));
+ this.goalSelector.a(5, new FoxPathfindGoalBreed(this, 1.0D));
+ this.goalSelector.a(7, new PathfinderGoalFollowParent(this, 1.1D));
+ this.goalSelector.a(7, new FoxPathfindGoalBeg(this, 8.0F));
+ this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
+ this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this));
+ this.goalSelector.a(9, new FoxPathfindGoalPickBushes(this, 1.2000000476837158D, 12, 2));
+ this.goalSelector.a(9, new FoxPathfindGoalPickBushes(this, 1.2000000476837158D, 12, 2));
+ this.goalSelector.a(10, new FoxPathfindGoalRandomStrollLand(this, 1.0D));
+ this.targetSelector.a(1, new FoxPathfindGoalHurtByTarget(this));
+ this.targetSelector.a(2, new FoxPathfindGoalOwnerHurtByTarget(this));
+
+ this.goalAttack = new PathfinderGoalNearestAttackableTarget(this, EntityLiving.class, 10, false, false,
+ entityLiving -> !isTamed && (entityLiving instanceof EntityChicken || entityLiving instanceof EntityRabbit));
+
+ if (!isTamed || (plugin.isTamedAttackRabbitChicken() && isTamed)) {
+ this.targetSelector.a(4, goalAttack);
+ }
+
+ this.targetSelector.a(5, new FoxPathfindGoalHurtByTarget(this).a(new Class[0]));
+ }
+
+ protected void initAttributes() {
+ this.getAttributeMap().b(GenericAttributes.MAX_HEALTH);
+ this.getAttributeMap().b(GenericAttributes.KNOCKBACK_RESISTANCE);
+ this.getAttributeMap().b(GenericAttributes.MOVEMENT_SPEED);
+ this.getAttributeMap().b(GenericAttributes.ARMOR);
+ this.getAttributeMap().b(GenericAttributes.ARMOR_TOUGHNESS);
+ this.getAttributeMap().b(GenericAttributes.FOLLOW_RANGE).setValue(2.0D);
+ this.getAttributeMap().b(GenericAttributes.ATTACK_KNOCKBACK);
+ this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D);
+ this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(24.0D);
+ this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(32.0D);
+ this.getAttributeMap().b(GenericAttributes.ATTACK_DAMAGE).setValue(3.0D);
+ }
+
+ public EntityFox createChild(EntityAgeable entityageable) {
+ WorldServer world = ((CraftWorld) entityageable.getBukkitEntity().getWorld()).getHandle();
+ Location location = entityageable.getBukkitEntity().getLocation();
+ Entity b = plugin.getCustomType().b(world, null, null, null,
+ new BlockPosition(location.getX(), location.getY(), location.getZ()), null, false, false);
+ EntityFox entityfox = (EntityFox) b;
+ entityfox.setFoxType(this.random.nextBoolean() ? this.getFoxType() : ((EntityFox) entityageable).getFoxType());
+ return entityfox;
+ }
+
+ protected void a(EntityItem entityitem) {
+ ItemStack itemstack = entityitem.getItemStack();
+ if (!this.isTamed() && !CraftEventFactory.callEntityPickupItemEvent(this, entityitem,
+ itemstack.getCount() - 1, !this.g(itemstack)).isCancelled()) {
+ try {
+ int i = itemstack.getCount();
+ Method method;
+ if (i > 1) {
+ method = this.getClass().getSuperclass().getDeclaredMethod("l", ItemStack.class);
+ method.setAccessible(true);
+ method.invoke(this, itemstack.cloneAndSubtract(i - 1));
+ method.setAccessible(false);
+ }
+
+ method = this.getClass().getSuperclass().getDeclaredMethod("k", ItemStack.class);
+ method.setAccessible(true);
+ method.invoke(this, this.getEquipment(EnumItemSlot.MAINHAND));
+ method.setAccessible(false);
+ this.setSlot(EnumItemSlot.MAINHAND, itemstack.cloneAndSubtract(1));
+ this.dropChanceHand[EnumItemSlot.MAINHAND.b()] = 2.0F;
+ this.receive(entityitem, itemstack.getCount());
+ entityitem.die();
+ Field field = this.getClass().getSuperclass().getDeclaredField("bL");
+ field.setAccessible(true);
+ field.set(this, 0);
+ field.setAccessible(false);
+ } catch (NoSuchFieldException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+
+ public TamableFoxes getPlugin() {
+ return plugin;
+ }
+
+ public boolean isTamed() {
+ return this.isTamed;
+ }
+
+ public void setTamed(boolean tamed) {
+ this.isTamed = tamed;
+ // remove attack goal if now tamed
+ if (isTamed && plugin.isTamedAttackRabbitChicken())
+ this.targetSelector.a(goalAttack);
+ else this.targetSelector.a(4, goalAttack);
+ }
+
+ public String getChosenName() {
+ return chosenName;
+ }
+
+ public void setChosenName(String chosenName) {
+ this.chosenName = chosenName;
+ updateFoxVisual();
+ }
+
+ public EntityLiving getOwner() {
+ return this.owner;
+ }
+
+ public void setOwner(EntityLiving owner) {
+ this.owner = owner;
+ plugin.getConfigFoxes().set("Foxes." + getUniqueID() + ".owner", owner.getUniqueIDString()).save();
+ updateFoxVisual();
+ }
+
+ public boolean toggleSitting() {
+ this.sit = !this.sit;
+ updateFoxVisual();
+ return this.sit;
+ }
+
+ public void updateFox() {
+ updateFoxVisual();
+ }
+
+ public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler,
+ EnumMobSpawn enummobspawn, GroupDataEntity groupdataentity, NBTTagCompound nbttagcompound) {
+ BiomeBase biomebase = generatoraccess.getBiome(new BlockPosition(this));
+ Type entityfox_type = Type.a(biomebase);
+ boolean flag = false;
+ if (groupdataentity instanceof i) {
+ entityfox_type = ((i) groupdataentity).a;
+ if (((i) groupdataentity).a() >= 2) {
+ flag = true;
+ } else {
+ ((i) groupdataentity).b();
+ }
+ } else {
+ groupdataentity = new i(entityfox_type);
+ ((i) groupdataentity).b();
+ }
+
+ this.setFoxType(entityfox_type);
+ if (flag) {
+ this.setAgeRaw(-24000);
+ }
+
+ this.initPathfinder();
+ this.a(difficultydamagescaler);
+ this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).addModifier(new AttributeModifier("Random spawn bonus",
+ this.random.nextGaussian() * 0.05D, AttributeModifier.Operation.MULTIPLY_BASE));
+ if (this.random.nextFloat() < 0.05F) {
+ this.p(true);
+ } else {
+ this.p(false);
+ }
+
+ return groupdataentity;
+ }
+
+ public boolean isJumping() {
+ return this.jumping;
+ }
+
+ private void updateFoxVisual() {
+ this.sittingRunnable = new UpdateFoxRunnable(plugin).runTask(plugin);
+ }
+
+ private class UpdateFoxRunnable extends BukkitRunnable {
+
+ private final TamableFoxes plugin;
+
+ UpdateFoxRunnable(TamableFoxes plugin) {
+ this.plugin = plugin;
+ }
+
+ public void run() {
+ goalSit.setSitting(sit);
+ thisFox.setVelocity(new Vector(0, 0, 0));
+ setGoalTarget(null, EntityTargetEvent.TargetReason.CUSTOM, true);
+
+ getBukkitEntity().setCustomName((chosenName != null ? chosenName : "")
+ + (owner != null && plugin.isShowOwnerFoxName() ? ChatColor.RESET + " (" + owner.getName() + ")" : ""));
+ getBukkitEntity().setCustomNameVisible(plugin.isShowNameTags());
+ }
+ }
+
+}
diff --git a/src/main/java/net/seanomilk/tamablefoxes/TamableFoxes.java b/src/main/java/net/seanomilk/tamablefoxes/TamableFoxes.java
new file mode 100644
index 0000000..5e2dfbf
--- /dev/null
+++ b/src/main/java/net/seanomilk/tamablefoxes/TamableFoxes.java
@@ -0,0 +1,509 @@
+package net.seanomilk.tamablefoxes;
+
+import com.google.common.collect.Maps;
+import com.mojang.datafixers.DataFixUtils;
+import com.mojang.datafixers.types.Type;
+import net.seanomilk.tamablefoxes.command.CommandSpawnTamableFox;
+import net.seanomilk.tamablefoxes.io.FileManager;
+import net.minecraft.server.v1_15_R1.*;
+import org.bukkit.Chunk;
+import org.bukkit.Material;
+import org.bukkit.Particle;
+import org.bukkit.World;
+import org.bukkit.*;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
+import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity;
+import org.bukkit.craftbukkit.v1_15_R1.entity.CraftFox;
+import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
+import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.Fox;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.entity.CreatureSpawnEvent;
+import org.bukkit.event.entity.EntityDeathEvent;
+import org.bukkit.event.player.*;
+import org.bukkit.event.world.ChunkLoadEvent;
+import org.bukkit.inventory.EquipmentSlot;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+public class TamableFoxes extends JavaPlugin implements Listener {
+
+ public static final String ITEM_INSPECTOR_LORE = ChatColor.BLUE + "Tamable Fox Inspector";
+ public static final String TAG_TAME_FOX = "tameablefox";
+
+ private FileManager fileManager;
+
+ private Map foxUUIDs;
+ private EntityTypes customType;
+
+ private boolean isOnLoad = true;
+
+ private Map lookupCache;
+
+ private FileManager.Config config, configFoxes;
+
+ private Map waitingName;
+
+ @Override
+ public void onEnable() {
+ fileManager = new FileManager(this);
+ this.config = fileManager.getConfig("config.yml");
+ this.config.copyDefaults(true).save();
+ this.configFoxes = fileManager.getConfig("foxes.yml");
+ this.configFoxes.copyDefaults(true).save();
+
+ this.getServer().getPluginManager().registerEvents(this, this);
+ this.getCommand("spawntamablefox").setExecutor(new CommandSpawnTamableFox(this));
+
+ this.foxUUIDs = Maps.newHashMap();
+ this.lookupCache = Maps.newHashMap();
+ this.waitingName = Maps.newHashMap();
+
+ final Map> types = (Map>) DataConverterRegistry.a()
+ .getSchema(DataFixUtils.makeKey(SharedConstants.getGameVersion().getWorldVersion()))
+ .findChoiceType(DataConverterTypes.ENTITY).types();
+ types.put("minecraft:" + TAG_TAME_FOX, types.get("minecraft:fox"));
+
+ EntityTypes.a a = EntityTypes.a.a((entityTypes, world) ->
+ new EntityTamableFox(this, entityTypes, world), EnumCreatureType.AMBIENT);
+ customType = IRegistry.a(IRegistry.ENTITY_TYPE, "tameablefox", a.a("tameablefox"));
+
+ this.replaceFoxesOnLoad();
+ }
+
+ @Override
+ public void onDisable() {
+
+ }
+
+ private void replaceFoxesOnLoad() {
+ int amountReplaced = 0;
+
+ for (World world : Bukkit.getWorlds()) {
+ Chunk[] loadedChunks = world.getLoadedChunks();
+ for (Chunk chunk : loadedChunks) {
+ Entity[] entities = chunk.getEntities();
+ for (Entity entity : entities) {
+ if (!(entity instanceof Fox))
+ continue;
+ if (this.isTamableFox(entity))
+ continue;
+ EntityTamableFox tamableFox = (EntityTamableFox) spawnTamableFox(entity.getLocation(), ((CraftFox) entity).getHandle().getFoxType());
+
+ final YamlConfiguration configuration = configFoxes.get();
+ // get living entity data
+ if (configuration.isConfigurationSection("Foxes." + entity.getUniqueId())) {
+ String owner = configuration.getString("Foxes." + entity.getUniqueId() + ".owner");
+
+ // make new data
+ if (owner.equals("none")) {
+ foxUUIDs.replace(tamableFox.getUniqueID(), null);
+ configuration.set("Foxes." + tamableFox.getUniqueID() + ".owner", "none");
+ } else {
+ foxUUIDs.replace(tamableFox.getUniqueID(), UUID.fromString(owner));
+ tamableFox.setTamed(true);
+ configuration.set("Foxes." + tamableFox.getUniqueID() + ".owner", owner);
+ }
+
+ // set name
+ if (configuration.isSet("Foxes." + entity.getUniqueId() + ".name")) {
+ final String name = configuration.getString("Foxes." + entity.getUniqueId() + ".name");
+ configuration.set("Foxes." + tamableFox.getUniqueID() + ".name", name);
+ tamableFox.setChosenName(name);
+ }
+
+ // delete old data
+ configuration.set("Foxes." + entity.getUniqueId(), null);
+
+ tamableFox.setSitting(((EntityFox) ((CraftEntity) entity).getHandle()).isSitting());
+ tamableFox.updateFox();
+ tamableFox.setAge(((CraftFox) entity).getAge());
+ ItemStack entityMouthItem = ((CraftFox) entity).getEquipment().getItemInMainHand();
+ if (entityMouthItem.getType() != Material.AIR) {
+ tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new ItemStack(entityMouthItem.getType(), 1)));
+ } else {
+ tamableFox.setSlot(EnumItemSlot.MAINHAND, new net.minecraft.server.v1_15_R1.ItemStack(Items.AIR));
+ }
+
+ } else {
+ configuration.set("Foxes." + tamableFox.getUniqueID() + ".owner", "none");
+
+ tamableFox.setAge(((CraftFox) entity).getAge());
+ ItemStack entityMouthItem = ((CraftFox) entity).getEquipment().getItemInMainHand();
+ if (entityMouthItem.getType() != Material.AIR) {
+ tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new ItemStack(entityMouthItem.getType(), 1)));
+ } else {
+ tamableFox.setSlot(EnumItemSlot.MAINHAND, new net.minecraft.server.v1_15_R1.ItemStack(Items.AIR));
+ }
+ }
+
+ entity.remove();
+ ++amountReplaced;
+ }
+ }
+ }
+
+ configFoxes.save();
+ this.isOnLoad = false;
+ }
+
+ public net.minecraft.server.v1_15_R1.Entity spawnTamableFox(Location location, net.minecraft.server.v1_15_R1.EntityFox.Type type) {
+ WorldServer world = ((CraftWorld) location.getWorld()).getHandle();
+ net.minecraft.server.v1_15_R1.Entity spawnedEntity = customType.b(world, null, null, null,
+ new BlockPosition(location.getX(), location.getY(), location.getZ()), null, false, false);
+
+ world.addEntity(spawnedEntity);
+ EntityFox fox = (EntityFox) spawnedEntity;
+ fox.setFoxType(type);
+
+ configFoxes.get().set("Foxes." + spawnedEntity.getUniqueID() + ".owner", "none");
+ fileManager.saveConfig("foxes.yml");
+ return fox;
+ }
+
+ @EventHandler
+ public void onChunkLoad(ChunkLoadEvent event) {
+ if (isOnLoad)
+ return;
+ Chunk chunk = event.getChunk();
+ Entity[] entities = chunk.getEntities();
+
+ for (Entity entity : entities) {
+ if (entity instanceof Fox && !this.isTamableFox(entity)) {
+ EntityTamableFox tamableFox = (EntityTamableFox) spawnTamableFox(entity.getLocation(), ((CraftFox) entity).getHandle().getFoxType());
+ final YamlConfiguration configuration = configFoxes.get();
+ // if has data
+ if (configuration.isConfigurationSection("Foxes." + entity.getUniqueId())) {
+ String owner = configuration.getString("Foxes." + entity.getUniqueId() + ".owner", "none");
+
+ // if has owner
+ if (!owner.equals("none")) {
+ foxUUIDs.replace(tamableFox.getUniqueID(), UUID.fromString(owner));
+ configuration.set("Foxes." + tamableFox.getUniqueID() + ".owner", owner);
+
+ // set name
+ if (configuration.isSet("Foxes." + entity.getUniqueId() + ".name")) {
+ String name = configuration.getString("Foxes." + entity.getUniqueId() + ".name");
+
+ configuration.set("Foxes." + tamableFox.getUniqueID() + ".name", name);
+ tamableFox.setChosenName(name);
+ }
+
+ // remove old data
+ configuration.set("Foxes." + entity.getUniqueId(), null);
+
+ tamableFox.setTamed(true);
+ tamableFox.setSitting(((EntityFox) ((CraftEntity) entity).getHandle()).isSitting());
+ tamableFox.updateFox();
+ tamableFox.setAge(((CraftFox) entity).getAge());
+ ItemStack entityMouthItem = ((CraftFox) entity).getEquipment().getItemInMainHand();
+ if (entityMouthItem.getType() != Material.AIR) {
+ tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new ItemStack(entityMouthItem.getType(), 1)));
+ } else {
+ tamableFox.setSlot(EnumItemSlot.MAINHAND, new net.minecraft.server.v1_15_R1.ItemStack(Items.AIR));
+ }
+ }
+ } else {
+ configuration.set("Foxes." + tamableFox.getUniqueID() + ".owner", "none");
+
+ tamableFox.setAge(((CraftFox) entity).getAge());
+ ItemStack entityMouthItem = ((CraftFox) entity).getEquipment().getItemInMainHand();
+ if (entityMouthItem.getType() != Material.AIR) {
+ tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new ItemStack(entityMouthItem.getType(), 1)));
+ } else {
+ tamableFox.setSlot(EnumItemSlot.MAINHAND, new net.minecraft.server.v1_15_R1.ItemStack(Items.AIR));
+ }
+ }
+
+ entity.remove();
+ }
+ }
+
+ }
+
+ @EventHandler
+ public void onPlayerJoin(PlayerJoinEvent event) {
+ Player player = event.getPlayer();
+
+ getFoxesOf(player).forEach(uuid -> {
+ EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) this.getEntityByUniqueId(uuid)).getHandle();
+ tamableFox.setOwner(((CraftPlayer) player).getHandle());
+ tamableFox.setTamed(true);
+ foxUUIDs.replace(tamableFox.getUniqueID(), player.getUniqueId());
+ });
+ }
+
+ @EventHandler
+ public void onPlayerInteractEntityEvent(PlayerInteractEntityEvent event) {
+ Entity entity = event.getRightClicked();
+ Player player = event.getPlayer();
+
+ if (event.getHand() != EquipmentSlot.HAND)
+ return;
+
+ final ItemStack playerHand = player.getInventory().getItemInMainHand();
+ ItemMeta itemMeta = playerHand.getItemMeta();
+
+ if (itemMeta != null && playerHand.getType() == Material.REDSTONE_TORCH
+ && itemMeta.hasLore() && itemMeta.getLore().contains(ITEM_INSPECTOR_LORE)) {
+ List lore;
+
+ if (!this.isTamableFox(entity)) {
+ lore = Arrays.asList(ITEM_INSPECTOR_LORE,
+ "UUID: " + entity.getUniqueId(),
+ "Entity ID: " + entity.getEntityId());
+ } else {
+ EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) entity).getHandle();
+
+ if (tamableFox.getOwner() == null) {
+ lore = Arrays.asList(ITEM_INSPECTOR_LORE,
+ "UUID: " + entity.getUniqueId(),
+ "Entity ID: " + entity.getEntityId(),
+ "Tamable",
+ "Owner: None");
+ } else {
+ lore = Arrays.asList(ITEM_INSPECTOR_LORE,
+ "UUID: " + entity.getUniqueId(),
+ "Entity ID: " + entity.getEntityId(),
+ "Tamable",
+ "Owner: " + tamableFox.getOwner().getName());
+ }
+ }
+
+ // update item
+ itemMeta.setLore(lore);
+ playerHand.setItemMeta(itemMeta);
+ player.getInventory().setItemInMainHand(playerHand);
+
+ event.setCancelled(true);
+ player.sendMessage(getPrefix() + "Inspected Entity.");
+ return;
+ }
+
+ if (this.isTamableFox(entity)) {
+ EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) entity).getHandle();
+
+ if (tamableFox.isTamed() && tamableFox.getOwner() != null &&
+ playerHand.getType() != Material.SWEET_BERRIES) {
+ // if this fox is theirs
+ if (foxUUIDs.get(entity.getUniqueId()).equals(player.getUniqueId())) {
+ if (player.isSneaking()) {
+ net.minecraft.server.v1_15_R1.ItemStack wolfHolding = tamableFox.getEquipment(EnumItemSlot.MAINHAND);
+ net.minecraft.server.v1_15_R1.ItemStack playerItemInHandNMS;
+ if (wolfHolding.isEmpty()) {
+ if (playerHand.getType() == Material.AIR) {
+ return;
+ }
+
+ playerItemInHandNMS = CraftItemStack.asNMSCopy(playerHand);
+ playerItemInHandNMS.setCount(1);
+ tamableFox.setSlot(EnumItemSlot.MAINHAND, playerItemInHandNMS);
+ playerHand.setAmount(playerHand.getAmount() - 1);
+ player.getInventory().setItemInMainHand(playerHand);
+ } else if (playerHand.getType() == Material.AIR) {
+ entity.getWorld().dropItem(tamableFox.getBukkitEntity().getLocation().add(0.0D, 0.2D, 0.0D),
+ CraftItemStack.asBukkitCopy(wolfHolding));
+ tamableFox.setSlot(EnumItemSlot.MAINHAND, new net.minecraft.server.v1_15_R1.ItemStack(Items.AIR));
+ } else {
+ playerItemInHandNMS = CraftItemStack.asNMSCopy(playerHand);
+ entity.getWorld().dropItem(tamableFox.getBukkitEntity().getLocation().add(0.0D, 0.2D, 0.0D),
+ CraftItemStack.asBukkitCopy(wolfHolding));
+ playerItemInHandNMS.setCount(1);
+ tamableFox.setSlot(EnumItemSlot.MAINHAND, playerItemInHandNMS);
+ playerHand.setAmount(playerHand.getAmount() - 1);
+ player.getInventory().setItemInMainHand(playerHand);
+ }
+ } else {
+ tamableFox.toggleSitting();
+ }
+
+ event.setCancelled(true);
+ }
+ } else if (playerHand.getType() == Material.CHICKEN) {
+ if (Math.random() < 0.33D) {
+ tamableFox.setTamed(true);
+ tamableFox.setOwner(((CraftPlayer) player).getHandle());
+ foxUUIDs.replace(tamableFox.getUniqueID(), null, player.getUniqueId());
+ player.getWorld().spawnParticle(Particle.HEART, entity.getLocation(), 6, 0.5D, 0.5D, 0.5D);
+
+ // Name process
+ player.sendMessage(ChatColor.RED + ChatColor.BOLD.toString() + "You just tamed a wild fox!");
+ player.sendMessage(ChatColor.RED + "What do you want to call it?");
+ player.sendMessage(ChatColor.GRAY + "Type a name in chat");
+ waitingName.put(player, tamableFox.getUniqueID());
+ tamableFox.setChosenName("???");
+
+ } else {
+ player.getWorld().spawnParticle(Particle.SMOKE_NORMAL, entity.getLocation(), 10, 0.3D, 0.3D, 0.3D, 0.15D);
+ }
+
+ if (!player.getGameMode().equals(GameMode.CREATIVE)) {
+ playerHand.setAmount(playerHand.getAmount() - 1);
+ }
+
+ event.setCancelled(true);
+ }
+ }
+
+ }
+
+ @EventHandler
+ public void onChat(AsyncPlayerChatEvent event) {
+ final Player player = event.getPlayer();
+
+ final UUID foxUuid = waitingName.get(player);
+ if (foxUuid == null)
+ return;
+
+ event.setCancelled(true);
+
+ final Entity entityFox = getEntityByUniqueId(foxUuid);
+ if (entityFox == null || entityFox.isDead()) {
+ player.sendMessage(ChatColor.RED + "R.I.P Foxy :(");
+ waitingName.remove(player);
+ return;
+ }
+
+ EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) entityFox).getHandle();
+
+ final String chosenName = ChatColor.translateAlternateColorCodes('&', event.getMessage().trim());
+ tamableFox.setChosenName(chosenName);
+
+ configFoxes.set("Foxes." + entityFox.getUniqueId() + ".name", chosenName).save();
+
+ player.sendMessage(chosenName + ChatColor.RESET + ChatColor.GREEN + " is perfect.");
+ waitingName.remove(player);
+ }
+
+ @EventHandler
+ public void onPlayerBedEnterEvent(PlayerBedEnterEvent event) {
+ Player player = event.getPlayer();
+ List dogsToSleep = getFoxesOf(player);
+
+ for (UUID uuid : dogsToSleep) {
+ EntityTamableFox tamableFox = (EntityTamableFox) ((CraftFox) this.getEntityByUniqueId(uuid)).getHandle();
+ if (player.getWorld().getTime() > 12541L && player.getWorld().getTime() < 23460L) {
+ tamableFox.setSleeping(true);
+ }
+ }
+
+ }
+
+ @EventHandler
+ public void onPlayerBedLeaveEvent(PlayerBedLeaveEvent event) {
+ Player player = event.getPlayer();
+ final List foxesOf = getFoxesOf(player);
+
+ for (UUID uuid : foxesOf) {
+ EntityTamableFox tamableFox = (EntityTamableFox) ((CraftFox) this.getEntityByUniqueId(uuid)).getHandle();
+ tamableFox.setSleeping(false);
+ }
+
+ }
+
+ @EventHandler
+ public void onCreatureSpawnEvent(CreatureSpawnEvent event) {
+ org.bukkit.entity.Entity entity = event.getEntity();
+ if (entity instanceof Fox && !this.isTamableFox(entity)) {
+ net.minecraft.server.v1_15_R1.EntityFox.Type foxType = ((EntityFox) ((CraftEntity) entity).getHandle()).getFoxType();
+ spawnTamableFox(entity.getLocation(), foxType);
+ event.setCancelled(true);
+ }
+
+ }
+
+ public Entity getEntityByUniqueId(UUID uniqueId) {
+ final Entity cacheEntity = lookupCache.get(uniqueId);
+ if (cacheEntity != null) {
+ if (cacheEntity.isDead())
+ lookupCache.remove(uniqueId);
+ else return cacheEntity;
+ }
+
+ for (World world : Bukkit.getWorlds()) {
+ for (Chunk loadedChunk : world.getLoadedChunks()) {
+ for (Entity entity : loadedChunk.getEntities()) {
+ if (entity.getUniqueId().equals(uniqueId)) {
+ this.lookupCache.put(uniqueId, entity);
+ return entity;
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @EventHandler
+ public void onEntityDeathEvent(EntityDeathEvent event) {
+ Entity entity = event.getEntity();
+ if (!this.isTamableFox(entity))
+ return;
+ this.lookupCache.remove(entity.getUniqueId());
+ foxUUIDs.remove(entity.getUniqueId());
+
+ if (configFoxes.get().getConfigurationSection("Foxes").contains(entity.getUniqueId().toString())) {
+ configFoxes.get().set("Foxes." + entity.getUniqueId(), null);
+ fileManager.saveConfig("foxes.yml");
+ }
+
+ }
+
+ public boolean isTamableFox(org.bukkit.entity.Entity entity) {
+ return ((CraftEntity) entity).getHandle().getClass().getName().contains("TamableFox")
+ || ((CraftEntity) entity).getHandle() instanceof EntityTamableFox;
+ }
+
+ public List getFoxesOf(Player player) {
+ return foxUUIDs.entrySet().stream().filter(foxPlayer -> foxPlayer.getValue() != null && foxPlayer.getValue().equals(player.getUniqueId()))
+ .map(Map.Entry::getKey).collect(Collectors.toList());
+ }
+
+ public FileManager getFileManager() {
+ return fileManager;
+ }
+
+ public FileManager.Config getMainConfig() {
+ return config;
+ }
+
+ public FileManager.Config getConfigFoxes() {
+ return configFoxes;
+ }
+
+ public EntityTypes getCustomType() {
+ return customType;
+ }
+
+ public Map getFoxUUIDs() {
+ return foxUUIDs;
+ }
+
+ public String getPrefix() {
+ return ChatColor.translateAlternateColorCodes('&', (String) config.get("prefix"));
+ }
+
+ public boolean isShowOwnerFoxName() {
+ return (boolean) config.get("show-owner-in-fox-name");
+ }
+
+ public boolean isShowNameTags() {
+ return (boolean) config.get("show-nametags");
+ }
+
+ public boolean isTamedAttackRabbitChicken() {
+ return (boolean) config.get("tamed-behavior.no-attack-chicken-rabbit");
+ }
+
+}
diff --git a/src/main/java/net/seanomilk/tamablefoxes/command/CommandSpawnTamableFox.java b/src/main/java/net/seanomilk/tamablefoxes/command/CommandSpawnTamableFox.java
new file mode 100644
index 0000000..b9380ab
--- /dev/null
+++ b/src/main/java/net/seanomilk/tamablefoxes/command/CommandSpawnTamableFox.java
@@ -0,0 +1,81 @@
+package net.seanomilk.tamablefoxes.command;
+
+import net.seanomilk.tamablefoxes.TamableFoxes;
+import net.minecraft.server.v1_15_R1.EntityFox;
+import org.bukkit.ChatColor;
+import org.bukkit.Material;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+import java.util.Collections;
+import java.util.List;
+
+public class CommandSpawnTamableFox implements CommandExecutor {
+
+ private final TamableFoxes plugin;
+
+ public CommandSpawnTamableFox(TamableFoxes plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ if (!(sender instanceof Player)) {
+ sender.sendMessage("Command can only be run from player state.");
+ return true;
+ }
+
+ if (!sender.hasPermission("tamablefoxes.spawntamablefox")) {
+ sender.sendMessage(ChatColor.RED + "You do not have the permission for this command.");
+ return true;
+ }
+
+ Player player = (Player) sender;
+ if (args.length != 0) {
+ switch (args[0]) {
+ case "red":
+ plugin.spawnTamableFox(player.getLocation(), EntityFox.Type.RED);
+ player.sendMessage(plugin.getPrefix() + ChatColor.RESET + "Spawned a " + ChatColor.RED + "Red" + ChatColor.WHITE + " fox.");
+ break;
+ case "snow":
+ plugin.spawnTamableFox(player.getLocation(), EntityFox.Type.SNOW);
+ player.sendMessage(plugin.getPrefix() + ChatColor.RESET + "Spawned a Snow fox.");
+ break;
+ case "verbose":
+ player.sendMessage(plugin.getFoxUUIDs().toString());
+ break;
+ case "inspect":
+ ItemStack itemStack = new ItemStack(Material.REDSTONE_TORCH, 1);
+ ItemMeta itemMeta = itemStack.getItemMeta();
+ List lore = Collections.singletonList(TamableFoxes.ITEM_INSPECTOR_LORE);
+ itemMeta.setLore(lore);
+ itemStack.setItemMeta(itemMeta);
+
+ if (player.getInventory().getItemInMainHand().getType() == Material.AIR) {
+ player.getInventory().setItemInMainHand(itemStack);
+ player.sendMessage(plugin.getPrefix() + ChatColor.GREEN + "Given Inspector item.");
+ } else if (player.getInventory().firstEmpty() == -1) {
+ player.sendMessage(plugin.getPrefix() + ChatColor.RED + "Your inventory is full!");
+ } else {
+ player.sendMessage(plugin.getPrefix() + ChatColor.GREEN + "Added item to inventory.");
+ player.getInventory().addItem(itemStack);
+ }
+ break;
+ case "reload":
+ plugin.getMainConfig().reload();
+ plugin.getConfigFoxes().reload();
+ player.sendMessage(plugin.getPrefix() + ChatColor.GREEN + "Reloaded.");
+ break;
+ }
+ } else {
+ player.sendMessage(ChatColor.RED + "/spawntamablefox " + ChatColor.GRAY + "[red | snow | verbose | inspect | reload]");
+ }
+
+ return true;
+ }
+
+}
diff --git a/src/main/java/net/seanomilk/tamablefoxes/io/FileManager.java b/src/main/java/net/seanomilk/tamablefoxes/io/FileManager.java
new file mode 100644
index 0000000..18b7a7d
--- /dev/null
+++ b/src/main/java/net/seanomilk/tamablefoxes/io/FileManager.java
@@ -0,0 +1,113 @@
+package net.seanomilk.tamablefoxes.io;
+
+import com.google.common.collect.Maps;
+import net.seanomilk.tamablefoxes.TamableFoxes;
+import org.bukkit.configuration.file.YamlConfiguration;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+
+public class FileManager {
+
+ private final TamableFoxes plugin;
+ private HashMap configs;
+
+ public FileManager(TamableFoxes plugin) {
+ this.plugin = plugin;
+ this.configs = Maps.newHashMap();
+ }
+
+ public Config getConfig(String name) {
+ if (!this.configs.containsKey(name)) {
+ this.configs.put(name, new Config(name));
+ }
+
+ return this.configs.get(name);
+ }
+
+ public Config saveConfig(String name) {
+ return this.getConfig(name).save();
+ }
+
+ public Config reloadConfig(String name) {
+ return this.getConfig(name).reload();
+ }
+
+ public class Config {
+ private String name;
+ private File file;
+ private YamlConfiguration config;
+
+ public Config(String name) {
+ this.name = name;
+ }
+
+ public Config save() {
+ if (this.config != null && this.file != null) {
+ try {
+ if (this.config.getKeys(true).size() != 0) {
+ this.config.save(this.file);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return this;
+ } else {
+ return this;
+ }
+ }
+
+ public YamlConfiguration get() {
+ if (this.config == null) {
+ this.reload();
+ }
+
+ return this.config;
+ }
+
+ public Config saveDefaultConfig() {
+ this.file = new File(plugin.getDataFolder(), this.name);
+ plugin.saveResource(this.name, false);
+ return this;
+ }
+
+ public Config reload() {
+ if (this.file == null) {
+ this.file = new File(plugin.getDataFolder(), this.name);
+ }
+
+ this.config = YamlConfiguration.loadConfiguration(this.file);
+
+ try {
+ Reader defConfigStream = new InputStreamReader(plugin.getResource(this.name), StandardCharsets.UTF_8);
+ if (defConfigStream != null) {
+ YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream);
+ this.config.setDefaults(defConfig);
+ }
+ } catch (NullPointerException ignored) {
+ }
+
+ return this;
+ }
+
+ public Config copyDefaults(boolean force) {
+ this.get().options().copyDefaults(force);
+ return this;
+ }
+
+ public Config set(String key, Object value) {
+ this.get().set(key, value);
+ return this;
+ }
+
+ public Object get(String key) {
+ return this.get().get(key);
+ }
+ }
+
+}
diff --git a/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalBeg.java b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalBeg.java
new file mode 100644
index 0000000..c2e3a8d
--- /dev/null
+++ b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalBeg.java
@@ -0,0 +1,64 @@
+package net.seanomilk.tamablefoxes.pathfinding;
+
+import net.seanomilk.tamablefoxes.EntityTamableFox;
+import net.minecraft.server.v1_15_R1.*;
+
+import java.util.EnumSet;
+
+public class FoxPathfindGoalBeg extends PathfinderGoal {
+
+ private final EntityFox a;
+ private final EntityTamableFox z;
+ private final World c;
+ private final float d;
+ private final PathfinderTargetCondition f;
+ private EntityHuman b;
+ private int e;
+
+ public FoxPathfindGoalBeg(EntityTamableFox tamableFox, float var1) {
+ this.a = tamableFox;
+ this.c = tamableFox.world;
+ this.d = var1;
+ this.f = (new PathfinderTargetCondition()).a((double) var1).a().b().d();
+ this.a(EnumSet.of(PathfinderGoal.Type.LOOK));
+ this.z = tamableFox;
+ }
+
+ public boolean a() {
+ this.b = this.c.a(this.f, this.a);
+ return this.b != null && this.a(this.b);
+ }
+
+ public boolean b() {
+ if (!this.b.isAlive()) {
+ return false;
+ } else if (this.a.h(this.b) > (double) (this.d * this.d)) {
+ return false;
+ } else {
+ return this.e > 0 && this.a(this.b);
+ }
+ }
+
+ public void e() {
+ this.a.getControllerLook().a(this.b.locX(), this.b.locY() + (double) this.b.getHeadHeight(), this.b.locZ(), 10.0F, (float) this.a.dU());
+ --this.e;
+ }
+
+ private boolean a(EntityHuman var0) {
+ EnumHand[] var2 = EnumHand.values();
+ int var3 = var2.length;
+
+ for (int var4 = 0; var4 < var3; ++var4) {
+ if (this.z.isTamed() && var0.getItemInMainHand().getItem() == Items.SWEET_BERRIES) {
+ return true;
+ }
+
+ if (this.a.i(var0.getItemInMainHand())) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+}
diff --git a/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalBreed.java b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalBreed.java
new file mode 100644
index 0000000..03f0282
--- /dev/null
+++ b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalBreed.java
@@ -0,0 +1,113 @@
+package net.seanomilk.tamablefoxes.pathfinding;
+
+import net.seanomilk.tamablefoxes.EntityTamableFox;
+import net.minecraft.server.v1_15_R1.*;
+import org.bukkit.craftbukkit.v1_15_R1.event.CraftEventFactory;
+import org.bukkit.event.entity.CreatureSpawnEvent;
+import org.bukkit.event.entity.EntityBreedEvent;
+
+import javax.annotation.Nullable;
+import java.util.EnumSet;
+import java.util.List;
+
+public class FoxPathfindGoalBreed extends PathfinderGoal {
+
+ private static final PathfinderTargetCondition d = new PathfinderTargetCondition().a(8.0D).a().b().c();
+ protected final EntityTamableFox animal;
+ protected final World b;
+ private final Class extends EntityAnimal> e;
+ private final double g;
+ protected EntityAnimal partner;
+ private int f;
+
+ public FoxPathfindGoalBreed(EntityTamableFox entity, double d0) {
+ this(entity, d0, entity.getClass());
+ }
+
+ public FoxPathfindGoalBreed(EntityTamableFox entity, double d0, Class extends EntityAnimal> oclass) {
+ this.animal = entity;
+ this.b = entity.world;
+ this.e = oclass;
+ this.g = d0;
+ a(EnumSet.of(PathfinderGoal.Type.MOVE, PathfinderGoal.Type.LOOK));
+ }
+
+ public boolean a() {
+ if (!this.animal.isInLove()) {
+ return false;
+ }
+ this.partner = h();
+ return this.partner != null;
+ }
+
+ public boolean b() {
+ return (this.partner.isAlive()) && (this.partner.isInLove()) && (this.f < 60);
+ }
+
+ public void d() {
+ this.partner = null;
+ this.f = 0;
+ }
+
+ public void e() {
+ this.animal.getControllerLook().a(this.partner, 10.0F, this.animal.dU());
+ this.animal.getNavigation().a(this.partner, this.g);
+ this.f += 1;
+ if ((this.f >= 60) && (this.animal.h(this.partner) < 9.0D)) {
+ g();
+ }
+ }
+
+ @Nullable
+ private EntityAnimal h() {
+ List list = this.b.a(this.e, d, this.animal, this.animal.getBoundingBox().g(8.0D));
+ double d0 = Double.MAX_VALUE;
+ EntityAnimal entityanimal = null;
+ for (EntityAnimal entityAnimal : list) {
+ if ((this.animal.mate(entityAnimal)) && (this.animal.h(entityAnimal) < d0)) {
+ entityanimal = entityAnimal;
+ d0 = this.animal.h(entityAnimal);
+ }
+ }
+ return entityanimal;
+ }
+
+ protected void g() {
+ EntityAgeable entityAgeable = this.animal.createChild(this.animal);
+ EntityTamableFox tamableFoxAgeable = (EntityTamableFox) entityAgeable.getBukkitEntity().getHandle();
+ if (tamableFoxAgeable != null) {
+ EntityPlayer entityplayer = this.animal.getBreedCause();
+ if ((entityplayer == null) && (this.partner.getBreedCause() != null)) {
+ entityplayer = this.partner.getBreedCause();
+ }
+ int experience = this.animal.getRandom().nextInt(7) + 1;
+ EntityBreedEvent entityBreedEvent = CraftEventFactory.callEntityBreedEvent(entityAgeable, this.animal, this.partner, entityplayer, this.animal.breedItem, experience);
+ if (entityBreedEvent.isCancelled()) {
+ return;
+ }
+ experience = entityBreedEvent.getExperience();
+ if (entityplayer != null) {
+ entityplayer.a(StatisticList.ANIMALS_BRED);
+ CriterionTriggers.o.a(entityplayer, this.animal, this.partner, entityAgeable);
+ }
+ this.animal.setAgeRaw(6000);
+ this.partner.setAgeRaw(6000);
+ this.animal.resetLove();
+ this.partner.resetLove();
+ entityAgeable.setAgeRaw(41536);
+ entityAgeable.setPositionRotation(this.animal.locX(), this.animal.locY(), this.animal.locZ(), 0.0F, 0.0F);
+ this.b.addEntity(entityAgeable, CreatureSpawnEvent.SpawnReason.BREEDING);
+ this.b.broadcastEntityEffect(this.animal, (byte) 18);
+
+ EntityTamableFox tamableFoxBaby = (EntityTamableFox) entityAgeable;
+ tamableFoxBaby.setTamed(Boolean.TRUE);
+ tamableFoxBaby.setOwner(entityplayer);
+
+ animal.getPlugin().getFoxUUIDs().replace(tamableFoxBaby.getUniqueID(), null, entityplayer.getUniqueID());
+ if ((this.b.getGameRules().getBoolean(GameRules.DO_MOB_LOOT)) && (experience > 0)) {
+ this.b.addEntity(new EntityExperienceOrb(this.b, this.animal.locX(), this.animal.locY(), this.animal.locZ(), experience));
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalFleeSun.java b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalFleeSun.java
new file mode 100644
index 0000000..bbbf9cb
--- /dev/null
+++ b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalFleeSun.java
@@ -0,0 +1,55 @@
+package net.seanomilk.tamablefoxes.pathfinding;
+
+import net.seanomilk.tamablefoxes.EntityTamableFox;
+import net.minecraft.server.v1_15_R1.BlockPosition;
+import net.minecraft.server.v1_15_R1.PathfinderGoalFleeSun;
+import net.minecraft.server.v1_15_R1.WorldServer;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public class FoxPathfindGoalFleeSun extends PathfinderGoalFleeSun {
+
+ protected EntityTamableFox tamableFox;
+ private int c = 100;
+
+ public FoxPathfindGoalFleeSun(EntityTamableFox tamableFox, double d0) {
+ super(tamableFox, d0);
+ this.tamableFox = tamableFox;
+ }
+
+ public boolean a() {
+ if (this.tamableFox.isTamed()) {
+ return false;
+ } else if (!this.tamableFox.isSleeping() && this.a.getGoalTarget() == null) {
+ if (this.tamableFox.world.U()) {
+ return true;
+ } else if (this.c > 0) {
+ --this.c;
+ return false;
+ } else {
+ this.c = 100;
+ BlockPosition blockposition = new BlockPosition(this.a);
+ return this.tamableFox.world.isDay() && this.tamableFox.world.f(blockposition) && !((WorldServer) this.tamableFox.world).b_(blockposition)
+ && this.g();
+ }
+ } else {
+ return false;
+ }
+ }
+
+ public void c() {
+ try {
+ Class> entityFoxClass = Class.forName("net.minecraft.server.v1_15_R1.EntityFox");
+ Method method = entityFoxClass.getDeclaredMethod("eH");
+ method.setAccessible(true);
+ method.invoke(this.tamableFox);
+ method.setAccessible(false);
+ } catch (IllegalAccessException | InvocationTargetException | ClassNotFoundException | NoSuchMethodException var3) {
+ var3.printStackTrace();
+ }
+
+ super.c();
+ }
+
+}
diff --git a/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalFloat.java b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalFloat.java
new file mode 100644
index 0000000..3d98611
--- /dev/null
+++ b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalFloat.java
@@ -0,0 +1,34 @@
+package net.seanomilk.tamablefoxes.pathfinding;
+
+import net.seanomilk.tamablefoxes.EntityTamableFox;
+import net.minecraft.server.v1_15_R1.PathfinderGoalFloat;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public class FoxPathfindGoalFloat extends PathfinderGoalFloat {
+
+ protected EntityTamableFox tamableFox;
+
+ public FoxPathfindGoalFloat(EntityTamableFox tamableFox) {
+ super(tamableFox);
+ this.tamableFox = tamableFox;
+ }
+
+ public void c() {
+ try {
+ super.c();
+ Method method = this.tamableFox.getClass().getSuperclass().getDeclaredMethod("eH");
+ method.setAccessible(true);
+ method.invoke(this.tamableFox);
+ method.setAccessible(false);
+ } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public boolean a() {
+ return this.tamableFox.isInWater() && this.tamableFox.co() > 0.25D || this.tamableFox.aH();
+ }
+
+}
diff --git a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalFollowOwner.java b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalFollowOwner.java
similarity index 71%
rename from src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalFollowOwner.java
rename to src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalFollowOwner.java
index 03ac84b..9e447cf 100644
--- a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalFollowOwner.java
+++ b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalFollowOwner.java
@@ -1,103 +1,105 @@
-package net.seanomik.tamablefoxes.CustomPathfinding;
-
-import net.minecraft.server.v1_14_R1.*;
-import net.seanomik.tamablefoxes.TamableFox;
-import org.bukkit.Location;
-import org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity;
-import org.bukkit.event.entity.EntityTeleportEvent;
-
-import java.util.EnumSet;
-
-public class FoxPathfinderGoalFollowOwner extends PathfinderGoal {
- protected final TamableFox a;
- private EntityLiving c;
- protected final IWorldReader b;
- private final double d;
- private final NavigationAbstract e;
- private int f;
- private final float g;
- private final float h;
- private float i;
-
- public FoxPathfinderGoalFollowOwner(TamableFox tamableFox, double d0, float f, float f1) {
- this.a = tamableFox;
- this.b = tamableFox.world;
- this.d = d0;
- this.e = tamableFox.getNavigation();
- this.h = f;
- this.g = f1;
- this.a(EnumSet.of(Type.MOVE, Type.LOOK));
- if (!(tamableFox.getNavigation() instanceof Navigation) && !(tamableFox.getNavigation() instanceof NavigationFlying)) {
- throw new IllegalArgumentException("Unsupported mob type for FollowOwnerGoal");
- }
- }
-
- public boolean a() {
- EntityLiving entityliving = this.a.getOwner();
- if (entityliving == null) {
- return false;
- } else if (entityliving instanceof EntityHuman && ((EntityHuman)entityliving).isSpectator()) {
- return false;
- } else if (this.a.isSitting()) {
- return false;
- } else if (this.a.h(entityliving) < (double)(this.h * this.h)) {
- return false;
- } else {
- this.c = entityliving;
- return true;
- }
- }
-
- public boolean b() {
- return !this.e.n() && this.a.h(this.c) > (double)(this.g * this.g) && !this.a.isSitting();
- }
-
- public void c() {
- this.f = 0;
- this.i = this.a.a(PathType.WATER);
- this.a.a(PathType.WATER, 0.0F);
- }
-
- public void d() {
- this.c = null;
- this.e.o();
- this.a.a(PathType.WATER, this.i);
- }
-
- public void e() {
- this.a.getControllerLook().a(this.c, 10.0F, (float)this.a.M());
- if (!this.a.isSitting() && --this.f <= 0) {
- this.f = 10;
- if (!this.e.a(this.c, this.d) && !this.a.isLeashed() && !this.a.isPassenger() && this.a.h(this.c) >= 144.0D) {
- int i = MathHelper.floor(this.c.locX) - 2;
- int j = MathHelper.floor(this.c.locZ) - 2;
- int k = MathHelper.floor(this.c.getBoundingBox().minY);
-
- for(int l = 0; l <= 4; ++l) {
- for(int i1 = 0; i1 <= 4; ++i1) {
- if ((l < 1 || i1 < 1 || l > 3 || i1 > 3) && this.a(new BlockPosition(i + l, k - 1, j + i1))) {
- CraftEntity entity = this.a.getBukkitEntity();
- Location to = new Location(entity.getWorld(), (double)((float)(i + l) + 0.5F), (double)k, (double)((float)(j + i1) + 0.5F), this.a.yaw, this.a.pitch);
- EntityTeleportEvent event = new EntityTeleportEvent(entity, entity.getLocation(), to);
- this.a.world.getServer().getPluginManager().callEvent(event);
- if (event.isCancelled()) {
- return;
- }
-
- to = event.getTo();
- this.a.setPositionRotation(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch());
- this.e.o();
- return;
- }
- }
- }
- }
- }
-
- }
-
- protected boolean a(BlockPosition blockposition) {
- IBlockData iblockdata = this.b.getType(blockposition);
- return iblockdata.a(this.b, blockposition, this.a.getEntityType()) && this.b.isEmpty(blockposition.up()) && this.b.isEmpty(blockposition.up(2));
- }
-}
+package net.seanomilk.tamablefoxes.pathfinding;
+
+import net.seanomilk.tamablefoxes.EntityTamableFox;
+import net.minecraft.server.v1_15_R1.*;
+import org.bukkit.Location;
+import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity;
+import org.bukkit.event.entity.EntityTeleportEvent;
+
+import java.util.EnumSet;
+
+public class FoxPathfindGoalFollowOwner extends PathfinderGoal {
+
+ protected final EntityTamableFox a;
+ protected final IWorldReader b;
+ private final double d;
+ private final NavigationAbstract e;
+ private final float g;
+ private final float h;
+ private EntityLiving c;
+ private int f;
+ private float i;
+
+ public FoxPathfindGoalFollowOwner(EntityTamableFox tamableFox, double d0, float f, float f1) {
+ this.a = tamableFox;
+ this.b = tamableFox.world;
+ this.d = d0;
+ this.e = tamableFox.getNavigation();
+ this.h = f;
+ this.g = f1;
+ this.a(EnumSet.of(Type.MOVE, Type.LOOK));
+ if (!(tamableFox.getNavigation() instanceof Navigation) && !(tamableFox.getNavigation() instanceof NavigationFlying)) {
+ throw new IllegalArgumentException("Unsupported mob type for FollowOwnerGoal");
+ }
+ }
+
+ public boolean a() {
+ EntityLiving entityliving = this.a.getOwner();
+ if (entityliving == null) {
+ return false;
+ } else if (entityliving instanceof EntityHuman && entityliving.isSpectator()) {
+ return false;
+ } else if (this.a.isSitting()) {
+ return false;
+ } else if (this.a.h(entityliving) < (double) (this.h * this.h)) {
+ return false;
+ } else {
+ this.c = entityliving;
+ return true;
+ }
+ }
+
+ public boolean b() {
+ return !this.e.n() && this.a.h(this.c) > (double) (this.g * this.g) && !this.a.isSitting();
+ }
+
+ public void c() {
+ this.f = 0;
+ this.i = this.a.a(PathType.WATER);
+ this.a.a(PathType.WATER, 0.0F);
+ }
+
+ public void d() {
+ this.c = null;
+ this.e.o();
+ this.a.a(PathType.WATER, this.i);
+ }
+
+ public void e() {
+ this.a.getControllerLook().a(this.c, 10.0F, (float) this.a.dU());
+ if (!this.a.isSitting() && --this.f <= 0) {
+ this.f = 10;
+ if (!this.e.a(this.c, this.d) && !this.a.isLeashed() && !this.a.isPassenger() && this.a.h(this.c) >= 144.0D) {
+ int i = MathHelper.floor(this.c.locX()) - 2;
+ int j = MathHelper.floor(this.c.locZ()) - 2;
+ int k = MathHelper.floor(this.c.getBoundingBox().minY);
+
+ for (int l = 0; l <= 4; ++l) {
+ for (int i1 = 0; i1 <= 4; ++i1) {
+ if ((l < 1 || i1 < 1 || l > 3 || i1 > 3) && this.a(new BlockPosition(i + l, k - 1, j + i1))) {
+ CraftEntity entity = this.a.getBukkitEntity();
+ Location to = new Location(entity.getWorld(), (double) ((float) (i + l) + 0.5F), k, ((float) (j + i1) + 0.5F), this.a.yaw, this.a.pitch);
+ EntityTeleportEvent event = new EntityTeleportEvent(entity, entity.getLocation(), to);
+ this.a.world.getServer().getPluginManager().callEvent(event);
+ if (event.isCancelled()) {
+ return;
+ }
+
+ to = event.getTo();
+ this.a.setPositionRotation(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch());
+ this.e.o();
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+ protected boolean a(BlockPosition blockposition) {
+ IBlockData iblockdata = this.b.getType(blockposition);
+ return iblockdata.a(this.b, blockposition, this.a.getEntityType()) && this.b.isEmpty(blockposition.up()) && this.b.isEmpty(blockposition.up(2));
+ }
+
+}
diff --git a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalHurtByTarget.java b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalHurtByTarget.java
similarity index 57%
rename from src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalHurtByTarget.java
rename to src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalHurtByTarget.java
index e3e20c4..42ac510 100644
--- a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalHurtByTarget.java
+++ b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalHurtByTarget.java
@@ -1,120 +1,117 @@
-package net.seanomik.tamablefoxes.CustomPathfinding;
-
-import net.minecraft.server.v1_14_R1.*;
-import net.seanomik.tamablefoxes.TamableFox;
-import org.bukkit.Bukkit;
-import org.bukkit.event.entity.EntityTargetEvent;
-
-import java.util.EnumSet;
-import java.util.Iterator;
-import java.util.List;
-
-public class FoxPathfinderGoalHurtByTarget extends PathfinderGoalTarget {
- private static final PathfinderTargetCondition a = (new PathfinderTargetCondition()).c().e();
- private boolean b;
- private int c;
- private final Class>[] d;
- private Class>[] i;
-
- public FoxPathfinderGoalHurtByTarget(TamableFox entitycreature, Class>... aclass) {
- super(entitycreature, true);
- this.d = aclass;
- this.a(EnumSet.of(Type.TARGET));
- }
-
- public boolean a() {
- int i = this.e.ct();
- EntityLiving entityliving = this.e.getLastDamager();
- if (i != this.c && entityliving != null) {
- Class[] aclass = this.d;
- int j = aclass.length;
-
- for(int k = 0; k < j; ++k) {
- Class> oclass = aclass[k];
- if (oclass.isAssignableFrom(entityliving.getClass())) {
- return false;
- }
- }
-
- return this.a(entityliving, a);
- } else {
- return false;
- }
- }
-
- public FoxPathfinderGoalHurtByTarget a(Class>... aclass) {
- this.b = true;
- this.i = aclass;
- return this;
- }
-
- public void c() {
- if ( !(e instanceof TamableFox && ((TamableFox) e).getOwner() == e.getLastDamager()) ) {
- this.e.setGoalTarget(this.e.getLastDamager(), EntityTargetEvent.TargetReason.TARGET_ATTACKED_ENTITY, true);
- }
-
- this.g = this.e.getGoalTarget();
- this.c = this.e.ct();
- this.h = 300;
- if (this.b) {
- this.g();
- }
-
- super.c();
- }
-
- protected void g() {
- double d0 = this.k();
- List list = this.e.world.b(this.e.getClass(), (new AxisAlignedBB(this.e.locX, this.e.locY, this.e.locZ, this.e.locX + 1.0D, this.e.locY + 1.0D, this.e.locZ + 1.0D)).grow(d0, 10.0D, d0));
- Iterator iterator = list.iterator();
-
- while(true) {
- EntityInsentient entityinsentient;
- boolean flag;
- do {
- do {
- do {
- do {
- do {
- if (!iterator.hasNext()) {
- return;
- }
-
- entityinsentient = (EntityInsentient)iterator.next();
- } while (this.e == entityinsentient);
- } while (entityinsentient.getGoalTarget() != null);
-
- //Bukkit.broadcastMessage(String.valueOf(this.e instanceof TamableFox && ((TamableFox)this.e).getOwner() != ((TamableFox) entityinsentient).getOwner()));
-
- } while (this.e instanceof TamableFox && ((TamableFox)this.e).getOwner() != ((TamableFox) entityinsentient).getOwner());
- } while (entityinsentient.r(this.e.getLastDamager()));
-
- if (this.i == null) {
- break;
- }
-
- flag = false;
- Class[] aclass = this.i;
- int i = aclass.length;
-
- for(int j = 0; j < i; ++j) {
- Class> oclass = aclass[j];
- if (entityinsentient.getClass() == oclass) {
- flag = true;
- break;
- }
- }
- } while(flag);
-
- this.a(entityinsentient, this.e.getLastDamager());
- }
- }
-
- protected void a(EntityInsentient entityinsentient, EntityLiving entityliving) {
- if (entityinsentient instanceof TamableFox && ((TamableFox) entityinsentient).getOwner() == entityliving) {
- return;
- }
-
- entityinsentient.setGoalTarget(entityliving, EntityTargetEvent.TargetReason.TARGET_ATTACKED_NEARBY_ENTITY, true);
- }
-}
+package net.seanomilk.tamablefoxes.pathfinding;
+
+import net.seanomilk.tamablefoxes.EntityTamableFox;
+import net.minecraft.server.v1_15_R1.*;
+import org.bukkit.event.entity.EntityTargetEvent.TargetReason;
+
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.List;
+
+public class FoxPathfindGoalHurtByTarget extends PathfinderGoalTarget {
+
+ private static final PathfinderTargetCondition a = (new PathfinderTargetCondition()).c().e();
+ private final Class>[] d;
+ private boolean b;
+ private int c;
+ private Class>[] i;
+
+ public FoxPathfindGoalHurtByTarget(EntityTamableFox entitycreature, Class>... aclass) {
+ super(entitycreature, true);
+ this.d = aclass;
+ this.a(EnumSet.of(Type.TARGET));
+ }
+
+ public boolean a() {
+ int i = this.e.cI();
+ EntityLiving entityliving = this.e.getLastDamager();
+ if (i != this.c && entityliving != null) {
+ Class[] aclass = this.d;
+ int j = aclass.length;
+
+ for (Class> oclass : aclass) {
+ if (oclass.isAssignableFrom(entityliving.getClass())) {
+ return false;
+ }
+ }
+
+ return this.a(entityliving, a);
+ } else {
+ return false;
+ }
+ }
+
+ public FoxPathfindGoalHurtByTarget a(Class>... aclass) {
+ this.b = true;
+ this.i = aclass;
+ return this;
+ }
+
+ public void c() {
+ if (!(this.e instanceof EntityTamableFox) || ((EntityTamableFox) this.e).getOwner() != this.e.getLastDamager()) {
+ this.e.setGoalTarget(this.e.getLastDamager(), TargetReason.TARGET_ATTACKED_ENTITY, true);
+ }
+
+ this.g = this.e.getGoalTarget();
+ this.c = this.e.cI();
+ this.h = 300;
+ if (this.b) {
+ this.g();
+ }
+
+ super.c();
+ }
+
+ protected void g() {
+ double d0 = this.k();
+ List list = this.e.world.b(this.e.getClass(),
+ new AxisAlignedBB(this.e.locX(), this.e.locY(), this.e.locZ(), this.e.locX() + 1.0D, this.e.locY() + 1.0D, this.e.locZ() + 1.0D)
+ .grow(d0, 10.0D, d0));
+ Iterator iterator = list.iterator();
+
+ // kekw
+ while (true) {
+ EntityInsentient entityinsentient;
+ boolean flag;
+ do {
+ do {
+ do {
+ do {
+ do {
+ if (!iterator.hasNext()) {
+ return;
+ }
+
+ entityinsentient = (EntityInsentient) iterator.next();
+ } while (this.e == entityinsentient);
+ } while (entityinsentient.getGoalTarget() != null);
+ } while (this.e instanceof EntityTamableFox && ((EntityTamableFox) this.e).getOwner() != ((EntityTamableFox) entityinsentient).getOwner());
+ } while (entityinsentient.r(this.e.getLastDamager()));
+
+ if (this.i == null) {
+ break;
+ }
+
+ flag = false;
+ Class[] aclass = this.i;
+ int i = aclass.length;
+
+ for (Class> oclass : aclass) {
+ if (entityinsentient.getClass() == oclass) {
+ flag = true;
+ break;
+ }
+ }
+ } while (flag);
+
+ this.a(entityinsentient, this.e.getLastDamager());
+ }
+ }
+
+ protected void a(EntityInsentient entityinsentient, EntityLiving entityliving) {
+ if (!(entityinsentient instanceof EntityTamableFox) || ((EntityTamableFox) entityinsentient).getOwner() != entityliving) {
+ entityinsentient.setGoalTarget(entityliving, TargetReason.TARGET_ATTACKED_NEARBY_ENTITY, true);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalLunge.java b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalLunge.java
new file mode 100644
index 0000000..f6136ea
--- /dev/null
+++ b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalLunge.java
@@ -0,0 +1,125 @@
+package net.seanomilk.tamablefoxes.pathfinding;
+
+import net.seanomilk.tamablefoxes.EntityTamableFox;
+import net.minecraft.server.v1_15_R1.*;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public class FoxPathfindGoalLunge extends PathfinderGoalWaterJumpAbstract {
+
+ protected EntityTamableFox tamableFox;
+
+ public FoxPathfindGoalLunge(EntityTamableFox tamableFox) {
+ this.tamableFox = tamableFox;
+ }
+
+ public boolean a() {
+ if (!this.tamableFox.ez()) {
+ return false;
+ } else {
+ EntityLiving entityliving = this.tamableFox.getGoalTarget();
+ if (entityliving != null && entityliving.isAlive()) {
+ if (entityliving.getAdjustedDirection() != entityliving.getDirection()) {
+ return false;
+ } else {
+ boolean flag = EntityFox.a(this.tamableFox, entityliving);
+ if (!flag) {
+ this.tamableFox.getNavigation().a(entityliving, 0);
+ this.tamableFox.setCrouching(false);
+ this.tamableFox.u(false);
+ }
+
+ return flag;
+ }
+ } else {
+ return false;
+ }
+ }
+ }
+
+ public boolean b() {
+ EntityLiving entityliving = this.tamableFox.getGoalTarget();
+ if (entityliving != null && entityliving.isAlive()) {
+ double d0 = this.tamableFox.getMot().y;
+ return (d0 * d0 >= 0.05000000074505806D || Math.abs(this.tamableFox.pitch) >= 15.0F || !this.tamableFox.onGround) && !this.tamableFox.es();
+ } else {
+ return false;
+ }
+ }
+
+ public boolean E_() {
+ return false;
+ }
+
+ public void c() {
+ this.tamableFox.setJumping(true);
+ this.tamableFox.s(true);
+ this.tamableFox.u(false);
+ EntityLiving entityliving = this.tamableFox.getGoalTarget();
+ this.tamableFox.getControllerLook().a(entityliving, 60.0F, 30.0F);
+ Vec3D vec3d = (new Vec3D(entityliving.locX() - this.tamableFox.locX(),
+ entityliving.locY() - this.tamableFox.locY(), entityliving.locZ() - this.tamableFox.locZ())).d();
+ this.tamableFox.setMot(this.tamableFox.getMot().add(vec3d.x * 0.8D, 0.9D, vec3d.z * 0.8D));
+ this.tamableFox.getNavigation().o();
+ }
+
+ public void d() {
+ this.tamableFox.setCrouching(false);
+
+ try {
+ Class> entityFoxClass = Class.forName("net.minecraft.server.v1_15_R1.EntityFox");
+ Field field = entityFoxClass.getDeclaredField("bK");
+ field.setAccessible(true);
+ field.set(this.tamableFox, 0.0F);
+ field.setAccessible(false);
+ field = entityFoxClass.getDeclaredField("bL");
+ field.setAccessible(true);
+ field.set(this.tamableFox, 0);
+ field.setAccessible(false);
+ } catch (IllegalAccessException | ClassNotFoundException | NoSuchFieldException var3) {
+ var3.printStackTrace();
+ }
+
+ this.tamableFox.u(false);
+ this.tamableFox.s(false);
+ }
+
+ public void e() {
+ EntityLiving entityliving = this.tamableFox.getGoalTarget();
+ if (entityliving != null) {
+ this.tamableFox.getControllerLook().a(entityliving, 60.0F, 30.0F);
+ }
+
+ if (!this.tamableFox.es()) {
+ Vec3D vec3d = this.tamableFox.getMot();
+ if (vec3d.y * vec3d.y < 0.029999999329447746D && this.tamableFox.pitch != 0.0F) {
+ this.tamableFox.pitch = MathHelper.j(this.tamableFox.pitch, 0.0F, 0.2F);
+ } else {
+ double d0 = Math.sqrt(Entity.b(vec3d));
+ double d1 = Math.signum(-vec3d.y) * Math.acos(d0 / vec3d.f()) * 57.2957763671875D;
+ this.tamableFox.pitch = (float) d1;
+ }
+ }
+
+ if (entityliving != null && this.tamableFox.g(entityliving) <= 2.0F) {
+ this.tamableFox.B(entityliving);
+ } else if (this.tamableFox.pitch > 0.0F && this.tamableFox.onGround && (float) this.tamableFox.getMot().y != 0.0F && this.tamableFox.world.getType(new BlockPosition(this.tamableFox)).getBlock() == Blocks.SNOW) {
+ this.tamableFox.pitch = 60.0F;
+ this.tamableFox.setGoalTarget(null);
+
+ try {
+ Class> entityFoxClass = Class.forName("net.minecraft.server.v1_15_R1.EntityFox");
+ Method method = entityFoxClass.getDeclaredMethod("v", Boolean.TYPE);
+ method.setAccessible(true);
+ method.invoke(this.tamableFox, true);
+ method.setAccessible(false);
+ } catch (IllegalAccessException | InvocationTargetException | ClassNotFoundException | NoSuchMethodException var7) {
+ var7.printStackTrace();
+ }
+ }
+
+ }
+}
+
diff --git a/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalLungeUNKNOWN_USE.java b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalLungeUNKNOWN_USE.java
new file mode 100644
index 0000000..e17be8c
--- /dev/null
+++ b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalLungeUNKNOWN_USE.java
@@ -0,0 +1,85 @@
+package net.seanomilk.tamablefoxes.pathfinding;
+
+import net.seanomilk.tamablefoxes.EntityTamableFox;
+import net.minecraft.server.v1_15_R1.Entity;
+import net.minecraft.server.v1_15_R1.EntityFox;
+import net.minecraft.server.v1_15_R1.EntityLiving;
+import net.minecraft.server.v1_15_R1.PathfinderGoal;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.EnumSet;
+import java.util.function.Predicate;
+
+public class FoxPathfindGoalLungeUNKNOWN_USE extends PathfinderGoal {
+
+ protected EntityTamableFox tamableFox;
+
+ public FoxPathfindGoalLungeUNKNOWN_USE(EntityTamableFox tamableFox) {
+ this.a(EnumSet.of(Type.MOVE, Type.LOOK));
+ this.tamableFox = tamableFox;
+ }
+
+ public boolean a() {
+ if (this.tamableFox.isSleeping()) {
+ return false;
+ } else {
+ EntityLiving entityliving = this.tamableFox.getGoalTarget();
+
+ try {
+ Class> entityFoxClass = Class.forName("net.minecraft.server.v1_15_R1.EntityFox");
+ Field field = entityFoxClass.getDeclaredField("bD");
+ field.setAccessible(true);
+ Predicate bG = (Predicate) field.get(this.tamableFox);
+ field.setAccessible(false);
+ return entityliving != null && entityliving.isAlive() && bG.test(entityliving) && this.tamableFox.h(entityliving) > 36.0D
+ && !this.tamableFox.isCrouching() && !this.tamableFox.eg() && !this.tamableFox.isJumping();
+ } catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException var5) {
+ var5.printStackTrace();
+ throw new NullPointerException();
+ }
+ }
+ }
+
+ public void c() {
+ this.tamableFox.setSitting(false);
+
+ try {
+ Method method = this.tamableFox.getClass().getSuperclass().getDeclaredMethod("v", Boolean.TYPE);
+ method.setAccessible(true);
+ method.invoke(this.tamableFox, false);
+ method.setAccessible(false);
+ } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException var2) {
+ var2.printStackTrace();
+ }
+
+ }
+
+ public void d() {
+ EntityLiving entityliving = this.tamableFox.getGoalTarget();
+ if (entityliving != null && EntityFox.a(this.tamableFox, entityliving)) {
+ this.tamableFox.u(true);
+ this.tamableFox.setCrouching(true);
+ this.tamableFox.getNavigation().o();
+ this.tamableFox.getControllerLook().a(entityliving, (float) this.tamableFox.dV(), (float) this.tamableFox.dU());
+ } else {
+ this.tamableFox.u(false);
+ this.tamableFox.setCrouching(false);
+ }
+
+ }
+
+ public void e() {
+ EntityLiving entityliving = this.tamableFox.getGoalTarget();
+ this.tamableFox.getControllerLook().a(entityliving, (float) this.tamableFox.dV(), (float) this.tamableFox.dU());
+ if (this.tamableFox.h(entityliving) <= 36.0D) {
+ this.tamableFox.u(true);
+ this.tamableFox.setCrouching(true);
+ this.tamableFox.getNavigation().o();
+ } else {
+ this.tamableFox.getNavigation().a(entityliving, 1.5D);
+ }
+ }
+
+}
diff --git a/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalMeleeAttack.java b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalMeleeAttack.java
new file mode 100644
index 0000000..6357f36
--- /dev/null
+++ b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalMeleeAttack.java
@@ -0,0 +1,36 @@
+package net.seanomilk.tamablefoxes.pathfinding;
+
+import net.seanomilk.tamablefoxes.EntityTamableFox;
+import net.minecraft.server.v1_15_R1.EntityLiving;
+import net.minecraft.server.v1_15_R1.PathfinderGoalMeleeAttack;
+import net.minecraft.server.v1_15_R1.SoundEffects;
+
+public class FoxPathfindGoalMeleeAttack extends PathfinderGoalMeleeAttack {
+
+ protected EntityTamableFox tamableFox;
+
+ public FoxPathfindGoalMeleeAttack(EntityTamableFox tamableFox, double d0, boolean flag) {
+ super(tamableFox, d0, flag);
+ this.tamableFox = tamableFox;
+ }
+
+ protected void a(EntityLiving entityliving, double d0) {
+ double d1 = this.a(entityliving);
+ if (d0 <= d1 && this.b <= 0) {
+ this.b = 20;
+ this.a.B(entityliving);
+ this.tamableFox.a(SoundEffects.ENTITY_FOX_BITE, 1.0F, 1.0F);
+ }
+
+ }
+
+ public void c() {
+ this.tamableFox.u(false);
+ super.c();
+ }
+
+ public boolean a() {
+ return !this.tamableFox.isSitting() && !this.tamableFox.isSleeping() && !this.tamableFox.isCrouching() && !this.tamableFox.es() && super.a();
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalOwnerHurtByTarget.java b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalOwnerHurtByTarget.java
similarity index 61%
rename from src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalOwnerHurtByTarget.java
rename to src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalOwnerHurtByTarget.java
index 88700d5..ca3c922 100644
--- a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalOwnerHurtByTarget.java
+++ b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalOwnerHurtByTarget.java
@@ -1,45 +1,48 @@
-package net.seanomik.tamablefoxes.CustomPathfinding;
-
-import java.util.EnumSet;
-
-import net.minecraft.server.v1_14_R1.*;
-import net.minecraft.server.v1_14_R1.PathfinderGoal.Type;
-import net.seanomik.tamablefoxes.TamableFox;
-import org.bukkit.event.entity.EntityTargetEvent.TargetReason;
-
-public class FoxPathfinderGoalOwnerHurtByTarget extends PathfinderGoalTarget {
- private final TamableFox a; // the Fox
- private EntityLiving b;
- private int c;
-
- public FoxPathfinderGoalOwnerHurtByTarget(TamableFox tamableFox) {
- super(tamableFox, false);
- this.a = tamableFox;
- this.a(EnumSet.of(Type.TARGET));
- }
-
- public boolean a() {
- if (this.a.isTamed() && !this.a.isSitting()) {
- EntityLiving entityliving = this.a.getOwner();
- if (entityliving == null) {
- return false;
- } else {
- this.b = entityliving.getLastDamager();
- int i = entityliving.ct();
- return i != this.c && this.a(this.b, PathfinderTargetCondition.a); //&& this.a.a(this.b, entityliving);
- }
- } else {
- return false;
- }
- }
-
- public void c() {
- this.e.setGoalTarget(this.b, TargetReason.TARGET_ATTACKED_OWNER, true);
- EntityLiving entityliving = this.a.getOwner();
- if (entityliving != null) {
- this.c = entityliving.ct();
- }
-
- super.c();
- }
-}
+package net.seanomilk.tamablefoxes.pathfinding;
+
+import net.seanomilk.tamablefoxes.EntityTamableFox;
+import net.minecraft.server.v1_15_R1.EntityLiving;
+import net.minecraft.server.v1_15_R1.PathfinderGoalTarget;
+import net.minecraft.server.v1_15_R1.PathfinderTargetCondition;
+import org.bukkit.event.entity.EntityTargetEvent.TargetReason;
+
+import java.util.EnumSet;
+
+public class FoxPathfindGoalOwnerHurtByTarget extends PathfinderGoalTarget {
+
+ private final EntityTamableFox a;
+ private EntityLiving b;
+ private int c;
+
+ public FoxPathfindGoalOwnerHurtByTarget(EntityTamableFox tamableFox) {
+ super(tamableFox, false);
+ this.a = tamableFox;
+ this.a(EnumSet.of(Type.TARGET));
+ }
+
+ public boolean a() {
+ if (this.a.isTamed() && !this.a.isSitting()) {
+ EntityLiving entityliving = this.a.getOwner();
+ if (entityliving == null) {
+ return false;
+ } else {
+ this.b = entityliving.getLastDamager();
+ int i = entityliving.cI();
+ return i != this.c && this.a(this.b, PathfinderTargetCondition.a);
+ }
+ } else {
+ return false;
+ }
+ }
+
+ public void c() {
+ this.e.setGoalTarget(this.b, TargetReason.TARGET_ATTACKED_OWNER, true);
+ EntityLiving entityliving = this.a.getOwner();
+ if (entityliving != null) {
+ this.c = entityliving.cI();
+ }
+
+ super.c();
+ }
+
+}
diff --git a/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalOwnerHurtTarget.java b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalOwnerHurtTarget.java
new file mode 100644
index 0000000..23833a8
--- /dev/null
+++ b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalOwnerHurtTarget.java
@@ -0,0 +1,47 @@
+package net.seanomilk.tamablefoxes.pathfinding;
+
+import net.seanomilk.tamablefoxes.EntityTamableFox;
+import net.minecraft.server.v1_15_R1.EntityLiving;
+import net.minecraft.server.v1_15_R1.PathfinderGoalTarget;
+import net.minecraft.server.v1_15_R1.PathfinderTargetCondition;
+import org.bukkit.event.entity.EntityTargetEvent.TargetReason;
+
+import java.util.EnumSet;
+
+public class FoxPathfindGoalOwnerHurtTarget extends PathfinderGoalTarget {
+
+ private final EntityTamableFox a;
+ private EntityLiving b;
+ private int c;
+
+ public FoxPathfindGoalOwnerHurtTarget(EntityTamableFox tamableFox) {
+ super(tamableFox, false);
+ this.a = tamableFox;
+ this.a(EnumSet.of(Type.TARGET));
+ }
+
+ public boolean a() {
+ if (this.a.isTamed() && !this.a.isSitting()) {
+ EntityLiving entityliving = this.a.getOwner();
+ if (entityliving == null) {
+ return false;
+ } else {
+ this.b = entityliving.cJ();
+ int i = entityliving.cK();
+ return i != this.c && this.a(this.b, PathfinderTargetCondition.a);
+ }
+ } else {
+ return false;
+ }
+ }
+
+ public void c() {
+ this.e.setGoalTarget(this.b, TargetReason.OWNER_ATTACKED_TARGET, true);
+ EntityLiving entityliving = this.a.getOwner();
+ if (entityliving != null) {
+ this.c = entityliving.cK();
+ }
+
+ super.c();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalPickBushes.java b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalPickBushes.java
new file mode 100644
index 0000000..a267cd3
--- /dev/null
+++ b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalPickBushes.java
@@ -0,0 +1,85 @@
+package net.seanomilk.tamablefoxes.pathfinding;
+
+import net.seanomilk.tamablefoxes.EntityTamableFox;
+import net.minecraft.server.v1_15_R1.*;
+import org.bukkit.craftbukkit.v1_15_R1.event.CraftEventFactory;
+
+public class FoxPathfindGoalPickBushes extends PathfinderGoalGotoTarget {
+
+ protected int g;
+ protected EntityTamableFox tamableFox;
+
+ public FoxPathfindGoalPickBushes(EntityTamableFox tamableFox, double d0, int i, int j) {
+ super(tamableFox, d0, i, j);
+ this.tamableFox = tamableFox;
+ }
+
+ public double h() {
+ return 2.0D;
+ }
+
+ public boolean j() {
+ return this.d % 100 == 0;
+ }
+
+ protected boolean a(IWorldReader iworldreader, BlockPosition blockposition) {
+ if (this.tamableFox.isTamed()) {
+ return false;
+ } else {
+ IBlockData iblockdata = iworldreader.getType(blockposition);
+ return iblockdata.getBlock() == Blocks.SWEET_BERRY_BUSH && (Integer) iblockdata.get(BlockSweetBerryBush.a) >= 2;
+ }
+ }
+
+ public void e() {
+ if (this.k()) {
+ if (this.g >= 40) {
+ this.m();
+ } else {
+ ++this.g;
+ }
+ } else if (!this.k() && this.tamableFox.getRandom().nextFloat() < 0.05F && !this.tamableFox.isTamed()) {
+ this.tamableFox.a(SoundEffects.ENTITY_FOX_SNIFF, 1.0F, 1.0F);
+ }
+
+ super.e();
+ }
+
+ protected void m() {
+ if (this.tamableFox.world.getGameRules().getBoolean(GameRules.DO_MOB_LOOT) && !this.tamableFox.isTamed()) {
+ IBlockData iblockdata = this.tamableFox.world.getType(this.e);
+ if (iblockdata.getBlock() == Blocks.SWEET_BERRY_BUSH) {
+ int i = (Integer) iblockdata.get(BlockSweetBerryBush.a);
+ iblockdata.set(BlockSweetBerryBush.a, 1);
+ if (CraftEventFactory.callEntityChangeBlockEvent(this.tamableFox, this.e, (IBlockData) iblockdata.set(BlockSweetBerryBush.a, 1)).isCancelled()) {
+ return;
+ }
+
+ int j = 1 + this.tamableFox.world.random.nextInt(2) + (i == 3 ? 1 : 0);
+ ItemStack itemstack = this.tamableFox.getEquipment(EnumItemSlot.MAINHAND);
+ if (itemstack.isEmpty()) {
+ this.tamableFox.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.SWEET_BERRIES));
+ --j;
+ }
+
+ if (j > 0) {
+ Block.a(this.tamableFox.world, this.e, new ItemStack(Items.SWEET_BERRIES, j));
+ }
+
+ this.tamableFox.a(SoundEffects.ITEM_SWEET_BERRIES_PICK_FROM_BUSH, 1.0F, 1.0F);
+ this.tamableFox.world.setTypeAndData(this.e, (IBlockData) iblockdata.set(BlockSweetBerryBush.a, 1), 2);
+ }
+ }
+
+ }
+
+ public boolean a() {
+ return !this.tamableFox.isSleeping() && super.a();
+ }
+
+ public void c() {
+ this.g = 0;
+ this.tamableFox.setSitting(false);
+ super.c();
+ }
+}
diff --git a/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalRandomStrollLand.java b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalRandomStrollLand.java
new file mode 100644
index 0000000..b465875
--- /dev/null
+++ b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalRandomStrollLand.java
@@ -0,0 +1,98 @@
+package net.seanomilk.tamablefoxes.pathfinding;
+
+import net.seanomilk.tamablefoxes.EntityTamableFox;
+import net.minecraft.server.v1_15_R1.PathfinderGoalRandomStroll;
+import net.minecraft.server.v1_15_R1.RandomPositionGenerator;
+import net.minecraft.server.v1_15_R1.Vec3D;
+
+import javax.annotation.Nullable;
+
+public class FoxPathfindGoalRandomStrollLand extends PathfinderGoalRandomStroll {
+
+ protected final float h;
+ protected EntityTamableFox tamableFox;
+ protected Vec3D vec3D;
+
+ public FoxPathfindGoalRandomStrollLand(EntityTamableFox var0, double var1) {
+ this(var0, var1, 0.001F);
+ this.tamableFox = var0;
+ }
+
+ public FoxPathfindGoalRandomStrollLand(EntityTamableFox var0, double var1, float var3) {
+ super(var0, var1);
+ this.h = var3;
+ this.tamableFox = var0;
+ }
+
+ public boolean a() {
+ if (this.a.isVehicle()) {
+ return false;
+ } else {
+ if (!this.g) {
+ if (this.a.cL() >= 100) {
+ return false;
+ }
+
+ if (this.a.getRandom().nextInt(this.f) != 0) {
+ return false;
+ }
+ }
+
+ if (!this.tamableFox.isSitting()) {
+ this.vec3D = this.g();
+ }
+
+ if (this.vec3D == null) {
+ return false;
+ } else {
+ this.b = this.vec3D.x;
+ this.c = this.vec3D.y;
+ this.d = this.vec3D.z;
+ this.g = false;
+ return true;
+ }
+ }
+ }
+
+ @Nullable
+ protected Vec3D g() {
+ if (this.a.az()) {
+ Vec3D var0 = RandomPositionGenerator.b(this.a, 15, 7);
+ return var0 == null ? super.g() : var0;
+ } else {
+ return this.a.getRandom().nextFloat() >= this.h ? RandomPositionGenerator.b(this.a, 10, 7) : super.g();
+ }
+ }
+
+ public boolean b() {
+ return !this.a.getNavigation().n();
+ }
+
+ public void c() {
+ this.a.getNavigation().a(this.b, this.c, this.d, this.e);
+ }
+
+ public void h() {
+ this.g = true;
+ }
+
+ public void setTimeBetweenMovement(int var0) {
+ this.f = var0;
+ }
+
+ public void e() {
+ if (this.tamableFox.isSitting()) {
+ this.vec3D = null;
+ }
+ }
+
+ public boolean E_() {
+ if (this.tamableFox.isSitting()) {
+ this.vec3D = null;
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+}
diff --git a/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalRandomTargetNonTamed.java b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalRandomTargetNonTamed.java
new file mode 100644
index 0000000..aa1e08f
--- /dev/null
+++ b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalRandomTargetNonTamed.java
@@ -0,0 +1,27 @@
+package net.seanomilk.tamablefoxes.pathfinding;
+
+import net.seanomilk.tamablefoxes.EntityTamableFox;
+import net.minecraft.server.v1_15_R1.EntityLiving;
+import net.minecraft.server.v1_15_R1.PathfinderGoalNearestAttackableTarget;
+
+import javax.annotation.Nullable;
+import java.util.function.Predicate;
+
+public class FoxPathfindGoalRandomTargetNonTamed extends PathfinderGoalNearestAttackableTarget {
+
+ private final EntityTamableFox tamableFox;
+
+ public FoxPathfindGoalRandomTargetNonTamed(EntityTamableFox tamableFox, Class var1, boolean var2, @Nullable Predicate var3) {
+ super(tamableFox, var1, 10, var2, false, var3);
+ this.tamableFox = tamableFox;
+ }
+
+ public boolean a() {
+ return !this.tamableFox.isTamed() && super.a();
+ }
+
+ public boolean b() {
+ return this.d != null ? this.d.a(this.e, this.c) : super.b();
+ }
+
+}
diff --git a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalSit.java b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalSit.java
similarity index 52%
rename from src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalSit.java
rename to src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalSit.java
index a392a17..91431dc 100644
--- a/src/main/java/net/seanomik/tamablefoxes/CustomPathfinding/FoxPathfinderGoalSit.java
+++ b/src/main/java/net/seanomilk/tamablefoxes/pathfinding/FoxPathfindGoalSit.java
@@ -1,49 +1,49 @@
-package net.seanomik.tamablefoxes.CustomPathfinding;
-
-import java.util.EnumSet;
-
-import net.minecraft.server.v1_14_R1.EntityLiving;
-import net.minecraft.server.v1_14_R1.EntityTameableAnimal;
-import net.minecraft.server.v1_14_R1.PathfinderGoal;
-import net.minecraft.server.v1_14_R1.PathfinderGoal.Type;
-import net.seanomik.tamablefoxes.TamableFox;
-
-public class FoxPathfinderGoalSit extends PathfinderGoal {
- private final TamableFox entity;
- private boolean willSit;
-
- public FoxPathfinderGoalSit(TamableFox tamableFox) {
- this.entity = tamableFox;
- this.a(EnumSet.of(Type.JUMP, Type.MOVE));
- }
-
- public boolean b() {
- return this.willSit;
- }
-
- public boolean a() {
- if (!this.entity.isTamed()) {
- return this.willSit && this.entity.getGoalTarget() == null;
- } else if (this.entity.av()) {
- return false;
- } else if (!this.entity.onGround) {
- return false;
- } else {
- EntityLiving entityliving = this.entity.getOwner();
- return entityliving == null ? true : (this.entity.h(entityliving) < 144.0D && entityliving.getLastDamager() != null ? false : this.willSit);
- }
- }
-
- public void c() {
- this.entity.getNavigation().o();
- this.entity.setSitting(true);
- }
-
- public void d() {
- this.entity.setSitting(false);
- }
-
- public void setSitting(boolean flag) {
- this.willSit = flag;
- }
-}
\ No newline at end of file
+package net.seanomilk.tamablefoxes.pathfinding;
+
+import net.seanomilk.tamablefoxes.EntityTamableFox;
+import net.minecraft.server.v1_15_R1.EntityLiving;
+import net.minecraft.server.v1_15_R1.PathfinderGoal;
+
+import java.util.EnumSet;
+
+public class FoxPathfindGoalSit extends PathfinderGoal {
+
+ private final EntityTamableFox entity;
+ private boolean willSit;
+
+ public FoxPathfindGoalSit(EntityTamableFox tamableFox) {
+ this.entity = tamableFox;
+ this.a(EnumSet.of(Type.JUMP, Type.MOVE));
+ }
+
+ public boolean b() {
+ return this.willSit;
+ }
+
+ public boolean a() {
+ if (!this.entity.isTamed()) {
+ return this.willSit && this.entity.getGoalTarget() == null;
+ } else if (this.entity.az()) {
+ return false;
+ } else if (!this.entity.onGround) {
+ return false;
+ } else {
+ EntityLiving entityliving = this.entity.getOwner();
+ return entityliving == null || ((!(this.entity.h(entityliving) < 144.0D) || entityliving.getLastDamager() == null) && this.willSit);
+ }
+ }
+
+ public void c() {
+ this.entity.getNavigation().o();
+ this.entity.setSitting(true);
+ }
+
+ public void d() {
+ this.entity.setSitting(false);
+ }
+
+ public void setSitting(boolean flag) {
+ this.willSit = flag;
+ }
+
+}
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index 514f71e..0c501e5 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -1 +1,8 @@
-show-owner-in-fox-name: true
\ No newline at end of file
+# Config for Tamable Foxes modified for 1.15.1
+prefix: '&c[Tamable Foxes] '
+
+show-owner-in-fox-name: true
+show-nametags: true
+
+tamed-behavior:
+ no-attack-chicken-rabbit: true
\ No newline at end of file
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 4e5b274..5335dd1 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -1,11 +1,13 @@
name: TamableFoxes
-version: ${project.version}
-main: net.seanomik.tamablefoxes.TamableFoxes
-api-version: 1.14
+version: 1.4-RELEASE
+main: net.seanomilk.tamablefoxes.TamableFoxes
+api-version: 1.15
load: POSTWORLD
+description: Modified version of TamableFoxes for 1.15.1.
+
commands:
spawntamablefox:
- aliases: [stf, spawntf]
+ aliases: [tamablefox, stf, spawntf]
usage: /spawntamablefox [type]
description: Spawn a tamable fox at the standing location. Type can be snow or red, or left empty for a red.
permissions: