From ba48f8e4689d417ef545dce8863c1fafb722c113 Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Fri, 24 Jan 2020 10:21:13 -0600 Subject: [PATCH] Rewrite and got the custom entity replacing the EntityFox I found out how to get my custom entity to replace the vanilla EntityFox. This should fix most of the errors people were getting. I also rewrote the entire plugin. It saves some data with SQLite and some parts of it are cleaned up, optimized, or certain things moved in an appropriate class. --- .idea/compiler.xml | 6 +- .idea/encodings.xml | 1 - .idea/misc.xml | 3 +- .idea/workspace.xml | 259 +++++---- pom.xml | 22 +- .../net/seanomik/tamablefoxes/Config.java | 24 + .../tamablefoxes/EntityTamableFox.java | 518 +++++++++++++----- .../seanomik/tamablefoxes/TamableFoxes.java | 468 ++++------------ .../java/net/seanomik/tamablefoxes/Utils.java | 89 +++ .../command/CommandSpawnTamableFox.java | 52 +- .../seanomik/tamablefoxes/io/FileManager.java | 113 ---- .../pathfinding/FoxPathfindGoalBeg.java | 64 --- .../pathfinding/FoxPathfindGoalBreed.java | 113 ---- .../pathfinding/FoxPathfindGoalFleeSun.java | 55 -- .../pathfinding/FoxPathfindGoalFloat.java | 34 -- .../FoxPathfindGoalFollowOwner.java | 105 ---- .../pathfinding/FoxPathfindGoalLunge.java | 125 ----- .../FoxPathfindGoalLungeUNKNOWN_USE.java | 85 --- .../FoxPathfindGoalOwnerHurtTarget.java | 47 -- .../FoxPathfindGoalPickBushes.java | 85 --- .../FoxPathfindGoalRandomStrollLand.java | 98 ---- .../FoxPathfindGoalRandomTargetNonTamed.java | 27 - .../FoxPathfinderGoalFollowOwner.java | 139 +++++ ...ava => FoxPathfinderGoalHurtByTarget.java} | 6 +- ...java => FoxPathfinderGoalMeleeAttack.java} | 22 +- ...> FoxPathfinderGoalOwnerHurtByTarget.java} | 6 +- .../FoxPathfinderGoalOwnerHurtTarget.java | 57 ++ .../pathfinding/FoxPathfinderGoalPanic.java | 30 + ...GoalSit.java => FoxPathfinderGoalSit.java} | 4 +- .../sqlite/SQLiteSetterGetter.java | 125 +++-- src/main/resources/config.yml | 5 +- src/main/resources/foxes.yml | 2 - src/main/resources/plugin.yml | 9 +- target/classes/config.yml | 5 +- target/classes/foxes.yml | 2 - target/classes/plugin.yml | 9 +- target/maven-archiver/pom.properties | 6 +- .../compile/default-compile/createdFiles.lst | 29 +- .../compile/default-compile/inputFiles.lst | 34 +- 39 files changed, 1141 insertions(+), 1742 deletions(-) create mode 100644 src/main/java/net/seanomik/tamablefoxes/Config.java create mode 100644 src/main/java/net/seanomik/tamablefoxes/Utils.java delete mode 100644 src/main/java/net/seanomik/tamablefoxes/io/FileManager.java delete mode 100644 src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalBeg.java delete mode 100644 src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalBreed.java delete mode 100644 src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalFleeSun.java delete mode 100644 src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalFloat.java delete mode 100644 src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalFollowOwner.java delete mode 100644 src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalLunge.java delete mode 100644 src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalLungeUNKNOWN_USE.java delete mode 100644 src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalOwnerHurtTarget.java delete mode 100644 src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalPickBushes.java delete mode 100644 src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalRandomStrollLand.java delete mode 100644 src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalRandomTargetNonTamed.java create mode 100644 src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfinderGoalFollowOwner.java rename src/main/java/net/seanomik/tamablefoxes/pathfinding/{FoxPathfindGoalHurtByTarget.java => FoxPathfinderGoalHurtByTarget.java} (93%) rename src/main/java/net/seanomik/tamablefoxes/pathfinding/{FoxPathfindGoalMeleeAttack.java => FoxPathfinderGoalMeleeAttack.java} (52%) rename src/main/java/net/seanomik/tamablefoxes/pathfinding/{FoxPathfindGoalOwnerHurtByTarget.java => FoxPathfinderGoalOwnerHurtByTarget.java} (84%) create mode 100644 src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfinderGoalOwnerHurtTarget.java create mode 100644 src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfinderGoalPanic.java rename src/main/java/net/seanomik/tamablefoxes/pathfinding/{FoxPathfindGoalSit.java => FoxPathfinderGoalSit.java} (90%) delete mode 100644 src/main/resources/foxes.yml delete mode 100644 target/classes/foxes.yml diff --git a/.idea/compiler.xml b/.idea/compiler.xml index f275097..4a9b692 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -6,9 +6,11 @@ - - + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml index bee17f4..a156f52 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -1,7 +1,6 @@ - diff --git a/.idea/misc.xml b/.idea/misc.xml index 072970c..6fb7c97 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -5,7 +5,6 @@ - - + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 28c1e46..3936248 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -1,31 +1,41 @@ - - - + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 0309366..f853677 100644 --- a/pom.xml +++ b/pom.xml @@ -5,11 +5,11 @@ 4.0.0 net.seanomik - tamableFoxes - 1.4.1-SNAPSHOT + tamablefoxes + 1.5-SNAPSHOT jar - TamableFoxes + Tamablefoxes 1.8 @@ -24,8 +24,8 @@ maven-compiler-plugin 3.7.0 - 1.8 - 1.8 + ${java.version} + ${java.version} @@ -39,7 +39,8 @@ shade - D:\Code\java\spigotPlugins\TEST_SERVER\plugins\${project.artifactId}-${project.version}.jar + + E:\_TEST_SERVER_1.15.1_\plugins\${project.artifactId}-MC-1.15.1-${project.version}.jar false @@ -70,11 +71,18 @@ - + + + org.spigotmc + spigot + 1.15.1 + system + E:/spigot-1.15.1.jar com.github.WesJD.AnvilGUI diff --git a/src/main/java/net/seanomik/tamablefoxes/Config.java b/src/main/java/net/seanomik/tamablefoxes/Config.java new file mode 100644 index 0000000..27efc7d --- /dev/null +++ b/src/main/java/net/seanomik/tamablefoxes/Config.java @@ -0,0 +1,24 @@ +package net.seanomik.tamablefoxes; + +import org.bukkit.entity.Player; + +public class Config { + private static TamableFoxes plugin = TamableFoxes.getPlugin(); + + public static boolean doesShowOwnerFoxName() { + return plugin.getConfig().getBoolean("show-owner-in-fox-name"); + } + + public static boolean doesShowNameTags() { + return plugin.getConfig().getBoolean("show-nametags"); + } + + public static boolean doesTamedAttackWildAnimals() { + return plugin.getConfig().getBoolean("tamed-behavior.attack-wild-animals"); + } + + public static boolean canPlayerTameFox(Player player) { + return !plugin.getConfig().getBoolean("enable-taming-permission") || (plugin.getConfig().getBoolean("enable-taming-permission") && (player.hasPermission("tamablefoxes.tame") || player.isOp())); + } + +} diff --git a/src/main/java/net/seanomik/tamablefoxes/EntityTamableFox.java b/src/main/java/net/seanomik/tamablefoxes/EntityTamableFox.java index 636c00c..c256742 100644 --- a/src/main/java/net/seanomik/tamablefoxes/EntityTamableFox.java +++ b/src/main/java/net/seanomik/tamablefoxes/EntityTamableFox.java @@ -1,80 +1,120 @@ package net.seanomik.tamablefoxes; +import com.mojang.datafixers.Dynamic; import net.minecraft.server.v1_15_R1.*; import net.seanomik.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.craftbukkit.v1_15_R1.inventory.CraftItemStack; +import org.bukkit.entity.Item; 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 javax.annotation.Nullable; import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; public class EntityTamableFox extends EntityFox { - private static Fox thisFox; - private final TamableFoxes plugin; - - private boolean isTamed; - private EntityLiving owner; + private boolean tamed; + private boolean sitting; + private boolean sleeping; private String chosenName; - private boolean sit = false; - private BukkitTask sittingRunnable; + private EntityLiving owner; + private UUID ownerUUID; - private FoxPathfindGoalSit goalSit; - private PathfinderGoalNearestAttackableTarget goalAttack; + private FoxPathfinderGoalSit goalSit; + private PathfinderGoal goalRandomSitting; + private PathfinderGoal goalBerryPicking; + private PathfinderGoal goalFleeSun; + private PathfinderGoal goalNearestVillage; - public int databaseID = -1; + public EntityTamableFox(EntityTypes entitytypes, World world) { + super(entitytypes, world); + } - public EntityTamableFox(TamableFoxes plugin, EntityTypes entitytypes, World world) { - super(EntityTypes.FOX, world); - this.plugin = plugin; - thisFox = (Fox) this.getBukkitEntity(); + private PathfinderGoal getFoxInnerPathfinderGoal(String innerName, List args, List> argTypes) { + return (PathfinderGoal) Utils.instantiatePrivateInnerClass(EntityFox.class, innerName, this, args, argTypes); + } - if (!plugin.getFoxUUIDs().containsKey(thisFox.getUniqueId())) { - plugin.getFoxUUIDs().put(this.getBukkitEntity().getUniqueId(), null); - } - - this.setPersistent(); + private PathfinderGoal getFoxInnerPathfinderGoal(String innerName) { + return (PathfinderGoal) Utils.instantiatePrivateInnerClass(EntityFox.class, innerName, this, Arrays.asList(), Arrays.asList()); } @Override 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)); + try { + this.goalSit = new FoxPathfinderGoalSit(this); + this.goalSelector.a(0, getFoxInnerPathfinderGoal("g")); // Swim + this.goalSelector.a(1, this.goalSit); + this.goalSelector.a(1, getFoxInnerPathfinderGoal("b")); // Unknown - this.goalAttack = new PathfinderGoalNearestAttackableTarget(this, EntityLiving.class, 10, false, false, - entityLiving -> !isTamed && (entityLiving instanceof EntityChicken || entityLiving instanceof EntityRabbit)); + // Panic + this.goalSelector.a(2, new FoxPathfinderGoalPanic(this, 2.2D)); - if (!isTamed || (plugin.isTamedAttackRabbitChicken() && isTamed)) { - this.targetSelector.a(4, goalAttack); + // Breed + this.goalSelector.a(3, getFoxInnerPathfinderGoal("n", Arrays.asList(1.0D), Arrays.asList(double.class))); + + // Avoid human only if not tamed + this.goalSelector.a(4, new PathfinderGoalAvoidTarget(this, EntityHuman.class, 16.0F, 1.6D, 1.4D, (entityliving) -> !tamed)); + + // Avoid wolf if it is not tamed + this.goalSelector.a(4, new PathfinderGoalAvoidTarget(this, EntityWolf.class, 8.0F, 1.6D, 1.4D, (entityliving) -> { + try { + Method eFMethod = EntityFox.class.getDeclaredMethod("eF"); + eFMethod.setAccessible(true); + boolean eF = (boolean) eFMethod.invoke(this); + eFMethod.setAccessible(false); + + return !((EntityWolf) entityliving).isTamed() && !eF; + } catch (Exception e) { + return !((EntityWolf) entityliving).isTamed(); + } + })); + this.goalSelector.a(4, new FoxPathfinderGoalMeleeAttack(this, 1.2000000476837158D, true)); + this.goalSelector.a(5, new FoxPathfinderGoalFollowOwner(this, 1.3D, 10.0F, 2.0F, false)); + this.goalSelector.a(6, getFoxInnerPathfinderGoal("u")); // Lunge shake + this.goalSelector.a(7, new EntityFox.o()); // Lunge + + // Flee sun + goalFleeSun = getFoxInnerPathfinderGoal("s", Arrays.asList(1.25D), Arrays.asList(double.class)); + this.goalSelector.a(7, goalFleeSun); + + this.goalSelector.a(8, getFoxInnerPathfinderGoal("t")); // Sleeping under trees + this.goalSelector.a(9, getFoxInnerPathfinderGoal("h", Arrays.asList(this, 1.25D), Arrays.asList(EntityFox.class, double.class))); // Follow parent + + // Nearest village + goalNearestVillage = getFoxInnerPathfinderGoal("q", Arrays.asList(32, 200), Arrays.asList(int.class, int.class)); + this.goalSelector.a(9, goalNearestVillage); + + // Pick berry bushes + goalBerryPicking = new EntityFox.f(1.2000000476837158D, 12, 2); + this.goalSelector.a(10, goalBerryPicking); + + this.goalSelector.a(10, new PathfinderGoalLeapAtTarget(this, 0.4F)); + this.goalSelector.a(11, new PathfinderGoalRandomStrollLand(this, 1.15D)); + + this.goalSelector.a(11, getFoxInnerPathfinderGoal("p")); // If a item is on the ground, go to it and take it + this.goalSelector.a(12, getFoxInnerPathfinderGoal("j", Arrays.asList(this, EntityHuman.class, 24.0f), Arrays.asList(EntityInsentient.class, Class.class, float.class))); // Look at player + + // The random sitting(?) + this.goalRandomSitting = getFoxInnerPathfinderGoal("r"); + this.goalSelector.a(13, goalRandomSitting); + + this.targetSelector.a(1, new FoxPathfinderGoalOwnerHurtByTarget(this)); + this.targetSelector.a(2, new FoxPathfinderGoalOwnerHurtTarget(this)); + this.targetSelector.a(3, (new FoxPathfinderGoalHurtByTarget(this, new Class[0])).a(new Class[0])); + + // Wild animal attacking + this.targetSelector.a(4, new PathfinderGoalNearestAttackableTarget(this, EntityLiving.class, 10, false, false, + entityLiving -> (!tamed || (Config.doesTamedAttackWildAnimals() && tamed)) && ( + entityLiving instanceof EntityChicken || + entityLiving instanceof EntityRabbit || + (entityLiving instanceof EntityTurtle && EntityTurtle.bw.test((EntityLiving) entityLiving)) || + entityLiving instanceof EntityFishSchool))); + } catch (Exception e) { + e.printStackTrace(); } - - this.targetSelector.a(5, new FoxPathfindGoalHurtByTarget(this).a(new Class[0])); } @Override @@ -84,106 +124,311 @@ public class EntityTamableFox extends EntityFox { 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.FOLLOW_RANGE).setValue(16.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; - } + public boolean isOtherFoxFamily(EntityLiving living) { + if (living instanceof EntityTamableFox) { + EntityTamableFox tamableFox = (EntityTamableFox) living; - 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(); - } + return (tamableFox.isTamed() && tamableFox.getOwner().getUniqueID() == this.getOwner().getUniqueID()); + } else { + return false; } - - } - - public TamableFoxes getPlugin() { - return plugin; - } - - public boolean isTamed() { - return this.isTamed; } public void setTamed(boolean tamed) { - this.isTamed = tamed; + this.tamed = tamed; - // Remove attack goal if tamed - if (isTamed && plugin.isTamedAttackRabbitChicken()) { - this.targetSelector.a(goalAttack); - } else { // Adds it - this.targetSelector.a(4, goalAttack); - } + // Remove goals that are not needed when named, or defeats the purpose of taming + this.goalSelector.a(goalRandomSitting); + this.goalSelector.a(goalBerryPicking); + this.goalSelector.a(goalFleeSun); + this.goalSelector.a(goalNearestVillage); + } + + public boolean isTamed() { + return tamed; + } + + public void setOwner(EntityLiving entityLiving) { + this.owner = entityLiving; + updateFoxVisual(); + } + + public EntityLiving getOwner() { + return owner; + } + + public void setOwnerUUID(UUID uuid) { + this.ownerUUID = uuid; + } + + public UUID getOwnerUUID() { + return ownerUUID; + } + + public void setChosenName(String name) { + this.chosenName = name; + updateFoxVisual(); } public String getChosenName() { return chosenName; } - public void setChosenName(String chosenName) { - this.chosenName = chosenName; + public void setMouthItem(ItemStack item) { + item.setCount(1); + setSlot(EnumItemSlot.MAINHAND, item); + + TamableFoxes.getPlugin().sqLiteSetterGetter.saveFox(this); + } + + public void setMouthItem(org.bukkit.inventory.ItemStack item) { + ItemStack itemNMS = CraftItemStack.asNMSCopy(item); + setMouthItem(itemNMS); + } + + public ItemStack getMouthItem() { + return getEquipment(EnumItemSlot.MAINHAND); + } + + public Item dropMouthItem() { + Item droppedItem = getBukkitEntity().getWorld().dropItem(getBukkitEntity().getLocation().add(0, 0, 0), CraftItemStack.asBukkitCopy(getMouthItem())); + setSlot(EnumItemSlot.MAINHAND, new net.minecraft.server.v1_15_R1.ItemStack(Items.AIR)); + + return droppedItem; + } + + @Override + public void setSitting(boolean sit) { + super.setSitting(sit); + + if (sleeping) { + sleeping = false; + super.setSleeping(false); + } + updateFoxVisual(); } - public EntityLiving getOwner() { - return this.owner; - } + public void setHardSitting(boolean sit) { + super.setSitting(sit); + this.sitting = sit; + + if (sleeping) { + sleeping = false; + super.setSleeping(false); + } - public void setOwner(EntityLiving owner) { - this.owner = owner; updateFoxVisual(); } public boolean toggleSitting() { - this.sit = !this.sit; - updateFoxVisual(); + this.sitting = !this.sitting; + setHardSitting(sitting); - plugin.sqLiteSetterGetter.saveFox(this); - return this.sit; + return this.sitting; } - public void updateFox() { - updateFoxVisual(); + public boolean isJumping() { + return this.jumping; } + private void updateFoxVisual() { + new UpdateFoxRunnable().runTask(TamableFoxes.getPlugin()); + } + + private class UpdateFoxRunnable extends BukkitRunnable { + UpdateFoxRunnable() { + + } + + public void run() { + goalSit.setSitting(sitting); + + if (tamed) { + getBukkitEntity().setCustomName((chosenName != null ? chosenName : "") + + (owner != null && Config.doesShowOwnerFoxName() ? ChatColor.RESET + " (" + owner.getName() + ")" : "")); + getBukkitEntity().setCustomNameVisible(Config.doesShowNameTags()); + } + } + } + + + // Used for all the nasty stuff below. + private static boolean isLevelAtLeast(NBTTagCompound tag, int level) { + return tag.hasKey("Bukkit.updateLevel") && tag.getInt("Bukkit.updateLevel") >= level; + } + + // To remove a call to initializePathFinderGoals() + // This is all from every super class that has a method like this. + // This was needed because you cant call a "super.super.method()" + @Override + public void a(NBTTagCompound nbttagcompound) { + try { + // EntityLiving + this.setAbsorptionHearts(nbttagcompound.getFloat("AbsorptionAmount")); + if (nbttagcompound.hasKeyOfType("Attributes", 9) && this.world != null && !this.world.isClientSide) { + GenericAttributes.a(this.getAttributeMap(), nbttagcompound.getList("Attributes", 10)); + } + + if (nbttagcompound.hasKeyOfType("ActiveEffects", 9)) { + NBTTagList nbttaglist = nbttagcompound.getList("ActiveEffects", 10); + + for(int i = 0; i < nbttaglist.size(); ++i) { + NBTTagCompound nbttagcompound1 = nbttaglist.getCompound(i); + MobEffect mobeffect = MobEffect.b(nbttagcompound1); + if (mobeffect != null) { + this.effects.put(mobeffect.getMobEffect(), mobeffect); + } + } + } + + if (nbttagcompound.hasKey("Bukkit.MaxHealth")) { + NBTBase nbtbase = nbttagcompound.get("Bukkit.MaxHealth"); + if (nbtbase.getTypeId() == 5) { + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(((NBTTagFloat)nbtbase).asDouble()); + } else if (nbtbase.getTypeId() == 3) { + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(((NBTTagInt)nbtbase).asDouble()); + } + } + + if (nbttagcompound.hasKeyOfType("Health", 99)) { + this.setHealth(nbttagcompound.getFloat("Health")); + } + + this.hurtTicks = nbttagcompound.getShort("HurtTime"); + this.deathTicks = nbttagcompound.getShort("DeathTime"); + this.hurtTimestamp = nbttagcompound.getInt("HurtByTimestamp"); + if (nbttagcompound.hasKeyOfType("Team", 8)) { + String s = nbttagcompound.getString("Team"); + ScoreboardTeam scoreboardteam = this.world.getScoreboard().getTeam(s); + boolean flag = scoreboardteam != null && this.world.getScoreboard().addPlayerToTeam(this.getUniqueIDString(), scoreboardteam); + if (!flag) { + LOGGER.warn("Unable to add mob to team \"{}\" (that team probably doesn't exist)", s); + } + } + + if (nbttagcompound.getBoolean("FallFlying")) { + this.setFlag(7, true); + } + + if (nbttagcompound.hasKeyOfType("SleepingX", 99) && nbttagcompound.hasKeyOfType("SleepingY", 99) && nbttagcompound.hasKeyOfType("SleepingZ", 99)) { + BlockPosition blockposition = new BlockPosition(nbttagcompound.getInt("SleepingX"), nbttagcompound.getInt("SleepingY"), nbttagcompound.getInt("SleepingZ")); + this.d(blockposition); + this.datawatcher.set(POSE, EntityPose.SLEEPING); + if (!this.justCreated) { + this.a(blockposition); + } + } + + if (nbttagcompound.hasKeyOfType("Brain", 10)) { + this.bo = this.a(new Dynamic(DynamicOpsNBT.a, nbttagcompound.get("Brain"))); + } + // EntityInsentient + NonNullList by = (NonNullList) Utils.getPrivateFieldValue(EntityInsentient.class, "by", this); + NonNullList bx = (NonNullList) Utils.getPrivateFieldValue(EntityInsentient.class, "bx", this); + + boolean data; + if (nbttagcompound.hasKeyOfType("CanPickUpLoot", 1)) { + data = nbttagcompound.getBoolean("CanPickUpLoot"); + if (isLevelAtLeast(nbttagcompound, 1) || data) { + this.setCanPickupLoot(data); + } + } + + data = nbttagcompound.getBoolean("PersistenceRequired"); + if (isLevelAtLeast(nbttagcompound, 1) || data) { + this.persistent = data; + } + + NBTTagList nbttaglist; + int i; + if (nbttagcompound.hasKeyOfType("ArmorItems", 9)) { + nbttaglist = nbttagcompound.getList("ArmorItems", 10); + + for(i = 0; i < by.size(); ++i) { + by.set(i, ItemStack.a(nbttaglist.getCompound(i))); + } + } + + if (nbttagcompound.hasKeyOfType("HandItems", 9)) { + nbttaglist = nbttagcompound.getList("HandItems", 10); + + for(i = 0; i < bx.size(); ++i) { + bx.set(i, ItemStack.a(nbttaglist.getCompound(i))); + } + } + + if (nbttagcompound.hasKeyOfType("ArmorDropChances", 9)) { + nbttaglist = nbttagcompound.getList("ArmorDropChances", 5); + + for(i = 0; i < nbttaglist.size(); ++i) { + this.dropChanceArmor[i] = nbttaglist.i(i); + } + } + + if (nbttagcompound.hasKeyOfType("HandDropChances", 9)) { + nbttaglist = nbttagcompound.getList("HandDropChances", 5); + + for(i = 0; i < nbttaglist.size(); ++i) { + this.dropChanceHand[i] = nbttaglist.i(i); + } + } + + if (nbttagcompound.hasKeyOfType("Leash", 10)) { + //this.bG = nbttagcompound.getCompound("Leash"); + Utils.setPrivateFieldValue(EntityInsentient.class, "bG", this, nbttagcompound.getCompound("Leash")); + } + + this.p(nbttagcompound.getBoolean("LeftHanded")); + if (nbttagcompound.hasKeyOfType("DeathLootTable", 8)) { + this.lootTableKey = new MinecraftKey(nbttagcompound.getString("DeathLootTable")); + this.lootTableSeed = nbttagcompound.getLong("DeathLootTableSeed"); + } + + this.setNoAI(nbttagcompound.getBoolean("NoAI")); + // EntityAgeable + this.setAgeRaw(nbttagcompound.getInt("Age")); + this.c = nbttagcompound.getInt("ForcedAge"); + this.ageLocked = nbttagcompound.getBoolean("AgeLocked"); + // EntityAnimal + this.loveTicks = nbttagcompound.getInt("InLove"); + this.breedCause = nbttagcompound.b("LoveCause") ? nbttagcompound.a("LoveCause") : null; + + NBTTagList foxNBTTagList = nbttagcompound.getList("TrustedUUIDs", 10); + + Method method = this.getClass().getSuperclass().getDeclaredMethod("b", UUID.class); + method.setAccessible(true); + for (int index = 0; index < foxNBTTagList.size(); ++index) { + //this.b(GameProfileSerializer.b(nbttaglist.getCompound(i))); + method.invoke(this, GameProfileSerializer.b(foxNBTTagList.getCompound(index))); + } + method.setAccessible(false); + + this.setSleeping(nbttagcompound.getBoolean("Sleeping")); + this.setFoxType(EntityFox.Type.a(nbttagcompound.getString("Type"))); + + // Use super class due to the new set sitting causing errors + super.setSitting(nbttagcompound.getBoolean("Sitting")); + + this.setCrouching(nbttagcompound.getBoolean("Crouching")); + } catch (Exception e) { + e.printStackTrace(); + } + } + + // To remove the last call to initializePathFinderGoals() + // Cant just override because its a private method + @Override + @Nullable public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, GroupDataEntity groupdataentity, NBTTagCompound nbttagcompound) { BiomeBase biomebase = generatoraccess.getBiome(new BlockPosition(this)); @@ -218,31 +463,4 @@ public class EntityTamableFox extends EntityFox { 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/seanomik/tamablefoxes/TamableFoxes.java b/src/main/java/net/seanomik/tamablefoxes/TamableFoxes.java index 669eaaf..fbda1de 100644 --- a/src/main/java/net/seanomik/tamablefoxes/TamableFoxes.java +++ b/src/main/java/net/seanomik/tamablefoxes/TamableFoxes.java @@ -1,232 +1,132 @@ package net.seanomik.tamablefoxes; -import com.google.common.collect.Maps; -import com.mojang.datafixers.DataFixUtils; -import com.mojang.datafixers.types.Type; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import net.minecraft.server.v1_15_R1.EntityFox; +import net.minecraft.server.v1_15_R1.EntityLiving; +import net.minecraft.server.v1_15_R1.EntityTypes; +import net.minecraft.server.v1_15_R1.EnumItemSlot; import net.seanomik.tamablefoxes.command.CommandSpawnTamableFox; -import net.seanomik.tamablefoxes.io.FileManager; -import net.minecraft.server.v1_15_R1.*; import net.seanomik.tamablefoxes.sqlite.SQLiteHandler; import net.seanomik.tamablefoxes.sqlite.SQLiteSetterGetter; import net.wesjd.anvilgui.AnvilGUI; -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.EntityType; 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.entity.EntityTargetEvent; -import org.bukkit.event.player.*; -import org.bukkit.event.world.ChunkLoadEvent; +import org.bukkit.event.entity.EntitySpawnEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.world.WorldSaveEvent; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.plugin.java.JavaPlugin; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; -import java.util.Arrays; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.stream.Collectors; // @TODO: Add language.yml +// Foxes will be loaded in as sitting, even if they weren't when the server was shutdown +// Add fox sleeping when the player sleeps +public final class TamableFoxes extends JavaPlugin implements Listener { + private static TamableFoxes plugin; + public List spawnedFoxes = new ArrayList<>(); -public class TamableFoxes extends JavaPlugin implements Listener { + public SQLiteSetterGetter sqLiteSetterGetter = new SQLiteSetterGetter(); + public SQLiteHandler sqLiteHandler = new SQLiteHandler(); - public static final String ITEM_INSPECTOR_LORE = ChatColor.BLUE + "Tamable Fox Inspector"; - public static final String TAG_TAME_FOX = "tameablefox"; + @Override + public void onLoad() { + String version = Bukkit.getServer().getClass().getPackage().getName(); - private FileManager fileManager = new FileManager(this); + if (!version.equals("org.bukkit.craftbukkit.v1_15_R1")) { + Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.RED + "This plugin version only supports 1.15.1! Not registering entity!"); + return; + } - private Map foxUUIDs = Maps.newHashMap(); // FoxUUID, OwnerUUID - private EntityTypes customType; - private boolean isOnLoad = true; - private Map lookupCache = Maps.newHashMap(); - private List spawnedFoxes; - private FileManager.Config config;//, configFoxes; - public static SQLiteHandler sqLiteHandler = new SQLiteHandler(); - public static SQLiteSetterGetter sqLiteSetterGetter = new SQLiteSetterGetter(); + try { // Replace the fox entity + Field field = EntityTypes.FOX.getClass().getDeclaredField("ba"); + field.setAccessible(true); + + // Remove the final modifier from the "ba" variable + Field fieldMutable = field.getClass().getDeclaredField("modifiers"); + fieldMutable.setAccessible(true); + fieldMutable.set(field, fieldMutable.getInt(field) & ~Modifier.FINAL); + fieldMutable.setAccessible(false); + + field.set(EntityTypes.FOX, (EntityTypes.b) (type, world) -> new EntityTamableFox(type, world)); + + field.setAccessible(false); + + getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.GREEN + "Replaced tamable fox entity!"); + } catch (Exception e) { + e.printStackTrace(); + getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.RED + "Failed to replace tamable fox entity!"); + } + + } @Override public void onEnable() { String version = Bukkit.getServer().getClass().getPackage().getName(); if (!version.equals("org.bukkit.craftbukkit.v1_15_R1")) { - Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.RED + "This plugin version only supports 1.15.1!"); + Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.RED + "This plugin version only supports 1.15.1! Disabling plugin!"); getServer().getPluginManager().disablePlugin(this); return; } - this.config = fileManager.getConfig("config.yml"); - this.config.copyDefaults(true).save(); + plugin = this; - sqLiteHandler.connect(); - sqLiteSetterGetter.createTablesIfNotExist(); - - this.getServer().getPluginManager().registerEvents(this, this); + getServer().getPluginManager().registerEvents(this, this); this.getCommand("spawntamablefox").setExecutor(new CommandSpawnTamableFox(this)); - 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")); + sqLiteSetterGetter.createTablesIfNotExist(); + this.saveDefaultConfig(); + getConfig().options().copyDefaults(true); + saveConfig(); - 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(); + spawnedFoxes = sqLiteSetterGetter.loadFoxes(); } @Override public void onDisable() { - try { - for (EntityTamableFox fox : spawnedFoxes) { - sqLiteSetterGetter.saveFox(fox); - - fox.getBukkitEntity().remove(); - } - - getServer().getConsoleSender().sendMessage(getPrefix() + ChatColor.GREEN + "Saved all foxes successfully!"); - } catch (Exception e) { - getServer().getConsoleSender().sendMessage(getPrefix() + ChatColor.RED + "Failed to save foxes!"); - } + getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.YELLOW + "Saving foxes."); + sqLiteSetterGetter.saveFoxes(spawnedFoxes); } - 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(); - entityMouthItem.setAmount(1); - - if (entityMouthItem.getType() != Material.AIR) { - tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(entityMouthItem)); - } 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(); - entityMouthItem.setAmount(1); - - if (entityMouthItem.getType() != Material.AIR) { - tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(entityMouthItem)); - } else { - tamableFox.setSlot(EnumItemSlot.MAINHAND, new net.minecraft.server.v1_15_R1.ItemStack(Items.AIR)); - } - } - - entity.remove(); - ++amountReplaced; - } - } - } - - configFoxes.save();*/ - - spawnedFoxes = sqLiteSetterGetter.spawnFoxes(); - 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(); - EntityTamableFox spawnedFox = (EntityTamableFox) customType.b(world, null, null, null, - new BlockPosition(location.getX(), location.getY(), location.getZ()), null, false, false); - - if (!world.addEntity(spawnedFox)) { // Throw a error if the fox failed to spawn - throw new RuntimeException("Failed to spawn fox!"); - } - - spawnedFox.setFoxType(type); - - sqLiteSetterGetter.saveFox((EntityTamableFox) spawnedFox); - - return spawnedFox; - } - - private class SaveFoxRunnable extends BukkitRunnable { - private final TamableFoxes plugin; - - SaveFoxRunnable(TamableFoxes plugin) { - this.plugin = plugin; - } - - public void run() { - try { - sqLiteSetterGetter.saveFoxes(spawnedFoxes); - - getServer().getConsoleSender().sendMessage(getPrefix() + ChatColor.GREEN + "Saved all foxes successfully!"); - } catch (Exception e) { - getServer().getConsoleSender().sendMessage(getPrefix() + ChatColor.RED + "Failed to save foxes!"); - } - } + @EventHandler + public void onWorldSaveEvent(WorldSaveEvent event) { + sqLiteSetterGetter.saveFoxes(spawnedFoxes); } @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { Player player = event.getPlayer(); - getFoxesOf(player).forEach(uuid -> { - EntityTamableFox tamableFox = getSpawnedFox(uuid); - tamableFox.setOwner(((CraftPlayer) player).getHandle()); - tamableFox.setTamed(true); - foxUUIDs.replace(tamableFox.getUniqueID(), player.getUniqueId()); - }); + for (EntityTamableFox fox : getFoxesOf(player)) { + fox.setOwner((EntityLiving) ((CraftEntity) player).getHandle()); + } + } + + @EventHandler + public void onEntitySpawn(EntitySpawnEvent event) { + Entity entity = event.getEntity(); + + if (Utils.isTamableFox(entity)) { + EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) entity).getHandle(); + + spawnedFoxes.add(tamableFox); + } } @EventHandler @@ -234,76 +134,35 @@ public class TamableFoxes extends JavaPlugin implements Listener { Entity entity = event.getRightClicked(); Player player = event.getPlayer(); - if (event.getHand() != EquipmentSlot.HAND) - return; + if (event.getHand() != EquipmentSlot.HAND) return; - final ItemStack playerHand = player.getInventory().getItemInMainHand(); - ItemMeta itemMeta = playerHand.getItemMeta(); + ItemStack itemHand = player.getInventory().getItemInMainHand(); + ItemMeta handMeta = itemHand.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(), - "Entity type: " + ((CraftEntity) entity).getHandle()); - } else { - EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) entity).getHandle(); - - lore = Arrays.asList(ITEM_INSPECTOR_LORE, - "UUID: " + entity.getUniqueId(), - "Entity ID: " + entity.getEntityId(), - "Tamable", - "Owner: " + ((tamableFox.getOwner() == null) ? "none" : 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)) { + // Checks if the entity is EntityTamableFox and that the player is allowed to tame foxes + if (Utils.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())) { + // Check if its tamed but ignore it if the player is holding sweet berries for breeding + if (tamableFox.isTamed() && tamableFox.getOwner() != null && itemHand.getType() != Material.SWEET_BERRIES) { + if (tamableFox.getOwner().getUniqueID() == 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; - } + net.minecraft.server.v1_15_R1.ItemStack foxMouth = tamableFox.getEquipment(EnumItemSlot.MAINHAND); - 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); + if (foxMouth.isEmpty() && itemHand.getType() != Material.AIR) { // Giving an item + tamableFox.setMouthItem(itemHand); + itemHand.setAmount(itemHand.getAmount() - 1); + } else if (!foxMouth.isEmpty() && itemHand.getType() == Material.AIR) { // Taking the item + tamableFox.dropMouthItem(); + } else if (!foxMouth.isEmpty() && itemHand.getType() != Material.AIR){ // Swapping items + // Drop item + tamableFox.dropMouthItem(); + + // Give item and take one away from player + tamableFox.setMouthItem(itemHand); + itemHand.setAmount(itemHand.getAmount() - 1); } - } else if (playerHand.getType() == Material.NAME_TAG) { - ItemMeta handMeta = playerHand.getItemMeta(); + } else if (itemHand.getType() == Material.NAME_TAG) { tamableFox.setChosenName(handMeta.getDisplayName()); } else { tamableFox.toggleSitting(); @@ -311,39 +170,42 @@ public class TamableFoxes extends JavaPlugin implements Listener { event.setCancelled(true); } - } else if (playerHand.getType() == Material.CHICKEN) { - if (Math.random() < 0.33D) { + } else if (itemHand.getType() == Material.CHICKEN && Config.canPlayerTameFox(player)) { + if (Math.random() < 0.33D) { // tamed tamableFox.setTamed(true); tamableFox.setOwner(((CraftPlayer) player).getHandle()); - foxUUIDs.replace(tamableFox.getUniqueID(), null, player.getUniqueId()); + // store uuid player.getWorld().spawnParticle(Particle.HEART, entity.getLocation(), 6, 0.5D, 0.5D, 0.5D); - // Name process + // Name fox player.sendMessage(ChatColor.RED + ChatColor.BOLD.toString() + "You just tamed a wild fox!"); player.sendMessage(ChatColor.RED + "What do you want to call it?"); tamableFox.setChosenName("???"); + //TamableFoxes.getPlugin().sqLiteSetterGetter.saveFox(tamableFox); + event.setCancelled(true); new AnvilGUI.Builder() .onComplete((plr, text) -> { // Called when the inventory output slot is clicked if(!text.equals("")) { tamableFox.setChosenName(text); - plr.sendMessage(getPrefix() + ChatColor.GREEN + text + " is perfect!"); + plr.sendMessage(Utils.getPrefix() + ChatColor.GREEN + text + " is perfect!"); + + TamableFoxes.getPlugin().sqLiteSetterGetter.saveFox(tamableFox); } return AnvilGUI.Response.close(); }) - //.preventClose() // Prevents the inventory from being closed + //.preventClose() // Prevents the inventory from being closed .text("Fox name") // Sets the text the GUI should start with .plugin(this) // Set the plugin instance .open(player); // Opens the GUI for the player provided - - } else { // Failed to tame + } else { // Tame failed 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); + itemHand.setAmount(itemHand.getAmount() - 1); } event.setCancelled(true); @@ -351,112 +213,18 @@ public class TamableFoxes extends JavaPlugin implements Listener { } } - @EventHandler - public void onPlayerBedEnterEvent(PlayerBedEnterEvent event) { - Player player = event.getPlayer(); + public EntityTamableFox spawnTamableFox(Location loc, EntityFox.Type type) { + EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) loc.getWorld().spawnEntity(loc, EntityType.FOX)).getHandle(); + tamableFox.setFoxType(type); - getFoxesOf(player).forEach(uuid -> { - EntityTamableFox tamableFox = getSpawnedFox(uuid); - if (player.getWorld().getTime() > 12541L && player.getWorld().getTime() < 23460L) { - tamableFox.setSleeping(true); - } else return; // Stop the loop, no point of iterating through all the foxes if the condition will be the same. - }); + return tamableFox; } - @EventHandler - public void onPlayerBedLeaveEvent(PlayerBedLeaveEvent event) { - Player player = event.getPlayer(); - - getFoxesOf(player).forEach(uuid -> { - EntityTamableFox tamableFox = getSpawnedFox(uuid); - tamableFox.setSleeping(false); - }); + public List getFoxesOf(Player player) { + return spawnedFoxes.stream().filter(fox -> fox.getOwnerUUID() != null && fox.getOwnerUUID().equals(player.getUniqueId())).collect(Collectors.toList()); } - @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 static TamableFoxes getPlugin() { + return plugin; } - - @EventHandler - public void onEntityDeathEvent(EntityDeathEvent event) { - Entity entity = event.getEntity(); - if (!this.isTamableFox(entity)) return; // Is the entity a tamable fox? - - // Remove the fox from storage - lookupCache.remove(entity.getUniqueId()); - foxUUIDs.remove(entity.getUniqueId()); - spawnedFoxes.remove(entity.getUniqueId()); - - // Notify the owner - EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) entity).getHandle(); - if (tamableFox.getOwner() != null) { - Player owner = ((EntityPlayer)tamableFox.getOwner()).getBukkitEntity(); - owner.sendMessage(getPrefix() + ChatColor.RED + tamableFox.getChosenName() + " was killed!"); - } - - // Remove the fox from database - sqLiteSetterGetter.removeFox(tamableFox); - } - - public EntityTamableFox getSpawnedFox(UUID uniqueId) { - for (EntityTamableFox fox : spawnedFoxes) { - if (fox.getUniqueID() == uniqueId) { - return fox; - } - } - - return null; - } - - 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 EntityTypes getCustomType() { - return customType; - } - - public Map getFoxUUIDs() { - return foxUUIDs; - } - - public List getSpawnedFoxes() { - return spawnedFoxes; - } - - public static String getPrefix() { - //return ChatColor.translateAlternateColorCodes('&', (String) config.get("prefix")); - return ChatColor.RED + "[Tamable Foxes] "; - } - - 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.attack-chicken-rabbit"); - } - } diff --git a/src/main/java/net/seanomik/tamablefoxes/Utils.java b/src/main/java/net/seanomik/tamablefoxes/Utils.java new file mode 100644 index 0000000..d451527 --- /dev/null +++ b/src/main/java/net/seanomik/tamablefoxes/Utils.java @@ -0,0 +1,89 @@ +package net.seanomik.tamablefoxes; + +import org.bukkit.ChatColor; +import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class Utils { + + public static boolean isTamableFox(org.bukkit.entity.Entity entity) { + return ((CraftEntity) entity).getHandle().getClass().getName().contains("TamableFox") || ((CraftEntity) entity).getHandle() instanceof EntityTamableFox; + } + + public static String getPrefix() { + return ChatColor.RED + "[Tamable Foxes] "; + } + + public static Object getPrivateFieldValue(Class c, String field, Object instance) { + Object value = null; + try { + Field f = c.getDeclaredField(field); + f.setAccessible(true); + value = f.get(instance); + f.setAccessible(false); + } catch (Exception e) { + e.printStackTrace(); + } + + return value; + } + + public static void setPrivateFieldValue(Class c, String field, Object instance, Object value) { + try { + Field f = c.getDeclaredField(field); + f.setAccessible(true); + f.set(instance, value); + f.setAccessible(false); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void sendConsoleMessage(String message) { + TamableFoxes.getPlugin().getServer().getConsoleSender().sendMessage(message); + } + + 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/command/CommandSpawnTamableFox.java b/src/main/java/net/seanomik/tamablefoxes/command/CommandSpawnTamableFox.java index 69271e4..9934ffe 100644 --- a/src/main/java/net/seanomik/tamablefoxes/command/CommandSpawnTamableFox.java +++ b/src/main/java/net/seanomik/tamablefoxes/command/CommandSpawnTamableFox.java @@ -1,8 +1,11 @@ package net.seanomik.tamablefoxes.command; +import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; +import net.seanomik.tamablefoxes.Config; import net.seanomik.tamablefoxes.EntityTamableFox; import net.seanomik.tamablefoxes.TamableFoxes; import net.minecraft.server.v1_15_R1.EntityFox; +import net.seanomik.tamablefoxes.Utils; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.command.Command; @@ -42,56 +45,37 @@ public class CommandSpawnTamableFox implements TabExecutor { switch (args[0]) { case "red": try { - EntityTamableFox fox = (EntityTamableFox) plugin.spawnTamableFox(player.getLocation(), EntityFox.Type.RED); - plugin.getSpawnedFoxes().add(fox); + EntityTamableFox fox = plugin.spawnTamableFox(player.getLocation(), EntityFox.Type.RED); + //plugin.getSpawnedFoxes().add(fox); plugin.sqLiteSetterGetter.saveFox(fox); - player.sendMessage(plugin.getPrefix() + ChatColor.RESET + "Spawned a " + ChatColor.RED + "Red" + ChatColor.WHITE + " fox."); + player.sendMessage(Utils.getPrefix() + ChatColor.RESET + "Spawned a " + ChatColor.RED + "Red" + ChatColor.WHITE + " fox."); } catch (Exception e) { - player.sendMessage(plugin.getPrefix() + ChatColor.RED + "Failed to spawn fox, check console!"); + e.printStackTrace(); + player.sendMessage(Utils.getPrefix() + ChatColor.RED + "Failed to spawn fox, check console!"); } break; case "snow": try { - EntityTamableFox spawnedFox = (EntityTamableFox) plugin.spawnTamableFox(player.getLocation(), EntityFox.Type.SNOW); - plugin.getSpawnedFoxes().add(spawnedFox); + EntityTamableFox spawnedFox = plugin.spawnTamableFox(player.getLocation(), EntityFox.Type.SNOW); + //plugin.getSpawnedFoxes().add(spawnedFox); plugin.sqLiteSetterGetter.saveFox(spawnedFox); - player.sendMessage(plugin.getPrefix() + ChatColor.RESET + "Spawned a " + ChatColor.AQUA + "Snow" + ChatColor.WHITE + " fox."); + player.sendMessage(Utils.getPrefix() + ChatColor.RESET + "Spawned a " + ChatColor.AQUA + "Snow" + ChatColor.WHITE + " fox."); } catch (Exception e) { - player.sendMessage(plugin.getPrefix() + ChatColor.RED + "Failed to spawn fox, check console!"); - } - 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 + "Gave 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); + e.printStackTrace(); + player.sendMessage(Utils.getPrefix() + ChatColor.RED + "Failed to spawn fox, check console!"); } break; case "reload": - plugin.getMainConfig().reload(); - //plugin.getConfigFoxes().reload(); - player.sendMessage(plugin.getPrefix() + ChatColor.GREEN + "Reloaded."); + plugin.reloadConfig(); + player.sendMessage(Utils.getPrefix() + ChatColor.GREEN + "Reloaded."); break; default: - player.sendMessage(ChatColor.RED + "/spawntamablefox " + ChatColor.GRAY + "[red | snow | verbose | inspect | reload]"); + player.sendMessage(ChatColor.RED + "/spawntamablefox " + ChatColor.GRAY + "[red | snow | reload]"); } } else { - player.sendMessage(ChatColor.RED + "/spawntamablefox " + ChatColor.GRAY + "[red | snow | verbose | inspect | reload]"); + player.sendMessage(ChatColor.RED + "/spawntamablefox " + ChatColor.GRAY + "[red | snow | reload]"); } return true; @@ -102,8 +86,6 @@ public class CommandSpawnTamableFox implements TabExecutor { return new LinkedList<>(Arrays.asList( "red", "snow", - "verbose", - "inspect", "reload" )); } diff --git a/src/main/java/net/seanomik/tamablefoxes/io/FileManager.java b/src/main/java/net/seanomik/tamablefoxes/io/FileManager.java deleted file mode 100644 index a771998..0000000 --- a/src/main/java/net/seanomik/tamablefoxes/io/FileManager.java +++ /dev/null @@ -1,113 +0,0 @@ -package net.seanomik.tamablefoxes.io; - -import com.google.common.collect.Maps; -import net.seanomik.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/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalBeg.java b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalBeg.java deleted file mode 100644 index cd8d69f..0000000 --- a/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalBeg.java +++ /dev/null @@ -1,64 +0,0 @@ -package net.seanomik.tamablefoxes.pathfinding; - -import net.seanomik.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/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalBreed.java b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalBreed.java deleted file mode 100644 index 0a96b94..0000000 --- a/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalBreed.java +++ /dev/null @@ -1,113 +0,0 @@ -package net.seanomik.tamablefoxes.pathfinding; - -import net.seanomik.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 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 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/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalFleeSun.java b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalFleeSun.java deleted file mode 100644 index b30786f..0000000 --- a/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalFleeSun.java +++ /dev/null @@ -1,55 +0,0 @@ -package net.seanomik.tamablefoxes.pathfinding; - -import net.seanomik.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/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalFloat.java b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalFloat.java deleted file mode 100644 index 6f80acd..0000000 --- a/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalFloat.java +++ /dev/null @@ -1,34 +0,0 @@ -package net.seanomik.tamablefoxes.pathfinding; - -import net.seanomik.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/pathfinding/FoxPathfindGoalFollowOwner.java b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalFollowOwner.java deleted file mode 100644 index 46cc35d..0000000 --- a/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalFollowOwner.java +++ /dev/null @@ -1,105 +0,0 @@ -package net.seanomik.tamablefoxes.pathfinding; - -import net.seanomik.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/pathfinding/FoxPathfindGoalLunge.java b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalLunge.java deleted file mode 100644 index a95c24e..0000000 --- a/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalLunge.java +++ /dev/null @@ -1,125 +0,0 @@ -package net.seanomik.tamablefoxes.pathfinding; - -import net.seanomik.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/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalLungeUNKNOWN_USE.java b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalLungeUNKNOWN_USE.java deleted file mode 100644 index 76d2972..0000000 --- a/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalLungeUNKNOWN_USE.java +++ /dev/null @@ -1,85 +0,0 @@ -package net.seanomik.tamablefoxes.pathfinding; - -import net.seanomik.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/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalOwnerHurtTarget.java b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalOwnerHurtTarget.java deleted file mode 100644 index b205318..0000000 --- a/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalOwnerHurtTarget.java +++ /dev/null @@ -1,47 +0,0 @@ -package net.seanomik.tamablefoxes.pathfinding; - -import net.seanomik.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/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalPickBushes.java b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalPickBushes.java deleted file mode 100644 index 567c5cc..0000000 --- a/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalPickBushes.java +++ /dev/null @@ -1,85 +0,0 @@ -package net.seanomik.tamablefoxes.pathfinding; - -import net.seanomik.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/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalRandomStrollLand.java b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalRandomStrollLand.java deleted file mode 100644 index ad1f434..0000000 --- a/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalRandomStrollLand.java +++ /dev/null @@ -1,98 +0,0 @@ -package net.seanomik.tamablefoxes.pathfinding; - -import net.seanomik.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/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalRandomTargetNonTamed.java b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalRandomTargetNonTamed.java deleted file mode 100644 index be17afe..0000000 --- a/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalRandomTargetNonTamed.java +++ /dev/null @@ -1,27 +0,0 @@ -package net.seanomik.tamablefoxes.pathfinding; - -import net.seanomik.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/pathfinding/FoxPathfinderGoalFollowOwner.java b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfinderGoalFollowOwner.java new file mode 100644 index 0000000..e4fd60c --- /dev/null +++ b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfinderGoalFollowOwner.java @@ -0,0 +1,139 @@ +package net.seanomik.tamablefoxes.pathfinding; + +import net.seanomik.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 FoxPathfinderGoalFollowOwner extends PathfinderGoal { + private final EntityTamableFox a; + private EntityLiving b; + private final IWorldReader c; + private final double d; + private final NavigationAbstract e; + private int f; + private final float g; + private final float h; + private float i; + private final boolean j; + + public FoxPathfinderGoalFollowOwner(EntityTamableFox entityTamableFox, double d0, float f, float f1, boolean flag) { + this.a = entityTamableFox; + this.c = entityTamableFox.world; + this.d = d0; + this.e = entityTamableFox.getNavigation(); + this.h = f; + this.g = f1; + this.j = flag; + this.a(EnumSet.of(Type.MOVE, Type.LOOK)); + if (!(entityTamableFox.getNavigation() instanceof Navigation) && !(entityTamableFox.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.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.b = entityliving; + return true; + } + } + + public boolean b() { + return this.e.m() ? false : (this.a.isSitting() ? false : this.a.h(this.b) > (double)(this.g * this.g)); + } + + public void c() { + this.f = 0; + this.i = this.a.a(PathType.WATER); + this.a.a(PathType.WATER, 0.0F); + } + + public void d() { + this.b = null; + this.e.o(); + this.a.a(PathType.WATER, this.i); + } + + public void e() { + this.a.getControllerLook().a(this.b, 10.0F, (float)this.a.dU()); + if (--this.f <= 0) { + this.f = 10; + if (!this.a.isLeashed() && !this.a.isPassenger()) { + if (this.a.h(this.b) >= 144.0D) { + this.g(); + } else { + this.e.a(this.b, this.d); + } + } + } + + } + + private void g() { + BlockPosition blockposition = new BlockPosition(this.b); + + for(int i = 0; i < 10; ++i) { + int j = this.a(-3, 3); + int k = this.a(-1, 1); + int l = this.a(-3, 3); + boolean flag = this.a(blockposition.getX() + j, blockposition.getY() + k, blockposition.getZ() + l); + if (flag) { + return; + } + } + + } + + private boolean a(int i, int j, int k) { + if (Math.abs((double)i - this.b.locX()) < 2.0D && Math.abs((double)k - this.b.locZ()) < 2.0D) { + return false; + } else if (!this.a(new BlockPosition(i, j, k))) { + return false; + } else { + CraftEntity entity = this.a.getBukkitEntity(); + Location to = new Location(entity.getWorld(), (double)((float)i + 0.5F), (double)j, (double)((float)k + 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 false; + } else { + to = event.getTo(); + this.a.setPositionRotation(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch()); + this.e.o(); + return true; + } + } + } + + private boolean a(BlockPosition blockposition) { + PathType pathtype = PathfinderNormal.b(this.c, blockposition.getX(), blockposition.getY(), blockposition.getZ()); + if (pathtype != PathType.WALKABLE) { + return false; + } else { + IBlockData iblockdata = this.c.getType(blockposition.down()); + if (!this.j && iblockdata.getBlock() instanceof BlockLeaves) { + return false; + } else { + BlockPosition blockposition1 = blockposition.b(new BlockPosition(this.a)); + return this.c.getCubes(this.a, this.a.getBoundingBox().a(blockposition1)); + } + } + } + + private int a(int i, int j) { + return this.a.getRandom().nextInt(j - i + 1) + i; + } + +} diff --git a/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalHurtByTarget.java b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfinderGoalHurtByTarget.java similarity index 93% rename from src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalHurtByTarget.java rename to src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfinderGoalHurtByTarget.java index 61bb279..2247077 100644 --- a/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalHurtByTarget.java +++ b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfinderGoalHurtByTarget.java @@ -8,7 +8,7 @@ import java.util.EnumSet; import java.util.Iterator; import java.util.List; -public class FoxPathfindGoalHurtByTarget extends PathfinderGoalTarget { +public class FoxPathfinderGoalHurtByTarget extends PathfinderGoalTarget { private static final PathfinderTargetCondition a = (new PathfinderTargetCondition()).c().e(); private final Class[] d; @@ -16,7 +16,7 @@ public class FoxPathfindGoalHurtByTarget extends PathfinderGoalTarget { private int c; private Class[] i; - public FoxPathfindGoalHurtByTarget(EntityTamableFox entitycreature, Class... aclass) { + public FoxPathfinderGoalHurtByTarget(EntityTamableFox entitycreature, Class... aclass) { super(entitycreature, true); this.d = aclass; this.a(EnumSet.of(Type.TARGET)); @@ -41,7 +41,7 @@ public class FoxPathfindGoalHurtByTarget extends PathfinderGoalTarget { } } - public FoxPathfindGoalHurtByTarget a(Class... aclass) { + public FoxPathfinderGoalHurtByTarget a(Class... aclass) { this.b = true; this.i = aclass; return this; diff --git a/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalMeleeAttack.java b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfinderGoalMeleeAttack.java similarity index 52% rename from src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalMeleeAttack.java rename to src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfinderGoalMeleeAttack.java index 5a3445c..968724c 100644 --- a/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalMeleeAttack.java +++ b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfinderGoalMeleeAttack.java @@ -1,36 +1,38 @@ package net.seanomik.tamablefoxes.pathfinding; -import net.seanomik.tamablefoxes.EntityTamableFox; +import net.minecraft.server.v1_15_R1.EntityFox; import net.minecraft.server.v1_15_R1.EntityLiving; import net.minecraft.server.v1_15_R1.PathfinderGoalMeleeAttack; import net.minecraft.server.v1_15_R1.SoundEffects; +import net.seanomik.tamablefoxes.EntityTamableFox; -public class FoxPathfindGoalMeleeAttack extends PathfinderGoalMeleeAttack { +public class FoxPathfinderGoalMeleeAttack extends PathfinderGoalMeleeAttack { + EntityTamableFox tamableFox; + EntityLiving enemy; - protected EntityTamableFox tamableFox; - - public FoxPathfindGoalMeleeAttack(EntityTamableFox tamableFox, double d0, boolean flag) { + public FoxPathfinderGoalMeleeAttack(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); + this.enemy = 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); + tamableFox.a(SoundEffects.ENTITY_FOX_BITE, 1.0F, 1.0F); } } public void c() { - this.tamableFox.u(false); + tamableFox.u(false); super.c(); } public boolean a() { - return !this.tamableFox.isSitting() && !this.tamableFox.isSleeping() && !this.tamableFox.isCrouching() && !this.tamableFox.es() && super.a(); + return !tamableFox.isSitting() && !tamableFox.isSleeping() && !tamableFox.isCrouching() && !tamableFox.es() && !tamableFox.isOtherFoxFamily(enemy) && super.a(); } - -} \ No newline at end of file +} diff --git a/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalOwnerHurtByTarget.java b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfinderGoalOwnerHurtByTarget.java similarity index 84% rename from src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalOwnerHurtByTarget.java rename to src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfinderGoalOwnerHurtByTarget.java index b360a43..640e8ce 100644 --- a/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalOwnerHurtByTarget.java +++ b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfinderGoalOwnerHurtByTarget.java @@ -8,13 +8,13 @@ import org.bukkit.event.entity.EntityTargetEvent.TargetReason; import java.util.EnumSet; -public class FoxPathfindGoalOwnerHurtByTarget extends PathfinderGoalTarget { +public class FoxPathfinderGoalOwnerHurtByTarget extends PathfinderGoalTarget { private final EntityTamableFox a; private EntityLiving b; private int c; - public FoxPathfindGoalOwnerHurtByTarget(EntityTamableFox tamableFox) { + public FoxPathfinderGoalOwnerHurtByTarget(EntityTamableFox tamableFox) { super(tamableFox, false); this.a = tamableFox; this.a(EnumSet.of(Type.TARGET)); @@ -28,7 +28,7 @@ public class FoxPathfindGoalOwnerHurtByTarget extends PathfinderGoalTarget { } else { this.b = entityliving.getLastDamager(); int i = entityliving.cI(); - return i != this.c && this.a(this.b, PathfinderTargetCondition.a); + return i != this.c && this.a(this.b, PathfinderTargetCondition.a); //&& this.a.a(this.b, entityliving); // Returns true in any condition } } else { return false; diff --git a/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfinderGoalOwnerHurtTarget.java b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfinderGoalOwnerHurtTarget.java new file mode 100644 index 0000000..253710c --- /dev/null +++ b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfinderGoalOwnerHurtTarget.java @@ -0,0 +1,57 @@ +package net.seanomik.tamablefoxes.pathfinding; + +import net.minecraft.server.v1_15_R1.EntityTameableAnimal; +import net.seanomik.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 net.seanomik.tamablefoxes.Utils; +import org.bukkit.event.entity.EntityTargetEvent.TargetReason; + +import javax.rmi.CORBA.Util; +import java.util.EnumSet; + +public class FoxPathfinderGoalOwnerHurtTarget extends PathfinderGoalTarget { + private final EntityTamableFox fox; + private EntityLiving hitEntity; + private int c; + + public FoxPathfinderGoalOwnerHurtTarget(EntityTamableFox entityTamableFox) { + super(entityTamableFox, false); + this.fox = entityTamableFox; + this.a(EnumSet.of(Type.TARGET)); + } + + public boolean a() { + if (fox.isTamed() && !fox.isSitting()) { + EntityLiving entityliving = fox.getOwner(); + if (entityliving == null) { + e.setGoalTarget(null); + return false; + } else if (fox.isOtherFoxFamily(hitEntity)) { + e.setGoalTarget(null); + return false; + } else { + hitEntity = entityliving.cJ(); + int i = entityliving.cK(); + return i != this.c && this.a(hitEntity, PathfinderTargetCondition.a);// && fox.a.a(hitEntity, entityliving); // Just returns true in any case + } + } else { + return false; + } + } + + public void c() { + if (!fox.isOtherFoxFamily(hitEntity)) { + this.e.setGoalTarget(hitEntity, TargetReason.OWNER_ATTACKED_TARGET, true); + EntityLiving entityliving = fox.getOwner(); + if (entityliving != null) { + this.c = entityliving.cK(); + } + + super.c(); + } else { + e.setGoalTarget(null); + } + } +} \ No newline at end of file diff --git a/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfinderGoalPanic.java b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfinderGoalPanic.java new file mode 100644 index 0000000..031895e --- /dev/null +++ b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfinderGoalPanic.java @@ -0,0 +1,30 @@ +package net.seanomik.tamablefoxes.pathfinding; + +import net.minecraft.server.v1_15_R1.EntityFox; +import net.minecraft.server.v1_15_R1.PathfinderGoalPanic; +import net.seanomik.tamablefoxes.EntityTamableFox; + +import java.lang.reflect.Method; + +public class FoxPathfinderGoalPanic extends PathfinderGoalPanic { + EntityTamableFox tamableFox; + + public FoxPathfinderGoalPanic(EntityTamableFox tamableFox, double d0) { + super(tamableFox, d0); + this.tamableFox = tamableFox; + } + + public boolean a() { + try { + Method eFMethod = EntityFox.class.getDeclaredMethod("eF"); + eFMethod.setAccessible(true); + boolean eF = (boolean) eFMethod.invoke(tamableFox); + eFMethod.setAccessible(false); + + return !tamableFox.isTamed() && !eF && super.a(); + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } +} diff --git a/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalSit.java b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfinderGoalSit.java similarity index 90% rename from src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalSit.java rename to src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfinderGoalSit.java index efcbdfc..26b2a60 100644 --- a/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfindGoalSit.java +++ b/src/main/java/net/seanomik/tamablefoxes/pathfinding/FoxPathfinderGoalSit.java @@ -6,12 +6,12 @@ import net.minecraft.server.v1_15_R1.PathfinderGoal; import java.util.EnumSet; -public class FoxPathfindGoalSit extends PathfinderGoal { +public class FoxPathfinderGoalSit extends PathfinderGoal { private final EntityTamableFox entity; private boolean willSit; - public FoxPathfindGoalSit(EntityTamableFox tamableFox) { + public FoxPathfinderGoalSit(EntityTamableFox tamableFox) { this.entity = tamableFox; this.a(EnumSet.of(Type.JUMP, Type.MOVE)); } diff --git a/src/main/java/net/seanomik/tamablefoxes/sqlite/SQLiteSetterGetter.java b/src/main/java/net/seanomik/tamablefoxes/sqlite/SQLiteSetterGetter.java index d50ba83..f1901e8 100644 --- a/src/main/java/net/seanomik/tamablefoxes/sqlite/SQLiteSetterGetter.java +++ b/src/main/java/net/seanomik/tamablefoxes/sqlite/SQLiteSetterGetter.java @@ -1,16 +1,21 @@ package net.seanomik.tamablefoxes.sqlite; import net.minecraft.server.v1_15_R1.EntityFox; +import net.minecraft.server.v1_15_R1.EntityLiving; import net.minecraft.server.v1_15_R1.EnumItemSlot; import net.seanomik.tamablefoxes.EntityTamableFox; import net.seanomik.tamablefoxes.TamableFoxes; +import net.seanomik.tamablefoxes.Utils; import org.apache.commons.lang.ObjectUtils; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.OfflinePlayer; +import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity; 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.Player; import org.bukkit.inventory.ItemStack; import java.sql.DatabaseMetaData; @@ -25,19 +30,15 @@ public class SQLiteSetterGetter { public void createTablesIfNotExist() { plugin = TamableFoxes.getPlugin(TamableFoxes.class); - sqLiteHandler = TamableFoxes.sqLiteHandler; - //String pluginDatabase = Reference.SQLiteDatabase; + sqLiteHandler = plugin.sqLiteHandler; String foxesTable = "CREATE TABLE IF NOT EXISTS `foxes` ( " + - "`ID` INTEGER PRIMARY KEY AUTOINCREMENT , " + + "`ENTITY_UUID` TEXT PRIMARY KEY , " + "`OWNER_UUID` TEXT NOT NULL , " + - "`NAME` TEXT , " + - "`LOCATION` TEXT NOT NULL , " + - "`TYPE` TEXT NOT NULL , " + + "`NAME` TEXT, " + "`SITTING` INTEGER NOT NULL , " + - "`SLEEPING` INTEGER NOT NULL , " + - "`MOUTH_ITEM` TEXT NOT NULL);"; + "`SLEEPING` INTEGER NOT NULL);"; try { sqLiteHandler.connect(); @@ -48,7 +49,7 @@ public class SQLiteSetterGetter { PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement(foxesTable); statement.executeUpdate(); - plugin.getServer().getConsoleSender().sendMessage(TamableFoxes.getPrefix() + "Created foxes table!"); + plugin.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + "Created foxes table!"); } } catch (SQLException e) { e.printStackTrace(); @@ -65,27 +66,37 @@ public class SQLiteSetterGetter { public void saveFox(EntityTamableFox fox) { plugin = TamableFoxes.getPlugin(TamableFoxes.class); + + // If the fox is null or not alive, delete it from the database + if (fox == null || !fox.isAlive()) { + removeFox(fox); + return; + } + try { sqLiteHandler.connect(); - PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement("INSERT INTO foxes (OWNER_UUID,NAME,LOCATION,TYPE,MOUTH_ITEM,SITTING,SLEEPING) VALUES (?,?,?,?,?,?,?)"); - if (fox.databaseID != -1) { - statement = sqLiteHandler.getConnection().prepareStatement("UPDATE foxes SET OWNER_UUID=?, NAME=?, LOCATION=?, TYPE=?, MOUTH_ITEM=?, SITTING=?, SLEEPING=? WHERE ID=" + fox.databaseID); + PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement("INSERT INTO foxes (ENTITY_UUID,OWNER_UUID,NAME,SITTING,SLEEPING) VALUES (?,?,?,?,?)"); + + // If the database does contain this fox, then change the statement to an update statement instead of insert. + PreparedStatement hasFoxStatement = sqLiteHandler.getConnection().prepareStatement("SELECT * FROM foxes WHERE ENTITY_UUID=?"); + hasFoxStatement.setString(1, fox.getUniqueID().toString()); + ResultSet results = hasFoxStatement.executeQuery(); + if (results.next()) { + statement = sqLiteHandler.getConnection().prepareStatement("UPDATE foxes SET OWNER_UUID=?, NAME=?, SITTING=?, SLEEPING=? WHERE ENTITY_UUID='" + fox.getUniqueID().toString() + "'"); + statement.setString(1, (fox.getOwner() == null) ? "none" : fox.getOwner().getUniqueID().toString()); + statement.setString(2, fox.getChosenName()); + statement.setInt(3, (fox.isSitting()) ? 1 : 0); + statement.setInt(4, (fox.isSleeping()) ? 1 : 0); + } else { + statement.setString(1, fox.getUniqueID().toString()); + statement.setString(2, (fox.getOwner() == null) ? "none" : fox.getOwner().getUniqueID().toString()); + statement.setString(3, fox.getChosenName()); + statement.setInt(4, (fox.isSitting()) ? 1 : 0); + statement.setInt(5, (fox.isSleeping()) ? 1 : 0); } - statement.setString(1, (fox.getOwner() == null) ? "none" : fox.getOwner().getUniqueID().toString()); - statement.setString(2, fox.getChosenName()); - statement.setString(3, fox.getWorld().worldData.getName() + "," + fox.locX() + "," + fox.locY() + "," + fox.locZ()); - statement.setString(4, fox.getFoxType().toString()); - statement.setString(5, fox.getEquipment(EnumItemSlot.MAINHAND).toString().toUpperCase().substring(fox.getEquipment(EnumItemSlot.MAINHAND).toString().indexOf(' ')+1)); - statement.setInt(6, (fox.isSitting()) ? 1 : 0); - statement.setInt(7, (fox.isSleeping()) ? 1 : 0); statement.executeUpdate(); - - ResultSet result = statement.getGeneratedKeys(); - while (result.next()) { - fox.databaseID = result.getInt(1); - } } catch (SQLException e) { e.printStackTrace(); } finally { @@ -99,48 +110,59 @@ public class SQLiteSetterGetter { } } - public void saveFoxes(List foxes) { // @TODO: Optimize + public void saveFoxes(List foxes) { // @TODO: Optimize? + if (foxes == null || foxes.size() == 0) return; + for (EntityTamableFox fox : foxes) { saveFox(fox); } } - public List spawnFoxes() { + public List loadFoxes() { plugin = TamableFoxes.getPlugin(TamableFoxes.class); + List toRemoveLater = new ArrayList<>(); try { sqLiteHandler.connect(); PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement("SELECT * FROM foxes"); ResultSet results = statement.executeQuery(); - List foxList = new ArrayList<>(); + List spawnedFoxes = new ArrayList<>(); while (results.next()) { // Loop through each row - List locationList = Arrays.asList(results.getString("LOCATION").split("\\s*,\\s*")); - Location loc = new Location(Bukkit.getWorld(locationList.get(0)), Double.parseDouble(locationList.get(1)), Double.parseDouble(locationList.get(2)), Double.parseDouble(locationList.get(3))); + UUID entityUUID = UUID.fromString(results.getString("ENTITY_UUID")); + String ownerUUIDString = results.getString("OWNER_UUID"); + String name = results.getString("NAME"); + boolean sitting = results.getInt("SITTING") == 1; + boolean sleeping = results.getInt("SLEEPING") == 1; - EntityTamableFox spawnedFox = (EntityTamableFox) plugin.spawnTamableFox(loc, EntityFox.Type.valueOf(results.getString("TYPE"))); - spawnedFox.databaseID = results.getInt("ID"); - spawnedFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new ItemStack(Material.valueOf(results.getString("MOUTH_ITEM")), 1))); - - spawnedFox.setSitting(results.getInt("SITTING") == 1); - spawnedFox.setSleeping(results.getInt("SLEEPING") == 1); - - if (!results.getString("OWNER_UUID").equals("none")) { - UUID ownerUUID = UUID.fromString(results.getString("OWNER_UUID")); - - OfflinePlayer owner = plugin.getServer().getOfflinePlayer(ownerUUID); + // If the entity is null, it doesn't exist anymore so remove it from database + if (plugin.getServer().getEntity(entityUUID) == null) { + toRemoveLater.add(entityUUID); + continue; + } + EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) plugin.getServer().getEntity(entityUUID)).getHandle(); + if (!ownerUUIDString.equals("none")) { + OfflinePlayer owner = plugin.getServer().getOfflinePlayer(UUID.fromString(ownerUUIDString)); if (owner.isOnline()) { - spawnedFox.setOwner(((CraftPlayer) owner.getPlayer()).getHandle()); + EntityLiving livingOwner = (EntityLiving) ((CraftEntity) owner).getHandle(); + tamableFox.setOwner(livingOwner); } - plugin.getFoxUUIDs().put(spawnedFox.getUniqueID(), ownerUUID); - spawnedFox.setChosenName(results.getString("NAME")); - spawnedFox.setTamed(true); + tamableFox.setOwnerUUID(owner.getUniqueId()); + tamableFox.setTamed(true); + tamableFox.setChosenName(name); } - foxList.add(spawnedFox); + // Fox may spawn standing if the server was closed while it was sitting. + if (sitting) { + tamableFox.setHardSitting(true); + } else if (sleeping) { + tamableFox.setSleeping(true); + } + + spawnedFoxes.add(tamableFox); } - return foxList; + return spawnedFoxes; } catch (SQLException e) { e.printStackTrace(); } finally { @@ -151,16 +173,21 @@ public class SQLiteSetterGetter { e.printStackTrace(); } } + + // Remove those to remove later UUIDs + for (UUID uuid : toRemoveLater) { + removeFox(uuid); + } } return null; } - public void removeFox(int databaseID) { + public void removeFox(UUID uuid) { plugin = TamableFoxes.getPlugin(TamableFoxes.class); try { sqLiteHandler.connect(); - PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement("DELETE FROM foxes WHERE ID=" + databaseID); + PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement("DELETE FROM foxes WHERE ENTITY_UUID='" + uuid.toString() + "'"); statement.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); @@ -176,6 +203,6 @@ public class SQLiteSetterGetter { } public void removeFox(EntityTamableFox fox) { - removeFox(fox.databaseID); + removeFox(fox.getUniqueID()); } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 99e8f34..0741882 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,6 +1,7 @@ -# Config for Tamable Foxes modified for 1.15.1 +# Config for Tamable Foxes show-owner-in-fox-name: true show-nametags: true +enable-taming-permission: true tamed-behavior: - attack-chicken-rabbit: true \ No newline at end of file + attack-wild-animals: true \ No newline at end of file diff --git a/src/main/resources/foxes.yml b/src/main/resources/foxes.yml deleted file mode 100644 index 0803ad5..0000000 --- a/src/main/resources/foxes.yml +++ /dev/null @@ -1,2 +0,0 @@ -# Foxes are saved here: -Foxes: {} \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 22fdcb4..dbedb0a 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,9 +1,9 @@ -name: TamableFoxes -version: 1.4.1-SNAPSHOT +name: Tamablefoxes +version: ${project.version} main: net.seanomik.tamablefoxes.TamableFoxes api-version: 1.15 +#load: STARTUP load: POSTWORLD -description: Modified version of TamableFoxes for 1.15.1. commands: spawntamablefox: @@ -14,3 +14,6 @@ permissions: tamablefoxes.spawn: description: "Gives the player the ability to spawn tamable foxes." default: false + tamablefoxes.tame: + description: "Gives the player the ability to tame a fox." + default: false diff --git a/target/classes/config.yml b/target/classes/config.yml index 99e8f34..0741882 100644 --- a/target/classes/config.yml +++ b/target/classes/config.yml @@ -1,6 +1,7 @@ -# Config for Tamable Foxes modified for 1.15.1 +# Config for Tamable Foxes show-owner-in-fox-name: true show-nametags: true +enable-taming-permission: true tamed-behavior: - attack-chicken-rabbit: true \ No newline at end of file + attack-wild-animals: true \ No newline at end of file diff --git a/target/classes/foxes.yml b/target/classes/foxes.yml deleted file mode 100644 index 0803ad5..0000000 --- a/target/classes/foxes.yml +++ /dev/null @@ -1,2 +0,0 @@ -# Foxes are saved here: -Foxes: {} \ No newline at end of file diff --git a/target/classes/plugin.yml b/target/classes/plugin.yml index 22fdcb4..6204fef 100644 --- a/target/classes/plugin.yml +++ b/target/classes/plugin.yml @@ -1,9 +1,9 @@ -name: TamableFoxes -version: 1.4.1-SNAPSHOT +name: Tamablefoxes +version: 1.5-SNAPSHOT main: net.seanomik.tamablefoxes.TamableFoxes api-version: 1.15 +#load: STARTUP load: POSTWORLD -description: Modified version of TamableFoxes for 1.15.1. commands: spawntamablefox: @@ -14,3 +14,6 @@ permissions: tamablefoxes.spawn: description: "Gives the player the ability to spawn tamable foxes." default: false + tamablefoxes.tame: + description: "Gives the player the ability to tame a fox." + default: false diff --git a/target/maven-archiver/pom.properties b/target/maven-archiver/pom.properties index 919f7c4..39e6256 100644 --- a/target/maven-archiver/pom.properties +++ b/target/maven-archiver/pom.properties @@ -1,5 +1,5 @@ #Generated by Maven -#Sat Jan 18 14:21:47 CST 2020 -version=1.4.1-SNAPSHOT +#Wed Jan 22 08:36:01 CST 2020 +version=1.5-SNAPSHOT groupId=net.seanomik -artifactId=tamableFoxes +artifactId=tamablefoxes diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst index 367fca1..3bce520 100644 --- a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -1,24 +1,15 @@ net\seanomik\tamablefoxes\EntityTamableFox.class -net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalOwnerHurtByTarget.class -net\seanomik\tamablefoxes\io\FileManager$Config.class +net\seanomik\tamablefoxes\pathfinding\FoxPathfinderGoalOwnerHurtByTarget.class net\seanomik\tamablefoxes\command\CommandSpawnTamableFox.class -net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalSit.class -net\seanomik\tamablefoxes\sqlite\SQLiteSetterGetter.class -net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalBeg.class -net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalRandomStrollLand.class -net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalLunge.class -net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalFloat.class -net\seanomik\tamablefoxes\TamableFoxes$SaveFoxRunnable.class -net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalMeleeAttack.class -net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalRandomTargetNonTamed.class -net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalFleeSun.class -net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalOwnerHurtTarget.class -net\seanomik\tamablefoxes\io\FileManager.class -net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalBreed.class -net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalFollowOwner.class +net\seanomik\tamablefoxes\pathfinding\FoxPathfinderGoalFollowOwner.class +net\seanomik\tamablefoxes\pathfinding\FoxPathfinderGoalSit.class net\seanomik\tamablefoxes\sqlite\SQLiteHandler.class net\seanomik\tamablefoxes\TamableFoxes.class net\seanomik\tamablefoxes\EntityTamableFox$UpdateFoxRunnable.class -net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalLungeUNKNOWN_USE.class -net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalPickBushes.class -net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalHurtByTarget.class +net\seanomik\tamablefoxes\Config.class +net\seanomik\tamablefoxes\pathfinding\FoxPathfinderGoalHurtByTarget.class +net\seanomik\tamablefoxes\sqlite\SQLiteSetterGetter.class +net\seanomik\tamablefoxes\pathfinding\FoxPathfinderGoalPanic.class +net\seanomik\tamablefoxes\Utils.class +net\seanomik\tamablefoxes\pathfinding\FoxPathfinderGoalOwnerHurtTarget.class +net\seanomik\tamablefoxes\pathfinding\FoxPathfinderGoalMeleeAttack.class diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst index 1d1e33c..60ba81a 100644 --- a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -1,21 +1,13 @@ -C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalFloat.java -C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalRandomTargetNonTamed.java -C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\command\CommandSpawnTamableFox.java -C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalOwnerHurtByTarget.java -C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\sqlite\SQLiteHandler.java -C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\EntityTamableFox.java -C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalMeleeAttack.java -C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalHurtByTarget.java -C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalSit.java -C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalOwnerHurtTarget.java -C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalPickBushes.java -C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalBreed.java -C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\io\FileManager.java -C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalBeg.java -C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalLungeUNKNOWN_USE.java -C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\sqlite\SQLiteSetterGetter.java -C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\TamableFoxes.java -C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalLunge.java -C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalRandomStrollLand.java -C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalFollowOwner.java -C:\code\java\TamableFoxes\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalFleeSun.java +E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\sqlite\SQLiteHandler.java +E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalOwnerHurtByTarget.java +E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalSit.java +E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalHurtByTarget.java +E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\Config.java +E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfinderGoalMeleeAttack.java +E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\EntityTamableFox.java +E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalOwnerHurtTarget.java +E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\sqlite\SQLiteSetterGetter.java +E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\Utils.java +E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\command\CommandSpawnTamableFox.java +E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\TamableFoxes.java +E:\TamableFoxesCustomEntity\src\main\java\net\seanomik\tamablefoxes\pathfinding\FoxPathfindGoalFollowOwner.java