package net.minecraft.entity;

import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.ai.attributes.AttributeModifier;
import net.minecraft.entity.ai.attributes.BaseAttributeMap;
import net.minecraft.entity.ai.attributes.IAttribute;
import net.minecraft.entity.ai.attributes.IAttributeInstance;
import net.minecraft.entity.ai.attributes.ServersideAttributeMap;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.item.EntityXPOrb;
import net.minecraft.entity.monster.EntityZombie;
import net.minecraft.entity.passive.EntityPig;
import net.minecraft.entity.passive.EntityWolf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.projectile.EntityArrow;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemArmor;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagFloat;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTTagShort;
import net.minecraft.network.play.server.S04PacketEntityEquipment;
import net.minecraft.network.play.server.S0BPacketAnimation;
import net.minecraft.network.play.server.S0DPacketCollectItem;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.potion.PotionHelper;
import net.minecraft.scoreboard.Team;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.CombatTracker;
import net.minecraft.util.DamageSource;
import net.minecraft.util.IIcon;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.ForgeHooks;

public abstract class EntityLivingBase extends Entity
{
	private static final UUID sprintingSpeedBoostModifierUUID = UUID.fromString("662A6B8D-DA3E-4C1C-8813-96EA6097278D");
	private static final AttributeModifier sprintingSpeedBoostModifier = (new AttributeModifier(sprintingSpeedBoostModifierUUID, "Sprinting speed boost", 0.30000001192092896D, 2)).setSaved(false);
	private BaseAttributeMap attributeMap;
	private final CombatTracker _combatTracker = new CombatTracker(this);
	private final HashMap activePotionsMap = new HashMap();
	private final ItemStack[] previousEquipment = new ItemStack[5];
	public boolean isSwingInProgress;
	public int swingProgressInt;
	public int arrowHitTimer;
	public float prevHealth;
	public int hurtTime;
	public int maxHurtTime;
	public float attackedAtYaw;
	public int deathTime;
	public int attackTime;
	public float prevSwingProgress;
	public float swingProgress;
	public float prevLimbSwingAmount;
	public float limbSwingAmount;
	public float limbSwing;
	public int maxHurtResistantTime = 20;
	public float prevCameraPitch;
	public float cameraPitch;
	public float field_70769_ao;
	public float field_70770_ap;
	public float renderYawOffset;
	public float prevRenderYawOffset;
	public float rotationYawHead;
	public float prevRotationYawHead;
	public float jumpMovementFactor = 0.02F;
	protected EntityPlayer attackingPlayer;
	protected int recentlyHit;
	protected boolean dead;
	protected int entityAge;
	protected float field_70768_au;
	protected float field_110154_aX;
	protected float field_70764_aw;
	protected float field_70763_ax;
	protected float field_70741_aB;
	protected int scoreValue;
	protected float lastDamage;
	protected boolean isJumping;
	public float moveStrafing;
	public float moveForward;
	protected float randomYawVelocity;
	protected int newPosRotationIncrements;
	protected double newPosX;
	protected double newPosY;
	protected double newPosZ;
	protected double newRotationYaw;
	protected double newRotationPitch;
	private boolean potionsNeedUpdate = true;
	private EntityLivingBase entityLivingToAttack;
	private int revengeTimer;
	private EntityLivingBase lastAttacker;
	private int lastAttackerTime;
	private float landMovementFactor;
	private int jumpTicks;
	private float field_110151_bq;
	private static final String __OBFID = "CL_00001549";

	public EntityLivingBase(World par1World)
	{
		super(par1World);
		this.applyEntityAttributes();
		this.setHealth(this.getMaxHealth());
		this.preventEntitySpawning = true;
		this.field_70770_ap = (float)(Math.random() + 1.0D) * 0.01F;
		this.setPosition(this.posX, this.posY, this.posZ);
		this.field_70769_ao = (float)Math.random() * 12398.0F;
		this.rotationYaw = (float)(Math.random() * Math.PI * 2.0D);
		this.rotationYawHead = this.rotationYaw;
		this.stepHeight = 0.5F;
	}

	protected void entityInit()
	{
		this.dataWatcher.addObject(7, Integer.valueOf(0));
		this.dataWatcher.addObject(8, Byte.valueOf((byte)0));
		this.dataWatcher.addObject(9, Byte.valueOf((byte)0));
		this.dataWatcher.addObject(6, Float.valueOf(1.0F));
	}

	protected void applyEntityAttributes()
	{
		this.getAttributeMap().registerAttribute(SharedMonsterAttributes.maxHealth);
		this.getAttributeMap().registerAttribute(SharedMonsterAttributes.knockbackResistance);
		this.getAttributeMap().registerAttribute(SharedMonsterAttributes.movementSpeed);

		if (!this.isAIEnabled())
		{
			this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.10000000149011612D);
		}
	}

	protected void updateFallState(double par1, boolean par3)
	{
		if (!this.isInWater())
		{
			this.handleWaterMovement();
		}

		if (par3 && this.fallDistance > 0.0F)
		{
			int i = MathHelper.floor_double(this.posX);
			int j = MathHelper.floor_double(this.posY - 0.20000000298023224D - (double)this.yOffset);
			int k = MathHelper.floor_double(this.posZ);
			Block block = this.worldObj.getBlock(i, j, k);

			if (block.getMaterial() == Material.air)
			{
				int l = this.worldObj.getBlock(i, j - 1, k).getRenderType();

				if (l == 11 || l == 32 || l == 21)
				{
					block = this.worldObj.getBlock(i, j - 1, k);
				}
			}
			else if (!this.worldObj.isRemote && this.fallDistance > 3.0F)
			{
				this.worldObj.playAuxSFX(2006, i, j, k, MathHelper.ceiling_float_int(this.fallDistance - 3.0F));
			}

			block.onFallenUpon(this.worldObj, i, j, k, this, this.fallDistance);
		}

		super.updateFallState(par1, par3);
	}

	public boolean canBreatheUnderwater()
	{
		return false;
	}

	public void onEntityUpdate()
	{
		this.prevSwingProgress = this.swingProgress;
		super.onEntityUpdate();
		this.worldObj.theProfiler.startSection("livingEntityBaseTick");

		if (this.isEntityAlive() && this.isEntityInsideOpaqueBlock())
		{
			this.attackEntityFrom(DamageSource.inWall, 1.0F);
		}

		if (this.isImmuneToFire() || this.worldObj.isRemote)
		{
			this.extinguish();
		}

		boolean flag = this instanceof EntityPlayer && ((EntityPlayer)this).capabilities.disableDamage;

		if (this.isEntityAlive() && this.isInsideOfMaterial(Material.water))
		{
			if (!this.canBreatheUnderwater() && !this.isPotionActive(Potion.waterBreathing.id) && !flag)
			{
				this.setAir(this.decreaseAirSupply(this.getAir()));

				if (this.getAir() == -20)
				{
					this.setAir(0);

					for (int i = 0; i < 8; ++i)
					{
						float f = this.rand.nextFloat() - this.rand.nextFloat();
						float f1 = this.rand.nextFloat() - this.rand.nextFloat();
						float f2 = this.rand.nextFloat() - this.rand.nextFloat();
						this.worldObj.spawnParticle("bubble", this.posX + (double)f, this.posY + (double)f1, this.posZ + (double)f2, this.motionX, this.motionY, this.motionZ);
					}

					this.attackEntityFrom(DamageSource.drown, 2.0F);
				}
			}

			if (!this.worldObj.isRemote && this.isRiding() && this.ridingEntity != null && ridingEntity.shouldDismountInWater(this))
			{
				this.mountEntity((Entity)null);
			}
		}
		else
		{
			this.setAir(300);
		}

		if (this.isEntityAlive() && this.isWet())
		{
			this.extinguish();
		}

		this.prevCameraPitch = this.cameraPitch;

		if (this.attackTime > 0)
		{
			--this.attackTime;
		}

		if (this.hurtTime > 0)
		{
			--this.hurtTime;
		}

		if (this.hurtResistantTime > 0 && !(this instanceof EntityPlayerMP))
		{
			--this.hurtResistantTime;
		}

		if (this.getHealth() <= 0.0F)
		{
			this.onDeathUpdate();
		}

		if (this.recentlyHit > 0)
		{
			--this.recentlyHit;
		}
		else
		{
			this.attackingPlayer = null;
		}

		if (this.lastAttacker != null && !this.lastAttacker.isEntityAlive())
		{
			this.lastAttacker = null;
		}

		if (this.entityLivingToAttack != null)
		{
			if (!this.entityLivingToAttack.isEntityAlive())
			{
				this.setRevengeTarget((EntityLivingBase)null);
			}
			else if (this.ticksExisted - this.revengeTimer > 100)
			{
				this.setRevengeTarget((EntityLivingBase)null);
			}
		}

		this.updatePotionEffects();
		this.field_70763_ax = this.field_70764_aw;
		this.prevRenderYawOffset = this.renderYawOffset;
		this.prevRotationYawHead = this.rotationYawHead;
		this.prevRotationYaw = this.rotationYaw;
		this.prevRotationPitch = this.rotationPitch;
		this.worldObj.theProfiler.endSection();
	}

	public boolean isChild()
	{
		return false;
	}

	protected void onDeathUpdate()
	{
		++this.deathTime;

		if (this.deathTime == 20)
		{
			int i;

			if (!this.worldObj.isRemote && (this.recentlyHit > 0 || this.isPlayer()) && this.func_146066_aG() && this.worldObj.getGameRules().getGameRuleBooleanValue("doMobLoot"))
			{
				i = this.getExperiencePoints(this.attackingPlayer);

				while (i > 0)
				{
					int j = EntityXPOrb.getXPSplit(i);
					i -= j;
					this.worldObj.spawnEntityInWorld(new EntityXPOrb(this.worldObj, this.posX, this.posY, this.posZ, j));
				}
			}

			this.setDead();

			for (i = 0; i < 20; ++i)
			{
				double d2 = this.rand.nextGaussian() * 0.02D;
				double d0 = this.rand.nextGaussian() * 0.02D;
				double d1 = this.rand.nextGaussian() * 0.02D;
				this.worldObj.spawnParticle("explode", this.posX + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width, this.posY + (double)(this.rand.nextFloat() * this.height), this.posZ + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width, d2, d0, d1);
			}
		}
	}

	protected boolean func_146066_aG()
	{
		return !this.isChild();
	}

	protected int decreaseAirSupply(int par1)
	{
		int j = EnchantmentHelper.getRespiration(this);
		return j > 0 && this.rand.nextInt(j + 1) > 0 ? par1 : par1 - 1;
	}

	protected int getExperiencePoints(EntityPlayer par1EntityPlayer)
	{
		return 0;
	}

	protected boolean isPlayer()
	{
		return false;
	}

	public Random getRNG()
	{
		return this.rand;
	}

	public EntityLivingBase getAITarget()
	{
		return this.entityLivingToAttack;
	}

	public int func_142015_aE()
	{
		return this.revengeTimer;
	}

	public void setRevengeTarget(EntityLivingBase par1EntityLivingBase)
	{
		this.entityLivingToAttack = par1EntityLivingBase;
		this.revengeTimer = this.ticksExisted;
		ForgeHooks.onLivingSetAttackTarget(this, par1EntityLivingBase);
	}

	public EntityLivingBase getLastAttacker()
	{
		return this.lastAttacker;
	}

	public int getLastAttackerTime()
	{
		return this.lastAttackerTime;
	}

	public void setLastAttacker(Entity par1Entity)
	{
		if (par1Entity instanceof EntityLivingBase)
		{
			this.lastAttacker = (EntityLivingBase)par1Entity;
		}
		else
		{
			this.lastAttacker = null;
		}

		this.lastAttackerTime = this.ticksExisted;
	}

	public int getAge()
	{
		return this.entityAge;
	}

	public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
	{
		par1NBTTagCompound.setFloat("HealF", this.getHealth());
		par1NBTTagCompound.setShort("Health", (short)((int)Math.ceil((double)this.getHealth())));
		par1NBTTagCompound.setShort("HurtTime", (short)this.hurtTime);
		par1NBTTagCompound.setShort("DeathTime", (short)this.deathTime);
		par1NBTTagCompound.setShort("AttackTime", (short)this.attackTime);
		par1NBTTagCompound.setFloat("AbsorptionAmount", this.getAbsorptionAmount());
		ItemStack[] aitemstack = this.getLastActiveItems();
		int i = aitemstack.length;
		int j;
		ItemStack itemstack;

		for (j = 0; j < i; ++j)
		{
			itemstack = aitemstack[j];

			if (itemstack != null)
			{
				this.attributeMap.removeAttributeModifiers(itemstack.getAttributeModifiers());
			}
		}

		par1NBTTagCompound.setTag("Attributes", SharedMonsterAttributes.writeBaseAttributeMapToNBT(this.getAttributeMap()));
		aitemstack = this.getLastActiveItems();
		i = aitemstack.length;

		for (j = 0; j < i; ++j)
		{
			itemstack = aitemstack[j];

			if (itemstack != null)
			{
				this.attributeMap.applyAttributeModifiers(itemstack.getAttributeModifiers());
			}
		}

		if (!this.activePotionsMap.isEmpty())
		{
			NBTTagList nbttaglist = new NBTTagList();
			Iterator iterator = this.activePotionsMap.values().iterator();

			while (iterator.hasNext())
			{
				PotionEffect potioneffect = (PotionEffect)iterator.next();
				nbttaglist.appendTag(potioneffect.writeCustomPotionEffectToNBT(new NBTTagCompound()));
			}

			par1NBTTagCompound.setTag("ActiveEffects", nbttaglist);
		}
	}

	public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
	{
		this.setAbsorptionAmount(par1NBTTagCompound.getFloat("AbsorptionAmount"));

		if (par1NBTTagCompound.hasKey("Attributes", 9) && this.worldObj != null && !this.worldObj.isRemote)
		{
			SharedMonsterAttributes.func_151475_a(this.getAttributeMap(), par1NBTTagCompound.getTagList("Attributes", 10));
		}

		if (par1NBTTagCompound.hasKey("ActiveEffects", 9))
		{
			NBTTagList nbttaglist = par1NBTTagCompound.getTagList("ActiveEffects", 10);

			for (int i = 0; i < nbttaglist.tagCount(); ++i)
			{
				NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i);
				PotionEffect potioneffect = PotionEffect.readCustomPotionEffectFromNBT(nbttagcompound1);

				if (potioneffect != null)
				{
					this.activePotionsMap.put(Integer.valueOf(potioneffect.getPotionID()), potioneffect);
				}
			}
		}

		if (par1NBTTagCompound.hasKey("HealF", 99))
		{
			this.setHealth(par1NBTTagCompound.getFloat("HealF"));
		}
		else
		{
			NBTBase nbtbase = par1NBTTagCompound.getTag("Health");

			if (nbtbase == null)
			{
				this.setHealth(this.getMaxHealth());
			}
			else if (nbtbase.getId() == 5)
			{
				this.setHealth(((NBTTagFloat)nbtbase).func_150288_h());
			}
			else if (nbtbase.getId() == 2)
			{
				this.setHealth((float)((NBTTagShort)nbtbase).func_150289_e());
			}
		}

		this.hurtTime = par1NBTTagCompound.getShort("HurtTime");
		this.deathTime = par1NBTTagCompound.getShort("DeathTime");
		this.attackTime = par1NBTTagCompound.getShort("AttackTime");
	}

	protected void updatePotionEffects()
	{
		Iterator iterator = this.activePotionsMap.keySet().iterator();

		while (iterator.hasNext())
		{
			Integer integer = (Integer)iterator.next();
			PotionEffect potioneffect = (PotionEffect)this.activePotionsMap.get(integer);

			if (!potioneffect.onUpdate(this))
			{
				if (!this.worldObj.isRemote)
				{
					iterator.remove();
					this.onFinishedPotionEffect(potioneffect);
				}
			}
			else if (potioneffect.getDuration() % 600 == 0)
			{
				this.onChangedPotionEffect(potioneffect, false);
			}
		}

		int i;

		if (this.potionsNeedUpdate)
		{
			if (!this.worldObj.isRemote)
			{
				if (this.activePotionsMap.isEmpty())
				{
					this.dataWatcher.updateObject(8, Byte.valueOf((byte)0));
					this.dataWatcher.updateObject(7, Integer.valueOf(0));
					this.setInvisible(false);
				}
				else
				{
					i = PotionHelper.calcPotionLiquidColor(this.activePotionsMap.values());
					this.dataWatcher.updateObject(8, Byte.valueOf((byte)(PotionHelper.func_82817_b(this.activePotionsMap.values()) ? 1 : 0)));
					this.dataWatcher.updateObject(7, Integer.valueOf(i));
					this.setInvisible(this.isPotionActive(Potion.invisibility.id));
				}
			}

			this.potionsNeedUpdate = false;
		}

		i = this.dataWatcher.getWatchableObjectInt(7);
		boolean flag1 = this.dataWatcher.getWatchableObjectByte(8) > 0;

		if (i > 0)
		{
			boolean flag = false;

			if (!this.isInvisible())
			{
				flag = this.rand.nextBoolean();
			}
			else
			{
				flag = this.rand.nextInt(15) == 0;
			}

			if (flag1)
			{
				flag &= this.rand.nextInt(5) == 0;
			}

			if (flag && i > 0)
			{
				double d0 = (double)(i >> 16 & 255) / 255.0D;
				double d1 = (double)(i >> 8 & 255) / 255.0D;
				double d2 = (double)(i >> 0 & 255) / 255.0D;
				this.worldObj.spawnParticle(flag1 ? "mobSpellAmbient" : "mobSpell", this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height - (double)this.yOffset, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, d0, d1, d2);
			}
		}
	}

	public void clearActivePotions()
	{
		Iterator iterator = this.activePotionsMap.keySet().iterator();

		while (iterator.hasNext())
		{
			Integer integer = (Integer)iterator.next();
			PotionEffect potioneffect = (PotionEffect)this.activePotionsMap.get(integer);

			if (!this.worldObj.isRemote)
			{
				iterator.remove();
				this.onFinishedPotionEffect(potioneffect);
			}
		}
	}

	public Collection getActivePotionEffects()
	{
		return this.activePotionsMap.values();
	}

	public boolean isPotionActive(int par1)
	{
		return this.activePotionsMap.containsKey(Integer.valueOf(par1));
	}

	public boolean isPotionActive(Potion par1Potion)
	{
		return this.activePotionsMap.containsKey(Integer.valueOf(par1Potion.id));
	}

	public PotionEffect getActivePotionEffect(Potion par1Potion)
	{
		return (PotionEffect)this.activePotionsMap.get(Integer.valueOf(par1Potion.id));
	}

	public void addPotionEffect(PotionEffect par1PotionEffect)
	{
		if (this.isPotionApplicable(par1PotionEffect))
		{
			if (this.activePotionsMap.containsKey(Integer.valueOf(par1PotionEffect.getPotionID())))
			{
				((PotionEffect)this.activePotionsMap.get(Integer.valueOf(par1PotionEffect.getPotionID()))).combine(par1PotionEffect);
				this.onChangedPotionEffect((PotionEffect)this.activePotionsMap.get(Integer.valueOf(par1PotionEffect.getPotionID())), true);
			}
			else
			{
				this.activePotionsMap.put(Integer.valueOf(par1PotionEffect.getPotionID()), par1PotionEffect);
				this.onNewPotionEffect(par1PotionEffect);
			}
		}
	}

	public boolean isPotionApplicable(PotionEffect par1PotionEffect)
	{
		if (this.getCreatureAttribute() == EnumCreatureAttribute.UNDEAD)
		{
			int i = par1PotionEffect.getPotionID();

			if (i == Potion.regeneration.id || i == Potion.poison.id)
			{
				return false;
			}
		}

		return true;
	}

	public boolean isEntityUndead()
	{
		return this.getCreatureAttribute() == EnumCreatureAttribute.UNDEAD;
	}

	public void removePotionEffectClient(int par1)
	{
		this.activePotionsMap.remove(Integer.valueOf(par1));
	}

	public void removePotionEffect(int par1)
	{
		PotionEffect potioneffect = (PotionEffect)this.activePotionsMap.remove(Integer.valueOf(par1));

		if (potioneffect != null)
		{
			this.onFinishedPotionEffect(potioneffect);
		}
	}

	protected void onNewPotionEffect(PotionEffect par1PotionEffect)
	{
		this.potionsNeedUpdate = true;

		if (!this.worldObj.isRemote)
		{
			Potion.potionTypes[par1PotionEffect.getPotionID()].applyAttributesModifiersToEntity(this, this.getAttributeMap(), par1PotionEffect.getAmplifier());
		}
	}

	protected void onChangedPotionEffect(PotionEffect par1PotionEffect, boolean par2)
	{
		this.potionsNeedUpdate = true;

		if (par2 && !this.worldObj.isRemote)
		{
			Potion.potionTypes[par1PotionEffect.getPotionID()].removeAttributesModifiersFromEntity(this, this.getAttributeMap(), par1PotionEffect.getAmplifier());
			Potion.potionTypes[par1PotionEffect.getPotionID()].applyAttributesModifiersToEntity(this, this.getAttributeMap(), par1PotionEffect.getAmplifier());
		}
	}

	protected void onFinishedPotionEffect(PotionEffect par1PotionEffect)
	{
		this.potionsNeedUpdate = true;

		if (!this.worldObj.isRemote)
		{
			Potion.potionTypes[par1PotionEffect.getPotionID()].removeAttributesModifiersFromEntity(this, this.getAttributeMap(), par1PotionEffect.getAmplifier());
		}
	}

	public void heal(float par1)
	{
		float f1 = this.getHealth();

		if (f1 > 0.0F)
		{
			this.setHealth(f1 + par1);
		}
	}

	public final float getHealth()
	{
		return this.dataWatcher.getWatchableObjectFloat(6);
	}

	public void setHealth(float par1)
	{
		this.dataWatcher.updateObject(6, Float.valueOf(MathHelper.clamp_float(par1, 0.0F, this.getMaxHealth())));
	}

	public boolean attackEntityFrom(DamageSource par1DamageSource, float par2)
	{
		if (ForgeHooks.onLivingAttack(this, par1DamageSource, par2)) return false;
		if (this.isEntityInvulnerable())
		{
			return false;
		}
		else if (this.worldObj.isRemote)
		{
			return false;
		}
		else
		{
			this.entityAge = 0;

			if (this.getHealth() <= 0.0F)
			{
				return false;
			}
			else if (par1DamageSource.isFireDamage() && this.isPotionActive(Potion.fireResistance))
			{
				return false;
			}
			else
			{
				if ((par1DamageSource == DamageSource.anvil || par1DamageSource == DamageSource.fallingBlock) && this.getEquipmentInSlot(4) != null)
				{
					this.getEquipmentInSlot(4).damageItem((int)(par2 * 4.0F + this.rand.nextFloat() * par2 * 2.0F), this);
					par2 *= 0.75F;
				}

				this.limbSwingAmount = 1.5F;
				boolean flag = true;

				if ((float)this.hurtResistantTime > (float)this.maxHurtResistantTime / 2.0F)
				{
					if (par2 <= this.lastDamage)
					{
						return false;
					}

					this.damageEntity(par1DamageSource, par2 - this.lastDamage);
					this.lastDamage = par2;
					flag = false;
				}
				else
				{
					this.lastDamage = par2;
					this.prevHealth = this.getHealth();
					this.hurtResistantTime = this.maxHurtResistantTime;
					this.damageEntity(par1DamageSource, par2);
					this.hurtTime = this.maxHurtTime = 10;
				}

				this.attackedAtYaw = 0.0F;
				Entity entity = par1DamageSource.getEntity();

				if (entity != null)
				{
					if (entity instanceof EntityLivingBase)
					{
						this.setRevengeTarget((EntityLivingBase)entity);
					}

					if (entity instanceof EntityPlayer)
					{
						this.recentlyHit = 100;
						this.attackingPlayer = (EntityPlayer)entity;
					}
					else if (entity instanceof net.minecraft.entity.passive.EntityTameable)
					{
						net.minecraft.entity.passive.EntityTameable entitywolf = (net.minecraft.entity.passive.EntityTameable)entity;

						if (entitywolf.isTamed())
						{
							this.recentlyHit = 100;
							this.attackingPlayer = null;
						}
					}
				}

				if (flag)
				{
					this.worldObj.setEntityState(this, (byte)2);

					if (par1DamageSource != DamageSource.drown)
					{
						this.setBeenAttacked();
					}

					if (entity != null)
					{
						double d1 = entity.posX - this.posX;
						double d0;

						for (d0 = entity.posZ - this.posZ; d1 * d1 + d0 * d0 < 1.0E-4D; d0 = (Math.random() - Math.random()) * 0.01D)
						{
							d1 = (Math.random() - Math.random()) * 0.01D;
						}

						this.attackedAtYaw = (float)(Math.atan2(d0, d1) * 180.0D / Math.PI) - this.rotationYaw;
						this.knockBack(entity, par2, d1, d0);
					}
					else
					{
						this.attackedAtYaw = (float)((int)(Math.random() * 2.0D) * 180);
					}
				}

				String s;

				if (this.getHealth() <= 0.0F)
				{
					s = this.getDeathSound();

					if (flag && s != null)
					{
						this.playSound(s, this.getSoundVolume(), this.getSoundPitch());
					}

					this.onDeath(par1DamageSource);
				}
				else
				{
					s = this.getHurtSound();

					if (flag && s != null)
					{
						this.playSound(s, this.getSoundVolume(), this.getSoundPitch());
					}
				}

				return true;
			}
		}
	}

	public void renderBrokenItemStack(ItemStack par1ItemStack)
	{
		this.playSound("random.break", 0.8F, 0.8F + this.worldObj.rand.nextFloat() * 0.4F);

		for (int i = 0; i < 5; ++i)
		{
			Vec3 vec3 = this.worldObj.getWorldVec3Pool().getVecFromPool(((double)this.rand.nextFloat() - 0.5D) * 0.1D, Math.random() * 0.1D + 0.1D, 0.0D);
			vec3.rotateAroundX(-this.rotationPitch * (float)Math.PI / 180.0F);
			vec3.rotateAroundY(-this.rotationYaw * (float)Math.PI / 180.0F);
			Vec3 vec31 = this.worldObj.getWorldVec3Pool().getVecFromPool(((double)this.rand.nextFloat() - 0.5D) * 0.3D, (double)(-this.rand.nextFloat()) * 0.6D - 0.3D, 0.6D);
			vec31.rotateAroundX(-this.rotationPitch * (float)Math.PI / 180.0F);
			vec31.rotateAroundY(-this.rotationYaw * (float)Math.PI / 180.0F);
			vec31 = vec31.addVector(this.posX, this.posY + (double)this.getEyeHeight(), this.posZ);
			this.worldObj.spawnParticle("iconcrack_" + Item.getIdFromItem(par1ItemStack.getItem()), vec31.xCoord, vec31.yCoord, vec31.zCoord, vec3.xCoord, vec3.yCoord + 0.05D, vec3.zCoord);
		}
	}

	public void onDeath(DamageSource par1DamageSource)
	{
		if (ForgeHooks.onLivingDeath(this, par1DamageSource)) return;
		Entity entity = par1DamageSource.getEntity();
		EntityLivingBase entitylivingbase = this.func_94060_bK();

		if (this.scoreValue >= 0 && entitylivingbase != null)
		{
			entitylivingbase.addToPlayerScore(this, this.scoreValue);
		}

		if (entity != null)
		{
			entity.onKillEntity(this);
		}

		this.dead = true;

		if (!this.worldObj.isRemote)
		{
			int i = 0;

			if (entity instanceof EntityPlayer)
			{
				i = EnchantmentHelper.getLootingModifier((EntityLivingBase)entity);
			}

			captureDrops = true;
			capturedDrops.clear();
			int j = 0;

			if (this.func_146066_aG() && this.worldObj.getGameRules().getGameRuleBooleanValue("doMobLoot"))
			{
				this.dropFewItems(this.recentlyHit > 0, i);
				this.dropEquipment(this.recentlyHit > 0, i);

				if (this.recentlyHit > 0)
				{
					j = this.rand.nextInt(200) - i;

					if (j < 5)
					{
						this.dropRareDrop(j <= 0 ? 1 : 0);
					}
				}
			}

			captureDrops = false;

			if (!ForgeHooks.onLivingDrops(this, par1DamageSource, capturedDrops, i, recentlyHit > 0, j))
			{
				for (EntityItem item : capturedDrops)
				{
					worldObj.spawnEntityInWorld(item);
				}
			}
		}

		this.worldObj.setEntityState(this, (byte)3);
	}

	protected void dropEquipment(boolean par1, int par2) {}

	public void knockBack(Entity par1Entity, float par2, double par3, double par5)
	{
		if (this.rand.nextDouble() >= this.getEntityAttribute(SharedMonsterAttributes.knockbackResistance).getAttributeValue())
		{
			this.isAirBorne = true;
			float f1 = MathHelper.sqrt_double(par3 * par3 + par5 * par5);
			float f2 = 0.4F;
			this.motionX /= 2.0D;
			this.motionY /= 2.0D;
			this.motionZ /= 2.0D;
			this.motionX -= par3 / (double)f1 * (double)f2;
			this.motionY += (double)f2;
			this.motionZ -= par5 / (double)f1 * (double)f2;

			if (this.motionY > 0.4000000059604645D)
			{
				this.motionY = 0.4000000059604645D;
			}
		}
	}

	protected String getHurtSound()
	{
		return "game.neutral.hurt";
	}

	protected String getDeathSound()
	{
		return "game.neutral.die";
	}

	protected void dropRareDrop(int par1) {}

	protected void dropFewItems(boolean par1, int par2) {}

	public boolean isOnLadder()
	{
		int i = MathHelper.floor_double(this.posX);
		int j = MathHelper.floor_double(this.boundingBox.minY);
		int k = MathHelper.floor_double(this.posZ);
		Block block = this.worldObj.getBlock(i, j, k);
		return ForgeHooks.isLivingOnLadder(block, worldObj, i, j, k, this);
	}

	public boolean isEntityAlive()
	{
		return !this.isDead && this.getHealth() > 0.0F;
	}

	protected void fall(float par1)
	{
		par1 = ForgeHooks.onLivingFall(this, par1);
		if (par1 <= 0) return;
		super.fall(par1);
		PotionEffect potioneffect = this.getActivePotionEffect(Potion.jump);
		float f1 = potioneffect != null ? (float)(potioneffect.getAmplifier() + 1) : 0.0F;
		int i = MathHelper.ceiling_float_int(par1 - 3.0F - f1);

		if (i > 0)
		{
			this.playSound(this.func_146067_o(i), 1.0F, 1.0F);
			this.attackEntityFrom(DamageSource.fall, (float)i);
			int j = MathHelper.floor_double(this.posX);
			int k = MathHelper.floor_double(this.posY - 0.20000000298023224D - (double)this.yOffset);
			int l = MathHelper.floor_double(this.posZ);
			Block block = this.worldObj.getBlock(j, k, l);

			if (block.getMaterial() != Material.air)
			{
				Block.SoundType soundtype = block.stepSound;
				this.playSound(soundtype.getStepResourcePath(), soundtype.getVolume() * 0.5F, soundtype.getPitch() * 0.75F);
			}
		}
	}

	protected String func_146067_o(int p_146067_1_)
	{
		return p_146067_1_ > 4 ? "game.neutral.hurt.fall.big" : "game.neutral.hurt.fall.small";
	}

	@SideOnly(Side.CLIENT)
	public void performHurtAnimation()
	{
		this.hurtTime = this.maxHurtTime = 10;
		this.attackedAtYaw = 0.0F;
	}

	public int getTotalArmorValue()
	{
		int i = 0;
		ItemStack[] aitemstack = this.getLastActiveItems();
		int j = aitemstack.length;

		for (int k = 0; k < j; ++k)
		{
			ItemStack itemstack = aitemstack[k];

			if (itemstack != null && itemstack.getItem() instanceof ItemArmor)
			{
				int l = ((ItemArmor)itemstack.getItem()).damageReduceAmount;
				i += l;
			}
		}

		return i;
	}

	protected void damageArmor(float par1) {}

	protected float applyArmorCalculations(DamageSource par1DamageSource, float par2)
	{
		if (!par1DamageSource.isUnblockable())
		{
			int i = 25 - this.getTotalArmorValue();
			float f1 = par2 * (float)i;
			this.damageArmor(par2);
			par2 = f1 / 25.0F;
		}

		return par2;
	}

	protected float applyPotionDamageCalculations(DamageSource par1DamageSource, float par2)
	{
		if (par1DamageSource.isDamageAbsolute())
		{
			return par2;
		}
		else
		{
			if (this instanceof EntityZombie)
			{
				//par2 = par2; // Forge: Noop Warning
			}

			int i;
			int j;
			float f1;

			if (this.isPotionActive(Potion.resistance) && par1DamageSource != DamageSource.outOfWorld)
			{
				i = (this.getActivePotionEffect(Potion.resistance).getAmplifier() + 1) * 5;
				j = 25 - i;
				f1 = par2 * (float)j;
				par2 = f1 / 25.0F;
			}

			if (par2 <= 0.0F)
			{
				return 0.0F;
			}
			else
			{
				i = EnchantmentHelper.getEnchantmentModifierDamage(this.getLastActiveItems(), par1DamageSource);

				if (i > 20)
				{
					i = 20;
				}

				if (i > 0 && i <= 20)
				{
					j = 25 - i;
					f1 = par2 * (float)j;
					par2 = f1 / 25.0F;
				}

				return par2;
			}
		}
	}

	protected void damageEntity(DamageSource par1DamageSource, float par2)
	{
		if (!this.isEntityInvulnerable())
		{
			par2 = ForgeHooks.onLivingHurt(this, par1DamageSource, par2);
			if (par2 <= 0) return;
			par2 = this.applyArmorCalculations(par1DamageSource, par2);
			par2 = this.applyPotionDamageCalculations(par1DamageSource, par2);
			float f1 = par2;
			par2 = Math.max(par2 - this.getAbsorptionAmount(), 0.0F);
			this.setAbsorptionAmount(this.getAbsorptionAmount() - (f1 - par2));

			if (par2 != 0.0F)
			{
				float f2 = this.getHealth();
				this.setHealth(f2 - par2);
				this.func_110142_aN().func_94547_a(par1DamageSource, f2, par2);
				this.setAbsorptionAmount(this.getAbsorptionAmount() - par2);
			}
		}
	}

	public CombatTracker func_110142_aN()
	{
		return this._combatTracker;
	}

	public EntityLivingBase func_94060_bK()
	{
		return (EntityLivingBase)(this._combatTracker.func_94550_c() != null ? this._combatTracker.func_94550_c() : (this.attackingPlayer != null ? this.attackingPlayer : (this.entityLivingToAttack != null ? this.entityLivingToAttack : null)));
	}

	public final float getMaxHealth()
	{
		return (float)this.getEntityAttribute(SharedMonsterAttributes.maxHealth).getAttributeValue();
	}

	public final int getArrowCountInEntity()
	{
		return this.dataWatcher.getWatchableObjectByte(9);
	}

	public final void setArrowCountInEntity(int par1)
	{
		this.dataWatcher.updateObject(9, Byte.valueOf((byte)par1));
	}

	private int getArmSwingAnimationEnd()
	{
		return this.isPotionActive(Potion.digSpeed) ? 6 - (1 + this.getActivePotionEffect(Potion.digSpeed).getAmplifier()) * 1 : (this.isPotionActive(Potion.digSlowdown) ? 6 + (1 + this.getActivePotionEffect(Potion.digSlowdown).getAmplifier()) * 2 : 6);
	}

	public void swingItem()
	{
		ItemStack stack = this.getHeldItem();

		if (stack != null && stack.getItem() != null)
		{
			Item item = stack.getItem();
			if (item.onEntitySwing(this, stack))
			{
				return;
			}
		}

		if (!this.isSwingInProgress || this.swingProgressInt >= this.getArmSwingAnimationEnd() / 2 || this.swingProgressInt < 0)
		{
			this.swingProgressInt = -1;
			this.isSwingInProgress = true;

			if (this.worldObj instanceof WorldServer)
			{
				((WorldServer)this.worldObj).getEntityTracker().func_151247_a(this, new S0BPacketAnimation(this, 0));
			}
		}
	}

	@SideOnly(Side.CLIENT)
	public void handleHealthUpdate(byte par1)
	{
		if (par1 == 2)
		{
			this.limbSwingAmount = 1.5F;
			this.hurtResistantTime = this.maxHurtResistantTime;
			this.hurtTime = this.maxHurtTime = 10;
			this.attackedAtYaw = 0.0F;
			this.playSound(this.getHurtSound(), this.getSoundVolume(), (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
			this.attackEntityFrom(DamageSource.generic, 0.0F);
		}
		else if (par1 == 3)
		{
			this.playSound(this.getDeathSound(), this.getSoundVolume(), (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
			this.setHealth(0.0F);
			this.onDeath(DamageSource.generic);
		}
		else
		{
			super.handleHealthUpdate(par1);
		}
	}

	protected void kill()
	{
		this.attackEntityFrom(DamageSource.outOfWorld, 4.0F);
	}

	protected void updateArmSwingProgress()
	{
		int i = this.getArmSwingAnimationEnd();

		if (this.isSwingInProgress)
		{
			++this.swingProgressInt;

			if (this.swingProgressInt >= i)
			{
				this.swingProgressInt = 0;
				this.isSwingInProgress = false;
			}
		}
		else
		{
			this.swingProgressInt = 0;
		}

		this.swingProgress = (float)this.swingProgressInt / (float)i;
	}

	public IAttributeInstance getEntityAttribute(IAttribute par1Attribute)
	{
		return this.getAttributeMap().getAttributeInstance(par1Attribute);
	}

	public BaseAttributeMap getAttributeMap()
	{
		if (this.attributeMap == null)
		{
			this.attributeMap = new ServersideAttributeMap();
		}

		return this.attributeMap;
	}

	public EnumCreatureAttribute getCreatureAttribute()
	{
		return EnumCreatureAttribute.UNDEFINED;
	}

	public abstract ItemStack getHeldItem();

	public abstract ItemStack getEquipmentInSlot(int var1);

	public abstract void setCurrentItemOrArmor(int var1, ItemStack var2);

	public void setSprinting(boolean par1)
	{
		super.setSprinting(par1);
		IAttributeInstance iattributeinstance = this.getEntityAttribute(SharedMonsterAttributes.movementSpeed);

		if (iattributeinstance.getModifier(sprintingSpeedBoostModifierUUID) != null)
		{
			iattributeinstance.removeModifier(sprintingSpeedBoostModifier);
		}

		if (par1)
		{
			iattributeinstance.applyModifier(sprintingSpeedBoostModifier);
		}
	}

	public abstract ItemStack[] getLastActiveItems();

	protected float getSoundVolume()
	{
		return 1.0F;
	}

	protected float getSoundPitch()
	{
		return this.isChild() ? (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.5F : (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F;
	}

	protected boolean isMovementBlocked()
	{
		return this.getHealth() <= 0.0F;
	}

	public void setPositionAndUpdate(double par1, double par3, double par5)
	{
		this.setLocationAndAngles(par1, par3, par5, this.rotationYaw, this.rotationPitch);
	}

	public void dismountEntity(Entity par1Entity)
	{
		double d0 = par1Entity.posX;
		double d1 = par1Entity.boundingBox.minY + (double)par1Entity.height;
		double d2 = par1Entity.posZ;
		byte b0 = 3;

		for (int i = -b0; i <= b0; ++i)
		{
			for (int j = -b0; j < b0; ++j)
			{
				if (i != 0 || j != 0)
				{
					int k = (int)(this.posX + (double)i);
					int l = (int)(this.posZ + (double)j);
					AxisAlignedBB axisalignedbb = this.boundingBox.getOffsetBoundingBox((double)i, 1.0D, (double)j);

					if (this.worldObj.func_147461_a(axisalignedbb).isEmpty())
					{
						if (World.doesBlockHaveSolidTopSurface(this.worldObj, k, (int)this.posY, l))
						{
							this.setPositionAndUpdate(this.posX + (double)i, this.posY + 1.0D, this.posZ + (double)j);
							return;
						}

						if (World.doesBlockHaveSolidTopSurface(this.worldObj, k, (int)this.posY - 1, l) || this.worldObj.getBlock(k, (int)this.posY - 1, l).getMaterial() == Material.water)
						{
							d0 = this.posX + (double)i;
							d1 = this.posY + 1.0D;
							d2 = this.posZ + (double)j;
						}
					}
				}
			}
		}

		this.setPositionAndUpdate(d0, d1, d2);
	}

	@SideOnly(Side.CLIENT)
	public boolean getAlwaysRenderNameTagForRender()
	{
		return false;
	}

	@SideOnly(Side.CLIENT)
	public IIcon getItemIcon(ItemStack par1ItemStack, int par2)
	{
		return par1ItemStack.getItem().requiresMultipleRenderPasses() ? par1ItemStack.getItem().getIconFromDamageForRenderPass(par1ItemStack.getItemDamage(), par2) : par1ItemStack.getIconIndex();
	}

	protected void jump()
	{
		this.motionY = 0.41999998688697815D;

		if (this.isPotionActive(Potion.jump))
		{
			this.motionY += (double)((float)(this.getActivePotionEffect(Potion.jump).getAmplifier() + 1) * 0.1F);
		}

		if (this.isSprinting())
		{
			float f = this.rotationYaw * 0.017453292F;
			this.motionX -= (double)(MathHelper.sin(f) * 0.2F);
			this.motionZ += (double)(MathHelper.cos(f) * 0.2F);
		}

		this.isAirBorne = true;
		ForgeHooks.onLivingJump(this);
	}

	public void moveEntityWithHeading(float par1, float par2)
	{
		double d0;

		if (this.isInWater() && (!(this instanceof EntityPlayer) || !((EntityPlayer)this).capabilities.isFlying))
		{
			d0 = this.posY;
			this.moveFlying(par1, par2, this.isAIEnabled() ? 0.04F : 0.02F);
			this.moveEntity(this.motionX, this.motionY, this.motionZ);
			this.motionX *= 0.800000011920929D;
			this.motionY *= 0.800000011920929D;
			this.motionZ *= 0.800000011920929D;
			this.motionY -= 0.02D;

			if (this.isCollidedHorizontally && this.isOffsetPositionInLiquid(this.motionX, this.motionY + 0.6000000238418579D - this.posY + d0, this.motionZ))
			{
				this.motionY = 0.30000001192092896D;
			}
		}
		else if (this.handleLavaMovement() && (!(this instanceof EntityPlayer) || !((EntityPlayer)this).capabilities.isFlying))
		{
			d0 = this.posY;
			this.moveFlying(par1, par2, 0.02F);
			this.moveEntity(this.motionX, this.motionY, this.motionZ);
			this.motionX *= 0.5D;
			this.motionY *= 0.5D;
			this.motionZ *= 0.5D;
			this.motionY -= 0.02D;

			if (this.isCollidedHorizontally && this.isOffsetPositionInLiquid(this.motionX, this.motionY + 0.6000000238418579D - this.posY + d0, this.motionZ))
			{
				this.motionY = 0.30000001192092896D;
			}
		}
		else
		{
			float f2 = 0.91F;

			if (this.onGround)
			{
				f2 = this.worldObj.getBlock(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.boundingBox.minY) - 1, MathHelper.floor_double(this.posZ)).slipperiness * 0.91F;
			}

			float f3 = 0.16277136F / (f2 * f2 * f2);
			float f4;

			if (this.onGround)
			{
				f4 = this.getAIMoveSpeed() * f3;
			}
			else
			{
				f4 = this.jumpMovementFactor;
			}

			this.moveFlying(par1, par2, f4);
			f2 = 0.91F;

			if (this.onGround)
			{
				f2 = this.worldObj.getBlock(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.boundingBox.minY) - 1, MathHelper.floor_double(this.posZ)).slipperiness * 0.91F;
			}

			if (this.isOnLadder())
			{
				float f5 = 0.15F;

				if (this.motionX < (double)(-f5))
				{
					this.motionX = (double)(-f5);
				}

				if (this.motionX > (double)f5)
				{
					this.motionX = (double)f5;
				}

				if (this.motionZ < (double)(-f5))
				{
					this.motionZ = (double)(-f5);
				}

				if (this.motionZ > (double)f5)
				{
					this.motionZ = (double)f5;
				}

				this.fallDistance = 0.0F;

				if (this.motionY < -0.15D)
				{
					this.motionY = -0.15D;
				}

				boolean flag = this.isSneaking() && this instanceof EntityPlayer;

				if (flag && this.motionY < 0.0D)
				{
					this.motionY = 0.0D;
				}
			}

			this.moveEntity(this.motionX, this.motionY, this.motionZ);

			if (this.isCollidedHorizontally && this.isOnLadder())
			{
				this.motionY = 0.2D;
			}

			if (this.worldObj.isRemote && (!this.worldObj.blockExists((int)this.posX, 0, (int)this.posZ) || !this.worldObj.getChunkFromBlockCoords((int)this.posX, (int)this.posZ).isChunkLoaded))
			{
				if (this.posY > 0.0D)
				{
					this.motionY = -0.1D;
				}
				else
				{
					this.motionY = 0.0D;
				}
			}
			else
			{
				this.motionY -= 0.08D;
			}

			this.motionY *= 0.9800000190734863D;
			this.motionX *= (double)f2;
			this.motionZ *= (double)f2;
		}

		this.prevLimbSwingAmount = this.limbSwingAmount;
		d0 = this.posX - this.prevPosX;
		double d1 = this.posZ - this.prevPosZ;
		float f6 = MathHelper.sqrt_double(d0 * d0 + d1 * d1) * 4.0F;

		if (f6 > 1.0F)
		{
			f6 = 1.0F;
		}

		this.limbSwingAmount += (f6 - this.limbSwingAmount) * 0.4F;
		this.limbSwing += this.limbSwingAmount;
	}

	protected boolean isAIEnabled()
	{
		return false;
	}

	public float getAIMoveSpeed()
	{
		return this.isAIEnabled() ? this.landMovementFactor : 0.1F;
	}

	public void setAIMoveSpeed(float par1)
	{
		this.landMovementFactor = par1;
	}

	public boolean attackEntityAsMob(Entity par1Entity)
	{
		this.setLastAttacker(par1Entity);
		return false;
	}

	public boolean isPlayerSleeping()
	{
		return false;
	}

	public void onUpdate()
	{
		if (ForgeHooks.onLivingUpdate(this)) return;
		super.onUpdate();

		if (!this.worldObj.isRemote)
		{
			int i = this.getArrowCountInEntity();

			if (i > 0)
			{
				if (this.arrowHitTimer <= 0)
				{
					this.arrowHitTimer = 20 * (30 - i);
				}

				--this.arrowHitTimer;

				if (this.arrowHitTimer <= 0)
				{
					this.setArrowCountInEntity(i - 1);
				}
			}

			for (int j = 0; j < 5; ++j)
			{
				ItemStack itemstack = this.previousEquipment[j];
				ItemStack itemstack1 = this.getEquipmentInSlot(j);

				if (!ItemStack.areItemStacksEqual(itemstack1, itemstack))
				{
					((WorldServer)this.worldObj).getEntityTracker().func_151247_a(this, new S04PacketEntityEquipment(this.getEntityId(), j, itemstack1));

					if (itemstack != null)
					{
						this.attributeMap.removeAttributeModifiers(itemstack.getAttributeModifiers());
					}

					if (itemstack1 != null)
					{
						this.attributeMap.applyAttributeModifiers(itemstack1.getAttributeModifiers());
					}

					this.previousEquipment[j] = itemstack1 == null ? null : itemstack1.copy();
				}
			}
		}

		this.onLivingUpdate();
		double d0 = this.posX - this.prevPosX;
		double d1 = this.posZ - this.prevPosZ;
		float f = (float)(d0 * d0 + d1 * d1);
		float f1 = this.renderYawOffset;
		float f2 = 0.0F;
		this.field_70768_au = this.field_110154_aX;
		float f3 = 0.0F;

		if (f > 0.0025000002F)
		{
			f3 = 1.0F;
			f2 = (float)Math.sqrt((double)f) * 3.0F;
			f1 = (float)Math.atan2(d1, d0) * 180.0F / (float)Math.PI - 90.0F;
		}

		if (this.swingProgress > 0.0F)
		{
			f1 = this.rotationYaw;
		}

		if (!this.onGround)
		{
			f3 = 0.0F;
		}

		this.field_110154_aX += (f3 - this.field_110154_aX) * 0.3F;
		this.worldObj.theProfiler.startSection("headTurn");
		f2 = this.func_110146_f(f1, f2);
		this.worldObj.theProfiler.endSection();
		this.worldObj.theProfiler.startSection("rangeChecks");

		while (this.rotationYaw - this.prevRotationYaw < -180.0F)
		{
			this.prevRotationYaw -= 360.0F;
		}

		while (this.rotationYaw - this.prevRotationYaw >= 180.0F)
		{
			this.prevRotationYaw += 360.0F;
		}

		while (this.renderYawOffset - this.prevRenderYawOffset < -180.0F)
		{
			this.prevRenderYawOffset -= 360.0F;
		}

		while (this.renderYawOffset - this.prevRenderYawOffset >= 180.0F)
		{
			this.prevRenderYawOffset += 360.0F;
		}

		while (this.rotationPitch - this.prevRotationPitch < -180.0F)
		{
			this.prevRotationPitch -= 360.0F;
		}

		while (this.rotationPitch - this.prevRotationPitch >= 180.0F)
		{
			this.prevRotationPitch += 360.0F;
		}

		while (this.rotationYawHead - this.prevRotationYawHead < -180.0F)
		{
			this.prevRotationYawHead -= 360.0F;
		}

		while (this.rotationYawHead - this.prevRotationYawHead >= 180.0F)
		{
			this.prevRotationYawHead += 360.0F;
		}

		this.worldObj.theProfiler.endSection();
		this.field_70764_aw += f2;
	}

	protected float func_110146_f(float par1, float par2)
	{
		float f2 = MathHelper.wrapAngleTo180_float(par1 - this.renderYawOffset);
		this.renderYawOffset += f2 * 0.3F;
		float f3 = MathHelper.wrapAngleTo180_float(this.rotationYaw - this.renderYawOffset);
		boolean flag = f3 < -90.0F || f3 >= 90.0F;

		if (f3 < -75.0F)
		{
			f3 = -75.0F;
		}

		if (f3 >= 75.0F)
		{
			f3 = 75.0F;
		}

		this.renderYawOffset = this.rotationYaw - f3;

		if (f3 * f3 > 2500.0F)
		{
			this.renderYawOffset += f3 * 0.2F;
		}

		if (flag)
		{
			par2 *= -1.0F;
		}

		return par2;
	}

	public void onLivingUpdate()
	{
		if (this.jumpTicks > 0)
		{
			--this.jumpTicks;
		}

		if (this.newPosRotationIncrements > 0)
		{
			double d0 = this.posX + (this.newPosX - this.posX) / (double)this.newPosRotationIncrements;
			double d1 = this.posY + (this.newPosY - this.posY) / (double)this.newPosRotationIncrements;
			double d2 = this.posZ + (this.newPosZ - this.posZ) / (double)this.newPosRotationIncrements;
			double d3 = MathHelper.wrapAngleTo180_double(this.newRotationYaw - (double)this.rotationYaw);
			this.rotationYaw = (float)((double)this.rotationYaw + d3 / (double)this.newPosRotationIncrements);
			this.rotationPitch = (float)((double)this.rotationPitch + (this.newRotationPitch - (double)this.rotationPitch) / (double)this.newPosRotationIncrements);
			--this.newPosRotationIncrements;
			this.setPosition(d0, d1, d2);
			this.setRotation(this.rotationYaw, this.rotationPitch);
		}
		else if (!this.isClientWorld())
		{
			this.motionX *= 0.98D;
			this.motionY *= 0.98D;
			this.motionZ *= 0.98D;
		}

		if (Math.abs(this.motionX) < 0.005D)
		{
			this.motionX = 0.0D;
		}

		if (Math.abs(this.motionY) < 0.005D)
		{
			this.motionY = 0.0D;
		}

		if (Math.abs(this.motionZ) < 0.005D)
		{
			this.motionZ = 0.0D;
		}

		this.worldObj.theProfiler.startSection("ai");

		if (this.isMovementBlocked())
		{
			this.isJumping = false;
			this.moveStrafing = 0.0F;
			this.moveForward = 0.0F;
			this.randomYawVelocity = 0.0F;
		}
		else if (this.isClientWorld())
		{
			if (this.isAIEnabled())
			{
				this.worldObj.theProfiler.startSection("newAi");
				this.updateAITasks();
				this.worldObj.theProfiler.endSection();
			}
			else
			{
				this.worldObj.theProfiler.startSection("oldAi");
				this.updateEntityActionState();
				this.worldObj.theProfiler.endSection();
				this.rotationYawHead = this.rotationYaw;
			}
		}

		this.worldObj.theProfiler.endSection();
		this.worldObj.theProfiler.startSection("jump");

		if (this.isJumping)
		{
			if (!this.isInWater() && !this.handleLavaMovement())
			{
				if (this.onGround && this.jumpTicks == 0)
				{
					this.jump();
					this.jumpTicks = 10;
				}
			}
			else
			{
				this.motionY += 0.03999999910593033D;
			}
		}
		else
		{
			this.jumpTicks = 0;
		}

		this.worldObj.theProfiler.endSection();
		this.worldObj.theProfiler.startSection("travel");
		this.moveStrafing *= 0.98F;
		this.moveForward *= 0.98F;
		this.randomYawVelocity *= 0.9F;
		this.moveEntityWithHeading(this.moveStrafing, this.moveForward);
		this.worldObj.theProfiler.endSection();
		this.worldObj.theProfiler.startSection("push");

		if (!this.worldObj.isRemote)
		{
			this.collideWithNearbyEntities();
		}

		this.worldObj.theProfiler.endSection();
	}

	protected void updateAITasks() {}

	protected void collideWithNearbyEntities()
	{
		List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D));

		if (list != null && !list.isEmpty())
		{
			for (int i = 0; i < list.size(); ++i)
			{
				Entity entity = (Entity)list.get(i);

				if (entity.canBePushed())
				{
					this.collideWithEntity(entity);
				}
			}
		}
	}

	protected void collideWithEntity(Entity par1Entity)
	{
		par1Entity.applyEntityCollision(this);
	}

	public void updateRidden()
	{
		super.updateRidden();
		this.field_70768_au = this.field_110154_aX;
		this.field_110154_aX = 0.0F;
		this.fallDistance = 0.0F;
	}

	@SideOnly(Side.CLIENT)
	public void setPositionAndRotation2(double par1, double par3, double par5, float par7, float par8, int par9)
	{
		this.yOffset = 0.0F;
		this.newPosX = par1;
		this.newPosY = par3;
		this.newPosZ = par5;
		this.newRotationYaw = (double)par7;
		this.newRotationPitch = (double)par8;
		this.newPosRotationIncrements = par9;
	}

	protected void updateAITick() {}

	protected void updateEntityActionState()
	{
		++this.entityAge;
	}

	public void setJumping(boolean par1)
	{
		this.isJumping = par1;
	}

	public void onItemPickup(Entity par1Entity, int par2)
	{
		if (!par1Entity.isDead && !this.worldObj.isRemote)
		{
			EntityTracker entitytracker = ((WorldServer)this.worldObj).getEntityTracker();

			if (par1Entity instanceof EntityItem)
			{
				entitytracker.func_151247_a(par1Entity, new S0DPacketCollectItem(par1Entity.getEntityId(), this.getEntityId()));
			}

			if (par1Entity instanceof EntityArrow)
			{
				entitytracker.func_151247_a(par1Entity, new S0DPacketCollectItem(par1Entity.getEntityId(), this.getEntityId()));
			}

			if (par1Entity instanceof EntityXPOrb)
			{
				entitytracker.func_151247_a(par1Entity, new S0DPacketCollectItem(par1Entity.getEntityId(), this.getEntityId()));
			}
		}
	}

	public boolean canEntityBeSeen(Entity par1Entity)
	{
		return this.worldObj.rayTraceBlocks(this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX, this.posY + (double)this.getEyeHeight(), this.posZ), this.worldObj.getWorldVec3Pool().getVecFromPool(par1Entity.posX, par1Entity.posY + (double)par1Entity.getEyeHeight(), par1Entity.posZ)) == null;
	}

	public Vec3 getLookVec()
	{
		return this.getLook(1.0F);
	}

	public Vec3 getLook(float par1)
	{
		float f1;
		float f2;
		float f3;
		float f4;

		if (par1 == 1.0F)
		{
			f1 = MathHelper.cos(-this.rotationYaw * 0.017453292F - (float)Math.PI);
			f2 = MathHelper.sin(-this.rotationYaw * 0.017453292F - (float)Math.PI);
			f3 = -MathHelper.cos(-this.rotationPitch * 0.017453292F);
			f4 = MathHelper.sin(-this.rotationPitch * 0.017453292F);
			return this.worldObj.getWorldVec3Pool().getVecFromPool((double)(f2 * f3), (double)f4, (double)(f1 * f3));
		}
		else
		{
			f1 = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * par1;
			f2 = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * par1;
			f3 = MathHelper.cos(-f2 * 0.017453292F - (float)Math.PI);
			f4 = MathHelper.sin(-f2 * 0.017453292F - (float)Math.PI);
			float f5 = -MathHelper.cos(-f1 * 0.017453292F);
			float f6 = MathHelper.sin(-f1 * 0.017453292F);
			return this.worldObj.getWorldVec3Pool().getVecFromPool((double)(f4 * f5), (double)f6, (double)(f3 * f5));
		}
	}

	@SideOnly(Side.CLIENT)
	public float getSwingProgress(float par1)
	{
		float f1 = this.swingProgress - this.prevSwingProgress;

		if (f1 < 0.0F)
		{
			++f1;
		}

		return this.prevSwingProgress + f1 * par1;
	}

	@SideOnly(Side.CLIENT)
	public Vec3 getPosition(float par1)
	{
		if (par1 == 1.0F)
		{
			return this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX, this.posY, this.posZ);
		}
		else
		{
			double d0 = this.prevPosX + (this.posX - this.prevPosX) * (double)par1;
			double d1 = this.prevPosY + (this.posY - this.prevPosY) * (double)par1;
			double d2 = this.prevPosZ + (this.posZ - this.prevPosZ) * (double)par1;
			return this.worldObj.getWorldVec3Pool().getVecFromPool(d0, d1, d2);
		}
	}

	@SideOnly(Side.CLIENT)
	public MovingObjectPosition rayTrace(double par1, float par3)
	{
		Vec3 vec3 = this.getPosition(par3);
		Vec3 vec31 = this.getLook(par3);
		Vec3 vec32 = vec3.addVector(vec31.xCoord * par1, vec31.yCoord * par1, vec31.zCoord * par1);
		return this.worldObj.func_147447_a(vec3, vec32, false, false, true);
	}

	public boolean isClientWorld()
	{
		return !this.worldObj.isRemote;
	}

	public boolean canBeCollidedWith()
	{
		return !this.isDead;
	}

	public boolean canBePushed()
	{
		return !this.isDead;
	}

	public float getEyeHeight()
	{
		return this.height * 0.85F;
	}

	protected void setBeenAttacked()
	{
		this.velocityChanged = this.rand.nextDouble() >= this.getEntityAttribute(SharedMonsterAttributes.knockbackResistance).getAttributeValue();
	}

	public float getRotationYawHead()
	{
		return this.rotationYawHead;
	}

	@SideOnly(Side.CLIENT)
	public void setRotationYawHead(float par1)
	{
		this.rotationYawHead = par1;
	}

	public float getAbsorptionAmount()
	{
		return this.field_110151_bq;
	}

	public void setAbsorptionAmount(float par1)
	{
		if (par1 < 0.0F)
		{
			par1 = 0.0F;
		}

		this.field_110151_bq = par1;
	}

	public Team getTeam()
	{
		return null;
	}

	public boolean isOnSameTeam(EntityLivingBase par1EntityLivingBase)
	{
		return this.isOnTeam(par1EntityLivingBase.getTeam());
	}

	public boolean isOnTeam(Team par1Team)
	{
		return this.getTeam() != null ? this.getTeam().isSameTeam(par1Team) : false;
	}

	/***
	 * Removes all potion effects that have curativeItem as a curative item for its effect
	 * @param curativeItem The itemstack we are using to cure potion effects
	 */
	public void curePotionEffects(ItemStack curativeItem)
	{
		Iterator<Integer> potionKey = activePotionsMap.keySet().iterator();

		if (worldObj.isRemote)
		{
			return;
		}

		while (potionKey.hasNext())
		{
			Integer key = potionKey.next();
			PotionEffect effect = (PotionEffect)activePotionsMap.get(key);

			if (effect.isCurativeItem(curativeItem))
			{
				potionKey.remove();
				onFinishedPotionEffect(effect);
			}
		}
	}

	/**
	 * Returns true if the entity's rider (EntityPlayer) should face forward when mounted.
	 * currently only used in vanilla code by pigs.
	 *
	 * @param player The player who is riding the entity.
	 * @return If the player should orient the same direction as this entity.
	 */
	public boolean shouldRiderFaceForward(EntityPlayer player)
	{
		return this instanceof EntityPig;
	}
}