--- a/net/minecraft/server/EntityInsentient.java +++ b/net/minecraft/server/EntityInsentient.java @@ -8,6 +8,15 @@ import java.util.Random; import java.util.UUID; +// CraftBukkit start +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.craftbukkit.entity.CraftLivingEntity; +import org.bukkit.event.entity.EntityTargetLivingEntityEvent; +import org.bukkit.event.entity.EntityTargetEvent; +import org.bukkit.event.entity.EntityUnleashEvent; +import org.bukkit.event.entity.EntityUnleashEvent.UnleashReason; +// CraftBukkit end + public abstract class EntityInsentient extends EntityLiving { private static final DataWatcherObject<Byte> a = DataWatcher.a(EntityInsentient.class, DataWatcherRegistry.a); @@ -60,6 +69,9 @@ this.r(); } + // CraftBukkit start - default persistance to type's persistance value + this.persistent = !isTypeNotPersistent(); + // CraftBukkit end } protected void r() {} @@ -110,7 +122,37 @@ } public void setGoalTarget(EntityLiving entityliving) { + // CraftBukkit start - fire event + setGoalTarget(entityliving, EntityTargetEvent.TargetReason.UNKNOWN, true); + } + + public void setGoalTarget(EntityLiving entityliving, EntityTargetEvent.TargetReason reason, boolean fireEvent) { + if (getGoalTarget() == entityliving) return; + if (fireEvent) { + if (reason == EntityTargetEvent.TargetReason.UNKNOWN && getGoalTarget() != null && entityliving == null) { + reason = getGoalTarget().isAlive() ? EntityTargetEvent.TargetReason.FORGOT_TARGET : EntityTargetEvent.TargetReason.TARGET_DIED; + } + if (reason == EntityTargetEvent.TargetReason.UNKNOWN) { + world.getServer().getLogger().log(java.util.logging.Level.WARNING, "Unknown target reason, please report on the issue tracker", new Exception()); + } + CraftLivingEntity ctarget = null; + if (entityliving != null) { + ctarget = (CraftLivingEntity) entityliving.getBukkitEntity(); + } + EntityTargetLivingEntityEvent event = new EntityTargetLivingEntityEvent(this.getBukkitEntity(), ctarget, reason); + world.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; + } + + if (event.getTarget() != null) { + entityliving = ((CraftLivingEntity) event.getTarget()).getHandle(); + } else { + entityliving = null; + } + } this.goalTarget = entityliving; + // CraftBukkit end } public boolean d(Class<? extends EntityLiving> oclass) { @@ -225,6 +267,7 @@ return null; } + protected ItemStack headDrop = null; // CraftBukkit protected void dropDeathLoot(boolean flag, int i) { Item item = this.getLoot(); @@ -240,6 +283,12 @@ } } + // CraftBukkit start + if (headDrop != null) { + this.a(headDrop, 0.0F); + headDrop = null; + } + // CraftBukkit end } public void b(NBTTagCompound nbttagcompound) { @@ -321,11 +370,20 @@ public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); + + // CraftBukkit start - If looting or persistence is false only use it if it was set after we started using it if (nbttagcompound.hasKeyOfType("CanPickUpLoot", 1)) { - this.l(nbttagcompound.getBoolean("CanPickUpLoot")); + boolean data = nbttagcompound.getBoolean("CanPickUpLoot"); + if (isLevelAtLeast(nbttagcompound, 1) || data) { + this.l(data); + } } - this.persistent = nbttagcompound.getBoolean("PersistenceRequired"); + boolean data = nbttagcompound.getBoolean("PersistenceRequired"); + if (isLevelAtLeast(nbttagcompound, 1) || data) { + this.persistent = data; + } + // CraftBukkit end NBTTagList nbttaglist; int i; @@ -549,11 +607,11 @@ double d2 = entityhuman.locZ - this.locZ; double d3 = d0 * d0 + d1 * d1 + d2 * d2; - if (this.isTypeNotPersistent() && d3 > 16384.0D) { + if (d3 > 16384.0D) { // CraftBukkit - remove isTypeNotPersistent() check this.die(); } - if (this.ticksFarFromPlayer > 600 && this.random.nextInt(800) == 0 && d3 > 1024.0D && this.isTypeNotPersistent()) { + if (this.ticksFarFromPlayer > 600 && this.random.nextInt(800) == 0 && d3 > 1024.0D) { // CraftBukkit - remove isTypeNotPersistent() check this.die(); } else if (d3 < 1024.0D) { this.ticksFarFromPlayer = 0; @@ -931,9 +989,21 @@ public final boolean a(EntityHuman entityhuman, ItemStack itemstack, EnumHand enumhand) { if (this.isLeashed() && this.getLeashHolder() == entityhuman) { + // CraftBukkit start - fire PlayerUnleashEntityEvent + if (CraftEventFactory.callPlayerUnleashEntityEvent(this, entityhuman).isCancelled()) { + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutAttachEntity(this, this.getLeashHolder())); + return false; + } + // CraftBukkit end this.unleash(true, !entityhuman.abilities.canInstantlyBuild); return true; } else if (itemstack != null && itemstack.getItem() == Items.LEAD && this.a(entityhuman)) { + // CraftBukkit start - fire PlayerLeashEntityEvent + if (CraftEventFactory.callPlayerLeashEntityEvent(this, entityhuman, entityhuman).isCancelled()) { + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutAttachEntity(this, this.getLeashHolder())); + return false; + } + // CraftBukkit end this.setLeashHolder(entityhuman, true); --itemstack.count; return true; @@ -953,10 +1023,12 @@ if (this.bC) { if (!this.isAlive()) { + this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.PLAYER_UNLEASH)); // CraftBukkit this.unleash(true, true); } if (this.leashHolder == null || this.leashHolder.dead) { + this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.HOLDER_GONE)); // CraftBukkit this.unleash(true, true); } } @@ -1037,6 +1109,7 @@ this.leashHolder = entityleash; } else { + this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.UNKNOWN)); // CraftBukkit this.unleash(false, true); } }