Merge remote-tracking branch 'origin/master'

This commit is contained in:
SeanOMik 2020-01-20 22:39:35 -06:00
commit 7db8c8b47a
No known key found for this signature in database
GPG Key ID: FA4D55AC05268A88
8 changed files with 2479 additions and 1022 deletions

View File

@ -1,248 +1,242 @@
package net.seanomik.tamablefoxes; package net.seanomilk.tamablefoxes;
import net.minecraft.server.v1_15_R1.*; import net.minecraft.server.v1_15_R1.*;
import net.seanomik.tamablefoxes.pathfinding.*; import net.seanomilk.tamablefoxes.pathfinding.*;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld; import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_15_R1.event.CraftEventFactory; import org.bukkit.craftbukkit.v1_15_R1.event.CraftEventFactory;
import org.bukkit.entity.Fox; import org.bukkit.entity.Fox;
import org.bukkit.event.entity.EntityTargetEvent; import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask; import org.bukkit.scheduler.BukkitTask;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
public class EntityTamableFox extends EntityFox { public class EntityTamableFox extends EntityFox {
private static Fox thisFox; private static Fox thisFox;
private final TamableFoxes plugin; private final TamableFoxes plugin;
private boolean isTamed; private boolean isTamed;
private EntityLiving owner; private EntityLiving owner;
private String chosenName; private String chosenName;
private boolean sit = false; private boolean sit = false;
private BukkitTask sittingRunnable; private BukkitTask sittingRunnable;
private FoxPathfindGoalSit goalSit; private FoxPathfindGoalSit goalSit;
private PathfinderGoalNearestAttackableTarget goalAttack; private PathfinderGoalNearestAttackableTarget goalAttack;
public int databaseIndex = -1; public EntityTamableFox(TamableFoxes plugin, EntityTypes entitytypes, World world) {
super(EntityTypes.FOX, world);
public EntityTamableFox(TamableFoxes plugin, EntityTypes entitytypes, World world) { this.plugin = plugin;
super(EntityTypes.FOX, world); thisFox = (Fox) this.getBukkitEntity();
this.plugin = plugin; plugin.getFoxUUIDs().put(this.getBukkitEntity().getUniqueId(), null);
thisFox = (Fox) this.getBukkitEntity(); this.setPersistent();
}
if (!plugin.getFoxUUIDs().containsKey(thisFox.getUniqueId())) {
plugin.getFoxUUIDs().put(this.getBukkitEntity().getUniqueId(), null); @Override
} protected void initPathfinder() {
this.goalSit = new FoxPathfindGoalSit(this);
this.setPersistent(); this.goalSelector.a(1, new FoxPathfindGoalFloat(this));
} this.goalSelector.a(2, this.goalSit);
this.goalSelector.a(3, new FoxPathfindGoalMeleeAttack(this, 1.2000000476837158D, true));
@Override this.goalSelector.a(3, new PathfinderGoalAvoidTarget(this, EntityWolf.class, 8.0F, 1.6D, 1.4D,
protected void initPathfinder() { entityliving -> !((EntityWolf) entityliving).isTamed()));
this.goalSit = new FoxPathfindGoalSit(this); this.goalSelector.a(4, new FoxPathfindGoalFollowOwner(this, 1.35D, 10.0F, 2.0F));
this.goalSelector.a(1, new FoxPathfindGoalFloat(this)); this.goalSelector.a(4, new FoxPathfindGoalLungeUNKNOWN_USE(this));
this.goalSelector.a(2, this.goalSit); this.goalSelector.a(5, new FoxPathfindGoalLunge(this));
this.goalSelector.a(3, new FoxPathfindGoalMeleeAttack(this, 1.2000000476837158D, true)); this.goalSelector.a(5, new FoxPathfindGoalFleeSun(this, 1.25D));
this.goalSelector.a(3, new PathfinderGoalAvoidTarget(this, EntityWolf.class, 8.0F, 1.6D, 1.4D, this.goalSelector.a(5, new FoxPathfindGoalBreed(this, 1.0D));
entityliving -> !((EntityWolf) entityliving).isTamed())); this.goalSelector.a(7, new PathfinderGoalFollowParent(this, 1.1D));
this.goalSelector.a(4, new FoxPathfindGoalFollowOwner(this, 1.35D, 10.0F, 2.0F)); this.goalSelector.a(7, new FoxPathfindGoalBeg(this, 8.0F));
this.goalSelector.a(4, new FoxPathfindGoalLungeUNKNOWN_USE(this)); this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
this.goalSelector.a(5, new FoxPathfindGoalLunge(this)); this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this));
this.goalSelector.a(5, new FoxPathfindGoalFleeSun(this, 1.25D)); this.goalSelector.a(9, new FoxPathfindGoalPickBushes(this, 1.2000000476837158D, 12, 2));
this.goalSelector.a(5, new FoxPathfindGoalBreed(this, 1.0D)); this.goalSelector.a(9, new FoxPathfindGoalPickBushes(this, 1.2000000476837158D, 12, 2));
this.goalSelector.a(7, new PathfinderGoalFollowParent(this, 1.1D)); this.goalSelector.a(10, new FoxPathfindGoalRandomStrollLand(this, 1.0D));
this.goalSelector.a(7, new FoxPathfindGoalBeg(this, 8.0F)); this.targetSelector.a(1, new FoxPathfindGoalHurtByTarget(this));
this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); this.targetSelector.a(2, new FoxPathfindGoalOwnerHurtByTarget(this));
this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this));
this.goalSelector.a(9, new FoxPathfindGoalPickBushes(this, 1.2000000476837158D, 12, 2)); this.goalAttack = new PathfinderGoalNearestAttackableTarget(this, EntityLiving.class, 10, false, false,
this.goalSelector.a(9, new FoxPathfindGoalPickBushes(this, 1.2000000476837158D, 12, 2)); entityLiving -> !isTamed && (entityLiving instanceof EntityChicken || entityLiving instanceof EntityRabbit));
this.goalSelector.a(10, new FoxPathfindGoalRandomStrollLand(this, 1.0D));
this.targetSelector.a(1, new FoxPathfindGoalHurtByTarget(this)); if (!isTamed || (plugin.isTamedAttackRabbitChicken() && isTamed)) {
this.targetSelector.a(2, new FoxPathfindGoalOwnerHurtByTarget(this)); this.targetSelector.a(4, goalAttack);
}
this.goalAttack = new PathfinderGoalNearestAttackableTarget(this, EntityLiving.class, 10, false, false,
entityLiving -> !isTamed && (entityLiving instanceof EntityChicken || entityLiving instanceof EntityRabbit)); this.targetSelector.a(5, new FoxPathfindGoalHurtByTarget(this).a(new Class[0]));
}
if (!isTamed || (plugin.isTamedAttackRabbitChicken() && isTamed)) {
this.targetSelector.a(4, goalAttack); @Override
} protected void initAttributes() {
this.getAttributeMap().b(GenericAttributes.MAX_HEALTH);
this.targetSelector.a(5, new FoxPathfindGoalHurtByTarget(this).a(new Class[0])); this.getAttributeMap().b(GenericAttributes.KNOCKBACK_RESISTANCE);
} this.getAttributeMap().b(GenericAttributes.MOVEMENT_SPEED);
this.getAttributeMap().b(GenericAttributes.ARMOR);
@Override this.getAttributeMap().b(GenericAttributes.ARMOR_TOUGHNESS);
protected void initAttributes() { this.getAttributeMap().b(GenericAttributes.FOLLOW_RANGE).setValue(2.0D);
this.getAttributeMap().b(GenericAttributes.MAX_HEALTH); this.getAttributeMap().b(GenericAttributes.ATTACK_KNOCKBACK);
this.getAttributeMap().b(GenericAttributes.KNOCKBACK_RESISTANCE); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D);
this.getAttributeMap().b(GenericAttributes.MOVEMENT_SPEED); this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(24.0D);
this.getAttributeMap().b(GenericAttributes.ARMOR); this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(32.0D);
this.getAttributeMap().b(GenericAttributes.ARMOR_TOUGHNESS); this.getAttributeMap().b(GenericAttributes.ATTACK_DAMAGE).setValue(3.0D);
this.getAttributeMap().b(GenericAttributes.FOLLOW_RANGE).setValue(2.0D); }
this.getAttributeMap().b(GenericAttributes.ATTACK_KNOCKBACK);
this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D); public EntityFox createChild(EntityAgeable entityageable) {
this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(24.0D); WorldServer world = ((CraftWorld) entityageable.getBukkitEntity().getWorld()).getHandle();
this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(32.0D); Location location = entityageable.getBukkitEntity().getLocation();
this.getAttributeMap().b(GenericAttributes.ATTACK_DAMAGE).setValue(3.0D); Entity b = plugin.getCustomType().b(world, null, null, null,
} new BlockPosition(location.getX(), location.getY(), location.getZ()), null, false, false);
EntityFox entityfox = (EntityFox) b;
public EntityFox createChild(EntityAgeable entityageable) { entityfox.setFoxType(this.random.nextBoolean() ? this.getFoxType() : ((EntityFox) entityageable).getFoxType());
WorldServer world = ((CraftWorld) entityageable.getBukkitEntity().getWorld()).getHandle(); return entityfox;
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); protected void a(EntityItem entityitem) {
EntityFox entityfox = (EntityFox) b; ItemStack itemstack = entityitem.getItemStack();
entityfox.setFoxType(this.random.nextBoolean() ? this.getFoxType() : ((EntityFox) entityageable).getFoxType()); if (!this.isTamed() && !CraftEventFactory.callEntityPickupItemEvent(this, entityitem,
return entityfox; itemstack.getCount() - 1, !this.g(itemstack)).isCancelled()) {
} try {
int i = itemstack.getCount();
protected void a(EntityItem entityitem) { Method method;
ItemStack itemstack = entityitem.getItemStack(); if (i > 1) {
if (!this.isTamed() && !CraftEventFactory.callEntityPickupItemEvent(this, entityitem, method = this.getClass().getSuperclass().getDeclaredMethod("l", ItemStack.class);
itemstack.getCount() - 1, !this.g(itemstack)).isCancelled()) { method.setAccessible(true);
try { method.invoke(this, itemstack.cloneAndSubtract(i - 1));
int i = itemstack.getCount(); method.setAccessible(false);
Method method; }
if (i > 1) {
method = this.getClass().getSuperclass().getDeclaredMethod("l", ItemStack.class); method = this.getClass().getSuperclass().getDeclaredMethod("k", ItemStack.class);
method.setAccessible(true); method.setAccessible(true);
method.invoke(this, itemstack.cloneAndSubtract(i - 1)); method.invoke(this, this.getEquipment(EnumItemSlot.MAINHAND));
method.setAccessible(false); method.setAccessible(false);
} this.setSlot(EnumItemSlot.MAINHAND, itemstack.cloneAndSubtract(1));
this.dropChanceHand[EnumItemSlot.MAINHAND.b()] = 2.0F;
method = this.getClass().getSuperclass().getDeclaredMethod("k", ItemStack.class); this.receive(entityitem, itemstack.getCount());
method.setAccessible(true); entityitem.die();
method.invoke(this, this.getEquipment(EnumItemSlot.MAINHAND)); Field field = this.getClass().getSuperclass().getDeclaredField("bL");
method.setAccessible(false); field.setAccessible(true);
this.setSlot(EnumItemSlot.MAINHAND, itemstack.cloneAndSubtract(1)); field.set(this, 0);
this.dropChanceHand[EnumItemSlot.MAINHAND.b()] = 2.0F; field.setAccessible(false);
this.receive(entityitem, itemstack.getCount()); } catch (NoSuchFieldException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
entityitem.die(); e.printStackTrace();
Field field = this.getClass().getSuperclass().getDeclaredField("bL"); }
field.setAccessible(true); }
field.set(this, 0);
field.setAccessible(false); }
} catch (NoSuchFieldException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace(); public TamableFoxes getPlugin() {
} return plugin;
} }
} public boolean isTamed() {
return this.isTamed;
public TamableFoxes getPlugin() { }
return plugin;
} public void setTamed(boolean tamed) {
this.isTamed = tamed;
public boolean isTamed() { // Remove attack goal if tamed
return this.isTamed; if (isTamed && plugin.isTamedAttackRabbitChicken()) {
} this.targetSelector.a(goalAttack);
} else {
public void setTamed(boolean tamed) { this.targetSelector.a(4, goalAttack);
this.isTamed = tamed; }
// Remove attack goal if tamed }
if (isTamed && plugin.isTamedAttackRabbitChicken()) {
this.targetSelector.a(goalAttack); public String getChosenName() {
} else { return chosenName;
this.targetSelector.a(4, goalAttack); }
}
} public void setChosenName(String chosenName) {
this.chosenName = chosenName;
public String getChosenName() { plugin.getConfigFoxes().set("Foxes." + getUniqueID() + ".name", chosenName).save();
return chosenName; updateFoxVisual();
} }
public void setChosenName(String chosenName) { public EntityLiving getOwner() {
this.chosenName = chosenName; return this.owner;
//plugin.getConfigFoxes().set("Foxes." + getUniqueID() + ".name", chosenName).save(); }
updateFoxVisual();
} public void setOwner(EntityLiving owner) {
this.owner = owner;
public EntityLiving getOwner() { plugin.getConfigFoxes().set("Foxes." + getUniqueID() + ".owner", owner.getUniqueIDString()).save();
return this.owner; updateFoxVisual();
} }
public void setOwner(EntityLiving owner) { public boolean toggleSitting() {
this.owner = owner; this.sit = !this.sit;
//plugin.getConfigFoxes().set("Foxes." + getUniqueID() + ".owner", owner.getUniqueIDString()).save(); updateFoxVisual();
updateFoxVisual(); return this.sit;
} }
public boolean toggleSitting() { public void updateFox() {
this.sit = !this.sit; updateFoxVisual();
updateFoxVisual(); }
return this.sit;
} public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler,
EnumMobSpawn enummobspawn, GroupDataEntity groupdataentity, NBTTagCompound nbttagcompound) {
public void updateFox() { BiomeBase biomebase = generatoraccess.getBiome(new BlockPosition(this));
updateFoxVisual(); Type entityfox_type = Type.a(biomebase);
} boolean flag = false;
if (groupdataentity instanceof i) {
public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, entityfox_type = ((i) groupdataentity).a;
EnumMobSpawn enummobspawn, GroupDataEntity groupdataentity, NBTTagCompound nbttagcompound) { if (((i) groupdataentity).a() >= 2) {
BiomeBase biomebase = generatoraccess.getBiome(new BlockPosition(this)); flag = true;
Type entityfox_type = Type.a(biomebase); } else {
boolean flag = false; ((i) groupdataentity).b();
if (groupdataentity instanceof i) { }
entityfox_type = ((i) groupdataentity).a; } else {
if (((i) groupdataentity).a() >= 2) { groupdataentity = new i(entityfox_type);
flag = true; ((i) groupdataentity).b();
} else { }
((i) groupdataentity).b();
} this.setFoxType(entityfox_type);
} else { if (flag) {
groupdataentity = new i(entityfox_type); this.setAgeRaw(-24000);
((i) groupdataentity).b(); }
}
this.initPathfinder();
this.setFoxType(entityfox_type); this.a(difficultydamagescaler);
if (flag) { this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).addModifier(new AttributeModifier("Random spawn bonus",
this.setAgeRaw(-24000); this.random.nextGaussian() * 0.05D, AttributeModifier.Operation.MULTIPLY_BASE));
} if (this.random.nextFloat() < 0.05F) {
this.p(true);
this.initPathfinder(); } else {
this.a(difficultydamagescaler); this.p(false);
this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).addModifier(new AttributeModifier("Random spawn bonus", }
this.random.nextGaussian() * 0.05D, AttributeModifier.Operation.MULTIPLY_BASE));
if (this.random.nextFloat() < 0.05F) { return groupdataentity;
this.p(true); }
} else {
this.p(false); public boolean isJumping() {
} return this.jumping;
}
return groupdataentity;
} private void updateFoxVisual() {
this.sittingRunnable = new UpdateFoxRunnable(plugin).runTask(plugin);
public boolean isJumping() { }
return this.jumping;
} private class UpdateFoxRunnable extends BukkitRunnable {
private void updateFoxVisual() { private final TamableFoxes plugin;
this.sittingRunnable = new UpdateFoxRunnable(plugin).runTask(plugin);
} UpdateFoxRunnable(TamableFoxes plugin) {
this.plugin = plugin;
private class UpdateFoxRunnable extends BukkitRunnable { }
private final TamableFoxes plugin; public void run() {
goalSit.setSitting(sit);
UpdateFoxRunnable(TamableFoxes plugin) { thisFox.setVelocity(new Vector(0, 0, 0));
this.plugin = plugin; setGoalTarget(null, EntityTargetEvent.TargetReason.CUSTOM, true);
}
getBukkitEntity().setCustomName((chosenName != null ? chosenName : "")
public void run() { + (owner != null && plugin.isShowOwnerFoxName() ? ChatColor.RESET + " (" + owner.getName() + ")" : ""));
goalSit.setSitting(sit); getBukkitEntity().setCustomNameVisible(plugin.isShowNameTags());
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());
}
}
}

View File

@ -0,0 +1,248 @@
package net.seanomik.tamablefoxes;
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.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import org.bukkit.util.Vector;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class EntityTamableFox extends EntityFox {
private static Fox thisFox;
private final TamableFoxes plugin;
private boolean isTamed;
private EntityLiving owner;
private String chosenName;
private boolean sit = false;
private BukkitTask sittingRunnable;
private FoxPathfindGoalSit goalSit;
private PathfinderGoalNearestAttackableTarget goalAttack;
public int databaseIndex = -1;
public EntityTamableFox(TamableFoxes plugin, EntityTypes entitytypes, World world) {
super(EntityTypes.FOX, world);
this.plugin = plugin;
thisFox = (Fox) this.getBukkitEntity();
if (!plugin.getFoxUUIDs().containsKey(thisFox.getUniqueId())) {
plugin.getFoxUUIDs().put(this.getBukkitEntity().getUniqueId(), null);
}
this.setPersistent();
}
@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));
this.goalAttack = new PathfinderGoalNearestAttackableTarget(this, EntityLiving.class, 10, false, false,
entityLiving -> !isTamed && (entityLiving instanceof EntityChicken || entityLiving instanceof EntityRabbit));
if (!isTamed || (plugin.isTamedAttackRabbitChicken() && isTamed)) {
this.targetSelector.a(4, goalAttack);
}
this.targetSelector.a(5, new FoxPathfindGoalHurtByTarget(this).a(new Class[0]));
}
@Override
protected void initAttributes() {
this.getAttributeMap().b(GenericAttributes.MAX_HEALTH);
this.getAttributeMap().b(GenericAttributes.KNOCKBACK_RESISTANCE);
this.getAttributeMap().b(GenericAttributes.MOVEMENT_SPEED);
this.getAttributeMap().b(GenericAttributes.ARMOR);
this.getAttributeMap().b(GenericAttributes.ARMOR_TOUGHNESS);
this.getAttributeMap().b(GenericAttributes.FOLLOW_RANGE).setValue(2.0D);
this.getAttributeMap().b(GenericAttributes.ATTACK_KNOCKBACK);
this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D);
this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(24.0D);
this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(32.0D);
this.getAttributeMap().b(GenericAttributes.ATTACK_DAMAGE).setValue(3.0D);
}
public EntityFox createChild(EntityAgeable entityageable) {
WorldServer world = ((CraftWorld) entityageable.getBukkitEntity().getWorld()).getHandle();
Location location = entityageable.getBukkitEntity().getLocation();
Entity b = plugin.getCustomType().b(world, null, null, null,
new BlockPosition(location.getX(), location.getY(), location.getZ()), null, false, false);
EntityFox entityfox = (EntityFox) b;
entityfox.setFoxType(this.random.nextBoolean() ? this.getFoxType() : ((EntityFox) entityageable).getFoxType());
return entityfox;
}
protected void a(EntityItem entityitem) {
ItemStack itemstack = entityitem.getItemStack();
if (!this.isTamed() && !CraftEventFactory.callEntityPickupItemEvent(this, entityitem,
itemstack.getCount() - 1, !this.g(itemstack)).isCancelled()) {
try {
int i = itemstack.getCount();
Method method;
if (i > 1) {
method = this.getClass().getSuperclass().getDeclaredMethod("l", ItemStack.class);
method.setAccessible(true);
method.invoke(this, itemstack.cloneAndSubtract(i - 1));
method.setAccessible(false);
}
method = this.getClass().getSuperclass().getDeclaredMethod("k", ItemStack.class);
method.setAccessible(true);
method.invoke(this, this.getEquipment(EnumItemSlot.MAINHAND));
method.setAccessible(false);
this.setSlot(EnumItemSlot.MAINHAND, itemstack.cloneAndSubtract(1));
this.dropChanceHand[EnumItemSlot.MAINHAND.b()] = 2.0F;
this.receive(entityitem, itemstack.getCount());
entityitem.die();
Field field = this.getClass().getSuperclass().getDeclaredField("bL");
field.setAccessible(true);
field.set(this, 0);
field.setAccessible(false);
} catch (NoSuchFieldException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
}
}
}
public TamableFoxes getPlugin() {
return plugin;
}
public boolean isTamed() {
return this.isTamed;
}
public void setTamed(boolean tamed) {
this.isTamed = tamed;
// Remove attack goal if tamed
if (isTamed && plugin.isTamedAttackRabbitChicken()) {
this.targetSelector.a(goalAttack);
} else {
this.targetSelector.a(4, goalAttack);
}
}
public String getChosenName() {
return chosenName;
}
public void setChosenName(String chosenName) {
this.chosenName = chosenName;
//plugin.getConfigFoxes().set("Foxes." + getUniqueID() + ".name", chosenName).save();
updateFoxVisual();
}
public EntityLiving getOwner() {
return this.owner;
}
public void setOwner(EntityLiving owner) {
this.owner = owner;
//plugin.getConfigFoxes().set("Foxes." + getUniqueID() + ".owner", owner.getUniqueIDString()).save();
updateFoxVisual();
}
public boolean toggleSitting() {
this.sit = !this.sit;
updateFoxVisual();
return this.sit;
}
public void updateFox() {
updateFoxVisual();
}
public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler,
EnumMobSpawn enummobspawn, GroupDataEntity groupdataentity, NBTTagCompound nbttagcompound) {
BiomeBase biomebase = generatoraccess.getBiome(new BlockPosition(this));
Type entityfox_type = Type.a(biomebase);
boolean flag = false;
if (groupdataentity instanceof i) {
entityfox_type = ((i) groupdataentity).a;
if (((i) groupdataentity).a() >= 2) {
flag = true;
} else {
((i) groupdataentity).b();
}
} else {
groupdataentity = new i(entityfox_type);
((i) groupdataentity).b();
}
this.setFoxType(entityfox_type);
if (flag) {
this.setAgeRaw(-24000);
}
this.initPathfinder();
this.a(difficultydamagescaler);
this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).addModifier(new AttributeModifier("Random spawn bonus",
this.random.nextGaussian() * 0.05D, AttributeModifier.Operation.MULTIPLY_BASE));
if (this.random.nextFloat() < 0.05F) {
this.p(true);
} else {
this.p(false);
}
return groupdataentity;
}
public boolean isJumping() {
return this.jumping;
}
private void updateFoxVisual() {
this.sittingRunnable = new UpdateFoxRunnable(plugin).runTask(plugin);
}
private class UpdateFoxRunnable extends BukkitRunnable {
private final TamableFoxes plugin;
UpdateFoxRunnable(TamableFoxes plugin) {
this.plugin = plugin;
}
public void run() {
goalSit.setSitting(sit);
thisFox.setVelocity(new Vector(0, 0, 0));
setGoalTarget(null, EntityTargetEvent.TargetReason.CUSTOM, true);
getBukkitEntity().setCustomName((chosenName != null ? chosenName : "")
+ (owner != null && plugin.isShowOwnerFoxName() ? ChatColor.RESET + " (" + owner.getName() + ")" : ""));
getBukkitEntity().setCustomNameVisible(plugin.isShowNameTags());
}
}
}

View File

@ -0,0 +1,242 @@
package net.seanomilk.tamablefoxes;
import net.minecraft.server.v1_15_R1.*;
import net.seanomilk.tamablefoxes.pathfinding.*;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_15_R1.event.CraftEventFactory;
import org.bukkit.entity.Fox;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import org.bukkit.util.Vector;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class EntityTamableFox extends EntityFox {
private static Fox thisFox;
private final TamableFoxes plugin;
private boolean isTamed;
private EntityLiving owner;
private String chosenName;
private boolean sit = false;
private BukkitTask sittingRunnable;
private FoxPathfindGoalSit goalSit;
private PathfinderGoalNearestAttackableTarget goalAttack;
public EntityTamableFox(TamableFoxes plugin, EntityTypes entitytypes, World world) {
super(EntityTypes.FOX, world);
this.plugin = plugin;
thisFox = (Fox) this.getBukkitEntity();
plugin.getFoxUUIDs().put(this.getBukkitEntity().getUniqueId(), null);
this.setPersistent();
}
@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));
this.goalAttack = new PathfinderGoalNearestAttackableTarget(this, EntityLiving.class, 10, false, false,
entityLiving -> !isTamed && (entityLiving instanceof EntityChicken || entityLiving instanceof EntityRabbit));
if (!isTamed || (plugin.isTamedAttackRabbitChicken() && isTamed)) {
this.targetSelector.a(4, goalAttack);
}
this.targetSelector.a(5, new FoxPathfindGoalHurtByTarget(this).a(new Class[0]));
}
@Override
protected void initAttributes() {
this.getAttributeMap().b(GenericAttributes.MAX_HEALTH);
this.getAttributeMap().b(GenericAttributes.KNOCKBACK_RESISTANCE);
this.getAttributeMap().b(GenericAttributes.MOVEMENT_SPEED);
this.getAttributeMap().b(GenericAttributes.ARMOR);
this.getAttributeMap().b(GenericAttributes.ARMOR_TOUGHNESS);
this.getAttributeMap().b(GenericAttributes.FOLLOW_RANGE).setValue(2.0D);
this.getAttributeMap().b(GenericAttributes.ATTACK_KNOCKBACK);
this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D);
this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(24.0D);
this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(32.0D);
this.getAttributeMap().b(GenericAttributes.ATTACK_DAMAGE).setValue(3.0D);
}
public EntityFox createChild(EntityAgeable entityageable) {
WorldServer world = ((CraftWorld) entityageable.getBukkitEntity().getWorld()).getHandle();
Location location = entityageable.getBukkitEntity().getLocation();
Entity b = plugin.getCustomType().b(world, null, null, null,
new BlockPosition(location.getX(), location.getY(), location.getZ()), null, false, false);
EntityFox entityfox = (EntityFox) b;
entityfox.setFoxType(this.random.nextBoolean() ? this.getFoxType() : ((EntityFox) entityageable).getFoxType());
return entityfox;
}
protected void a(EntityItem entityitem) {
ItemStack itemstack = entityitem.getItemStack();
if (!this.isTamed() && !CraftEventFactory.callEntityPickupItemEvent(this, entityitem,
itemstack.getCount() - 1, !this.g(itemstack)).isCancelled()) {
try {
int i = itemstack.getCount();
Method method;
if (i > 1) {
method = this.getClass().getSuperclass().getDeclaredMethod("l", ItemStack.class);
method.setAccessible(true);
method.invoke(this, itemstack.cloneAndSubtract(i - 1));
method.setAccessible(false);
}
method = this.getClass().getSuperclass().getDeclaredMethod("k", ItemStack.class);
method.setAccessible(true);
method.invoke(this, this.getEquipment(EnumItemSlot.MAINHAND));
method.setAccessible(false);
this.setSlot(EnumItemSlot.MAINHAND, itemstack.cloneAndSubtract(1));
this.dropChanceHand[EnumItemSlot.MAINHAND.b()] = 2.0F;
this.receive(entityitem, itemstack.getCount());
entityitem.die();
Field field = this.getClass().getSuperclass().getDeclaredField("bL");
field.setAccessible(true);
field.set(this, 0);
field.setAccessible(false);
} catch (NoSuchFieldException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
}
}
}
public TamableFoxes getPlugin() {
return plugin;
}
public boolean isTamed() {
return this.isTamed;
}
public void setTamed(boolean tamed) {
this.isTamed = tamed;
// Remove attack goal if tamed
if (isTamed && plugin.isTamedAttackRabbitChicken()) {
this.targetSelector.a(goalAttack);
} else {
this.targetSelector.a(4, goalAttack);
}
}
public String getChosenName() {
return chosenName;
}
public void setChosenName(String chosenName) {
this.chosenName = chosenName;
plugin.getConfigFoxes().set("Foxes." + getUniqueID() + ".name", chosenName).save();
updateFoxVisual();
}
public EntityLiving getOwner() {
return this.owner;
}
public void setOwner(EntityLiving owner) {
this.owner = owner;
plugin.getConfigFoxes().set("Foxes." + getUniqueID() + ".owner", owner.getUniqueIDString()).save();
updateFoxVisual();
}
public boolean toggleSitting() {
this.sit = !this.sit;
updateFoxVisual();
return this.sit;
}
public void updateFox() {
updateFoxVisual();
}
public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler,
EnumMobSpawn enummobspawn, GroupDataEntity groupdataentity, NBTTagCompound nbttagcompound) {
BiomeBase biomebase = generatoraccess.getBiome(new BlockPosition(this));
Type entityfox_type = Type.a(biomebase);
boolean flag = false;
if (groupdataentity instanceof i) {
entityfox_type = ((i) groupdataentity).a;
if (((i) groupdataentity).a() >= 2) {
flag = true;
} else {
((i) groupdataentity).b();
}
} else {
groupdataentity = new i(entityfox_type);
((i) groupdataentity).b();
}
this.setFoxType(entityfox_type);
if (flag) {
this.setAgeRaw(-24000);
}
this.initPathfinder();
this.a(difficultydamagescaler);
this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).addModifier(new AttributeModifier("Random spawn bonus",
this.random.nextGaussian() * 0.05D, AttributeModifier.Operation.MULTIPLY_BASE));
if (this.random.nextFloat() < 0.05F) {
this.p(true);
} else {
this.p(false);
}
return groupdataentity;
}
public boolean isJumping() {
return this.jumping;
}
private void updateFoxVisual() {
this.sittingRunnable = new UpdateFoxRunnable(plugin).runTask(plugin);
}
private class UpdateFoxRunnable extends BukkitRunnable {
private final TamableFoxes plugin;
UpdateFoxRunnable(TamableFoxes plugin) {
this.plugin = plugin;
}
public void run() {
goalSit.setSitting(sit);
thisFox.setVelocity(new Vector(0, 0, 0));
setGoalTarget(null, EntityTargetEvent.TargetReason.CUSTOM, true);
getBukkitEntity().setCustomName((chosenName != null ? chosenName : "")
+ (owner != null && plugin.isShowOwnerFoxName() ? ChatColor.RESET + " (" + owner.getName() + ")" : ""));
getBukkitEntity().setCustomNameVisible(plugin.isShowNameTags());
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,546 @@
package net.seanomik.tamablefoxes;
import com.google.common.collect.Maps;
import com.mojang.datafixers.DataFixUtils;
import com.mojang.datafixers.types.Type;
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.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.player.*;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
// @TODO: Add language.yml
public class TamableFoxes extends JavaPlugin implements Listener {
public static final String ITEM_INSPECTOR_LORE = ChatColor.BLUE + "Tamable Fox Inspector";
public static final String TAG_TAME_FOX = "tameablefox";
private FileManager fileManager = new FileManager(this);
private Map<UUID, UUID> foxUUIDs = Maps.newHashMap(); // FoxUUID, OwnerUUID
private EntityTypes customType;
private boolean isOnLoad = true;
private Map<UUID, Entity> lookupCache = Maps.newHashMap();
private List<EntityTamableFox> spawnedFoxes;
private FileManager.Config config;//, configFoxes;
public static SQLiteHandler sqLiteHandler = new SQLiteHandler();
public static SQLiteSetterGetter sqLiteSetterGetter = new SQLiteSetterGetter();
@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!");
getServer().getPluginManager().disablePlugin(this);
return;
}
sqLiteHandler.connect();
sqLiteSetterGetter.createTablesIfNotExist();
this.config = fileManager.getConfig("config.yml");
this.config.copyDefaults(true).save();
/*this.configFoxes = fileManager.getConfig("foxes.yml");
this.configFoxes.copyDefaults(true).save();*/
this.getServer().getPluginManager().registerEvents(this, this);
this.getCommand("spawntamablefox").setExecutor(new CommandSpawnTamableFox(this));
final Map<String, Type<?>> types = (Map<String, Type<?>>) DataConverterRegistry.a()
.getSchema(DataFixUtils.makeKey(SharedConstants.getGameVersion().getWorldVersion()))
.findChoiceType(DataConverterTypes.ENTITY).types();
types.put("minecraft:" + TAG_TAME_FOX, types.get("minecraft:fox"));
EntityTypes.a<net.minecraft.server.v1_15_R1.Entity> a = EntityTypes.a.a((entityTypes, world) ->
new EntityTamableFox(this, entityTypes, world), EnumCreatureType.AMBIENT);
customType = IRegistry.a(IRegistry.ENTITY_TYPE, "tameablefox", a.a("tameablefox"));
this.replaceFoxesOnLoad();
}
@Override
public void onDisable() {
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!");
}
}
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();
net.minecraft.server.v1_15_R1.Entity spawnedEntity = customType.b(world, null, null, null,
new BlockPosition(location.getX(), location.getY(), location.getZ()), null, false, false);
world.addEntity(spawnedEntity);
EntityFox fox = (EntityFox) spawnedEntity;
fox.setFoxType(type);
/*configFoxes.get().set("Foxes." + spawnedEntity.getUniqueID() + ".owner", "none");
fileManager.saveConfig("foxes.yml");*/
return fox;
}
@EventHandler
public void onChunkLoad(ChunkLoadEvent event) {
/*if (isOnLoad)
return;
Chunk chunk = event.getChunk();
Entity[] entities = chunk.getEntities();
for (Entity entity : entities) {
if (entity instanceof Fox && !this.isTamableFox(entity)) {
EntityTamableFox tamableFox = (EntityTamableFox) spawnTamableFox(entity.getLocation(), ((CraftFox) entity).getHandle().getFoxType());
final YamlConfiguration configuration = configFoxes.get();
// if has data
if (configuration.isConfigurationSection("Foxes." + entity.getUniqueId())) {
String owner = configuration.getString("Foxes." + entity.getUniqueId() + ".owner", "none");
// if has owner
if (!owner.equals("none")) {
foxUUIDs.replace(tamableFox.getUniqueID(), UUID.fromString(owner));
configuration.set("Foxes." + tamableFox.getUniqueID() + ".owner", owner);
// set name
if (configuration.isSet("Foxes." + entity.getUniqueId() + ".name")) {
String name = configuration.getString("Foxes." + entity.getUniqueId() + ".name");
configuration.set("Foxes." + tamableFox.getUniqueID() + ".name", name);
tamableFox.setChosenName(name);
}
// remove old data
configuration.set("Foxes." + entity.getUniqueId(), null);
tamableFox.setTamed(true);
tamableFox.setSitting(((EntityFox) ((CraftEntity) entity).getHandle()).isSitting());
tamableFox.updateFox();
tamableFox.setAge(((CraftFox) entity).getAge());
ItemStack entityMouthItem = ((CraftFox) entity).getEquipment().getItemInMainHand();
if (entityMouthItem.getType() != Material.AIR) {
tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new ItemStack(entityMouthItem.getType(), 1)));
} else {
tamableFox.setSlot(EnumItemSlot.MAINHAND, new net.minecraft.server.v1_15_R1.ItemStack(Items.AIR));
}
}
} else {
configuration.set("Foxes." + tamableFox.getUniqueID() + ".owner", "none");
tamableFox.setAge(((CraftFox) entity).getAge());
ItemStack entityMouthItem = ((CraftFox) entity).getEquipment().getItemInMainHand();
if (entityMouthItem.getType() != Material.AIR) {
tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new ItemStack(entityMouthItem.getType(), 1)));
} else {
tamableFox.setSlot(EnumItemSlot.MAINHAND, new net.minecraft.server.v1_15_R1.ItemStack(Items.AIR));
}
}
entity.remove();
}
}*/
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
getFoxesOf(player).forEach(uuid -> {
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) this.getEntityByUniqueId(uuid)).getHandle();
tamableFox.setOwner(((CraftPlayer) player).getHandle());
tamableFox.setTamed(true);
foxUUIDs.replace(tamableFox.getUniqueID(), player.getUniqueId());
});
}
@EventHandler
public void onPlayerInteractEntityEvent(PlayerInteractEntityEvent event) {
Entity entity = event.getRightClicked();
Player player = event.getPlayer();
if (event.getHand() != EquipmentSlot.HAND)
return;
final ItemStack playerHand = player.getInventory().getItemInMainHand();
ItemMeta itemMeta = playerHand.getItemMeta();
if (itemMeta != null && playerHand.getType() == Material.REDSTONE_TORCH
&& itemMeta.hasLore() && itemMeta.getLore().contains(ITEM_INSPECTOR_LORE)) {
List<String> lore;
if (!this.isTamableFox(entity)) {
lore = Arrays.asList(ITEM_INSPECTOR_LORE,
"UUID: " + entity.getUniqueId(),
"Entity ID: " + entity.getEntityId());
} else {
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) entity).getHandle();
if (tamableFox.getOwner() == null) {
lore = Arrays.asList(ITEM_INSPECTOR_LORE,
"UUID: " + entity.getUniqueId(),
"Entity ID: " + entity.getEntityId(),
"Tamable",
"Owner: None");
} else {
lore = Arrays.asList(ITEM_INSPECTOR_LORE,
"UUID: " + entity.getUniqueId(),
"Entity ID: " + entity.getEntityId(),
"Tamable",
"Owner: " + tamableFox.getOwner().getName());
}
}
// update item
itemMeta.setLore(lore);
playerHand.setItemMeta(itemMeta);
player.getInventory().setItemInMainHand(playerHand);
event.setCancelled(true);
player.sendMessage(getPrefix() + "Inspected Entity.");
return;
}
if (this.isTamableFox(entity)) {
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) entity).getHandle();
if (tamableFox.isTamed() && tamableFox.getOwner() != null &&
playerHand.getType() != Material.SWEET_BERRIES) {
// if this fox is theirs
if (foxUUIDs.get(entity.getUniqueId()).equals(player.getUniqueId())) {
if (player.isSneaking()) {
net.minecraft.server.v1_15_R1.ItemStack wolfHolding = tamableFox.getEquipment(EnumItemSlot.MAINHAND);
net.minecraft.server.v1_15_R1.ItemStack playerItemInHandNMS;
if (wolfHolding.isEmpty()) {
if (playerHand.getType() == Material.AIR) {
return;
}
playerItemInHandNMS = CraftItemStack.asNMSCopy(playerHand);
playerItemInHandNMS.setCount(1);
tamableFox.setSlot(EnumItemSlot.MAINHAND, playerItemInHandNMS);
playerHand.setAmount(playerHand.getAmount() - 1);
player.getInventory().setItemInMainHand(playerHand);
} else if (playerHand.getType() == Material.AIR) {
entity.getWorld().dropItem(tamableFox.getBukkitEntity().getLocation().add(0.0D, 0.2D, 0.0D),
CraftItemStack.asBukkitCopy(wolfHolding));
tamableFox.setSlot(EnumItemSlot.MAINHAND, new net.minecraft.server.v1_15_R1.ItemStack(Items.AIR));
} else {
playerItemInHandNMS = CraftItemStack.asNMSCopy(playerHand);
entity.getWorld().dropItem(tamableFox.getBukkitEntity().getLocation().add(0.0D, 0.2D, 0.0D),
CraftItemStack.asBukkitCopy(wolfHolding));
playerItemInHandNMS.setCount(1);
tamableFox.setSlot(EnumItemSlot.MAINHAND, playerItemInHandNMS);
playerHand.setAmount(playerHand.getAmount() - 1);
player.getInventory().setItemInMainHand(playerHand);
}
} else if (playerHand.getType() == Material.NAME_TAG) {
ItemMeta handMeta = playerHand.getItemMeta();
tamableFox.setChosenName(handMeta.getDisplayName());
} else {
tamableFox.toggleSitting();
}
event.setCancelled(true);
}
} else if (playerHand.getType() == Material.CHICKEN) {
if (Math.random() < 0.33D) {
tamableFox.setTamed(true);
tamableFox.setOwner(((CraftPlayer) player).getHandle());
foxUUIDs.replace(tamableFox.getUniqueID(), null, player.getUniqueId());
player.getWorld().spawnParticle(Particle.HEART, entity.getLocation(), 6, 0.5D, 0.5D, 0.5D);
// Name process
player.sendMessage(ChatColor.RED + ChatColor.BOLD.toString() + "You just tamed a wild fox!");
player.sendMessage(ChatColor.RED + "What do you want to call it?");
tamableFox.setChosenName("???");
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!");
}
return AnvilGUI.Response.close();
})
//.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 {
player.getWorld().spawnParticle(Particle.SMOKE_NORMAL, entity.getLocation(), 10, 0.3D, 0.3D, 0.3D, 0.15D);
}
if (!player.getGameMode().equals(GameMode.CREATIVE)) {
playerHand.setAmount(playerHand.getAmount() - 1);
}
event.setCancelled(true);
}
}
}
@EventHandler
public void onPlayerBedEnterEvent(PlayerBedEnterEvent event) {
Player player = event.getPlayer();
List<UUID> dogsToSleep = getFoxesOf(player);
for (UUID uuid : dogsToSleep) {
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftFox) this.getEntityByUniqueId(uuid)).getHandle();
if (player.getWorld().getTime() > 12541L && player.getWorld().getTime() < 23460L) {
tamableFox.setSleeping(true);
}
}
}
@EventHandler
public void onPlayerBedLeaveEvent(PlayerBedLeaveEvent event) {
Player player = event.getPlayer();
final List<UUID> foxesOf = getFoxesOf(player);
for (UUID uuid : foxesOf) {
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftFox) this.getEntityByUniqueId(uuid)).getHandle();
tamableFox.setSleeping(false);
}
}
@EventHandler
public void onCreatureSpawnEvent(CreatureSpawnEvent event) {
org.bukkit.entity.Entity entity = event.getEntity();
if (entity instanceof Fox && !this.isTamableFox(entity)) {
net.minecraft.server.v1_15_R1.EntityFox.Type foxType = ((EntityFox) ((CraftEntity) entity).getHandle()).getFoxType();
spawnTamableFox(entity.getLocation(), foxType);
event.setCancelled(true);
}
}
@EventHandler
public void onEntityDeathEvent(EntityDeathEvent event) {
Entity entity = event.getEntity();
if (!this.isTamableFox(entity)) {
return;
}
// Remove the fox from storage
lookupCache.remove(entity.getUniqueId());
foxUUIDs.remove(entity.getUniqueId());
spawnedFoxes.remove(entity.getUniqueId());
//sqLiteSetterGetter.removeFox();
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!");
}
sqLiteSetterGetter.removeFox(tamableFox);
/*if (configFoxes.get().getConfigurationSection("Foxes").contains(entity.getUniqueId().toString())) {
*//*EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) entity).getHandle();
if (tamableFox.getOwner() != null && tamableFox.getOwner() instanceof Player) {
Player owner = (Player) tamableFox.getOwner();
owner.sendMessage(getPrefix() + ChatColor.RED + tamableFox.getChosenName() + " was killed!");
}*//*
configFoxes.get().set("Foxes." + entity.getUniqueId(), null);
fileManager.saveConfig("foxes.yml");
}*/
}
public Entity getEntityByUniqueId(UUID uniqueId) {
final Entity cacheEntity = lookupCache.get(uniqueId);
if (cacheEntity != null) {
if (cacheEntity.isDead())
lookupCache.remove(uniqueId);
else return cacheEntity;
}
for (World world : Bukkit.getWorlds()) {
for (Chunk loadedChunk : world.getLoadedChunks()) {
for (Entity entity : loadedChunk.getEntities()) {
if (entity.getUniqueId().equals(uniqueId)) {
this.lookupCache.put(uniqueId, entity);
return entity;
}
}
}
}
return null;
}
public boolean isTamableFox(org.bukkit.entity.Entity entity) {
return ((CraftEntity) entity).getHandle().getClass().getName().contains("TamableFox")
|| ((CraftEntity) entity).getHandle() instanceof EntityTamableFox;
}
public List<UUID> getFoxesOf(Player player) {
return foxUUIDs.entrySet().stream().filter(foxPlayer -> foxPlayer.getValue() != null && foxPlayer.getValue().equals(player.getUniqueId()))
.map(Map.Entry::getKey).collect(Collectors.toList());
}
public FileManager getFileManager() {
return fileManager;
}
public FileManager.Config getMainConfig() {
return config;
}
/*public FileManager.Config getConfigFoxes() {
return configFoxes;
}*/
public EntityTypes getCustomType() {
return customType;
}
public Map<UUID, UUID> getFoxUUIDs() {
return foxUUIDs;
}
public List<EntityTamableFox> 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.no-attack-chicken-rabbit");
}
}

View File

@ -0,0 +1,515 @@
package net.seanomilk.tamablefoxes;
import com.google.common.collect.Maps;
import com.mojang.datafixers.DataFixUtils;
import com.mojang.datafixers.types.Type;
import net.seanomilk.tamablefoxes.command.CommandSpawnTamableFox;
import net.seanomilk.tamablefoxes.io.FileManager;
import net.minecraft.server.v1_15_R1.*;
import 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.CraftItem;
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.EntityType;
import org.bukkit.entity.Fox;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.player.*;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
public class TamableFoxes extends JavaPlugin implements Listener {
public static final String ITEM_INSPECTOR_LORE = ChatColor.BLUE + "Tamable Fox Inspector";
public static final String TAG_TAME_FOX = "tameablefox";
private FileManager fileManager;
private Map<UUID, UUID> foxUUIDs;
private EntityTypes customType;
private boolean isOnLoad = true;
private Map<UUID, Entity> lookupCache;
private FileManager.Config config, configFoxes;
private Map<Player, UUID> waitingName;
@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!");
getServer().getPluginManager().disablePlugin(this);
return;
}
fileManager = new FileManager(this);
this.config = fileManager.getConfig("config.yml");
this.config.copyDefaults(true).save();
this.configFoxes = fileManager.getConfig("foxes.yml");
this.configFoxes.copyDefaults(true).save();
this.getServer().getPluginManager().registerEvents(this, this);
this.getCommand("spawntamablefox").setExecutor(new CommandSpawnTamableFox(this));
this.foxUUIDs = Maps.newHashMap();
this.lookupCache = Maps.newHashMap();
this.waitingName = Maps.newHashMap();
final Map<String, Type<?>> types = (Map<String, Type<?>>) DataConverterRegistry.a()
.getSchema(DataFixUtils.makeKey(SharedConstants.getGameVersion().getWorldVersion()))
.findChoiceType(DataConverterTypes.ENTITY).types();
types.put("minecraft:" + TAG_TAME_FOX, types.get("minecraft:fox"));
EntityTypes.a<net.minecraft.server.v1_15_R1.Entity> a = EntityTypes.a.a((entityTypes, world) ->
new EntityTamableFox(this, entityTypes, world), EnumCreatureType.AMBIENT);
customType = IRegistry.a(IRegistry.ENTITY_TYPE, "tameablefox", a.a("tameablefox"));
this.replaceFoxesOnLoad();
}
@Override
public void onDisable() {
}
private void replaceFoxesOnLoad() {
int amountReplaced = 0;
for (World world : Bukkit.getWorlds()) {
Chunk[] loadedChunks = world.getLoadedChunks();
for (Chunk chunk : loadedChunks) {
Entity[] entities = chunk.getEntities();
for (Entity entity : entities) {
if (!(entity instanceof Fox))
continue;
if (this.isTamableFox(entity))
continue;
EntityTamableFox tamableFox = (EntityTamableFox) spawnTamableFox(entity.getLocation(), ((CraftFox) entity).getHandle().getFoxType());
final YamlConfiguration configuration = configFoxes.get();
// get living entity data
if (configuration.isConfigurationSection("Foxes." + entity.getUniqueId())) {
String owner = configuration.getString("Foxes." + entity.getUniqueId() + ".owner");
// make new data
if (owner.equals("none")) {
foxUUIDs.replace(tamableFox.getUniqueID(), null);
configuration.set("Foxes." + tamableFox.getUniqueID() + ".owner", "none");
} else {
foxUUIDs.replace(tamableFox.getUniqueID(), UUID.fromString(owner));
tamableFox.setTamed(true);
configuration.set("Foxes." + tamableFox.getUniqueID() + ".owner", owner);
}
// set name
if (configuration.isSet("Foxes." + entity.getUniqueId() + ".name")) {
final String name = configuration.getString("Foxes." + entity.getUniqueId() + ".name");
configuration.set("Foxes." + tamableFox.getUniqueID() + ".name", name);
tamableFox.setChosenName(name);
}
// delete old data
configuration.set("Foxes." + entity.getUniqueId(), null);
tamableFox.setSitting(((EntityFox) ((CraftEntity) entity).getHandle()).isSitting());
tamableFox.updateFox();
tamableFox.setAge(((CraftFox) entity).getAge());
ItemStack entityMouthItem = ((CraftFox) entity).getEquipment().getItemInMainHand();
if (entityMouthItem.getType() != Material.AIR) {
tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new ItemStack(entityMouthItem.getType(), 1)));
} else {
tamableFox.setSlot(EnumItemSlot.MAINHAND, new net.minecraft.server.v1_15_R1.ItemStack(Items.AIR));
}
} else {
configuration.set("Foxes." + tamableFox.getUniqueID() + ".owner", "none");
tamableFox.setAge(((CraftFox) entity).getAge());
ItemStack entityMouthItem = ((CraftFox) entity).getEquipment().getItemInMainHand();
if (entityMouthItem.getType() != Material.AIR) {
tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new ItemStack(entityMouthItem.getType(), 1)));
} else {
tamableFox.setSlot(EnumItemSlot.MAINHAND, new net.minecraft.server.v1_15_R1.ItemStack(Items.AIR));
}
}
entity.remove();
++amountReplaced;
}
}
}
configFoxes.save();
this.isOnLoad = false;
}
public net.minecraft.server.v1_15_R1.Entity spawnTamableFox(Location location, net.minecraft.server.v1_15_R1.EntityFox.Type type) {
WorldServer world = ((CraftWorld) location.getWorld()).getHandle();
net.minecraft.server.v1_15_R1.Entity spawnedEntity = customType.b(world, null, null, null,
new BlockPosition(location.getX(), location.getY(), location.getZ()), null, false, false);
world.addEntity(spawnedEntity);
EntityFox fox = (EntityFox) spawnedEntity;
fox.setFoxType(type);
configFoxes.get().set("Foxes." + spawnedEntity.getUniqueID() + ".owner", "none");
fileManager.saveConfig("foxes.yml");
return fox;
}
@EventHandler
public void onChunkLoad(ChunkLoadEvent event) {
if (isOnLoad)
return;
Chunk chunk = event.getChunk();
Entity[] entities = chunk.getEntities();
for (Entity entity : entities) {
if (entity instanceof Fox && !this.isTamableFox(entity)) {
EntityTamableFox tamableFox = (EntityTamableFox) spawnTamableFox(entity.getLocation(), ((CraftFox) entity).getHandle().getFoxType());
final YamlConfiguration configuration = configFoxes.get();
// if has data
if (configuration.isConfigurationSection("Foxes." + entity.getUniqueId())) {
String owner = configuration.getString("Foxes." + entity.getUniqueId() + ".owner", "none");
// if has owner
if (!owner.equals("none")) {
foxUUIDs.replace(tamableFox.getUniqueID(), UUID.fromString(owner));
configuration.set("Foxes." + tamableFox.getUniqueID() + ".owner", owner);
// set name
if (configuration.isSet("Foxes." + entity.getUniqueId() + ".name")) {
String name = configuration.getString("Foxes." + entity.getUniqueId() + ".name");
configuration.set("Foxes." + tamableFox.getUniqueID() + ".name", name);
tamableFox.setChosenName(name);
}
// remove old data
configuration.set("Foxes." + entity.getUniqueId(), null);
tamableFox.setTamed(true);
tamableFox.setSitting(((EntityFox) ((CraftEntity) entity).getHandle()).isSitting());
tamableFox.updateFox();
tamableFox.setAge(((CraftFox) entity).getAge());
ItemStack entityMouthItem = ((CraftFox) entity).getEquipment().getItemInMainHand();
if (entityMouthItem.getType() != Material.AIR) {
tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new ItemStack(entityMouthItem.getType(), 1)));
} else {
tamableFox.setSlot(EnumItemSlot.MAINHAND, new net.minecraft.server.v1_15_R1.ItemStack(Items.AIR));
}
}
} else {
configuration.set("Foxes." + tamableFox.getUniqueID() + ".owner", "none");
tamableFox.setAge(((CraftFox) entity).getAge());
ItemStack entityMouthItem = ((CraftFox) entity).getEquipment().getItemInMainHand();
if (entityMouthItem.getType() != Material.AIR) {
tamableFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new ItemStack(entityMouthItem.getType(), 1)));
} else {
tamableFox.setSlot(EnumItemSlot.MAINHAND, new net.minecraft.server.v1_15_R1.ItemStack(Items.AIR));
}
}
entity.remove();
}
}
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
getFoxesOf(player).forEach(uuid -> {
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) this.getEntityByUniqueId(uuid)).getHandle();
tamableFox.setOwner(((CraftPlayer) player).getHandle());
tamableFox.setTamed(true);
foxUUIDs.replace(tamableFox.getUniqueID(), player.getUniqueId());
});
}
@EventHandler
public void onPlayerInteractEntityEvent(PlayerInteractEntityEvent event) {
Entity entity = event.getRightClicked();
Player player = event.getPlayer();
if (event.getHand() != EquipmentSlot.HAND)
return;
final ItemStack playerHand = player.getInventory().getItemInMainHand();
ItemMeta itemMeta = playerHand.getItemMeta();
if (itemMeta != null && playerHand.getType() == Material.REDSTONE_TORCH
&& itemMeta.hasLore() && itemMeta.getLore().contains(ITEM_INSPECTOR_LORE)) {
List<String> lore;
if (!this.isTamableFox(entity)) {
lore = Arrays.asList(ITEM_INSPECTOR_LORE,
"UUID: " + entity.getUniqueId(),
"Entity ID: " + entity.getEntityId());
} else {
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) entity).getHandle();
if (tamableFox.getOwner() == null) {
lore = Arrays.asList(ITEM_INSPECTOR_LORE,
"UUID: " + entity.getUniqueId(),
"Entity ID: " + entity.getEntityId(),
"Tamable",
"Owner: None");
} else {
lore = Arrays.asList(ITEM_INSPECTOR_LORE,
"UUID: " + entity.getUniqueId(),
"Entity ID: " + entity.getEntityId(),
"Tamable",
"Owner: " + tamableFox.getOwner().getName());
}
}
// update item
itemMeta.setLore(lore);
playerHand.setItemMeta(itemMeta);
player.getInventory().setItemInMainHand(playerHand);
event.setCancelled(true);
player.sendMessage(getPrefix() + "Inspected Entity.");
return;
}
if (this.isTamableFox(entity)) {
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) entity).getHandle();
if (tamableFox.isTamed() && tamableFox.getOwner() != null &&
playerHand.getType() != Material.SWEET_BERRIES) {
// if this fox is theirs
if (foxUUIDs.get(entity.getUniqueId()).equals(player.getUniqueId())) {
if (player.isSneaking()) {
net.minecraft.server.v1_15_R1.ItemStack wolfHolding = tamableFox.getEquipment(EnumItemSlot.MAINHAND);
net.minecraft.server.v1_15_R1.ItemStack playerItemInHandNMS;
if (wolfHolding.isEmpty()) {
if (playerHand.getType() == Material.AIR) {
return;
}
playerItemInHandNMS = CraftItemStack.asNMSCopy(playerHand);
playerItemInHandNMS.setCount(1);
tamableFox.setSlot(EnumItemSlot.MAINHAND, playerItemInHandNMS);
playerHand.setAmount(playerHand.getAmount() - 1);
player.getInventory().setItemInMainHand(playerHand);
} else if (playerHand.getType() == Material.AIR) {
entity.getWorld().dropItem(tamableFox.getBukkitEntity().getLocation().add(0.0D, 0.2D, 0.0D),
CraftItemStack.asBukkitCopy(wolfHolding));
tamableFox.setSlot(EnumItemSlot.MAINHAND, new net.minecraft.server.v1_15_R1.ItemStack(Items.AIR));
} else {
playerItemInHandNMS = CraftItemStack.asNMSCopy(playerHand);
entity.getWorld().dropItem(tamableFox.getBukkitEntity().getLocation().add(0.0D, 0.2D, 0.0D),
CraftItemStack.asBukkitCopy(wolfHolding));
playerItemInHandNMS.setCount(1);
tamableFox.setSlot(EnumItemSlot.MAINHAND, playerItemInHandNMS);
playerHand.setAmount(playerHand.getAmount() - 1);
player.getInventory().setItemInMainHand(playerHand);
}
} else if (playerHand.getType() == Material.NAME_TAG) {
ItemMeta handMeta = playerHand.getItemMeta();
tamableFox.setChosenName(handMeta.getDisplayName());
} else {
tamableFox.toggleSitting();
}
event.setCancelled(true);
}
} else if (playerHand.getType() == Material.CHICKEN) {
if (Math.random() < 0.33D) {
tamableFox.setTamed(true);
tamableFox.setOwner(((CraftPlayer) player).getHandle());
foxUUIDs.replace(tamableFox.getUniqueID(), null, player.getUniqueId());
player.getWorld().spawnParticle(Particle.HEART, entity.getLocation(), 6, 0.5D, 0.5D, 0.5D);
// Name process
player.sendMessage(ChatColor.RED + ChatColor.BOLD.toString() + "You just tamed a wild fox!");
player.sendMessage(ChatColor.RED + "What do you want to call it?");
tamableFox.setChosenName("???");
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!");
return AnvilGUI.Response.close();
} else {
return AnvilGUI.Response.text("Insert a name for your fox!");
}
})
.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 {
player.getWorld().spawnParticle(Particle.SMOKE_NORMAL, entity.getLocation(), 10, 0.3D, 0.3D, 0.3D, 0.15D);
}
if (!player.getGameMode().equals(GameMode.CREATIVE)) {
playerHand.setAmount(playerHand.getAmount() - 1);
}
event.setCancelled(true);
}
}
}
@EventHandler
public void onPlayerBedEnterEvent(PlayerBedEnterEvent event) {
Player player = event.getPlayer();
List<UUID> dogsToSleep = getFoxesOf(player);
for (UUID uuid : dogsToSleep) {
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftFox) this.getEntityByUniqueId(uuid)).getHandle();
if (player.getWorld().getTime() > 12541L && player.getWorld().getTime() < 23460L) {
tamableFox.setSleeping(true);
}
}
}
@EventHandler
public void onPlayerBedLeaveEvent(PlayerBedLeaveEvent event) {
Player player = event.getPlayer();
final List<UUID> foxesOf = getFoxesOf(player);
for (UUID uuid : foxesOf) {
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftFox) this.getEntityByUniqueId(uuid)).getHandle();
tamableFox.setSleeping(false);
}
}
@EventHandler
public void onCreatureSpawnEvent(CreatureSpawnEvent event) {
org.bukkit.entity.Entity entity = event.getEntity();
if (entity instanceof Fox && !this.isTamableFox(entity)) {
net.minecraft.server.v1_15_R1.EntityFox.Type foxType = ((EntityFox) ((CraftEntity) entity).getHandle()).getFoxType();
spawnTamableFox(entity.getLocation(), foxType);
event.setCancelled(true);
}
}
public Entity getEntityByUniqueId(UUID uniqueId) {
final Entity cacheEntity = lookupCache.get(uniqueId);
if (cacheEntity != null) {
if (cacheEntity.isDead())
lookupCache.remove(uniqueId);
else return cacheEntity;
}
for (World world : Bukkit.getWorlds()) {
for (Chunk loadedChunk : world.getLoadedChunks()) {
for (Entity entity : loadedChunk.getEntities()) {
if (entity.getUniqueId().equals(uniqueId)) {
this.lookupCache.put(uniqueId, entity);
return entity;
}
}
}
}
return null;
}
@EventHandler
public void onEntityDeathEvent(EntityDeathEvent event) {
Entity entity = event.getEntity();
if (!this.isTamableFox(entity))
return;
this.lookupCache.remove(entity.getUniqueId());
foxUUIDs.remove(entity.getUniqueId());
if (configFoxes.get().getConfigurationSection("Foxes").contains(entity.getUniqueId().toString())) {
/*EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) entity).getHandle();
if (tamableFox.getOwner() != null && tamableFox.getOwner() instanceof Player) {
Player owner = (Player) tamableFox.getOwner();
owner.sendMessage(getPrefix() + ChatColor.RED + tamableFox.getChosenName() + " was killed!");
}*/
configFoxes.get().set("Foxes." + entity.getUniqueId(), null);
fileManager.saveConfig("foxes.yml");
}
}
public boolean isTamableFox(org.bukkit.entity.Entity entity) {
return ((CraftEntity) entity).getHandle().getClass().getName().contains("TamableFox")
|| ((CraftEntity) entity).getHandle() instanceof EntityTamableFox;
}
public List<UUID> getFoxesOf(Player player) {
return foxUUIDs.entrySet().stream().filter(foxPlayer -> foxPlayer.getValue() != null && foxPlayer.getValue().equals(player.getUniqueId()))
.map(Map.Entry::getKey).collect(Collectors.toList());
}
public FileManager getFileManager() {
return fileManager;
}
public FileManager.Config getMainConfig() {
return config;
}
public FileManager.Config getConfigFoxes() {
return configFoxes;
}
public EntityTypes getCustomType() {
return customType;
}
public Map<UUID, UUID> getFoxUUIDs() {
return foxUUIDs;
}
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.no-attack-chicken-rabbit");
}
}

View File

@ -1,51 +1,51 @@
package net.seanomik.tamablefoxes.sqlite; package net.seanomik.tamablefoxes.sqllite;
import net.seanomik.tamablefoxes.TamableFoxes; import net.seanomik.tamablefoxes.TamableFoxes;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
import java.sql.SQLException; import java.sql.SQLException;
public class SQLiteHandler { public class SQLiteHandler {
private Connection connection; private Connection connection;
public void connect() { public void connect() {
try { try {
String baseLoc = Bukkit.getWorldContainer().toURI().toString().substring(6); String baseLoc = Bukkit.getWorldContainer().toURI().toString().substring(6);
baseLoc = baseLoc.substring(0,baseLoc.length()-2); baseLoc = baseLoc.substring(0,baseLoc.length()-2);
String url = "jdbc:sqlite:" + baseLoc + "plugins/TamableFoxes/foxes.db"; String url = "jdbc:sqlite:" + baseLoc + "plugins/TamableFoxes/foxes.db";
connection = DriverManager.getConnection(url); connection = DriverManager.getConnection(url);
//Bukkit.getConsoleSender().sendMessage(TamableFoxes.getPrefix() + "Connection to SQLite has been established."); Bukkit.getConsoleSender().sendMessage(TamableFoxes.getPrefix() + "Connection to SQLite has been established.");
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public Connection getConnection() { public Connection getConnection() {
return connection; return connection;
} }
public void closeConnection() { public void closeConnection() {
try { try {
connection.close(); connection.close();
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public void newConnection() { public void newConnection() {
try { try {
connection.close(); connection.close();
connect(); connect();
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public void setConnection(Connection connection) { public void setConnection(Connection connection) {
this.connection = connection; this.connection = connection;
} }
} }

View File

@ -1,177 +1,120 @@
package net.seanomik.tamablefoxes.sqlite; package net.seanomik.tamablefoxes.sqllite;
import net.minecraft.server.v1_15_R1.BlockPosition; import net.minecraft.server.v1_15_R1.EnumItemSlot;
import net.minecraft.server.v1_15_R1.EntityFox; import net.seanomik.tamablefoxes.EntityTamableFox;
import net.minecraft.server.v1_15_R1.EnumItemSlot; import net.seanomik.tamablefoxes.TamableFoxes;
import net.seanomik.tamablefoxes.EntityTamableFox; import org.bukkit.plugin.Plugin;
import net.seanomik.tamablefoxes.TamableFoxes;
import org.bukkit.Bukkit; import java.sql.DatabaseMetaData;
import org.bukkit.Location; import java.sql.PreparedStatement;
import org.bukkit.Material; import java.sql.ResultSet;
import org.bukkit.OfflinePlayer; import java.sql.SQLException;
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld; import java.time.LocalDateTime;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; import java.time.format.DateTimeFormatter;
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack; import java.util.*;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin; public class SQLiteSetterGetter {
public static Plugin plugin;
import java.sql.DatabaseMetaData; public static SQLiteHandler sqLiteHandler;
import java.sql.PreparedStatement;
import java.sql.ResultSet; public void createTablesIfNotExist() {
import java.sql.SQLException; plugin = TamableFoxes.getPlugin(TamableFoxes.class);
import java.util.*; sqLiteHandler = TamableFoxes.sqLiteHandler;
//String pluginDatabase = Reference.SQLiteDatabase;
public class SQLiteSetterGetter {
public static TamableFoxes plugin; String foxesTable =
public static SQLiteHandler sqLiteHandler; "CREATE TABLE IF NOT EXISTS `foxes` ( " +
"`OWNER_UUID` TEXT PRIMARY KEY , " +
public void createTablesIfNotExist() { "`NAME` TEXT NOT NULL , " +
plugin = TamableFoxes.getPlugin(TamableFoxes.class); "`LOCATION` TEXT NOT NULL , " +
sqLiteHandler = TamableFoxes.sqLiteHandler; "`MOUTH_ITEM` TEXT NOT NULL);";
//String pluginDatabase = Reference.SQLiteDatabase;
try {
String foxesTable = sqLiteHandler.connect();
"CREATE TABLE IF NOT EXISTS `foxes` ( " + // Create previous bans table
"`INDEX` INTEGER PRIMARY KEY AUTOINCREMENT , " + DatabaseMetaData dbm = sqLiteHandler.getConnection().getMetaData();
"`OWNER_UUID` TEXT NOT NULL , " + ResultSet tables = dbm.getTables(null, null, "foxes", null);
"`NAME` TEXT , " + if (!tables.next()) {
"`LOCATION` TEXT NOT NULL , " + PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement(foxesTable);
"`TYPE` TEXT NOT NULL , " + statement.executeUpdate();
"`MOUTH_ITEM` TEXT NOT NULL);";
plugin.getServer().getConsoleSender().sendMessage(TamableFoxes.getPrefix() + "Created foxes table!");
try { }
sqLiteHandler.connect(); } catch (SQLException e) {
// Create previous bans table e.printStackTrace();
DatabaseMetaData dbm = sqLiteHandler.getConnection().getMetaData(); } finally {
ResultSet tables = dbm.getTables(null, null, "foxes", null); if (sqLiteHandler.getConnection() != null) {
if (!tables.next()) { try {
PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement(foxesTable); sqLiteHandler.getConnection().close();
statement.executeUpdate(); } catch (SQLException e) {
e.printStackTrace();
plugin.getServer().getConsoleSender().sendMessage(TamableFoxes.getPrefix() + "Created foxes table!"); }
} }
} catch (SQLException e) { }
e.printStackTrace(); }
} finally {
if (sqLiteHandler.getConnection() != null) { public void saveFox(EntityTamableFox fox) {
try { plugin = TamableFoxes.getPlugin(TamableFoxes.class);
sqLiteHandler.getConnection().close(); try {
} catch (SQLException e) { sqLiteHandler.connect();
e.printStackTrace(); PreparedStatement statement = sqLiteHandler.getConnection()
} .prepareStatement("INSERT INTO foxes (OWNER_UUID,NAME,LOCATION,MOUTH_ITEM) VALUES (?,?,?,?)");
}
} statement.setString(1, (fox.getOwner().getUniqueID() == null) ? "none" : fox.getOwner().getUniqueID().toString());
} statement.setString(2, fox.getChosenName());
public void saveFox(EntityTamableFox fox) { statement.setString(3, fox.locX() + "," + fox.locY() + "," + fox.locY());
plugin = TamableFoxes.getPlugin(TamableFoxes.class); statement.setString(4, fox.getEquipment(EnumItemSlot.MAINHAND).toString());
try { statement.executeUpdate();
sqLiteHandler.connect(); } catch (SQLException e) {
e.printStackTrace();
PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement("INSERT INTO foxes (OWNER_UUID,NAME,LOCATION,TYPE,MOUTH_ITEM) VALUES (?,?,?,?,?)"); } finally {
if (fox.databaseIndex != -1) { if (sqLiteHandler.getConnection() != null) {
statement = sqLiteHandler.getConnection().prepareStatement("UPDATE foxes SET OWNER_UUID=?, NAME=?, LOCATION=?, TYPE=?, MOUTH_ITEM=? WHERE INDEX=" + fox.databaseIndex); try {
} sqLiteHandler.getConnection().close();
} catch (SQLException e) {
statement.setString(1, (fox.getOwner() == null) ? "none" : fox.getOwner().getUniqueID().toString()); e.printStackTrace();
statement.setString(2, fox.getChosenName()); }
}
statement.setString(3, fox.getWorld().worldData.getName() + "," + fox.locX() + "," + fox.locY() + "," + fox.locY()); }
statement.setString(4, fox.getFoxType().toString()); }
statement.setString(5, fox.getEquipment(EnumItemSlot.MAINHAND).toString().toUpperCase().substring(fox.getEquipment(EnumItemSlot.MAINHAND).toString().indexOf(' ')+1));
statement.executeUpdate(); public List<EntityTamableFox> spawnFoxes() {
plugin = Dexun.getPlugin(Dexun.class);
ResultSet result = statement.getGeneratedKeys(); try {
if (result.next()) { sqLiteHandler.connect();
fox.databaseIndex = result.getInt("INDEX"); PreparedStatement statement = sqLiteHandler.getConnection()
} .prepareStatement("SELECT * FROM foxes");
} catch (SQLException e) { ResultSet results = statement.executeQuery();
e.printStackTrace(); results.next();
} finally {
if (sqLiteHandler.getConnection() != null) { String banReasonsSTR = results.getString("REASONS");
try { String banDatesSTR = results.getString("ON_DATES");
sqLiteHandler.getConnection().close(); String banEndDatesSTR = results.getString("END_DATES");
} catch (SQLException e) { String unbanReasonsSTR = results.getString("UNBAN_REASONS");
e.printStackTrace();
} List<String> banReasons = new LinkedList<String>(Arrays.asList(banReasonsSTR.substring(1).split(",")));
} List<String> banDates = new LinkedList<String>(Arrays.asList(banDatesSTR.substring(1).split(",")));
} List<String> banEndDates = new LinkedList<String>(Arrays.asList(banEndDatesSTR.substring(1).split(",")));
} List<String> unbanReasons = new LinkedList<String>(Arrays.asList(unbanReasonsSTR.substring(1).split(",")));
public void saveFoxes(List<EntityTamableFox> foxes) { // @TODO: Optimize List<List<String>> bans = new ArrayList<List<String>>();
for (EntityTamableFox fox : foxes) { bans.add(banReasons);
saveFox(fox); bans.add(banDates);
} bans.add(banEndDates);
} bans.add(unbanReasons);
public List<EntityTamableFox> spawnFoxes() { return bans;
plugin = TamableFoxes.getPlugin(TamableFoxes.class); } catch (SQLException e) {
try { e.printStackTrace();
sqLiteHandler.connect(); } finally {
PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement("SELECT * FROM foxes"); if (sqLiteHandler.getConnection() != null) {
ResultSet results = statement.executeQuery(); try {
sqLiteHandler.getConnection().close();
List<EntityTamableFox> foxList = new ArrayList<>(); } catch (SQLException e) {
while (results.next()) { // Loop through each row e.printStackTrace();
List<String> 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))); }
}
EntityTamableFox spawnedFox = (EntityTamableFox) plugin.spawnTamableFox(loc, EntityFox.Type.valueOf(results.getString("TYPE"))); }
spawnedFox.databaseIndex = results.getInt("INDEX"); }
spawnedFox.setSlot(EnumItemSlot.MAINHAND, CraftItemStack.asNMSCopy(new ItemStack(Material.valueOf(results.getString("MOUTH_ITEM")), 1)));
if (!results.getString("OWNER_UUID").equals("none")) {
UUID ownerUUID = UUID.fromString(results.getString("OWNER_UUID"));
OfflinePlayer owner = plugin.getServer().getOfflinePlayer(ownerUUID);
if (owner.isOnline()) {
spawnedFox.setOwner(((CraftPlayer) owner.getPlayer()).getHandle());
}
plugin.getFoxUUIDs().put(spawnedFox.getUniqueID(), ownerUUID);
spawnedFox.setChosenName(results.getString("NAME"));
}
foxList.add(spawnedFox);
}
return foxList;
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (sqLiteHandler.getConnection() != null) {
try {
sqLiteHandler.getConnection().close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return null;
}
public void removeFox(int databaseID) {
plugin = TamableFoxes.getPlugin(TamableFoxes.class);
try {
sqLiteHandler.connect();
PreparedStatement statement = sqLiteHandler.getConnection().prepareStatement("DELETE FROM foxes WHERE INDEX=" + databaseID);
statement.setInt(1, databaseID);
statement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (sqLiteHandler.getConnection() != null) {
try {
sqLiteHandler.getConnection().close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
public void removeFox(EntityTamableFox fox) {
removeFox(fox.databaseIndex);
}
}