1313 lines
45 KiB
Java
1313 lines
45 KiB
Java
package net.minecraft.server;
|
|
|
|
import com.google.common.collect.Maps;
|
|
import java.util.Arrays;
|
|
import java.util.Collection;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Random;
|
|
import java.util.UUID;
|
|
import javax.annotation.Nullable;
|
|
|
|
// CraftBukkit start
|
|
import org.bukkit.craftbukkit.event.CraftEventFactory;
|
|
import org.bukkit.craftbukkit.entity.CraftLivingEntity;
|
|
import org.bukkit.entity.LivingEntity;
|
|
import org.bukkit.event.entity.EntityCombustByEntityEvent;
|
|
import org.bukkit.event.entity.EntityPickupItemEvent;
|
|
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);
|
|
public int a_;
|
|
protected int b_;
|
|
protected ControllerLook lookController;
|
|
protected ControllerMove moveController;
|
|
protected ControllerJump h;
|
|
private final EntityAIBodyControl b;
|
|
protected NavigationAbstract navigation;
|
|
public PathfinderGoalSelector goalSelector;
|
|
@Nullable public PathfinderGoalFloat goalFloat; // Paper
|
|
public PathfinderGoalSelector targetSelector;
|
|
private EntityLiving goalTarget;
|
|
private final EntitySenses bC;
|
|
private final NonNullList<ItemStack> bD;
|
|
public float[] dropChanceHand;
|
|
private final NonNullList<ItemStack> bE;
|
|
public float[] dropChanceArmor;
|
|
// public boolean canPickUpLoot; // CraftBukkit - moved up to EntityLiving
|
|
public boolean persistent;
|
|
private final Map<PathType, Float> bH;
|
|
public MinecraftKey lootTableKey;
|
|
public long lootTableSeed;
|
|
private boolean bK;
|
|
private Entity leashHolder;
|
|
private NBTTagCompound bM;
|
|
|
|
protected EntityInsentient(EntityTypes<?> entitytypes, World world) {
|
|
super(entitytypes, world);
|
|
this.bD = NonNullList.a(2, ItemStack.a);
|
|
this.dropChanceHand = new float[2];
|
|
this.bE = NonNullList.a(4, ItemStack.a);
|
|
this.dropChanceArmor = new float[4];
|
|
this.bH = Maps.newEnumMap(PathType.class);
|
|
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.h = new ControllerJump(this);
|
|
this.b = this.o();
|
|
this.navigation = this.b(world);
|
|
this.bC = new EntitySenses(this);
|
|
Arrays.fill(this.dropChanceArmor, 0.085F);
|
|
Arrays.fill(this.dropChanceHand, 0.085F);
|
|
if (world != null && !world.isClientSide) {
|
|
this.n();
|
|
}
|
|
|
|
// CraftBukkit start - default persistance to type's persistance value
|
|
this.persistent = !isTypeNotPersistent();
|
|
// CraftBukkit end
|
|
}
|
|
|
|
protected void n() {}
|
|
|
|
protected void initAttributes() {
|
|
super.initAttributes();
|
|
this.getAttributeMap().b(GenericAttributes.FOLLOW_RANGE).setValue(16.0D);
|
|
}
|
|
|
|
protected NavigationAbstract b(World world) {
|
|
return new Navigation(this, world);
|
|
}
|
|
|
|
public float a(PathType pathtype) {
|
|
Float ofloat = (Float) this.bH.get(pathtype);
|
|
|
|
return ofloat == null ? pathtype.a() : ofloat;
|
|
}
|
|
|
|
public void a(PathType pathtype, float f) {
|
|
this.bH.put(pathtype, f);
|
|
}
|
|
|
|
protected EntityAIBodyControl o() {
|
|
return new EntityAIBodyControl(this);
|
|
}
|
|
|
|
public ControllerLook getControllerLook() {
|
|
return this.lookController;
|
|
}
|
|
|
|
// Paper start
|
|
@Override
|
|
public void inactiveTick() {
|
|
super.inactiveTick();
|
|
this.goalSelector.inactiveTick();
|
|
if (this.targetSelector.inactiveTick()) {
|
|
this.targetSelector.doTick();
|
|
}
|
|
}
|
|
// Paper end
|
|
|
|
public ControllerMove getControllerMove() {
|
|
return this.moveController;
|
|
}
|
|
|
|
public ControllerJump getControllerJump() {
|
|
return this.h;
|
|
}
|
|
|
|
public NavigationAbstract getNavigation() {
|
|
return this.navigation;
|
|
}
|
|
|
|
public EntitySenses getEntitySenses() {
|
|
return this.bC;
|
|
}
|
|
|
|
@Nullable
|
|
public EntityLiving getGoalTarget() {
|
|
return this.goalTarget;
|
|
}
|
|
|
|
public org.bukkit.craftbukkit.entity.CraftMob getBukkitMob() { return (org.bukkit.craftbukkit.entity.CraftMob) super.getBukkitEntity(); } // Paper
|
|
public void setGoalTarget(@Nullable EntityLiving entityliving) {
|
|
// CraftBukkit start - fire event
|
|
setGoalTarget(entityliving, EntityTargetEvent.TargetReason.UNKNOWN, true);
|
|
}
|
|
|
|
public boolean setGoalTarget(EntityLiving entityliving, EntityTargetEvent.TargetReason reason, boolean fireEvent) {
|
|
if (getGoalTarget() == entityliving) return false;
|
|
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 false;
|
|
}
|
|
|
|
if (event.getTarget() != null) {
|
|
entityliving = ((CraftLivingEntity) event.getTarget()).getHandle();
|
|
} else {
|
|
entityliving = null;
|
|
}
|
|
}
|
|
this.goalTarget = entityliving;
|
|
return true;
|
|
// CraftBukkit end
|
|
}
|
|
|
|
public boolean b(Class<? extends EntityLiving> oclass) {
|
|
return oclass != EntityGhast.class;
|
|
}
|
|
|
|
public void x() {}
|
|
|
|
protected void x_() {
|
|
super.x_();
|
|
this.datawatcher.register(EntityInsentient.a, (byte) 0);
|
|
}
|
|
|
|
public int z() {
|
|
return 80;
|
|
}
|
|
|
|
public void A() {
|
|
SoundEffect soundeffect = this.D();
|
|
|
|
if (soundeffect != null) {
|
|
this.a(soundeffect, this.cD(), this.cE());
|
|
}
|
|
|
|
}
|
|
|
|
public void W() {
|
|
super.W();
|
|
this.world.methodProfiler.enter("mobBaseTick");
|
|
if (this.isAlive() && this.random.nextInt(1000) < this.a_++) {
|
|
this.l();
|
|
this.A();
|
|
}
|
|
|
|
this.world.methodProfiler.exit();
|
|
}
|
|
|
|
protected void c(DamageSource damagesource) {
|
|
this.l();
|
|
super.c(damagesource);
|
|
}
|
|
|
|
private void l() {
|
|
this.a_ = -this.z();
|
|
}
|
|
|
|
protected int getExpValue(EntityHuman entityhuman) {
|
|
if (this.b_ > 0) {
|
|
int i = this.b_;
|
|
|
|
int j;
|
|
|
|
for (j = 0; j < this.bE.size(); ++j) {
|
|
if (!((ItemStack) this.bE.get(j)).isEmpty() && this.dropChanceArmor[j] <= 1.0F) {
|
|
i += 1 + this.random.nextInt(3);
|
|
}
|
|
}
|
|
|
|
for (j = 0; j < this.bD.size(); ++j) {
|
|
if (!((ItemStack) this.bD.get(j)).isEmpty() && this.dropChanceHand[j] <= 1.0F) {
|
|
i += 1 + this.random.nextInt(3);
|
|
}
|
|
}
|
|
|
|
return i;
|
|
} else {
|
|
return this.b_;
|
|
}
|
|
}
|
|
|
|
public void doSpawnEffect() {
|
|
if (this.world.isClientSide) {
|
|
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(Particles.J, this.locX + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width - d0 * 10.0D, this.locY + (double) (this.random.nextFloat() * this.length) - d1 * 10.0D, this.locZ + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width - d2 * 10.0D, d0, d1, d2);
|
|
}
|
|
} else {
|
|
this.world.broadcastEntityEffect(this, (byte) 20);
|
|
}
|
|
|
|
}
|
|
|
|
public void tick() {
|
|
super.tick();
|
|
if (!this.world.isClientSide) {
|
|
this.dl();
|
|
if (this.ticksLived % 5 == 0) {
|
|
boolean flag = !(this.bO() instanceof EntityInsentient);
|
|
boolean flag1 = !(this.getVehicle() instanceof EntityBoat);
|
|
|
|
this.goalSelector.a(1, flag);
|
|
this.goalSelector.a(4, flag && flag1);
|
|
this.goalSelector.a(2, flag);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
protected float e(float f, float f1) {
|
|
this.b.a();
|
|
return f1;
|
|
}
|
|
|
|
@Nullable
|
|
protected SoundEffect D() {
|
|
return null;
|
|
}
|
|
|
|
@Nullable
|
|
protected Item getLoot() {
|
|
return null;
|
|
}
|
|
|
|
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((IMaterial) item);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
public void b(NBTTagCompound nbttagcompound) {
|
|
super.b(nbttagcompound);
|
|
nbttagcompound.setBoolean("CanPickUpLoot", this.dj());
|
|
nbttagcompound.setBoolean("PersistenceRequired", this.persistent);
|
|
NBTTagList nbttaglist = new NBTTagList();
|
|
|
|
NBTTagCompound nbttagcompound1;
|
|
|
|
for (Iterator iterator = this.bE.iterator(); iterator.hasNext(); nbttaglist.add((NBTBase) nbttagcompound1)) {
|
|
ItemStack itemstack = (ItemStack) iterator.next();
|
|
|
|
nbttagcompound1 = new NBTTagCompound();
|
|
if (!itemstack.isEmpty()) {
|
|
itemstack.save(nbttagcompound1);
|
|
}
|
|
}
|
|
|
|
nbttagcompound.set("ArmorItems", nbttaglist);
|
|
NBTTagList nbttaglist1 = new NBTTagList();
|
|
|
|
NBTTagCompound nbttagcompound2;
|
|
|
|
for (Iterator iterator1 = this.bD.iterator(); iterator1.hasNext(); nbttaglist1.add((NBTBase) nbttagcompound2)) {
|
|
ItemStack itemstack1 = (ItemStack) iterator1.next();
|
|
|
|
nbttagcompound2 = new NBTTagCompound();
|
|
if (!itemstack1.isEmpty()) {
|
|
itemstack1.save(nbttagcompound2);
|
|
}
|
|
}
|
|
|
|
nbttagcompound.set("HandItems", nbttaglist1);
|
|
NBTTagList nbttaglist2 = new NBTTagList();
|
|
float[] afloat = this.dropChanceArmor;
|
|
int i = afloat.length;
|
|
|
|
int j;
|
|
|
|
for (j = 0; j < i; ++j) {
|
|
float f = afloat[j];
|
|
|
|
nbttaglist2.add((NBTBase) (new NBTTagFloat(f)));
|
|
}
|
|
|
|
nbttagcompound.set("ArmorDropChances", nbttaglist2);
|
|
NBTTagList nbttaglist3 = new NBTTagList();
|
|
float[] afloat1 = this.dropChanceHand;
|
|
|
|
j = afloat1.length;
|
|
|
|
for (int k = 0; k < j; ++k) {
|
|
float f1 = afloat1[k];
|
|
|
|
nbttaglist3.add((NBTBase) (new NBTTagFloat(f1)));
|
|
}
|
|
|
|
nbttagcompound.set("HandDropChances", nbttaglist3);
|
|
nbttagcompound.setBoolean("Leashed", this.bK);
|
|
if (this.leashHolder != null) {
|
|
nbttagcompound2 = new NBTTagCompound();
|
|
if (this.leashHolder instanceof EntityLiving) {
|
|
UUID uuid = this.leashHolder.getUniqueID();
|
|
|
|
nbttagcompound2.a("UUID", uuid);
|
|
} else if (this.leashHolder instanceof EntityHanging) {
|
|
BlockPosition blockposition = ((EntityHanging) this.leashHolder).getBlockPosition();
|
|
|
|
nbttagcompound2.setInt("X", blockposition.getX());
|
|
nbttagcompound2.setInt("Y", blockposition.getY());
|
|
nbttagcompound2.setInt("Z", blockposition.getZ());
|
|
}
|
|
|
|
nbttagcompound.set("Leash", nbttagcompound2);
|
|
}
|
|
|
|
nbttagcompound.setBoolean("LeftHanded", this.isLeftHanded());
|
|
if (this.lootTableKey != null) {
|
|
nbttagcompound.setString("DeathLootTable", this.lootTableKey.toString());
|
|
if (this.lootTableSeed != 0L) {
|
|
nbttagcompound.setLong("DeathLootTableSeed", this.lootTableSeed);
|
|
}
|
|
}
|
|
|
|
if (this.isNoAI()) {
|
|
nbttagcompound.setBoolean("NoAI", this.isNoAI());
|
|
}
|
|
|
|
}
|
|
|
|
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)) {
|
|
boolean data = nbttagcompound.getBoolean("CanPickUpLoot");
|
|
if (isLevelAtLeast(nbttagcompound, 1) || data) {
|
|
this.p(data);
|
|
}
|
|
}
|
|
|
|
boolean data = nbttagcompound.getBoolean("PersistenceRequired");
|
|
if (isLevelAtLeast(nbttagcompound, 1) || data) {
|
|
this.persistent = data;
|
|
}
|
|
// CraftBukkit end
|
|
NBTTagList nbttaglist;
|
|
int i;
|
|
|
|
if (nbttagcompound.hasKeyOfType("ArmorItems", 9)) {
|
|
nbttaglist = nbttagcompound.getList("ArmorItems", 10);
|
|
|
|
for (i = 0; i < this.bE.size(); ++i) {
|
|
this.bE.set(i, ItemStack.a(nbttaglist.getCompound(i)));
|
|
}
|
|
}
|
|
|
|
if (nbttagcompound.hasKeyOfType("HandItems", 9)) {
|
|
nbttaglist = nbttagcompound.getList("HandItems", 10);
|
|
|
|
for (i = 0; i < this.bD.size(); ++i) {
|
|
this.bD.set(i, ItemStack.a(nbttaglist.getCompound(i)));
|
|
}
|
|
}
|
|
|
|
if (nbttagcompound.hasKeyOfType("ArmorDropChances", 9)) {
|
|
nbttaglist = nbttagcompound.getList("ArmorDropChances", 5);
|
|
|
|
for (i = 0; i < nbttaglist.size(); ++i) {
|
|
this.dropChanceArmor[i] = nbttaglist.l(i);
|
|
}
|
|
}
|
|
|
|
if (nbttagcompound.hasKeyOfType("HandDropChances", 9)) {
|
|
nbttaglist = nbttagcompound.getList("HandDropChances", 5);
|
|
|
|
for (i = 0; i < nbttaglist.size(); ++i) {
|
|
this.dropChanceHand[i] = nbttaglist.l(i);
|
|
}
|
|
}
|
|
|
|
this.bK = nbttagcompound.getBoolean("Leashed");
|
|
if (this.bK && nbttagcompound.hasKeyOfType("Leash", 10)) {
|
|
this.bM = nbttagcompound.getCompound("Leash");
|
|
}
|
|
|
|
this.r(nbttagcompound.getBoolean("LeftHanded"));
|
|
if (nbttagcompound.hasKeyOfType("DeathLootTable", 8)) {
|
|
this.lootTableKey = new MinecraftKey(nbttagcompound.getString("DeathLootTable"));
|
|
this.lootTableSeed = nbttagcompound.getLong("DeathLootTableSeed");
|
|
}
|
|
|
|
this.setNoAI(nbttagcompound.getBoolean("NoAI"));
|
|
}
|
|
|
|
@Nullable
|
|
protected MinecraftKey getDefaultLootTable() {
|
|
return null;
|
|
}
|
|
// CraftBukkit - start
|
|
public MinecraftKey getLootTable() {
|
|
return getDefaultLootTable();
|
|
}
|
|
// CraftBukkit - end
|
|
|
|
protected void a(boolean flag, int i, DamageSource damagesource) {
|
|
MinecraftKey minecraftkey = this.lootTableKey;
|
|
|
|
if (minecraftkey == null) {
|
|
minecraftkey = this.getDefaultLootTable();
|
|
}
|
|
|
|
if (minecraftkey != null) {
|
|
LootTable loottable = this.world.getMinecraftServer().getLootTableRegistry().getLootTable(minecraftkey);
|
|
|
|
this.lootTableKey = null;
|
|
LootTableInfo.Builder loottableinfo_builder = (new LootTableInfo.Builder((WorldServer) this.world)).entity(this).damageSource(damagesource).position(new BlockPosition(this));
|
|
|
|
if (flag && this.killer != null) {
|
|
loottableinfo_builder = loottableinfo_builder.killer(this.killer).luck(this.killer.dJ());
|
|
}
|
|
|
|
Collection<ItemStack> collection = loottable.populateLoot(this.lootTableSeed == 0L ? this.random : new Random(this.lootTableSeed), loottableinfo_builder.build());
|
|
Iterator iterator = collection.iterator();
|
|
|
|
while (iterator.hasNext()) {
|
|
ItemStack itemstack = (ItemStack) iterator.next();
|
|
|
|
this.a_(itemstack);
|
|
}
|
|
|
|
this.dropEquipment(flag, i);
|
|
} else {
|
|
super.a(flag, i, damagesource);
|
|
}
|
|
|
|
}
|
|
|
|
public void r(float f) {
|
|
this.bj = f;
|
|
}
|
|
|
|
public void s(float f) {
|
|
this.bi = f;
|
|
}
|
|
|
|
public void t(float f) {
|
|
this.bh = f;
|
|
}
|
|
|
|
public void o(float f) {
|
|
super.o(f);
|
|
this.r(f);
|
|
}
|
|
|
|
public void movementTick() {
|
|
super.movementTick();
|
|
this.world.methodProfiler.enter("looting");
|
|
if (!this.world.isClientSide && this.dj() && !this.killed && this.world.getGameRules().getBoolean("mobGriefing")) {
|
|
List<EntityItem> list = this.world.a(EntityItem.class, this.getBoundingBox().grow(1.0D, 0.0D, 1.0D));
|
|
Iterator iterator = list.iterator();
|
|
|
|
while (iterator.hasNext()) {
|
|
EntityItem entityitem = (EntityItem) iterator.next();
|
|
|
|
if (!entityitem.dead && !entityitem.getItemStack().isEmpty() && !entityitem.q()) {
|
|
// Paper Start
|
|
if (!entityitem.canMobPickup) {
|
|
continue;
|
|
}
|
|
// Paper End
|
|
this.a(entityitem);
|
|
}
|
|
}
|
|
}
|
|
|
|
this.world.methodProfiler.exit();
|
|
}
|
|
|
|
protected void a(EntityItem entityitem) {
|
|
ItemStack itemstack = entityitem.getItemStack();
|
|
EnumItemSlot enumitemslot = e(itemstack);
|
|
ItemStack itemstack1 = this.getEquipment(enumitemslot);
|
|
boolean flag = this.a(itemstack, itemstack1, enumitemslot);
|
|
|
|
// CraftBukkit start
|
|
boolean canPickup = flag && this.d(itemstack);
|
|
|
|
EntityPickupItemEvent entityEvent = new EntityPickupItemEvent((LivingEntity) getBukkitEntity(), (org.bukkit.entity.Item) entityitem.getBukkitEntity(), 0);
|
|
entityEvent.setCancelled(!canPickup);
|
|
this.world.getServer().getPluginManager().callEvent(entityEvent);
|
|
canPickup = !entityEvent.isCancelled();
|
|
if (canPickup) {
|
|
// CraftBukkit end
|
|
double d0 = (double) this.c(enumitemslot);
|
|
|
|
if (!itemstack1.isEmpty() && (double) (this.random.nextFloat() - 0.1F) < d0) {
|
|
this.forceDrops = true; // CraftBukkit
|
|
this.a_(itemstack1);
|
|
this.forceDrops = false; // CraftBukkit
|
|
}
|
|
|
|
this.setSlot(enumitemslot, itemstack);
|
|
switch (enumitemslot.a()) {
|
|
case HAND:
|
|
this.dropChanceHand[enumitemslot.b()] = 2.0F;
|
|
break;
|
|
case ARMOR:
|
|
this.dropChanceArmor[enumitemslot.b()] = 2.0F;
|
|
}
|
|
|
|
this.persistent = true;
|
|
this.receive(entityitem, itemstack.getCount());
|
|
entityitem.die();
|
|
}
|
|
|
|
}
|
|
|
|
protected boolean a(ItemStack itemstack, ItemStack itemstack1, EnumItemSlot enumitemslot) {
|
|
boolean flag = true;
|
|
|
|
if (!itemstack1.isEmpty()) {
|
|
if (enumitemslot.a() == EnumItemSlot.Function.HAND) {
|
|
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.d() == itemsword1.d()) {
|
|
flag = itemstack.getDamage() < itemstack1.getDamage() || itemstack.hasTag() && !itemstack1.hasTag();
|
|
} else {
|
|
flag = itemsword.d() > itemsword1.d();
|
|
}
|
|
} else if (itemstack.getItem() instanceof ItemBow && itemstack1.getItem() instanceof ItemBow) {
|
|
flag = itemstack.hasTag() && !itemstack1.hasTag();
|
|
} 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 && !EnchantmentManager.d(itemstack1)) {
|
|
ItemArmor itemarmor = (ItemArmor) itemstack.getItem();
|
|
ItemArmor itemarmor1 = (ItemArmor) itemstack1.getItem();
|
|
|
|
if (itemarmor.e() == itemarmor1.e()) {
|
|
flag = itemstack.getDamage() < itemstack1.getDamage() || itemstack.hasTag() && !itemstack1.hasTag();
|
|
} else {
|
|
flag = itemarmor.e() > itemarmor1.e();
|
|
}
|
|
} else {
|
|
flag = false;
|
|
}
|
|
}
|
|
|
|
return flag;
|
|
}
|
|
|
|
protected boolean d(ItemStack itemstack) {
|
|
return true;
|
|
}
|
|
|
|
public boolean isTypeNotPersistent() {
|
|
return true;
|
|
}
|
|
|
|
protected void I() {
|
|
if (this.persistent) {
|
|
this.ticksFarFromPlayer = 0;
|
|
} else {
|
|
Chunk currentChunk = getChunkAtLocation(); // Paper
|
|
if (currentChunk != null && currentChunk.scheduledForUnload != null) return; // Paper
|
|
EntityHuman entityhuman = this.world.findNearbyPlayer(this, -1.0D);
|
|
|
|
if (entityhuman != null && entityhuman.affectsSpawning) { // Paper - Affects Spawning API
|
|
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 > world.paperConfig.hardDespawnDistance) { // CraftBukkit - remove isTypeNotPersistent() check // Paper - custom despawn distances
|
|
this.die();
|
|
}
|
|
|
|
if (this.ticksFarFromPlayer > 600 && this.random.nextInt(800) == 0 && d3 > world.paperConfig.softDespawnDistance) { // CraftBukkit - remove isTypeNotPersistent() check // Paper - custom despawn distances
|
|
this.die();
|
|
} else if (d3 < world.paperConfig.softDespawnDistance) { // Paper - custom despawn distances
|
|
this.ticksFarFromPlayer = 0;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
protected final void doTick() {
|
|
++this.ticksFarFromPlayer;
|
|
this.world.methodProfiler.enter("checkDespawn");
|
|
this.I();
|
|
this.world.methodProfiler.exit();
|
|
// Spigot Start
|
|
if ( this.fromMobSpawner )
|
|
{
|
|
// Paper start - Allow nerfed mobs to jump and float
|
|
if (goalFloat != null) {
|
|
if (goalFloat.validConditions()) goalFloat.update();
|
|
this.getControllerJump().jumpIfSet();
|
|
}
|
|
// Paper end
|
|
return;
|
|
}
|
|
// Spigot End
|
|
this.world.methodProfiler.enter("sensing");
|
|
this.bC.a();
|
|
this.world.methodProfiler.exit();
|
|
this.world.methodProfiler.enter("targetSelector");
|
|
this.targetSelector.doTick();
|
|
this.world.methodProfiler.exit();
|
|
this.world.methodProfiler.enter("goalSelector");
|
|
this.goalSelector.doTick();
|
|
this.world.methodProfiler.exit();
|
|
this.world.methodProfiler.enter("navigation");
|
|
this.navigation.d();
|
|
this.world.methodProfiler.exit();
|
|
this.world.methodProfiler.enter("mob tick");
|
|
this.mobTick();
|
|
this.world.methodProfiler.exit();
|
|
if (this.isPassenger() && this.getVehicle() instanceof EntityInsentient) {
|
|
EntityInsentient entityinsentient = (EntityInsentient) this.getVehicle();
|
|
|
|
entityinsentient.getNavigation().a(this.getNavigation().m(), 1.5D);
|
|
entityinsentient.getControllerMove().a(this.getControllerMove());
|
|
}
|
|
|
|
this.world.methodProfiler.enter("controls");
|
|
this.world.methodProfiler.enter("move");
|
|
this.moveController.a();
|
|
this.world.methodProfiler.exitEnter("look");
|
|
this.lookController.a();
|
|
this.world.methodProfiler.exitEnter("jump");
|
|
this.h.b();
|
|
this.world.methodProfiler.exit();
|
|
this.world.methodProfiler.exit();
|
|
}
|
|
|
|
protected void mobTick() {}
|
|
|
|
public int K() {
|
|
return 40;
|
|
}
|
|
|
|
public int L() {
|
|
return 10;
|
|
}
|
|
|
|
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.getBoundingBox().minY + entity.getBoundingBox().maxY) / 2.0D - (this.locY + (double) this.getHeadHeight());
|
|
}
|
|
|
|
double d3 = (double) MathHelper.sqrt(d0 * d0 + d1 * d1);
|
|
float f2 = (float) (MathHelper.c(d1, d0) * 57.2957763671875D) - 90.0F;
|
|
float f3 = (float) (-(MathHelper.c(d2, d3) * 57.2957763671875D));
|
|
|
|
this.pitch = this.c(this.pitch, f3, f1);
|
|
this.yaw = this.c(this.yaw, f2, f);
|
|
}
|
|
|
|
private float c(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 a(GeneratorAccess generatoraccess, boolean flag) {
|
|
IBlockData iblockdata = generatoraccess.getType((new BlockPosition(this)).down());
|
|
|
|
return iblockdata.a((Entity) this);
|
|
}
|
|
|
|
public final boolean canSpawn() {
|
|
return this.a((IWorldReader) this.world);
|
|
}
|
|
|
|
public boolean a(IWorldReader iworldreader) {
|
|
return !iworldreader.containsLiquid(this.getBoundingBox()) && iworldreader.getCubes(this, this.getBoundingBox()) && iworldreader.a_(this, this.getBoundingBox());
|
|
}
|
|
|
|
public int dg() {
|
|
return 4;
|
|
}
|
|
|
|
public boolean c(int i) {
|
|
return false;
|
|
}
|
|
|
|
public int bn() {
|
|
if (this.getGoalTarget() == null) {
|
|
return 3;
|
|
} else {
|
|
int i = (int) (this.getHealth() - this.getMaxHealth() * 0.33F);
|
|
|
|
i -= (3 - this.world.getDifficulty().a()) * 4;
|
|
if (i < 0) {
|
|
i = 0;
|
|
}
|
|
|
|
return i + 3;
|
|
}
|
|
}
|
|
|
|
public Iterable<ItemStack> aS() {
|
|
return this.bD;
|
|
}
|
|
|
|
public Iterable<ItemStack> getArmorItems() {
|
|
return this.bE;
|
|
}
|
|
|
|
public ItemStack getEquipment(EnumItemSlot enumitemslot) {
|
|
switch (enumitemslot.a()) {
|
|
case HAND:
|
|
return (ItemStack) this.bD.get(enumitemslot.b());
|
|
case ARMOR:
|
|
return (ItemStack) this.bE.get(enumitemslot.b());
|
|
default:
|
|
return ItemStack.a;
|
|
}
|
|
}
|
|
|
|
public void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack) {
|
|
switch (enumitemslot.a()) {
|
|
case HAND:
|
|
this.bD.set(enumitemslot.b(), itemstack);
|
|
break;
|
|
case ARMOR:
|
|
this.bE.set(enumitemslot.b(), itemstack);
|
|
}
|
|
|
|
}
|
|
|
|
protected void dropEquipment(boolean flag, int i) {
|
|
EnumItemSlot[] aenumitemslot = EnumItemSlot.values();
|
|
int j = aenumitemslot.length;
|
|
|
|
for (int k = 0; k < j; ++k) {
|
|
EnumItemSlot enumitemslot = aenumitemslot[k];
|
|
ItemStack itemstack = this.getEquipment(enumitemslot);
|
|
float f = this.c(enumitemslot);
|
|
boolean flag1 = f > 1.0F;
|
|
|
|
if (!itemstack.isEmpty() && !EnchantmentManager.shouldNotDrop(itemstack) && (flag || flag1) && this.random.nextFloat() - (float) i * 0.01F < f) {
|
|
if (!flag1 && itemstack.e()) {
|
|
itemstack.setDamage(itemstack.h() - this.random.nextInt(1 + this.random.nextInt(Math.max(itemstack.h() - 3, 1))));
|
|
}
|
|
|
|
this.a_(itemstack);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
protected float c(EnumItemSlot enumitemslot) {
|
|
float f;
|
|
|
|
switch (enumitemslot.a()) {
|
|
case HAND:
|
|
f = this.dropChanceHand[enumitemslot.b()];
|
|
break;
|
|
case ARMOR:
|
|
f = this.dropChanceArmor[enumitemslot.b()];
|
|
break;
|
|
default:
|
|
f = 0.0F;
|
|
}
|
|
|
|
return f;
|
|
}
|
|
|
|
protected void a(DifficultyDamageScaler difficultydamagescaler) {
|
|
if (this.random.nextFloat() < 0.15F * difficultydamagescaler.d()) {
|
|
int i = this.random.nextInt(2);
|
|
float f = this.world.getDifficulty() == 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;
|
|
}
|
|
|
|
boolean flag = true;
|
|
EnumItemSlot[] aenumitemslot = EnumItemSlot.values();
|
|
int j = aenumitemslot.length;
|
|
|
|
for (int k = 0; k < j; ++k) {
|
|
EnumItemSlot enumitemslot = aenumitemslot[k];
|
|
|
|
if (enumitemslot.a() == EnumItemSlot.Function.ARMOR) {
|
|
ItemStack itemstack = this.getEquipment(enumitemslot);
|
|
|
|
if (!flag && this.random.nextFloat() < f) {
|
|
break;
|
|
}
|
|
|
|
flag = false;
|
|
if (itemstack.isEmpty()) {
|
|
Item item = a(enumitemslot, i);
|
|
|
|
if (item != null) {
|
|
this.setSlot(enumitemslot, new ItemStack(item));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
public static EnumItemSlot e(ItemStack itemstack) {
|
|
Item item = itemstack.getItem();
|
|
|
|
return item != Blocks.CARVED_PUMPKIN.getItem() && (!(item instanceof ItemBlock) || !(((ItemBlock) item).getBlock() instanceof BlockSkullAbstract)) ? (item instanceof ItemArmor ? ((ItemArmor) item).b() : (item == Items.ELYTRA ? EnumItemSlot.CHEST : (item == Items.SHIELD ? EnumItemSlot.OFFHAND : EnumItemSlot.MAINHAND))) : EnumItemSlot.HEAD;
|
|
}
|
|
|
|
@Nullable
|
|
public static Item a(EnumItemSlot enumitemslot, int i) {
|
|
switch (enumitemslot) {
|
|
case HEAD:
|
|
if (i == 0) {
|
|
return Items.LEATHER_HELMET;
|
|
} else if (i == 1) {
|
|
return Items.GOLDEN_HELMET;
|
|
} else if (i == 2) {
|
|
return Items.CHAINMAIL_HELMET;
|
|
} else if (i == 3) {
|
|
return Items.IRON_HELMET;
|
|
} else if (i == 4) {
|
|
return Items.DIAMOND_HELMET;
|
|
}
|
|
case CHEST:
|
|
if (i == 0) {
|
|
return Items.LEATHER_CHESTPLATE;
|
|
} else if (i == 1) {
|
|
return Items.GOLDEN_CHESTPLATE;
|
|
} else if (i == 2) {
|
|
return Items.CHAINMAIL_CHESTPLATE;
|
|
} else if (i == 3) {
|
|
return Items.IRON_CHESTPLATE;
|
|
} else if (i == 4) {
|
|
return Items.DIAMOND_CHESTPLATE;
|
|
}
|
|
case LEGS:
|
|
if (i == 0) {
|
|
return Items.LEATHER_LEGGINGS;
|
|
} else if (i == 1) {
|
|
return Items.GOLDEN_LEGGINGS;
|
|
} else if (i == 2) {
|
|
return Items.CHAINMAIL_LEGGINGS;
|
|
} else if (i == 3) {
|
|
return Items.IRON_LEGGINGS;
|
|
} else if (i == 4) {
|
|
return Items.DIAMOND_LEGGINGS;
|
|
}
|
|
case FEET:
|
|
if (i == 0) {
|
|
return Items.LEATHER_BOOTS;
|
|
} else if (i == 1) {
|
|
return Items.GOLDEN_BOOTS;
|
|
} else if (i == 2) {
|
|
return Items.CHAINMAIL_BOOTS;
|
|
} else if (i == 3) {
|
|
return Items.IRON_BOOTS;
|
|
} else if (i == 4) {
|
|
return Items.DIAMOND_BOOTS;
|
|
}
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
protected void b(DifficultyDamageScaler difficultydamagescaler) {
|
|
float f = difficultydamagescaler.d();
|
|
|
|
if (!this.getItemInMainHand().isEmpty() && this.random.nextFloat() < 0.25F * f) {
|
|
this.setSlot(EnumItemSlot.MAINHAND, EnchantmentManager.a(this.random, this.getItemInMainHand(), (int) (5.0F + f * (float) this.random.nextInt(18)), false));
|
|
}
|
|
|
|
EnumItemSlot[] aenumitemslot = EnumItemSlot.values();
|
|
int i = aenumitemslot.length;
|
|
|
|
for (int j = 0; j < i; ++j) {
|
|
EnumItemSlot enumitemslot = aenumitemslot[j];
|
|
|
|
if (enumitemslot.a() == EnumItemSlot.Function.ARMOR) {
|
|
ItemStack itemstack = this.getEquipment(enumitemslot);
|
|
|
|
if (!itemstack.isEmpty() && this.random.nextFloat() < 0.5F * f) {
|
|
this.setSlot(enumitemslot, EnchantmentManager.a(this.random, itemstack, (int) (5.0F + f * (float) this.random.nextInt(18)), false));
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
@Nullable
|
|
public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) {
|
|
this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).b(new AttributeModifier("Random spawn bonus", this.random.nextGaussian() * 0.05D, 1));
|
|
if (this.random.nextFloat() < 0.05F) {
|
|
this.r(true);
|
|
} else {
|
|
this.r(false);
|
|
}
|
|
|
|
return groupdataentity;
|
|
}
|
|
|
|
public boolean dh() {
|
|
return false;
|
|
}
|
|
|
|
public void di() {
|
|
this.persistent = true;
|
|
}
|
|
|
|
public void a(EnumItemSlot enumitemslot, float f) {
|
|
switch (enumitemslot.a()) {
|
|
case HAND:
|
|
this.dropChanceHand[enumitemslot.b()] = f;
|
|
break;
|
|
case ARMOR:
|
|
this.dropChanceArmor[enumitemslot.b()] = f;
|
|
}
|
|
|
|
}
|
|
|
|
public boolean dj() {
|
|
return this.canPickUpLoot;
|
|
}
|
|
|
|
public void p(boolean flag) {
|
|
this.canPickUpLoot = flag;
|
|
}
|
|
|
|
public boolean isPersistent() {
|
|
return this.persistent;
|
|
}
|
|
|
|
public final boolean b(EntityHuman entityhuman, 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 {
|
|
ItemStack itemstack = entityhuman.b(enumhand);
|
|
|
|
if (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.subtract(1);
|
|
return true;
|
|
} else {
|
|
return this.a(entityhuman, enumhand) ? true : super.b(entityhuman, enumhand);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected boolean a(EntityHuman entityhuman, EnumHand enumhand) {
|
|
return false;
|
|
}
|
|
|
|
protected void dl() {
|
|
if (this.bM != null) {
|
|
this.dr();
|
|
}
|
|
|
|
if (this.bK) {
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void unleash(boolean flag, boolean flag1) {
|
|
if (this.bK) {
|
|
this.bK = false;
|
|
this.leashHolder = null;
|
|
if (!this.world.isClientSide && flag1) {
|
|
this.forceDrops = true; // CraftBukkit
|
|
this.a((IMaterial) Items.LEAD);
|
|
this.forceDrops = false; // CraftBukkit
|
|
}
|
|
|
|
if (!this.world.isClientSide && flag && this.world instanceof WorldServer) {
|
|
((WorldServer) this.world).getTracker().a((Entity) this, (Packet) (new PacketPlayOutAttachEntity(this, (Entity) null)));
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
public boolean a(EntityHuman entityhuman) {
|
|
return !this.isLeashed() && !(this instanceof IMonster);
|
|
}
|
|
|
|
public boolean isLeashed() {
|
|
return this.bK;
|
|
}
|
|
|
|
public Entity getLeashHolder() {
|
|
return this.leashHolder;
|
|
}
|
|
|
|
public void setLeashHolder(Entity entity, boolean flag) {
|
|
this.bK = true;
|
|
this.leashHolder = entity;
|
|
if (!this.world.isClientSide && flag && this.world instanceof WorldServer) {
|
|
((WorldServer) this.world).getTracker().a((Entity) this, (Packet) (new PacketPlayOutAttachEntity(this, this.leashHolder)));
|
|
}
|
|
|
|
if (this.isPassenger()) {
|
|
this.stopRiding();
|
|
}
|
|
|
|
}
|
|
|
|
public boolean a(Entity entity, boolean flag) {
|
|
boolean flag1 = super.a(entity, flag);
|
|
|
|
if (flag1 && this.isLeashed()) {
|
|
this.unleash(true, true);
|
|
}
|
|
|
|
return flag1;
|
|
}
|
|
|
|
private void dr() {
|
|
if (this.bK && this.bM != null) {
|
|
if (this.bM.b("UUID")) {
|
|
UUID uuid = this.bM.a("UUID");
|
|
List<EntityLiving> list = this.world.a(EntityLiving.class, this.getBoundingBox().g(10.0D));
|
|
Iterator iterator = list.iterator();
|
|
|
|
while (iterator.hasNext()) {
|
|
EntityLiving entityliving = (EntityLiving) iterator.next();
|
|
|
|
if (entityliving.getUniqueID().equals(uuid)) {
|
|
this.setLeashHolder(entityliving, true);
|
|
break;
|
|
}
|
|
}
|
|
} else if (this.bM.hasKeyOfType("X", 99) && this.bM.hasKeyOfType("Y", 99) && this.bM.hasKeyOfType("Z", 99)) {
|
|
BlockPosition blockposition = new BlockPosition(this.bM.getInt("X"), this.bM.getInt("Y"), this.bM.getInt("Z"));
|
|
EntityLeash entityleash = EntityLeash.b(this.world, blockposition);
|
|
|
|
if (entityleash == null) {
|
|
entityleash = EntityLeash.a(this.world, blockposition);
|
|
}
|
|
|
|
this.setLeashHolder(entityleash, true);
|
|
} else {
|
|
this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.UNKNOWN)); // CraftBukkit
|
|
this.unleash(false, true);
|
|
}
|
|
}
|
|
|
|
this.bM = null;
|
|
}
|
|
|
|
public boolean c(int i, ItemStack itemstack) {
|
|
EnumItemSlot enumitemslot;
|
|
|
|
if (i == 98) {
|
|
enumitemslot = EnumItemSlot.MAINHAND;
|
|
} else if (i == 99) {
|
|
enumitemslot = EnumItemSlot.OFFHAND;
|
|
} else if (i == 100 + EnumItemSlot.HEAD.b()) {
|
|
enumitemslot = EnumItemSlot.HEAD;
|
|
} else if (i == 100 + EnumItemSlot.CHEST.b()) {
|
|
enumitemslot = EnumItemSlot.CHEST;
|
|
} else if (i == 100 + EnumItemSlot.LEGS.b()) {
|
|
enumitemslot = EnumItemSlot.LEGS;
|
|
} else {
|
|
if (i != 100 + EnumItemSlot.FEET.b()) {
|
|
return false;
|
|
}
|
|
|
|
enumitemslot = EnumItemSlot.FEET;
|
|
}
|
|
|
|
if (!itemstack.isEmpty() && !b(enumitemslot, itemstack) && enumitemslot != EnumItemSlot.HEAD) {
|
|
return false;
|
|
} else {
|
|
this.setSlot(enumitemslot, itemstack);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public boolean bT() {
|
|
return this.dh() && super.bT();
|
|
}
|
|
|
|
public static boolean b(EnumItemSlot enumitemslot, ItemStack itemstack) {
|
|
EnumItemSlot enumitemslot1 = e(itemstack);
|
|
|
|
return enumitemslot1 == enumitemslot || enumitemslot1 == EnumItemSlot.MAINHAND && enumitemslot == EnumItemSlot.OFFHAND || enumitemslot1 == EnumItemSlot.OFFHAND && enumitemslot == EnumItemSlot.MAINHAND;
|
|
}
|
|
|
|
public boolean cP() {
|
|
return super.cP() && !this.isNoAI();
|
|
}
|
|
|
|
public void setNoAI(boolean flag) {
|
|
byte b0 = (Byte) this.datawatcher.get(EntityInsentient.a);
|
|
|
|
this.datawatcher.set(EntityInsentient.a, flag ? (byte) (b0 | 1) : (byte) (b0 & -2));
|
|
}
|
|
|
|
public void r(boolean flag) {
|
|
byte b0 = (Byte) this.datawatcher.get(EntityInsentient.a);
|
|
|
|
this.datawatcher.set(EntityInsentient.a, flag ? (byte) (b0 | 2) : (byte) (b0 & -3));
|
|
}
|
|
|
|
public boolean isNoAI() {
|
|
return ((Byte) this.datawatcher.get(EntityInsentient.a) & 1) != 0;
|
|
}
|
|
|
|
public boolean isLeftHanded() {
|
|
return ((Byte) this.datawatcher.get(EntityInsentient.a) & 2) != 0;
|
|
}
|
|
|
|
public EnumMainHand getMainHand() {
|
|
return this.isLeftHanded() ? EnumMainHand.LEFT : EnumMainHand.RIGHT;
|
|
}
|
|
|
|
public boolean B(Entity entity) {
|
|
float f = (float) this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).getValue();
|
|
int i = 0;
|
|
|
|
if (entity instanceof EntityLiving) {
|
|
f += EnchantmentManager.a(this.getItemInMainHand(), ((EntityLiving) entity).getMonsterType());
|
|
i += EnchantmentManager.b((EntityLiving) this);
|
|
}
|
|
|
|
boolean flag = entity.damageEntity(DamageSource.mobAttack(this), f);
|
|
|
|
if (flag) {
|
|
if (i > 0 && entity instanceof EntityLiving) {
|
|
((EntityLiving) entity).a(this, (float) i * 0.5F, (double) MathHelper.sin(this.yaw * 0.017453292F), (double) (-MathHelper.cos(this.yaw * 0.017453292F)));
|
|
this.motX *= 0.6D;
|
|
this.motZ *= 0.6D;
|
|
}
|
|
|
|
int j = EnchantmentManager.getFireAspectEnchantmentLevel(this);
|
|
|
|
if (j > 0) {
|
|
// CraftBukkit start - Call a combust event when somebody hits with a fire enchanted item
|
|
EntityCombustByEntityEvent combustEvent = new EntityCombustByEntityEvent(this.getBukkitEntity(), entity.getBukkitEntity(), j * 4);
|
|
org.bukkit.Bukkit.getPluginManager().callEvent(combustEvent);
|
|
|
|
if (!combustEvent.isCancelled()) {
|
|
entity.setOnFire(combustEvent.getDuration(), false);
|
|
}
|
|
// CraftBukkit end
|
|
}
|
|
|
|
if (entity instanceof EntityHuman) {
|
|
EntityHuman entityhuman = (EntityHuman) entity;
|
|
ItemStack itemstack = this.getItemInMainHand();
|
|
ItemStack itemstack1 = entityhuman.isHandRaised() ? entityhuman.cW() : ItemStack.a;
|
|
|
|
if (!itemstack.isEmpty() && !itemstack1.isEmpty() && itemstack.getItem() instanceof ItemAxe && itemstack1.getItem() == Items.SHIELD) {
|
|
float f1 = 0.25F + (float) EnchantmentManager.getDigSpeedEnchantmentLevel(this) * 0.05F;
|
|
|
|
if (this.random.nextFloat() < f1) {
|
|
entityhuman.getCooldownTracker().a(Items.SHIELD, 100);
|
|
this.world.broadcastEntityEffect(entityhuman, (byte) 30);
|
|
}
|
|
}
|
|
}
|
|
|
|
this.a((EntityLiving) this, entity);
|
|
}
|
|
|
|
return flag;
|
|
}
|
|
|
|
public boolean isInDaylight() { return dq(); } // Paper - OBFHELPER
|
|
protected boolean dq() {
|
|
if (this.world.L() && !this.world.isClientSide) {
|
|
float f = this.az();
|
|
BlockPosition blockposition = this.getVehicle() instanceof EntityBoat ? (new BlockPosition(this.locX, (double) Math.round(this.locY), this.locZ)).up() : new BlockPosition(this.locX, (double) Math.round(this.locY), this.locZ);
|
|
|
|
if (f > 0.5F && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.world.e(blockposition)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
protected void c(Tag<FluidType> tag) {
|
|
if (this.getNavigation().t()) {
|
|
super.c(tag);
|
|
} else {
|
|
this.motY += 0.30000001192092896D;
|
|
}
|
|
|
|
}
|
|
}
|