After the changes in d611cff2 we started including a mob's equipment when calling EntityDeathEvent so plugins can access this data. However, the changes to enable this triggered a bug that makes skeletons and pig zombies no longer drop equipment because they handle this differently than the rest. On top of this we don't handle dropping equipment for mobs that cannot pick up items in vanilla even though vanilla does drop equipment for them if you summon them with it. We also do not include a horse's inventory in the event so they drop their saddle, armor, chest, and chest contents with no way for a plugin to control this. To solve this issues we revert mob item dropping back to vanilla logic and instead just capture all their drops in the method they all call to spawn them into the world. We also move horse inventory dropping so it happens at a time when we're capturing these drops. With these changes all items mobs drop on death should now be included in the event and we have less diff to worry about for future updates.
893 lines
29 KiB
Java
893 lines
29 KiB
Java
package net.minecraft.server;
|
|
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.UUID;
|
|
|
|
// CraftBukkit start
|
|
import org.bukkit.craftbukkit.event.CraftEventFactory;
|
|
import org.bukkit.event.entity.EntityUnleashEvent;
|
|
import org.bukkit.event.entity.EntityUnleashEvent.UnleashReason;
|
|
// CraftBukkit end
|
|
|
|
public abstract class EntityInsentient extends EntityLiving {
|
|
|
|
public int a_;
|
|
protected int b;
|
|
private ControllerLook lookController;
|
|
private ControllerMove moveController;
|
|
private ControllerJump bm;
|
|
private EntityAIBodyControl bn;
|
|
private Navigation navigation;
|
|
protected final PathfinderGoalSelector goalSelector;
|
|
protected final PathfinderGoalSelector targetSelector;
|
|
private EntityLiving goalTarget;
|
|
private EntitySenses bq;
|
|
private ItemStack[] equipment = new ItemStack[5];
|
|
public float[] dropChances = new float[5]; // CraftBukkit - protected -> public
|
|
public boolean canPickUpLoot; // CraftBukkit - private -> public
|
|
public boolean persistent = !isTypeNotPersistent(); // CraftBukkit - private -> public
|
|
protected float f;
|
|
private Entity bu;
|
|
protected int g;
|
|
private boolean bv;
|
|
private Entity bw;
|
|
private NBTTagCompound bx;
|
|
|
|
public EntityInsentient(World world) {
|
|
super(world);
|
|
this.goalSelector = new PathfinderGoalSelector(world != null && world.methodProfiler != null ? world.methodProfiler : null);
|
|
this.targetSelector = new PathfinderGoalSelector(world != null && world.methodProfiler != null ? world.methodProfiler : null);
|
|
this.lookController = new ControllerLook(this);
|
|
this.moveController = new ControllerMove(this);
|
|
this.bm = new ControllerJump(this);
|
|
this.bn = new EntityAIBodyControl(this);
|
|
this.navigation = new Navigation(this, world);
|
|
this.bq = new EntitySenses(this);
|
|
|
|
for (int i = 0; i < this.dropChances.length; ++i) {
|
|
this.dropChances[i] = 0.085F;
|
|
}
|
|
}
|
|
|
|
protected void aC() {
|
|
super.aC();
|
|
this.bb().b(GenericAttributes.b).setValue(16.0D);
|
|
}
|
|
|
|
public ControllerLook getControllerLook() {
|
|
return this.lookController;
|
|
}
|
|
|
|
public ControllerMove getControllerMove() {
|
|
return this.moveController;
|
|
}
|
|
|
|
public ControllerJump getControllerJump() {
|
|
return this.bm;
|
|
}
|
|
|
|
public Navigation getNavigation() {
|
|
return this.navigation;
|
|
}
|
|
|
|
public EntitySenses getEntitySenses() {
|
|
return this.bq;
|
|
}
|
|
|
|
public EntityLiving getGoalTarget() {
|
|
return this.goalTarget;
|
|
}
|
|
|
|
public void setGoalTarget(EntityLiving entityliving) {
|
|
this.goalTarget = entityliving;
|
|
}
|
|
|
|
public boolean a(Class oclass) {
|
|
return EntityCreeper.class != oclass && EntityGhast.class != oclass;
|
|
}
|
|
|
|
public void p() {}
|
|
|
|
protected void c() {
|
|
super.c();
|
|
this.datawatcher.a(11, Byte.valueOf((byte) 0));
|
|
this.datawatcher.a(10, "");
|
|
}
|
|
|
|
public int q() {
|
|
return 80;
|
|
}
|
|
|
|
public void r() {
|
|
String s = this.t();
|
|
|
|
if (s != null) {
|
|
this.makeSound(s, this.be(), this.bf());
|
|
}
|
|
}
|
|
|
|
public void B() {
|
|
super.B();
|
|
this.world.methodProfiler.a("mobBaseTick");
|
|
if (this.isAlive() && this.random.nextInt(1000) < this.a_++) {
|
|
this.a_ = -this.q();
|
|
this.r();
|
|
}
|
|
|
|
this.world.methodProfiler.b();
|
|
}
|
|
|
|
protected int getExpValue(EntityHuman entityhuman) {
|
|
if (this.b > 0) {
|
|
int i = this.b;
|
|
ItemStack[] aitemstack = this.getEquipment();
|
|
|
|
for (int j = 0; j < aitemstack.length; ++j) {
|
|
if (aitemstack[j] != null && this.dropChances[j] <= 1.0F) {
|
|
i += 1 + this.random.nextInt(3);
|
|
}
|
|
}
|
|
|
|
return i;
|
|
} else {
|
|
return this.b;
|
|
}
|
|
}
|
|
|
|
public void s() {
|
|
for (int i = 0; i < 20; ++i) {
|
|
double d0 = this.random.nextGaussian() * 0.02D;
|
|
double d1 = this.random.nextGaussian() * 0.02D;
|
|
double d2 = this.random.nextGaussian() * 0.02D;
|
|
double d3 = 10.0D;
|
|
|
|
this.world.addParticle("explode", this.locX + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width - d0 * d3, this.locY + (double) (this.random.nextFloat() * this.length) - d1 * d3, this.locZ + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width - d2 * d3, d0, d1, d2);
|
|
}
|
|
}
|
|
|
|
public void h() {
|
|
super.h();
|
|
if (!this.world.isStatic) {
|
|
this.bL();
|
|
}
|
|
}
|
|
|
|
protected float f(float f, float f1) {
|
|
if (this.bj()) {
|
|
this.bn.a();
|
|
return f1;
|
|
} else {
|
|
return super.f(f, f1);
|
|
}
|
|
}
|
|
|
|
protected String t() {
|
|
return null;
|
|
}
|
|
|
|
protected Item getLoot() {
|
|
return Item.d(0);
|
|
}
|
|
|
|
protected void dropDeathLoot(boolean flag, int i) {
|
|
Item item = this.getLoot();
|
|
|
|
if (item != null) {
|
|
int j = this.random.nextInt(3);
|
|
|
|
if (i > 0) {
|
|
j += this.random.nextInt(i + 1);
|
|
}
|
|
|
|
for (int k = 0; k < j; ++k) {
|
|
this.a(item, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void b(NBTTagCompound nbttagcompound) {
|
|
super.b(nbttagcompound);
|
|
nbttagcompound.setBoolean("CanPickUpLoot", this.bJ());
|
|
nbttagcompound.setBoolean("PersistenceRequired", this.persistent);
|
|
NBTTagList nbttaglist = new NBTTagList();
|
|
|
|
NBTTagCompound nbttagcompound1;
|
|
|
|
for (int i = 0; i < this.equipment.length; ++i) {
|
|
nbttagcompound1 = new NBTTagCompound();
|
|
if (this.equipment[i] != null) {
|
|
this.equipment[i].save(nbttagcompound1);
|
|
}
|
|
|
|
nbttaglist.add(nbttagcompound1);
|
|
}
|
|
|
|
nbttagcompound.set("Equipment", nbttaglist);
|
|
NBTTagList nbttaglist1 = new NBTTagList();
|
|
|
|
for (int j = 0; j < this.dropChances.length; ++j) {
|
|
nbttaglist1.add(new NBTTagFloat(this.dropChances[j]));
|
|
}
|
|
|
|
nbttagcompound.set("DropChances", nbttaglist1);
|
|
nbttagcompound.setString("CustomName", this.getCustomName());
|
|
nbttagcompound.setBoolean("CustomNameVisible", this.getCustomNameVisible());
|
|
nbttagcompound.setBoolean("Leashed", this.bv);
|
|
if (this.bw != null) {
|
|
nbttagcompound1 = new NBTTagCompound();
|
|
if (this.bw instanceof EntityLiving) {
|
|
nbttagcompound1.setLong("UUIDMost", this.bw.getUniqueID().getMostSignificantBits());
|
|
nbttagcompound1.setLong("UUIDLeast", this.bw.getUniqueID().getLeastSignificantBits());
|
|
} else if (this.bw instanceof EntityHanging) {
|
|
EntityHanging entityhanging = (EntityHanging) this.bw;
|
|
|
|
nbttagcompound1.setInt("X", entityhanging.x);
|
|
nbttagcompound1.setInt("Y", entityhanging.y);
|
|
nbttagcompound1.setInt("Z", entityhanging.z);
|
|
}
|
|
|
|
nbttagcompound.set("Leash", nbttagcompound1);
|
|
}
|
|
}
|
|
|
|
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
|
|
boolean data = nbttagcompound.getBoolean("CanPickUpLoot");
|
|
if (isLevelAtLeast(nbttagcompound, 1) || data) {
|
|
this.canPickUpLoot = data;
|
|
}
|
|
|
|
data = nbttagcompound.getBoolean("PersistenceRequired");
|
|
if (isLevelAtLeast(nbttagcompound, 1) || data) {
|
|
this.persistent = data;
|
|
}
|
|
// CraftBukkit end
|
|
|
|
if (nbttagcompound.hasKeyOfType("CustomName", 8) && nbttagcompound.getString("CustomName").length() > 0) {
|
|
this.setCustomName(nbttagcompound.getString("CustomName"));
|
|
}
|
|
|
|
this.setCustomNameVisible(nbttagcompound.getBoolean("CustomNameVisible"));
|
|
NBTTagList nbttaglist;
|
|
int i;
|
|
|
|
if (nbttagcompound.hasKeyOfType("Equipment", 9)) {
|
|
nbttaglist = nbttagcompound.getList("Equipment", 10);
|
|
|
|
for (i = 0; i < this.equipment.length; ++i) {
|
|
this.equipment[i] = ItemStack.createStack(nbttaglist.get(i));
|
|
}
|
|
}
|
|
|
|
if (nbttagcompound.hasKeyOfType("DropChances", 9)) {
|
|
nbttaglist = nbttagcompound.getList("DropChances", 5);
|
|
|
|
for (i = 0; i < nbttaglist.size(); ++i) {
|
|
this.dropChances[i] = nbttaglist.e(i);
|
|
}
|
|
}
|
|
|
|
this.bv = nbttagcompound.getBoolean("Leashed");
|
|
if (this.bv && nbttagcompound.hasKeyOfType("Leash", 10)) {
|
|
this.bx = nbttagcompound.getCompound("Leash");
|
|
}
|
|
}
|
|
|
|
public void n(float f) {
|
|
this.be = f;
|
|
}
|
|
|
|
public void i(float f) {
|
|
super.i(f);
|
|
this.n(f);
|
|
}
|
|
|
|
public void e() {
|
|
super.e();
|
|
this.world.methodProfiler.a("looting");
|
|
if (!this.world.isStatic && this.bJ() && !this.aT && this.world.getGameRules().getBoolean("mobGriefing")) {
|
|
List list = this.world.a(EntityItem.class, this.boundingBox.grow(1.0D, 0.0D, 1.0D));
|
|
Iterator iterator = list.iterator();
|
|
|
|
while (iterator.hasNext()) {
|
|
EntityItem entityitem = (EntityItem) iterator.next();
|
|
|
|
if (!entityitem.dead && entityitem.getItemStack() != null) {
|
|
ItemStack itemstack = entityitem.getItemStack();
|
|
int i = b(itemstack);
|
|
|
|
if (i > -1) {
|
|
boolean flag = true;
|
|
ItemStack itemstack1 = this.getEquipment(i);
|
|
|
|
if (itemstack1 != null) {
|
|
if (i == 0) {
|
|
if (itemstack.getItem() instanceof ItemSword && !(itemstack1.getItem() instanceof ItemSword)) {
|
|
flag = true;
|
|
} else if (itemstack.getItem() instanceof ItemSword && itemstack1.getItem() instanceof ItemSword) {
|
|
ItemSword itemsword = (ItemSword) itemstack.getItem();
|
|
ItemSword itemsword1 = (ItemSword) itemstack1.getItem();
|
|
|
|
if (itemsword.i() == itemsword1.i()) {
|
|
flag = itemstack.getData() > itemstack1.getData() || itemstack.hasTag() && !itemstack1.hasTag();
|
|
} else {
|
|
flag = itemsword.i() > itemsword1.i();
|
|
}
|
|
} else {
|
|
flag = false;
|
|
}
|
|
} else if (itemstack.getItem() instanceof ItemArmor && !(itemstack1.getItem() instanceof ItemArmor)) {
|
|
flag = true;
|
|
} else if (itemstack.getItem() instanceof ItemArmor && itemstack1.getItem() instanceof ItemArmor) {
|
|
ItemArmor itemarmor = (ItemArmor) itemstack.getItem();
|
|
ItemArmor itemarmor1 = (ItemArmor) itemstack1.getItem();
|
|
|
|
if (itemarmor.c == itemarmor1.c) {
|
|
flag = itemstack.getData() > itemstack1.getData() || itemstack.hasTag() && !itemstack1.hasTag();
|
|
} else {
|
|
flag = itemarmor.c > itemarmor1.c;
|
|
}
|
|
} else {
|
|
flag = false;
|
|
}
|
|
}
|
|
|
|
if (flag) {
|
|
if (itemstack1 != null && this.random.nextFloat() - 0.1F < this.dropChances[i]) {
|
|
this.a(itemstack1, 0.0F);
|
|
}
|
|
|
|
if (itemstack.getItem() == Items.DIAMOND && entityitem.j() != null) {
|
|
EntityHuman entityhuman = this.world.a(entityitem.j());
|
|
|
|
if (entityhuman != null) {
|
|
entityhuman.a((Statistic) AchievementList.x);
|
|
}
|
|
}
|
|
|
|
this.setEquipment(i, itemstack);
|
|
this.dropChances[i] = 2.0F;
|
|
this.persistent = true;
|
|
this.receive(entityitem, 1);
|
|
entityitem.die();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
this.world.methodProfiler.b();
|
|
}
|
|
|
|
protected boolean bj() {
|
|
return false;
|
|
}
|
|
|
|
protected boolean isTypeNotPersistent() {
|
|
return true;
|
|
}
|
|
|
|
protected void w() {
|
|
if (this.persistent) {
|
|
this.aU = 0;
|
|
} else {
|
|
EntityHuman entityhuman = this.world.findNearbyPlayer(this, -1.0D);
|
|
|
|
if (entityhuman != null) {
|
|
double d0 = entityhuman.locX - this.locX;
|
|
double d1 = entityhuman.locY - this.locY;
|
|
double d2 = entityhuman.locZ - this.locZ;
|
|
double d3 = d0 * d0 + d1 * d1 + d2 * d2;
|
|
|
|
if (d3 > 16384.0D) { // CraftBukkit - remove isTypeNotPersistent() check
|
|
this.die();
|
|
}
|
|
|
|
if (this.aU > 600 && this.random.nextInt(800) == 0 && d3 > 1024.0D) { // CraftBukkit - remove isTypeNotPersistent() check
|
|
this.die();
|
|
} else if (d3 < 1024.0D) {
|
|
this.aU = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
protected void bm() {
|
|
++this.aU;
|
|
this.world.methodProfiler.a("checkDespawn");
|
|
this.w();
|
|
this.world.methodProfiler.b();
|
|
this.world.methodProfiler.a("sensing");
|
|
this.bq.a();
|
|
this.world.methodProfiler.b();
|
|
this.world.methodProfiler.a("targetSelector");
|
|
this.targetSelector.a();
|
|
this.world.methodProfiler.b();
|
|
this.world.methodProfiler.a("goalSelector");
|
|
this.goalSelector.a();
|
|
this.world.methodProfiler.b();
|
|
this.world.methodProfiler.a("navigation");
|
|
this.navigation.f();
|
|
this.world.methodProfiler.b();
|
|
this.world.methodProfiler.a("mob tick");
|
|
this.bo();
|
|
this.world.methodProfiler.b();
|
|
this.world.methodProfiler.a("controls");
|
|
this.world.methodProfiler.a("move");
|
|
this.moveController.c();
|
|
this.world.methodProfiler.c("look");
|
|
this.lookController.a();
|
|
this.world.methodProfiler.c("jump");
|
|
this.bm.b();
|
|
this.world.methodProfiler.b();
|
|
this.world.methodProfiler.b();
|
|
}
|
|
|
|
protected void bp() {
|
|
super.bp();
|
|
this.bd = 0.0F;
|
|
this.be = 0.0F;
|
|
this.w();
|
|
float f = 8.0F;
|
|
|
|
if (this.random.nextFloat() < 0.02F) {
|
|
EntityHuman entityhuman = this.world.findNearbyPlayer(this, (double) f);
|
|
|
|
if (entityhuman != null) {
|
|
this.bu = entityhuman;
|
|
this.g = 10 + this.random.nextInt(20);
|
|
} else {
|
|
this.bf = (this.random.nextFloat() - 0.5F) * 20.0F;
|
|
}
|
|
}
|
|
|
|
if (this.bu != null) {
|
|
this.a(this.bu, 10.0F, (float) this.bv());
|
|
if (this.g-- <= 0 || this.bu.dead || this.bu.f((Entity) this) > (double) (f * f)) {
|
|
this.bu = null;
|
|
}
|
|
} else {
|
|
if (this.random.nextFloat() < 0.05F) {
|
|
this.bf = (this.random.nextFloat() - 0.5F) * 20.0F;
|
|
}
|
|
|
|
this.yaw += this.bf;
|
|
this.pitch = this.f;
|
|
}
|
|
|
|
boolean flag = this.L();
|
|
boolean flag1 = this.O();
|
|
|
|
if (flag || flag1) {
|
|
this.bc = this.random.nextFloat() < 0.8F;
|
|
}
|
|
}
|
|
|
|
public int bv() {
|
|
return 40;
|
|
}
|
|
|
|
public void a(Entity entity, float f, float f1) {
|
|
double d0 = entity.locX - this.locX;
|
|
double d1 = entity.locZ - this.locZ;
|
|
double d2;
|
|
|
|
if (entity instanceof EntityLiving) {
|
|
EntityLiving entityliving = (EntityLiving) entity;
|
|
|
|
d2 = entityliving.locY + (double) entityliving.getHeadHeight() - (this.locY + (double) this.getHeadHeight());
|
|
} else {
|
|
d2 = (entity.boundingBox.b + entity.boundingBox.e) / 2.0D - (this.locY + (double) this.getHeadHeight());
|
|
}
|
|
|
|
double d3 = (double) MathHelper.sqrt(d0 * d0 + d1 * d1);
|
|
float f2 = (float) (Math.atan2(d1, d0) * 180.0D / 3.1415927410125732D) - 90.0F;
|
|
float f3 = (float) (-(Math.atan2(d2, d3) * 180.0D / 3.1415927410125732D));
|
|
|
|
this.pitch = this.b(this.pitch, f3, f1);
|
|
this.yaw = this.b(this.yaw, f2, f);
|
|
}
|
|
|
|
private float b(float f, float f1, float f2) {
|
|
float f3 = MathHelper.g(f1 - f);
|
|
|
|
if (f3 > f2) {
|
|
f3 = f2;
|
|
}
|
|
|
|
if (f3 < -f2) {
|
|
f3 = -f2;
|
|
}
|
|
|
|
return f + f3;
|
|
}
|
|
|
|
public boolean canSpawn() {
|
|
return this.world.b(this.boundingBox) && this.world.getCubes(this, this.boundingBox).isEmpty() && !this.world.containsLiquid(this.boundingBox);
|
|
}
|
|
|
|
public int bB() {
|
|
return 4;
|
|
}
|
|
|
|
public int aw() {
|
|
if (this.getGoalTarget() == null) {
|
|
return 3;
|
|
} else {
|
|
int i = (int) (this.getHealth() - this.getMaxHealth() * 0.33F);
|
|
|
|
i -= (3 - this.world.difficulty.a()) * 4;
|
|
if (i < 0) {
|
|
i = 0;
|
|
}
|
|
|
|
return i + 3;
|
|
}
|
|
}
|
|
|
|
public ItemStack bd() {
|
|
return this.equipment[0];
|
|
}
|
|
|
|
public ItemStack getEquipment(int i) {
|
|
return this.equipment[i];
|
|
}
|
|
|
|
public ItemStack r(int i) {
|
|
return this.equipment[i + 1];
|
|
}
|
|
|
|
public void setEquipment(int i, ItemStack itemstack) {
|
|
this.equipment[i] = itemstack;
|
|
}
|
|
|
|
public ItemStack[] getEquipment() {
|
|
return this.equipment;
|
|
}
|
|
|
|
protected void dropEquipment(boolean flag, int i) {
|
|
for (int j = 0; j < this.getEquipment().length; ++j) {
|
|
ItemStack itemstack = this.getEquipment(j);
|
|
boolean flag1 = this.dropChances[j] > 1.0F;
|
|
|
|
if (itemstack != null && (flag || flag1) && this.random.nextFloat() - (float) i * 0.01F < this.dropChances[j]) {
|
|
if (!flag1 && itemstack.g()) {
|
|
int k = Math.max(itemstack.l() - 25, 1);
|
|
int l = itemstack.l() - this.random.nextInt(this.random.nextInt(k) + 1);
|
|
|
|
if (l > k) {
|
|
l = k;
|
|
}
|
|
|
|
if (l < 1) {
|
|
l = 1;
|
|
}
|
|
|
|
itemstack.setData(l);
|
|
}
|
|
|
|
this.a(itemstack, 0.0F);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected void bC() {
|
|
if (this.random.nextFloat() < 0.15F * this.world.b(this.locX, this.locY, this.locZ)) {
|
|
int i = this.random.nextInt(2);
|
|
float f = this.world.difficulty == EnumDifficulty.HARD ? 0.1F : 0.25F;
|
|
|
|
if (this.random.nextFloat() < 0.095F) {
|
|
++i;
|
|
}
|
|
|
|
if (this.random.nextFloat() < 0.095F) {
|
|
++i;
|
|
}
|
|
|
|
if (this.random.nextFloat() < 0.095F) {
|
|
++i;
|
|
}
|
|
|
|
for (int j = 3; j >= 0; --j) {
|
|
ItemStack itemstack = this.r(j);
|
|
|
|
if (j < 3 && this.random.nextFloat() < f) {
|
|
break;
|
|
}
|
|
|
|
if (itemstack == null) {
|
|
Item item = a(j + 1, i);
|
|
|
|
if (item != null) {
|
|
this.setEquipment(j + 1, new ItemStack(item));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static int b(ItemStack itemstack) {
|
|
if (itemstack.getItem() != Item.getItemOf(Blocks.PUMPKIN) && itemstack.getItem() != Items.SKULL) {
|
|
if (itemstack.getItem() instanceof ItemArmor) {
|
|
switch (((ItemArmor) itemstack.getItem()).b) {
|
|
case 0:
|
|
return 4;
|
|
|
|
case 1:
|
|
return 3;
|
|
|
|
case 2:
|
|
return 2;
|
|
|
|
case 3:
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
} else {
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
public static Item a(int i, int j) {
|
|
switch (i) {
|
|
case 4:
|
|
if (j == 0) {
|
|
return Items.LEATHER_HELMET;
|
|
} else if (j == 1) {
|
|
return Items.GOLD_HELMET;
|
|
} else if (j == 2) {
|
|
return Items.CHAINMAIL_HELMET;
|
|
} else if (j == 3) {
|
|
return Items.IRON_HELMET;
|
|
} else if (j == 4) {
|
|
return Items.DIAMOND_HELMET;
|
|
}
|
|
|
|
case 3:
|
|
if (j == 0) {
|
|
return Items.LEATHER_CHESTPLATE;
|
|
} else if (j == 1) {
|
|
return Items.GOLD_CHESTPLATE;
|
|
} else if (j == 2) {
|
|
return Items.CHAINMAIL_CHESTPLATE;
|
|
} else if (j == 3) {
|
|
return Items.IRON_CHESTPLATE;
|
|
} else if (j == 4) {
|
|
return Items.DIAMOND_CHESTPLATE;
|
|
}
|
|
|
|
case 2:
|
|
if (j == 0) {
|
|
return Items.LEATHER_LEGGINGS;
|
|
} else if (j == 1) {
|
|
return Items.GOLD_LEGGINGS;
|
|
} else if (j == 2) {
|
|
return Items.CHAINMAIL_LEGGINGS;
|
|
} else if (j == 3) {
|
|
return Items.IRON_LEGGINGS;
|
|
} else if (j == 4) {
|
|
return Items.DIAMOND_LEGGINGS;
|
|
}
|
|
|
|
case 1:
|
|
if (j == 0) {
|
|
return Items.LEATHER_BOOTS;
|
|
} else if (j == 1) {
|
|
return Items.GOLD_BOOTS;
|
|
} else if (j == 2) {
|
|
return Items.CHAINMAIL_BOOTS;
|
|
} else if (j == 3) {
|
|
return Items.IRON_BOOTS;
|
|
} else if (j == 4) {
|
|
return Items.DIAMOND_BOOTS;
|
|
}
|
|
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
protected void bD() {
|
|
float f = this.world.b(this.locX, this.locY, this.locZ);
|
|
|
|
if (this.bd() != null && this.random.nextFloat() < 0.25F * f) {
|
|
EnchantmentManager.a(this.random, this.bd(), (int) (5.0F + f * (float) this.random.nextInt(18)));
|
|
}
|
|
|
|
for (int i = 0; i < 4; ++i) {
|
|
ItemStack itemstack = this.r(i);
|
|
|
|
if (itemstack != null && this.random.nextFloat() < 0.5F * f) {
|
|
EnchantmentManager.a(this.random, itemstack, (int) (5.0F + f * (float) this.random.nextInt(18)));
|
|
}
|
|
}
|
|
}
|
|
|
|
public GroupDataEntity a(GroupDataEntity groupdataentity) {
|
|
this.getAttributeInstance(GenericAttributes.b).a(new AttributeModifier("Random spawn bonus", this.random.nextGaussian() * 0.05D, 1));
|
|
return groupdataentity;
|
|
}
|
|
|
|
public boolean bE() {
|
|
return false;
|
|
}
|
|
|
|
public String getName() {
|
|
return this.hasCustomName() ? this.getCustomName() : super.getName();
|
|
}
|
|
|
|
public void bF() {
|
|
this.persistent = true;
|
|
}
|
|
|
|
public void setCustomName(String s) {
|
|
this.datawatcher.watch(10, s);
|
|
}
|
|
|
|
public String getCustomName() {
|
|
return this.datawatcher.getString(10);
|
|
}
|
|
|
|
public boolean hasCustomName() {
|
|
return this.datawatcher.getString(10).length() > 0;
|
|
}
|
|
|
|
public void setCustomNameVisible(boolean flag) {
|
|
this.datawatcher.watch(11, Byte.valueOf((byte) (flag ? 1 : 0)));
|
|
}
|
|
|
|
public boolean getCustomNameVisible() {
|
|
return this.datawatcher.getByte(11) == 1;
|
|
}
|
|
|
|
public void a(int i, float f) {
|
|
this.dropChances[i] = f;
|
|
}
|
|
|
|
public boolean bJ() {
|
|
return this.canPickUpLoot;
|
|
}
|
|
|
|
public void h(boolean flag) {
|
|
this.canPickUpLoot = flag;
|
|
}
|
|
|
|
public boolean isPersistent() {
|
|
return this.persistent;
|
|
}
|
|
|
|
public final boolean c(EntityHuman entityhuman) {
|
|
if (this.bN() && this.getLeashHolder() == entityhuman) {
|
|
// CraftBukkit start - fire PlayerUnleashEntityEvent
|
|
if (CraftEventFactory.callPlayerUnleashEntityEvent(this, entityhuman).isCancelled()) {
|
|
((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutAttachEntity(1, this, this.getLeashHolder()));
|
|
return false;
|
|
}
|
|
// CraftBukkit end
|
|
this.unleash(true, !entityhuman.abilities.canInstantlyBuild);
|
|
return true;
|
|
} else {
|
|
ItemStack itemstack = entityhuman.inventory.getItemInHand();
|
|
|
|
if (itemstack != null && itemstack.getItem() == Items.LEASH && this.bM()) {
|
|
if (!(this instanceof EntityTameableAnimal) || !((EntityTameableAnimal) this).isTamed()) {
|
|
// CraftBukkit start - fire PlayerLeashEntityEvent
|
|
if (CraftEventFactory.callPlayerLeashEntityEvent(this, entityhuman, entityhuman).isCancelled()) {
|
|
((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutAttachEntity(1, this, this.getLeashHolder()));
|
|
return false;
|
|
}
|
|
// CraftBukkit end
|
|
this.setLeashHolder(entityhuman, true);
|
|
--itemstack.count;
|
|
return true;
|
|
}
|
|
|
|
if (((EntityTameableAnimal) this).e(entityhuman)) {
|
|
// CraftBukkit start - fire PlayerLeashEntityEvent
|
|
if (CraftEventFactory.callPlayerLeashEntityEvent(this, entityhuman, entityhuman).isCancelled()) {
|
|
((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutAttachEntity(1, this, this.getLeashHolder()));
|
|
return false;
|
|
}
|
|
// CraftBukkit end
|
|
this.setLeashHolder(entityhuman, true);
|
|
--itemstack.count;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return this.a(entityhuman) ? true : super.c(entityhuman);
|
|
}
|
|
}
|
|
|
|
protected boolean a(EntityHuman entityhuman) {
|
|
return false;
|
|
}
|
|
|
|
protected void bL() {
|
|
if (this.bx != null) {
|
|
this.bP();
|
|
}
|
|
|
|
if (this.bv) {
|
|
if (this.bw == null || this.bw.dead) {
|
|
this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.HOLDER_GONE)); // CraftBukkit
|
|
this.unleash(true, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void unleash(boolean flag, boolean flag1) {
|
|
if (this.bv) {
|
|
this.bv = false;
|
|
this.bw = null;
|
|
if (!this.world.isStatic && flag1) {
|
|
this.a(Items.LEASH, 1);
|
|
}
|
|
|
|
if (!this.world.isStatic && flag && this.world instanceof WorldServer) {
|
|
((WorldServer) this.world).getTracker().a((Entity) this, (Packet) (new PacketPlayOutAttachEntity(1, this, (Entity) null)));
|
|
}
|
|
}
|
|
}
|
|
|
|
public boolean bM() {
|
|
return !this.bN() && !(this instanceof IMonster);
|
|
}
|
|
|
|
public boolean bN() {
|
|
return this.bv;
|
|
}
|
|
|
|
public Entity getLeashHolder() {
|
|
return this.bw;
|
|
}
|
|
|
|
public void setLeashHolder(Entity entity, boolean flag) {
|
|
this.bv = true;
|
|
this.bw = entity;
|
|
if (!this.world.isStatic && flag && this.world instanceof WorldServer) {
|
|
((WorldServer) this.world).getTracker().a((Entity) this, (Packet) (new PacketPlayOutAttachEntity(1, this, this.bw)));
|
|
}
|
|
}
|
|
|
|
private void bP() {
|
|
if (this.bv && this.bx != null) {
|
|
if (this.bx.hasKeyOfType("UUIDMost", 4) && this.bx.hasKeyOfType("UUIDLeast", 4)) {
|
|
UUID uuid = new UUID(this.bx.getLong("UUIDMost"), this.bx.getLong("UUIDLeast"));
|
|
List list = this.world.a(EntityLiving.class, this.boundingBox.grow(10.0D, 10.0D, 10.0D));
|
|
Iterator iterator = list.iterator();
|
|
|
|
while (iterator.hasNext()) {
|
|
EntityLiving entityliving = (EntityLiving) iterator.next();
|
|
|
|
if (entityliving.getUniqueID().equals(uuid)) {
|
|
this.bw = entityliving;
|
|
break;
|
|
}
|
|
}
|
|
} else if (this.bx.hasKeyOfType("X", 99) && this.bx.hasKeyOfType("Y", 99) && this.bx.hasKeyOfType("Z", 99)) {
|
|
int i = this.bx.getInt("X");
|
|
int j = this.bx.getInt("Y");
|
|
int k = this.bx.getInt("Z");
|
|
EntityLeash entityleash = EntityLeash.b(this.world, i, j, k);
|
|
|
|
if (entityleash == null) {
|
|
entityleash = EntityLeash.a(this.world, i, j, k);
|
|
}
|
|
|
|
this.bw = entityleash;
|
|
} else {
|
|
this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.UNKNOWN)); // CraftBukkit
|
|
this.unleash(false, true);
|
|
}
|
|
}
|
|
|
|
this.bx = null;
|
|
}
|
|
}
|