From de30d65fba99819a932359b548adda78433d5b63 Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Tue, 27 Oct 2020 20:39:56 -0500 Subject: [PATCH] Implement #26 and #28 in new 1.7.7 snapshot --- pom.xml | 5 +- .../seanomik/tamablefoxes/TamableFoxes.java | 47 ++++--- .../java/net/seanomik/tamablefoxes/Utils.java | 103 +++++++------- .../net/seanomik/tamablefoxes/io/Config.java | 6 +- .../tamablefoxes/io/LanguageConfig.java | 4 + .../tamablefoxes/io/sqlite/SQLiteHandler.java | 59 ++++++++ .../tamablefoxes/io/sqlite/SQLiteHelper.java | 130 ++++++++++++++++++ .../version_1_14_R1/EntityTamableFox.java | 20 +++ .../FoxPathfinderGoalRelaxOnOwner.java | 129 +++++++++++++++++ .../version_1_15_R1/EntityTamableFox.java | 21 ++- .../FoxPathfinderGoalRelaxOnOwner.java | 130 ++++++++++++++++++ .../version_1_16_R1/EntityTamableFox.java | 20 +++ .../FoxPathfinderGoalRelaxOnOwner.java | 129 +++++++++++++++++ .../version_1_16_R2/EntityTamableFox.java | 20 +++ .../FoxPathfinderGoalRelaxOnOwner.java | 129 +++++++++++++++++ src/main/resources/config.yml | 2 +- src/main/resources/language.yml | 1 + 17 files changed, 880 insertions(+), 75 deletions(-) create mode 100644 src/main/java/net/seanomik/tamablefoxes/io/sqlite/SQLiteHandler.java create mode 100644 src/main/java/net/seanomik/tamablefoxes/io/sqlite/SQLiteHelper.java create mode 100644 src/main/java/net/seanomik/tamablefoxes/versions/version_1_14_R1/pathfinding/FoxPathfinderGoalRelaxOnOwner.java create mode 100644 src/main/java/net/seanomik/tamablefoxes/versions/version_1_15_R1/pathfinding/FoxPathfinderGoalRelaxOnOwner.java create mode 100644 src/main/java/net/seanomik/tamablefoxes/versions/version_1_16_R1/pathfinding/FoxPathfinderGoalRelaxOnOwner.java create mode 100644 src/main/java/net/seanomik/tamablefoxes/versions/version_1_16_R2/pathfinding/FoxPathfinderGoalRelaxOnOwner.java diff --git a/pom.xml b/pom.xml index c7b6f92..a82c362 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ net.seanomik tamablefoxes - 1.7.6-SNAPSHOT + 1.7.7-SNAPSHOT jar Tamablefoxes @@ -44,7 +44,8 @@ - D:\Code\java\spigotPlugins\_TEST_SERVER_PAPER_1.16.2_\plugins\TamableFoxes_v${project.version}.jar + + D:\Code\java\spigotPlugins\_TEST_SERVER_1.16.3_\plugins\TamableFoxes_v${project.version}.jar false diff --git a/src/main/java/net/seanomik/tamablefoxes/TamableFoxes.java b/src/main/java/net/seanomik/tamablefoxes/TamableFoxes.java index 1f0c167..436604d 100644 --- a/src/main/java/net/seanomik/tamablefoxes/TamableFoxes.java +++ b/src/main/java/net/seanomik/tamablefoxes/TamableFoxes.java @@ -1,5 +1,8 @@ package net.seanomik.tamablefoxes; +import net.seanomik.tamablefoxes.io.Config; +import net.seanomik.tamablefoxes.io.sqlite.SQLiteHandler; +import net.seanomik.tamablefoxes.io.sqlite.SQLiteHelper; import net.seanomik.tamablefoxes.versions.NMSInterface; import net.seanomik.tamablefoxes.versions.version_1_14_R1.NMSInterface_1_14_R1; import net.seanomik.tamablefoxes.versions.version_1_15_R1.NMSInterface_1_15_R1; @@ -12,11 +15,9 @@ import org.bukkit.plugin.java.JavaPlugin; // @TODO: -/* @CHANGELOG (1.7-SNAPSHOT): - * Update to Minecraft 1.16.1. - * This jar file will also work with Minecraft 1.14.X, 1.15.X, and 1.16.X. - * Due to merging 1.14 support with all other versions, I also fixed SEVERAL issues that the versions for 1.14 had. - * Foxes now sleep with their owner once again. +/* @CHANGELOG (1.7.7-SNAPSHOT): + * Make foxes sleep on the bed with players, similar to what cats do. + * Add a configurable option to set the maximum about of foxes a player can tame. */ public final class TamableFoxes extends JavaPlugin implements Listener { private static TamableFoxes plugin; @@ -31,24 +32,34 @@ public final class TamableFoxes extends JavaPlugin implements Listener { LanguageConfig.getConfig().saveDefault(); + // Verify server version String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; - if (version.equals("v1_14_R1")) { - nmsInterface = new NMSInterface_1_14_R1(); - } else if (version.equals("v1_15_R1")) { - nmsInterface = new NMSInterface_1_15_R1(); - } else if (version.equals("v1_16_R1")) { - nmsInterface = new NMSInterface_1_16_R1(); - } else if (version.equals("v1_16_R2")) { - nmsInterface = new NMSInterface_1_16_R2(); - } else { - Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.RED + LanguageConfig.getUnsupportedMCVersionRegister()); - versionSupported = false; - return; + switch (version) { + case "v1_14_R1": + nmsInterface = new NMSInterface_1_14_R1(); + break; + case "v1_15_R1": + nmsInterface = new NMSInterface_1_15_R1(); + break; + case "v1_16_R1": + nmsInterface = new NMSInterface_1_16_R1(); + break; + case "v1_16_R2": + nmsInterface = new NMSInterface_1_16_R2(); + break; + default: + Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.RED + LanguageConfig.getUnsupportedMCVersionRegister()); + versionSupported = false; + return; } - // Display starting message + // Display starting message then register entity. Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.YELLOW + LanguageConfig.getMCVersionLoading(version)); nmsInterface.registerCustomFoxEntity(); + + if (Config.getMaxPlayerFoxTames() != 0) { + SQLiteHelper.getInstance().createTablesIfNotExist(); + } } @Override diff --git a/src/main/java/net/seanomik/tamablefoxes/Utils.java b/src/main/java/net/seanomik/tamablefoxes/Utils.java index 145ff23..9938e9c 100644 --- a/src/main/java/net/seanomik/tamablefoxes/Utils.java +++ b/src/main/java/net/seanomik/tamablefoxes/Utils.java @@ -1,52 +1,51 @@ -package net.seanomik.tamablefoxes; - -import org.bukkit.ChatColor; - -import java.lang.reflect.Constructor; -import java.util.List; - -public class Utils { - - public static String getPrefix() { - return ChatColor.RED + "[Tamable Foxes] "; - } - - public static Class getPrivateInnerClass(Class outer, String innerName) { - for (Class declaredClass : outer.getDeclaredClasses()) { - if (declaredClass.getSimpleName().equals(innerName)) return declaredClass; - } - - return null; - } - - public static Object instantiatePrivateInnerClass(Class outer, String innerName, Object outerObject, List args, List> argTypes) { - try { - Class innerClass = getPrivateInnerClass(outer, innerName); - - Object[] argObjects = new Object[args.size() + 1]; - Class[] argClasses = new Class[argTypes.size() + 1]; - - // Needed due to how List#toArray() converts the classes to objects - for (int i = 0; i < argClasses.length; i++) { - if (i == argClasses.length - 1) continue; - argObjects[i + 1] = args.get(i); - argClasses[i + 1] = argTypes.get(i); - } - argObjects[0] = outerObject; - argClasses[0] = outer; - - Constructor innerConstructor = innerClass.getDeclaredConstructor(argClasses); - innerConstructor.setAccessible(true); - - Object instantiatedClass = innerConstructor.newInstance(argObjects); - - innerConstructor.setAccessible(false); - - return instantiatedClass; - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - -} +package net.seanomik.tamablefoxes; + +import org.bukkit.ChatColor; + +import java.lang.reflect.Constructor; +import java.util.List; + +public class Utils { + public static String getPrefix() { + return ChatColor.RED + "[Tamable Foxes] "; + } + + public static Class getPrivateInnerClass(Class outer, String innerName) { + for (Class declaredClass : outer.getDeclaredClasses()) { + if (declaredClass.getSimpleName().equals(innerName)) return declaredClass; + } + + return null; + } + + public static Object instantiatePrivateInnerClass(Class outer, String innerName, Object outerObject, List args, List> argTypes) { + try { + Class innerClass = getPrivateInnerClass(outer, innerName); + + Object[] argObjects = new Object[args.size() + 1]; + Class[] argClasses = new Class[argTypes.size() + 1]; + + // Needed due to how List#toArray() converts the classes to objects + for (int i = 0; i < argClasses.length; i++) { + if (i == argClasses.length - 1) continue; + argObjects[i + 1] = args.get(i); + argClasses[i + 1] = argTypes.get(i); + } + argObjects[0] = outerObject; + argClasses[0] = outer; + + Constructor innerConstructor = innerClass.getDeclaredConstructor(argClasses); + innerConstructor.setAccessible(true); + + Object instantiatedClass = innerConstructor.newInstance(argObjects); + + innerConstructor.setAccessible(false); + + return instantiatedClass; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + +} diff --git a/src/main/java/net/seanomik/tamablefoxes/io/Config.java b/src/main/java/net/seanomik/tamablefoxes/io/Config.java index fa612a3..9d6e764 100644 --- a/src/main/java/net/seanomik/tamablefoxes/io/Config.java +++ b/src/main/java/net/seanomik/tamablefoxes/io/Config.java @@ -15,7 +15,11 @@ public class Config { // Check if the player can tame the fox. public static boolean canPlayerTameFox(Player player) { - return !config.getBoolean("enable-taming-permission") || (config.getBoolean("enable-taming-permission") && (player.hasPermission("tamablefoxes.tame") || player.isOp())); + return player.hasPermission("tamablefoxes.tame") || player.isOp(); + } + + public static int getMaxPlayerFoxTames() { + return config.getInt("max-fox-tames"); } // Check if the plugin asks for a fox name after taming. diff --git a/src/main/java/net/seanomik/tamablefoxes/io/LanguageConfig.java b/src/main/java/net/seanomik/tamablefoxes/io/LanguageConfig.java index 4013961..415b84b 100644 --- a/src/main/java/net/seanomik/tamablefoxes/io/LanguageConfig.java +++ b/src/main/java/net/seanomik/tamablefoxes/io/LanguageConfig.java @@ -132,6 +132,10 @@ public class LanguageConfig extends YamlConfiguration { return getConfig().getString((Config.doesShowOwnerInFoxName()) ? "fox-name-format" : "fox-name-no-owner-name-format").replaceAll("%FOX_NAME%", foxName).replaceAll("%OWNER%", ownerName); } + public static String getFoxDoesntTrust() { + return getConfig().getString("fox-doesnt-trust"); + } + public static String getNoPermMessage() { return getConfig().getString("no-permission"); } diff --git a/src/main/java/net/seanomik/tamablefoxes/io/sqlite/SQLiteHandler.java b/src/main/java/net/seanomik/tamablefoxes/io/sqlite/SQLiteHandler.java new file mode 100644 index 0000000..33f8f98 --- /dev/null +++ b/src/main/java/net/seanomik/tamablefoxes/io/sqlite/SQLiteHandler.java @@ -0,0 +1,59 @@ +package net.seanomik.tamablefoxes.io.sqlite; + +import org.bukkit.Bukkit; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +public class SQLiteHandler { + private Connection connection; + + private static SQLiteHandler instance; + + public static SQLiteHandler getInstance() { + if (instance == null) { + instance = new SQLiteHandler(); + } + + return instance; + } + + public void connect() { + try { + String baseLoc = Bukkit.getWorldContainer().toURI().toString().substring(6); + baseLoc = baseLoc.substring(0,baseLoc.length()-2); + + String url = "jdbc:sqlite:" + baseLoc + "plugins/Tamablefoxes/userFoxAmount.db"; + connection = DriverManager.getConnection(url); + + } catch (SQLException e) { + e.printStackTrace(); + } + } + + public Connection getConnection() { + return connection; + } + + public void closeConnection() { + try { + connection.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + public void newConnection() { + try { + connection.close(); + connect(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + public void setConnection(Connection connection) { + this.connection = connection; + } +} diff --git a/src/main/java/net/seanomik/tamablefoxes/io/sqlite/SQLiteHelper.java b/src/main/java/net/seanomik/tamablefoxes/io/sqlite/SQLiteHelper.java new file mode 100644 index 0000000..95c1e1b --- /dev/null +++ b/src/main/java/net/seanomik/tamablefoxes/io/sqlite/SQLiteHelper.java @@ -0,0 +1,130 @@ +package net.seanomik.tamablefoxes.io.sqlite; + +import net.seanomik.tamablefoxes.TamableFoxes; +import net.seanomik.tamablefoxes.Utils; +import org.bukkit.plugin.Plugin; + +import java.sql.DatabaseMetaData; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; + +public class SQLiteHelper { + public static Plugin plugin; + public static SQLiteHandler sqLiteHandler; + + private static SQLiteHelper instance; + private static String userAmountTableName = "USER_FOX_AMT"; + + public static SQLiteHelper getInstance() { + if (instance == null) { + instance = new SQLiteHelper(); + } + + return instance; + } + + public void createTablesIfNotExist() { + sqLiteHandler = SQLiteHandler.getInstance(); + + String userFoxAmountQuery = + "CREATE TABLE IF NOT EXISTS `" + userAmountTableName + "` ( " + + "`UUID` TEXT PRIMARY KEY , " + + "`AMOUNT` INT NOT NULL);"; + + try { + sqLiteHandler.connect(); + // Create previous bans table + DatabaseMetaData dbm = sqLiteHandler.getConnection().getMetaData(); + ResultSet tables = dbm.getTables(null, null, userAmountTableName, null); + if (!tables.next()) { + PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement(userFoxAmountQuery); + statement.executeUpdate(); + + plugin.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + "Created previous player bans table!"); + } + } catch (SQLException e) { + e.printStackTrace(); + } finally { + if (sqLiteHandler.getConnection() != null) { + try { + sqLiteHandler.getConnection().close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + } + } + + public int getPlayerFoxAmount(UUID uuid) { + try { + sqLiteHandler.connect(); + PreparedStatement statement = sqLiteHandler.getConnection() + .prepareStatement("SELECT * FROM " + userAmountTableName + " WHERE UUID=?"); + statement.setString(1, uuid.toString()); + ResultSet results = statement.executeQuery(); + + if (results.next()) { + return results.getInt("AMOUNT"); + } + } catch (SQLException e) { + e.printStackTrace(); + } finally { + if (sqLiteHandler.getConnection() != null) { + try { + sqLiteHandler.getConnection().close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + } + + return -1; + } + + public void addPlayerFoxAmount(UUID uuid, int amt) { + try { + String query = "UPDATE " + userAmountTableName + " SET AMOUNT = AMOUNT + " + amt + " WHERE UUID = '" + uuid.toString() + "'"; + if (getPlayerFoxAmount(uuid) == -1) { + query = "INSERT INTO " + userAmountTableName + " (UUID, AMOUNT) VALUES('" + uuid.toString() + "'," + amt + ")"; + } + + sqLiteHandler.connect(); + PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement(query); + + statement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } finally { + if (sqLiteHandler.getConnection() != null) { + try { + sqLiteHandler.getConnection().close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + } + } + + public void removePlayerFoxAmount(UUID uuid, int amt) { + try { + String query = "UPDATE " + userAmountTableName + " SET AMOUNT = AMOUNT - " + amt + " WHERE UUID = '" + uuid.toString() + "'"; + + sqLiteHandler.connect(); + PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement(query); + + statement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } finally { + if (sqLiteHandler.getConnection() != null) { + try { + sqLiteHandler.getConnection().close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + } + } +} diff --git a/src/main/java/net/seanomik/tamablefoxes/versions/version_1_14_R1/EntityTamableFox.java b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_14_R1/EntityTamableFox.java index da694f2..9c5bc5e 100644 --- a/src/main/java/net/seanomik/tamablefoxes/versions/version_1_14_R1/EntityTamableFox.java +++ b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_14_R1/EntityTamableFox.java @@ -5,6 +5,7 @@ import net.seanomik.tamablefoxes.TamableFoxes; import net.seanomik.tamablefoxes.Utils; import net.seanomik.tamablefoxes.io.Config; import net.seanomik.tamablefoxes.io.LanguageConfig; +import net.seanomik.tamablefoxes.io.sqlite.SQLiteHelper; import net.seanomik.tamablefoxes.versions.version_1_14_R1.pathfinding.*; import net.wesjd.anvilgui.AnvilGUI; import org.bukkit.Bukkit; @@ -73,6 +74,7 @@ public class EntityTamableFox extends EntityFox { this.goalSelector.a(0, getFoxInnerPathfinderGoal("g")); // FoxFloatGoal this.goalSelector.a(1, getFoxInnerPathfinderGoal("b")); // FaceplantGoal this.goalSelector.a(2, new FoxPathfinderGoalPanic(this, 2.2D)); + this.goalSelector.a(2, new FoxPathfinderGoalRelaxOnOwner(this)); this.goalSelector.a(3, getFoxInnerPathfinderGoal("e", Arrays.asList(1.0D), Arrays.asList(double.class))); // FoxBreedGoal this.goalSelector.a(4, new PathfinderGoalAvoidTarget(this, EntityHuman.class, 16.0F, 1.6D, 1.4D, (entityliving) -> { @@ -311,6 +313,14 @@ public class EntityTamableFox extends EntityFox { itemstack.subtract(1); } + SQLiteHelper sqLiteHelper = SQLiteHelper.getInstance(); + int maxTameCount = Config.getMaxPlayerFoxTames(); + if (maxTameCount > 0 && sqLiteHelper.getPlayerFoxAmount(entityhuman.getUniqueID()) >= maxTameCount) { + ((Player) entityhuman.getBukkitEntity()).sendMessage(Utils.getPrefix() + ChatColor.RED + LanguageConfig.getFoxDoesntTrust()); + + return true; + } + // 0.33% chance to tame the fox, also check if the called tame entity event is cancelled or not. if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) { this.tame(entityhuman); @@ -320,6 +330,10 @@ public class EntityTamableFox extends EntityFox { this.setGoalTarget(null); this.goalSit.setSitting(true); + if (maxTameCount > 0) { + sqLiteHelper.addPlayerFoxAmount(entityhuman.getUniqueID(), 1); + } + getBukkitEntity().getWorld().spawnParticle(org.bukkit.Particle.HEART, getBukkitEntity().getLocation(), 6, 0.5D, 0.5D, 0.5D); // Give player tamed message. @@ -477,6 +491,12 @@ public class EntityTamableFox extends EntityFox { public void die(DamageSource damageSource) { if (!this.world.isClientSide && this.world.getGameRules().getBoolean(GameRules.SHOW_DEATH_MESSAGES) && this.getOwner() instanceof EntityPlayer) { this.getOwner().sendMessage(this.getCombatTracker().getDeathMessage()); + + // Remove the amount of foxes the player has tamed if the limit is enabled. + if (Config.getMaxPlayerFoxTames() > 0) { + SQLiteHelper sqliteHelper = SQLiteHelper.getInstance(); + sqliteHelper.removePlayerFoxAmount(this.getOwner().getUniqueID(), 1); + } } super.die(damageSource); diff --git a/src/main/java/net/seanomik/tamablefoxes/versions/version_1_14_R1/pathfinding/FoxPathfinderGoalRelaxOnOwner.java b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_14_R1/pathfinding/FoxPathfinderGoalRelaxOnOwner.java new file mode 100644 index 0000000..9e5a2ce --- /dev/null +++ b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_14_R1/pathfinding/FoxPathfinderGoalRelaxOnOwner.java @@ -0,0 +1,129 @@ +package net.seanomik.tamablefoxes.versions.version_1_14_R1.pathfinding; + +import net.minecraft.server.v1_14_R1.*; +import net.seanomik.tamablefoxes.versions.version_1_14_R1.EntityTamableFox; + +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +public class FoxPathfinderGoalRelaxOnOwner extends PathfinderGoal { + private final EntityTamableFox a; + private EntityHuman b; + private BlockPosition c; + private int d; + + public FoxPathfinderGoalRelaxOnOwner(EntityTamableFox entityTamableFox) { + this.a = entityTamableFox; + } + + public boolean a() { + if (!this.a.isTamed()) { + return false; + } else if (this.a.isSitting()) { + return false; + } else { + EntityLiving entityliving = this.a.getOwner(); + if (entityliving instanceof EntityHuman) { + this.b = (EntityHuman)entityliving; + if (!entityliving.isSleeping()) { + return false; + } + + if (this.a.h(this.b) > 100.0D) { + return false; + } + + BlockPosition blockposition = new BlockPosition(this.b); + IBlockData iblockdata = this.a.world.getType(blockposition); + if (iblockdata.getBlock().a(TagsBlock.BEDS)) { + EnumDirection enumdirection = (EnumDirection)iblockdata.get(BlockBed.FACING); + this.c = new BlockPosition(blockposition.getX() - enumdirection.getAdjacentX(), blockposition.getY(), blockposition.getZ() - enumdirection.getAdjacentZ()); + return !this.g(); + } + } + + return false; + } + } + + private boolean g() { + List list = this.a.world.a(EntityTamableFox.class, (new AxisAlignedBB(this.c)).g(2.0D)); + Iterator iterator = list.iterator(); + + EntityTamableFox entityTamableFox; + do { + do { + if (!iterator.hasNext()) { + return false; + } + + entityTamableFox = (EntityTamableFox) iterator.next(); + } while(entityTamableFox == this.a); + } while(!entityTamableFox.isSleeping()); + + return true; + } + + public boolean b() { + return this.a.isTamed() && !this.a.isSitting() && this.b != null && this.b.isSleeping() && this.c != null && !this.g(); + } + + public void c() { + if (this.c != null) { + this.a.getGoalSit().setSitting(false); + this.a.getNavigation().a((double)this.c.getX(), (double)this.c.getY(), (double)this.c.getZ(), 1.100000023841858D); + } + + } + + public void d() { + this.a.u(false); + float f = this.a.world.j(1.0F); + if (this.b.dJ() >= 100 && (double)f > 0.77D && (double)f < 0.8D && (double)this.a.world.getRandom().nextFloat() < 0.7D) { + this.h(); + } + + this.d = 0; + //this.a.v(false); + this.a.getNavigation().o(); + } + + private void h() { + Random random = this.a.getRandom(); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + blockposition_mutableblockposition.a(this.a); + this.a.a((double)(blockposition_mutableblockposition.getX() + random.nextInt(11) - 5), (double)(blockposition_mutableblockposition.getY() + random.nextInt(5) - 2), (double)(blockposition_mutableblockposition.getZ() + random.nextInt(11) - 5), false); + blockposition_mutableblockposition.a(this.a); + LootTable loottable = this.a.world.getMinecraftServer().getLootTableRegistry().getLootTable(LootTables.af); + LootTableInfo.Builder loottableinfo_builder = (new LootTableInfo.Builder((WorldServer)this.a.world)).set(LootContextParameters.POSITION, blockposition_mutableblockposition).set(LootContextParameters.THIS_ENTITY, this.a).a(random); + List list = loottable.populateLoot(loottableinfo_builder.build(LootContextParameterSets.GIFT)); + Iterator iterator = list.iterator(); + + while(iterator.hasNext()) { + ItemStack itemstack = (ItemStack)iterator.next(); + this.a.world.addEntity(new EntityItem(this.a.world, (double)((float)blockposition_mutableblockposition.getX() - MathHelper.sin(this.a.aK * 0.017453292F)), (double)blockposition_mutableblockposition.getY(), (double)((float)blockposition_mutableblockposition.getZ() + MathHelper.cos(this.a.aK * 0.017453292F)), itemstack)); + } + + } + + public void e() { + if (this.b != null && this.c != null) { + this.a.getGoalSit().setSitting(false); + this.a.getNavigation().a((double)this.c.getX(), (double)this.c.getY(), (double)this.c.getZ(), 1.100000023841858D); + if (this.a.h(this.b) < 2.5D) { + ++this.d; + if (this.d > 16) { + this.a.setSleeping(true); + //this.a.v(false); + } else { + this.a.a(this.b, 45.0F, 45.0F); + //this.a.v(true); + } + } else { + this.a.u(false); + } + } + + } +} diff --git a/src/main/java/net/seanomik/tamablefoxes/versions/version_1_15_R1/EntityTamableFox.java b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_15_R1/EntityTamableFox.java index 3b1e1e4..7d14ea6 100644 --- a/src/main/java/net/seanomik/tamablefoxes/versions/version_1_15_R1/EntityTamableFox.java +++ b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_15_R1/EntityTamableFox.java @@ -5,6 +5,7 @@ import net.seanomik.tamablefoxes.TamableFoxes; import net.seanomik.tamablefoxes.Utils; import net.seanomik.tamablefoxes.io.Config; import net.seanomik.tamablefoxes.io.LanguageConfig; +import net.seanomik.tamablefoxes.io.sqlite.SQLiteHelper; import net.seanomik.tamablefoxes.versions.version_1_15_R1.pathfinding.*; import net.wesjd.anvilgui.AnvilGUI; import org.bukkit.Bukkit; @@ -16,7 +17,6 @@ import org.bukkit.entity.Player; import org.bukkit.event.entity.EntityRegainHealthEvent; import java.lang.reflect.Field; -import java.lang.reflect.Method; import java.util.*; import java.util.function.Predicate; @@ -73,6 +73,7 @@ public class EntityTamableFox extends EntityFox { this.goalSelector.a(0, getFoxInnerPathfinderGoal("g")); // FoxFloatGoal this.goalSelector.a(1, getFoxInnerPathfinderGoal("b")); // FaceplantGoal this.goalSelector.a(2, new FoxPathfinderGoalPanic(this, 2.2D)); + this.goalSelector.a(2, new FoxPathfinderGoalRelaxOnOwner(this)); this.goalSelector.a(3, getFoxInnerPathfinderGoal("e", Arrays.asList(1.0D), Arrays.asList(double.class))); // FoxBreedGoal this.goalSelector.a(4, new PathfinderGoalAvoidTarget(this, EntityHuman.class, 16.0F, 1.6D, 1.4D, (entityliving) -> { @@ -311,6 +312,14 @@ public class EntityTamableFox extends EntityFox { itemstack.subtract(1); } + SQLiteHelper sqLiteHelper = SQLiteHelper.getInstance(); + int maxTameCount = Config.getMaxPlayerFoxTames(); + if (maxTameCount > 0 && sqLiteHelper.getPlayerFoxAmount(entityhuman.getUniqueID()) >= maxTameCount) { + ((Player) entityhuman.getBukkitEntity()).sendMessage(Utils.getPrefix() + ChatColor.RED + LanguageConfig.getFoxDoesntTrust()); + + return true; + } + // 0.33% chance to tame the fox, also check if the called tame entity event is cancelled or not. if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) { this.tame(entityhuman); @@ -320,6 +329,10 @@ public class EntityTamableFox extends EntityFox { this.setGoalTarget(null); this.goalSit.setSitting(true); + if (maxTameCount > 0) { + sqLiteHelper.addPlayerFoxAmount(entityhuman.getUniqueID(), 1); + } + getBukkitEntity().getWorld().spawnParticle(org.bukkit.Particle.HEART, getBukkitEntity().getLocation(), 6, 0.5D, 0.5D, 0.5D); // Give player tamed message. @@ -477,6 +490,12 @@ public class EntityTamableFox extends EntityFox { public void die(DamageSource damageSource) { if (!this.world.isClientSide && this.world.getGameRules().getBoolean(GameRules.SHOW_DEATH_MESSAGES) && this.getOwner() instanceof EntityPlayer) { this.getOwner().sendMessage(this.getCombatTracker().getDeathMessage()); + + // Remove the amount of foxes the player has tamed if the limit is enabled. + if (Config.getMaxPlayerFoxTames() > 0) { + SQLiteHelper sqliteHelper = SQLiteHelper.getInstance(); + sqliteHelper.removePlayerFoxAmount(this.getOwner().getUniqueID(), 1); + } } super.die(damageSource); diff --git a/src/main/java/net/seanomik/tamablefoxes/versions/version_1_15_R1/pathfinding/FoxPathfinderGoalRelaxOnOwner.java b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_15_R1/pathfinding/FoxPathfinderGoalRelaxOnOwner.java new file mode 100644 index 0000000..912666b --- /dev/null +++ b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_15_R1/pathfinding/FoxPathfinderGoalRelaxOnOwner.java @@ -0,0 +1,130 @@ +package net.seanomik.tamablefoxes.versions.version_1_15_R1.pathfinding; + +import net.minecraft.server.v1_15_R1.*; +import net.seanomik.tamablefoxes.versions.version_1_15_R1.EntityTamableFox; + +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +public class FoxPathfinderGoalRelaxOnOwner extends PathfinderGoal { + private final EntityTamableFox a; + private EntityHuman b; + private BlockPosition c; + private int d; + + public FoxPathfinderGoalRelaxOnOwner(EntityTamableFox entityTamableFox) { + this.a = entityTamableFox; + } + + public boolean a() { + if (!this.a.isTamed()) { + return false; + } else if (this.a.isSitting()) { + return false; + } else { + EntityLiving entityliving = this.a.getOwner(); + if (entityliving instanceof EntityHuman) { + this.b = (EntityHuman)entityliving; + if (!entityliving.isSleeping()) { + return false; + } + + if (this.a.h(this.b) > 100.0D) { + return false; + } + + BlockPosition blockposition = new BlockPosition(this.b); + IBlockData iblockdata = this.a.world.getType(blockposition); + if (iblockdata.getBlock().a(TagsBlock.BEDS)) { + EnumDirection enumdirection = (EnumDirection)iblockdata.get(BlockBed.FACING); + this.c = new BlockPosition(blockposition.getX() - enumdirection.getAdjacentX(), blockposition.getY(), blockposition.getZ() - enumdirection.getAdjacentZ()); + return !this.g(); + } + } + + return false; + } + } + + private boolean g() { + List list = this.a.world.a(EntityTamableFox.class, (new AxisAlignedBB(this.c)).g(2.0D)); + Iterator iterator = list.iterator(); + + EntityTamableFox entityTamableFox; + do { + do { + if (!iterator.hasNext()) { + + return false; + } + + entityTamableFox = (EntityTamableFox) iterator.next(); + } while(entityTamableFox == this.a); + } while(!entityTamableFox.isSleeping()); + + return true; + } + + public boolean b() { + return this.a.isTamed() && !this.a.isSitting() && this.b != null && this.b.isSleeping() && this.c != null && !this.g(); + } + + public void c() { + if (this.c != null) { + this.a.setSitting(false); + this.a.getNavigation().a((double)this.c.getX(), (double)this.c.getY(), (double)this.c.getZ(), 1.100000023841858D); + } + + } + + public void d() { + this.a.u(false); + float f = this.a.world.f(1.0F); + if (this.b.ef() >= 100 && (double)f > 0.77D && (double)f < 0.8D && (double)this.a.world.getRandom().nextFloat() < 0.7D) { + this.h(); + } + + this.d = 0; + //this.a.v(false); + this.a.getNavigation().o(); + } + + private void h() { + Random random = this.a.getRandom(); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + blockposition_mutableblockposition.a(this.a); + this.a.a((double)(blockposition_mutableblockposition.getX() + random.nextInt(11) - 5), (double)(blockposition_mutableblockposition.getY() + random.nextInt(5) - 2), (double)(blockposition_mutableblockposition.getZ() + random.nextInt(11) - 5), false); + blockposition_mutableblockposition.a(this.a); + LootTable loottable = this.a.world.getMinecraftServer().getLootTableRegistry().getLootTable(LootTables.af); + LootTableInfo.Builder loottableinfo_builder = (new LootTableInfo.Builder((WorldServer)this.a.world)).set(LootContextParameters.POSITION, blockposition_mutableblockposition).set(LootContextParameters.THIS_ENTITY, this.a).a(random); + List list = loottable.populateLoot(loottableinfo_builder.build(LootContextParameterSets.GIFT)); + Iterator iterator = list.iterator(); + + while(iterator.hasNext()) { + ItemStack itemstack = (ItemStack)iterator.next(); + this.a.world.addEntity(new EntityItem(this.a.world, (double)((float)blockposition_mutableblockposition.getX() - MathHelper.sin(this.a.aI * 0.017453292F)), (double)blockposition_mutableblockposition.getY(), (double)((float)blockposition_mutableblockposition.getZ() + MathHelper.cos(this.a.aI * 0.017453292F)), itemstack)); + } + + } + + public void e() { + if (this.b != null && this.c != null) { + this.a.setSitting(false); + this.a.getNavigation().a((double)this.c.getX(), (double)this.c.getY(), (double)this.c.getZ(), 1.100000023841858D); + if (this.a.h(this.b) < 2.5D) { + ++this.d; + if (this.d > 16) { + this.a.u(true); + //this.a.v(false); + } else { + this.a.a(this.b, 45.0F, 45.0F); + //this.a.v(true); + } + } else { + this.a.u(false); + } + } + + } +} diff --git a/src/main/java/net/seanomik/tamablefoxes/versions/version_1_16_R1/EntityTamableFox.java b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_16_R1/EntityTamableFox.java index eedffb7..8c0b3c6 100644 --- a/src/main/java/net/seanomik/tamablefoxes/versions/version_1_16_R1/EntityTamableFox.java +++ b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_16_R1/EntityTamableFox.java @@ -5,6 +5,7 @@ import net.seanomik.tamablefoxes.TamableFoxes; import net.seanomik.tamablefoxes.Utils; import net.seanomik.tamablefoxes.io.Config; import net.seanomik.tamablefoxes.io.LanguageConfig; +import net.seanomik.tamablefoxes.io.sqlite.SQLiteHelper; import net.seanomik.tamablefoxes.versions.version_1_16_R1.pathfinding.*; import net.wesjd.anvilgui.AnvilGUI; import org.bukkit.Bukkit; @@ -80,6 +81,7 @@ public class EntityTamableFox extends EntityFox { this.goalSelector.a(0, getFoxInnerPathfinderGoal("g")); // FoxFloatGoal this.goalSelector.a(1, getFoxInnerPathfinderGoal("b")); // FaceplantGoal this.goalSelector.a(2, new FoxPathfinderGoalPanic(this, 2.2D)); + this.goalSelector.a(2, new FoxPathfinderGoalRelaxOnOwner(this)); this.goalSelector.a(3, getFoxInnerPathfinderGoal("e", Arrays.asList(1.0D), Arrays.asList(double.class))); // FoxBreedGoal this.goalSelector.a(4, new PathfinderGoalAvoidTarget(this, EntityHuman.class, 16.0F, 1.6D, 1.4D, (entityliving) -> { @@ -313,6 +315,14 @@ public class EntityTamableFox extends EntityFox { itemstack.subtract(1); } + SQLiteHelper sqLiteHelper = SQLiteHelper.getInstance(); + int maxTameCount = Config.getMaxPlayerFoxTames(); + if (maxTameCount > 0 && sqLiteHelper.getPlayerFoxAmount(entityhuman.getUniqueID()) >= maxTameCount) { + ((Player) entityhuman.getBukkitEntity()).sendMessage(Utils.getPrefix() + ChatColor.RED + LanguageConfig.getFoxDoesntTrust()); + + return EnumInteractionResult.SUCCESS; + } + // 0.33% chance to tame the fox, also check if the called tame entity event is cancelled or not. if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) { this.tame(entityhuman); @@ -322,6 +332,10 @@ public class EntityTamableFox extends EntityFox { this.setGoalTarget(null); this.goalSit.setSitting(true); + if (maxTameCount > 0) { + sqLiteHelper.addPlayerFoxAmount(entityhuman.getUniqueID(), 1); + } + getBukkitEntity().getWorld().spawnParticle(org.bukkit.Particle.HEART, getBukkitEntity().getLocation(), 6, 0.5D, 0.5D, 0.5D); // Give player tamed message. @@ -480,6 +494,12 @@ public class EntityTamableFox extends EntityFox { public void die(DamageSource damageSource) { if (!this.world.isClientSide && this.world.getGameRules().getBoolean(GameRules.SHOW_DEATH_MESSAGES) && this.getOwner() instanceof EntityPlayer) { this.getOwner().sendMessage(this.getCombatTracker().getDeathMessage(), getOwnerUUID()); + + // Remove the amount of foxes the player has tamed if the limit is enabled. + if (Config.getMaxPlayerFoxTames() > 0) { + SQLiteHelper sqliteHelper = SQLiteHelper.getInstance(); + sqliteHelper.removePlayerFoxAmount(this.getOwner().getUniqueID(), 1); + } } super.die(damageSource); diff --git a/src/main/java/net/seanomik/tamablefoxes/versions/version_1_16_R1/pathfinding/FoxPathfinderGoalRelaxOnOwner.java b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_16_R1/pathfinding/FoxPathfinderGoalRelaxOnOwner.java new file mode 100644 index 0000000..04d6a71 --- /dev/null +++ b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_16_R1/pathfinding/FoxPathfinderGoalRelaxOnOwner.java @@ -0,0 +1,129 @@ +package net.seanomik.tamablefoxes.versions.version_1_16_R1.pathfinding; + +import net.minecraft.server.v1_16_R1.*; +import net.seanomik.tamablefoxes.versions.version_1_16_R1.EntityTamableFox; + +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +public class FoxPathfinderGoalRelaxOnOwner extends PathfinderGoal { + private final EntityTamableFox a; + private EntityHuman b; + private BlockPosition c; + private int d; + + public FoxPathfinderGoalRelaxOnOwner(EntityTamableFox entityTamableFox) { + this.a = entityTamableFox; + } + + public boolean a() { + if (this.a.isTamed()) { + EntityLiving entityliving = this.a.getOwner(); + if (entityliving instanceof EntityHuman) { + this.b = (EntityHuman) entityliving; + if (!entityliving.isSleeping()) { + return false; + } + + if (this.a.h(this.b) > 100.0D) { + return false; + } + + BlockPosition blockposition = this.b.getChunkCoordinates(); + IBlockData iblockdata = this.a.world.getType(blockposition); + if (iblockdata.getBlock().a(TagsBlock.BEDS)) { + this.c = (BlockPosition) iblockdata.d(BlockBed.FACING).map((enumdirection) -> { + return blockposition.shift(enumdirection.opposite()); + }).orElseGet(() -> { + return new BlockPosition(blockposition); + }); + return !this.g(); + } + } + + } + + return false; + } + + private boolean g() { + List list = this.a.world.a(EntityTamableFox.class, (new AxisAlignedBB(this.c)).g(2.0D)); + Iterator iterator = list.iterator(); + + EntityTamableFox entityTamableFox; + do { + do { + if (!iterator.hasNext()) { + return false; + } + + entityTamableFox = (EntityTamableFox) iterator.next(); + } while(entityTamableFox == this.a); + } while(!entityTamableFox.isSleeping()); + + return true; + } + + public boolean b() { + return this.a.isTamed() && this.b != null && this.b.isSleeping() && this.c != null && !this.g(); + } + + public void c() { + if (this.c != null) { + this.a.setSitting(false); + this.a.getNavigation().a((double)this.c.getX(), (double)this.c.getY(), (double)this.c.getZ(), 1.100000023841858D); + } + + } + + public void d() { + this.a.setSleeping(false); + float f = this.a.world.f(1.0F); + if (this.b.eB() >= 100 && (double)f > 0.77D && (double)f < 0.8D && (double)this.a.world.getRandom().nextFloat() < 0.7D) { + this.h(); + } + + this.d = 0; + //this.a.y(false); + this.a.getNavigation().o(); + } + + private void h() { + Random random = this.a.getRandom(); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + blockposition_mutableblockposition.g(this.a.getChunkCoordinates()); + this.a.a((double)(blockposition_mutableblockposition.getX() + random.nextInt(11) - 5), (double)(blockposition_mutableblockposition.getY() + random.nextInt(5) - 2), (double)(blockposition_mutableblockposition.getZ() + random.nextInt(11) - 5), false); + blockposition_mutableblockposition.g(this.a.getChunkCoordinates()); + LootTable loottable = this.a.world.getMinecraftServer().getLootTableRegistry().getLootTable(LootTables.ak); + net.minecraft.server.v1_16_R1.LootTableInfo.Builder loottableinfo_builder = (new net.minecraft.server.v1_16_R1.LootTableInfo.Builder((WorldServer)this.a.world)).set(LootContextParameters.POSITION, blockposition_mutableblockposition).set(LootContextParameters.THIS_ENTITY, this.a).a(random); + List list = loottable.populateLoot(loottableinfo_builder.build(LootContextParameterSets.GIFT)); + Iterator iterator = list.iterator(); + + while(iterator.hasNext()) { + ItemStack itemstack = (ItemStack)iterator.next(); + this.a.world.addEntity(new EntityItem(this.a.world, (double)blockposition_mutableblockposition.getX() - (double)MathHelper.sin(this.a.aH * 0.017453292F), (double)blockposition_mutableblockposition.getY(), (double)blockposition_mutableblockposition.getZ() + (double)MathHelper.cos(this.a.aH * 0.017453292F), itemstack)); + } + + } + + public void e() { + if (this.b != null && this.c != null) { + this.a.setSitting(false); + this.a.getNavigation().a((double)this.c.getX(), (double)this.c.getY(), (double)this.c.getZ(), 1.100000023841858D); + if (this.a.h(this.b) < 2.5D) { + ++this.d; + if (this.d > 16) { + this.a.setSleeping(true); + //this.a.y(false); + } else { + this.a.a(this.b, 45.0F, 45.0F); + //this.a.y(true); + } + } else { + this.a.setSleeping(false); + } + } + + } +} diff --git a/src/main/java/net/seanomik/tamablefoxes/versions/version_1_16_R2/EntityTamableFox.java b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_16_R2/EntityTamableFox.java index 4522fac..f2b4980 100644 --- a/src/main/java/net/seanomik/tamablefoxes/versions/version_1_16_R2/EntityTamableFox.java +++ b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_16_R2/EntityTamableFox.java @@ -5,6 +5,7 @@ import net.seanomik.tamablefoxes.TamableFoxes; import net.seanomik.tamablefoxes.Utils; import net.seanomik.tamablefoxes.io.Config; import net.seanomik.tamablefoxes.io.LanguageConfig; +import net.seanomik.tamablefoxes.io.sqlite.SQLiteHelper; import net.seanomik.tamablefoxes.versions.version_1_16_R2.pathfinding.*; import net.wesjd.anvilgui.AnvilGUI; import org.bukkit.Bukkit; @@ -78,6 +79,7 @@ public class EntityTamableFox extends EntityFox { this.goalSelector.a(0, getFoxInnerPathfinderGoal("g")); // FoxFloatGoal this.goalSelector.a(1, getFoxInnerPathfinderGoal("b")); // FaceplantGoal this.goalSelector.a(2, new FoxPathfinderGoalPanic(this, 2.2D)); + this.goalSelector.a(2, new FoxPathfinderGoalRelaxOnOwner(this)); this.goalSelector.a(3, getFoxInnerPathfinderGoal("e", Arrays.asList(1.0D), Arrays.asList(double.class))); // FoxBreedGoal this.goalSelector.a(4, new PathfinderGoalAvoidTarget(this, EntityHuman.class, 16.0F, 1.6D, 1.4D, (entityliving) -> { @@ -310,6 +312,14 @@ public class EntityTamableFox extends EntityFox { itemstack.subtract(1); } + SQLiteHelper sqLiteHelper = SQLiteHelper.getInstance(); + int maxTameCount = Config.getMaxPlayerFoxTames(); + if (maxTameCount > 0 && sqLiteHelper.getPlayerFoxAmount(entityhuman.getUniqueID()) >= maxTameCount) { + ((Player) entityhuman.getBukkitEntity()).sendMessage(Utils.getPrefix() + ChatColor.RED + LanguageConfig.getFoxDoesntTrust()); + + return EnumInteractionResult.SUCCESS; + } + // 0.33% chance to tame the fox, also check if the called tame entity event is cancelled or not. if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) { this.tame(entityhuman); @@ -319,6 +329,10 @@ public class EntityTamableFox extends EntityFox { this.setGoalTarget(null); this.goalSit.setSitting(true); + if (maxTameCount > 0) { + sqLiteHelper.addPlayerFoxAmount(entityhuman.getUniqueID(), 1); + } + getBukkitEntity().getWorld().spawnParticle(org.bukkit.Particle.HEART, getBukkitEntity().getLocation(), 6, 0.5D, 0.5D, 0.5D); // Give player tamed message. @@ -477,6 +491,12 @@ public class EntityTamableFox extends EntityFox { public void die(DamageSource damageSource) { if (!this.world.isClientSide && this.world.getGameRules().getBoolean(GameRules.SHOW_DEATH_MESSAGES) && this.getOwner() instanceof EntityPlayer) { this.getOwner().sendMessage(this.getCombatTracker().getDeathMessage(), getOwnerUUID()); + + // Remove the amount of foxes the player has tamed if the limit is enabled. + if (Config.getMaxPlayerFoxTames() > 0) { + SQLiteHelper sqliteHelper = SQLiteHelper.getInstance(); + sqliteHelper.removePlayerFoxAmount(this.getOwner().getUniqueID(), 1); + } } super.die(damageSource); diff --git a/src/main/java/net/seanomik/tamablefoxes/versions/version_1_16_R2/pathfinding/FoxPathfinderGoalRelaxOnOwner.java b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_16_R2/pathfinding/FoxPathfinderGoalRelaxOnOwner.java new file mode 100644 index 0000000..6c5621f --- /dev/null +++ b/src/main/java/net/seanomik/tamablefoxes/versions/version_1_16_R2/pathfinding/FoxPathfinderGoalRelaxOnOwner.java @@ -0,0 +1,129 @@ +package net.seanomik.tamablefoxes.versions.version_1_16_R2.pathfinding; + +import net.minecraft.server.v1_16_R2.*; +import net.seanomik.tamablefoxes.versions.version_1_16_R2.EntityTamableFox; + +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +public class FoxPathfinderGoalRelaxOnOwner extends PathfinderGoal { + private final EntityTamableFox a; + private EntityHuman b; + private BlockPosition c; + private int d; + + public FoxPathfinderGoalRelaxOnOwner(EntityTamableFox entityTamableFox) { + this.a = entityTamableFox; + } + + public boolean a() { + if (this.a.isTamed()) { + EntityLiving entityliving = this.a.getOwner(); + if (entityliving instanceof EntityHuman) { + this.b = (EntityHuman) entityliving; + if (!entityliving.isSleeping()) { + return false; + } + + if (this.a.h(this.b) > 100.0D) { + return false; + } + + BlockPosition blockposition = this.b.getChunkCoordinates(); + IBlockData iblockdata = this.a.world.getType(blockposition); + if (iblockdata.getBlock().a(TagsBlock.BEDS)) { + this.c = (BlockPosition) iblockdata.d(BlockBed.FACING).map((enumdirection) -> { + return blockposition.shift(enumdirection.opposite()); + }).orElseGet(() -> { + return new BlockPosition(blockposition); + }); + return !this.g(); + } + } + + } + + return false; + } + + private boolean g() { + List list = this.a.world.a(EntityTamableFox.class, (new AxisAlignedBB(this.c)).g(2.0D)); + Iterator iterator = list.iterator(); + + EntityTamableFox entityTamableFox; + do { + do { + if (!iterator.hasNext()) { + return false; + } + + entityTamableFox = (EntityTamableFox) iterator.next(); + } while(entityTamableFox == this.a); + } while(!entityTamableFox.isSleeping()); + + return true; + } + + public boolean b() { + return this.a.isTamed() && this.b != null && this.b.isSleeping() && this.c != null && !this.g(); + } + + public void c() { + if (this.c != null) { + this.a.setSitting(false); + this.a.getNavigation().a((double)this.c.getX(), (double)this.c.getY(), (double)this.c.getZ(), 1.100000023841858D); + } + + } + + public void d() { + this.a.setSleeping(false); + float f = this.a.world.f(1.0F); + if (this.b.eB() >= 100 && (double)f > 0.77D && (double)f < 0.8D && (double)this.a.world.getRandom().nextFloat() < 0.7D) { + this.h(); + } + + this.d = 0; + //this.a.y(false); + this.a.getNavigation().o(); + } + + private void h() { + Random random = this.a.getRandom(); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + blockposition_mutableblockposition.g(this.a.getChunkCoordinates()); + this.a.a((double)(blockposition_mutableblockposition.getX() + random.nextInt(11) - 5), (double)(blockposition_mutableblockposition.getY() + random.nextInt(5) - 2), (double)(blockposition_mutableblockposition.getZ() + random.nextInt(11) - 5), false); + blockposition_mutableblockposition.g(this.a.getChunkCoordinates()); + LootTable loottable = this.a.world.getMinecraftServer().getLootTableRegistry().getLootTable(LootTables.ak); + net.minecraft.server.v1_16_R2.LootTableInfo.Builder loottableinfo_builder = (new net.minecraft.server.v1_16_R2.LootTableInfo.Builder((WorldServer)this.a.world)).set(LootContextParameters.ORIGIN, this.a.getPositionVector()).set(LootContextParameters.THIS_ENTITY, this.a).a(random); + List list = loottable.populateLoot(loottableinfo_builder.build(LootContextParameterSets.GIFT)); + Iterator iterator = list.iterator(); + + while(iterator.hasNext()) { + ItemStack itemstack = (ItemStack)iterator.next(); + this.a.world.addEntity(new EntityItem(this.a.world, (double)blockposition_mutableblockposition.getX() - (double)MathHelper.sin(this.a.aA * 0.017453292F), (double)blockposition_mutableblockposition.getY(), (double)blockposition_mutableblockposition.getZ() + (double)MathHelper.cos(this.a.aA * 0.017453292F), itemstack)); + } + + } + + public void e() { + if (this.b != null && this.c != null) { + this.a.setSitting(false); + this.a.getNavigation().a((double)this.c.getX(), (double)this.c.getY(), (double)this.c.getZ(), 1.100000023841858D); + if (this.a.h(this.b) < 2.5D) { + ++this.d; + if (this.d > 16) { + this.a.setSleeping(true); + //this.a.y(false); + } else { + this.a.a(this.b, 45.0F, 45.0F); + //this.a.y(true); + } + } else { + this.a.setSleeping(false); + } + } + + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 10d088c..5c59195 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,7 +1,7 @@ # Config for Tamable Foxes show-owner-in-fox-name: true -enable-taming-permission: true ask-for-name-after-taming: true +max-fox-tames: 0 tamed-behavior: attack-wild-animals: true \ No newline at end of file diff --git a/src/main/resources/language.yml b/src/main/resources/language.yml index ccfae0f..2036488 100644 --- a/src/main/resources/language.yml +++ b/src/main/resources/language.yml @@ -10,6 +10,7 @@ taming-asking-for-name-message: "What do you want to call it?" taming-chosen-name-perfect: "%NEW_FOX_NAME% is perfect!" fox-name-format: "%FOX_NAME% (%OWNER%'s Fox)" fox-name-no-owner-name-format: "%FOX_NAME%" +fox-doesnt-trust: "The fox doesn't trust you! You have too many foxes!" no-permission: "You do not have the permission for this command." only-run-by-player: "Command can only be run from player state!"