package net.minecraft.entity.monster;

import java.util.List;

import com.google.common.base.Predicate;

import net.minecraft.block.material.Material;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAIBase;
import net.minecraft.entity.ai.EntityAILookIdle;
import net.minecraft.entity.ai.EntityAIMoveTowardsRestriction;
import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
import net.minecraft.entity.ai.EntityAIWander;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.ai.EntityLookHelper;
import net.minecraft.entity.ai.EntityMoveHelper;
import net.minecraft.entity.passive.EntitySquid;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.projectile.EntityFishHook;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.ItemFishFood;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.play.server.S2BPacketChangeGameState;
import net.minecraft.pathfinding.PathNavigate;
import net.minecraft.pathfinding.PathNavigateSwimmer;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.BlockPos;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.MathHelper;
import net.minecraft.util.Vec3;
import net.minecraft.util.WeightedRandom;
import net.minecraft.util.WeightedRandomFishable;
import net.minecraft.world.EnumDifficulty;
import net.minecraft.world.World;

/**
 * + This portion of EaglercraftX contains deobfuscated Minecraft 1.8 source
 * code.
 *
 * Minecraft 1.8.8 bytecode is (c) 2015 Mojang AB. "Do not distribute!" Mod
 * Coder Pack v9.18 deobfuscation configs are (c) Copyright by the MCP Team
 *
 * EaglercraftX 1.8 patch files (c) 2022-2025 lax1dude, ayunami2000. All Rights
 * Reserved.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */
public class EntityGuardian extends EntityMob {
	static class AIGuardianAttack extends EntityAIBase {
		private EntityGuardian theEntity;
		private int tickCounter;

		public AIGuardianAttack(EntityGuardian parEntityGuardian) {
			this.theEntity = parEntityGuardian;
			this.setMutexBits(3);
		}

		@Override
		public boolean continueExecuting() {
			return super.continueExecuting() && (this.theEntity.isElder()
					|| this.theEntity.getDistanceSqToEntity(this.theEntity.getAttackTarget()) > 9.0D);
		}

		@Override
		public void resetTask() {
			this.theEntity.setTargetedEntity(0);
			this.theEntity.setAttackTarget((EntityLivingBase) null);
			this.theEntity.wander.makeUpdate();
		}

		@Override
		public boolean shouldExecute() {
			EntityLivingBase entitylivingbase = this.theEntity.getAttackTarget();
			return entitylivingbase != null && entitylivingbase.isEntityAlive();
		}

		@Override
		public void startExecuting() {
			this.tickCounter = -10;
			this.theEntity.getNavigator().clearPathEntity();
			this.theEntity.getLookHelper().setLookPositionWithEntity(this.theEntity.getAttackTarget(), 90.0F, 90.0F);
			this.theEntity.isAirBorne = true;
		}

		@Override
		public void updateTask() {
			EntityLivingBase entitylivingbase = this.theEntity.getAttackTarget();
			this.theEntity.getNavigator().clearPathEntity();
			this.theEntity.getLookHelper().setLookPositionWithEntity(entitylivingbase, 90.0F, 90.0F);
			if (!this.theEntity.canEntityBeSeen(entitylivingbase)) {
				this.theEntity.setAttackTarget((EntityLivingBase) null);
			} else {
				++this.tickCounter;
				if (this.tickCounter == 0) {
					this.theEntity.setTargetedEntity(this.theEntity.getAttackTarget().getEntityId());
					this.theEntity.worldObj.setEntityState(this.theEntity, (byte) 21);
				} else if (this.tickCounter >= this.theEntity.func_175464_ck()) {
					float f = 1.0F;
					if (this.theEntity.worldObj.getDifficulty() == EnumDifficulty.HARD) {
						f += 2.0F;
					}

					if (this.theEntity.isElder()) {
						f += 2.0F;
					}

					entitylivingbase
							.attackEntityFrom(DamageSource.causeIndirectMagicDamage(this.theEntity, this.theEntity), f);
					entitylivingbase.attackEntityFrom(DamageSource.causeMobDamage(this.theEntity),
							(float) this.theEntity.getEntityAttribute(SharedMonsterAttributes.attackDamage)
									.getAttributeValue());
					this.theEntity.setAttackTarget((EntityLivingBase) null);
				} else if (this.tickCounter >= 60 && this.tickCounter % 20 == 0) {
					;
				}

				super.updateTask();
			}
		}
	}

	static class GuardianMoveHelper extends EntityMoveHelper {
		private EntityGuardian entityGuardian;

		public GuardianMoveHelper(EntityGuardian parEntityGuardian) {
			super(parEntityGuardian);
			this.entityGuardian = parEntityGuardian;
		}

		@Override
		public void onUpdateMoveHelper() {
			if (this.update && !this.entityGuardian.getNavigator().noPath()) {
				double d0 = this.posX - this.entityGuardian.posX;
				double d1 = this.posY - this.entityGuardian.posY;
				double d2 = this.posZ - this.entityGuardian.posZ;
				double d3 = d0 * d0 + d1 * d1 + d2 * d2;
				d3 = (double) MathHelper.sqrt_double(d3);
				d1 = d1 / d3;
				float f = (float) (MathHelper.func_181159_b(d2, d0) * 180.0D / 3.1415927410125732D) - 90.0F;
				this.entityGuardian.rotationYaw = this.limitAngle(this.entityGuardian.rotationYaw, f, 30.0F);
				this.entityGuardian.renderYawOffset = this.entityGuardian.rotationYaw;
				float f1 = (float) (this.speed * this.entityGuardian
						.getEntityAttribute(SharedMonsterAttributes.movementSpeed).getAttributeValue());
				this.entityGuardian.setAIMoveSpeed(
						this.entityGuardian.getAIMoveSpeed() + (f1 - this.entityGuardian.getAIMoveSpeed()) * 0.125F);
				double d4 = Math.sin(
						(double) (this.entityGuardian.ticksExisted + this.entityGuardian.getEntityId()) * 0.5D) * 0.05D;
				double d5 = Math.cos((double) (this.entityGuardian.rotationYaw * 3.1415927F / 180.0F));
				double d6 = Math.sin((double) (this.entityGuardian.rotationYaw * 3.1415927F / 180.0F));
				this.entityGuardian.motionX += d4 * d5;
				this.entityGuardian.motionZ += d4 * d6;
				d4 = Math.sin((double) (this.entityGuardian.ticksExisted + this.entityGuardian.getEntityId()) * 0.75D)
						* 0.05D;
				this.entityGuardian.motionY += d4 * (d6 + d5) * 0.25D;
				this.entityGuardian.motionY += (double) this.entityGuardian.getAIMoveSpeed() * d1 * 0.1D;
				EntityLookHelper entitylookhelper = this.entityGuardian.getLookHelper();
				double d7 = this.entityGuardian.posX + d0 / d3 * 2.0D;
				double d8 = (double) this.entityGuardian.getEyeHeight() + this.entityGuardian.posY + d1 / d3 * 1.0D;
				double d9 = this.entityGuardian.posZ + d2 / d3 * 2.0D;
				double d10 = entitylookhelper.getLookPosX();
				double d11 = entitylookhelper.getLookPosY();
				double d12 = entitylookhelper.getLookPosZ();
				if (!entitylookhelper.getIsLooking()) {
					d10 = d7;
					d11 = d8;
					d12 = d9;
				}

				this.entityGuardian.getLookHelper().setLookPosition(d10 + (d7 - d10) * 0.125D,
						d11 + (d8 - d11) * 0.125D, d12 + (d9 - d12) * 0.125D, 10.0F, 40.0F);
				this.entityGuardian.func_175476_l(true);
			} else {
				this.entityGuardian.setAIMoveSpeed(0.0F);
				this.entityGuardian.func_175476_l(false);
			}
		}
	}

	static class GuardianTargetSelector implements Predicate<EntityLivingBase> {
		private EntityGuardian parentEntity;

		public GuardianTargetSelector(EntityGuardian parEntityGuardian) {
			this.parentEntity = parEntityGuardian;
		}

		@Override
		public boolean apply(EntityLivingBase entitylivingbase) {
			return (entitylivingbase instanceof EntityPlayer || entitylivingbase instanceof EntitySquid)
					&& entitylivingbase.getDistanceSqToEntity(this.parentEntity) > 9.0D;
		}
	}

	private float field_175482_b;
	private float field_175484_c;
	private float field_175483_bk;
	private float field_175485_bl;
	private float field_175486_bm;
	private EntityLivingBase targetedEntity;

	private int field_175479_bo;

	private boolean field_175480_bp;

	private EntityAIWander wander;

	public EntityGuardian(World worldIn) {
		super(worldIn);
		this.experienceValue = 10;
		this.setSize(0.85F, 0.85F);
		this.tasks.addTask(4, new EntityGuardian.AIGuardianAttack(this));
		EntityAIMoveTowardsRestriction entityaimovetowardsrestriction;
		this.tasks.addTask(5, entityaimovetowardsrestriction = new EntityAIMoveTowardsRestriction(this, 1.0D));
		this.tasks.addTask(7, this.wander = new EntityAIWander(this, 1.0D, 80));
		this.tasks.addTask(8, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
		this.tasks.addTask(8, new EntityAIWatchClosest(this, EntityGuardian.class, 12.0F, 0.01F));
		this.tasks.addTask(9, new EntityAILookIdle(this));
		this.wander.setMutexBits(3);
		entityaimovetowardsrestriction.setMutexBits(3);
		this.targetTasks.addTask(1, new EntityAINearestAttackableTarget(this, EntityLivingBase.class, 10, true, false,
				new EntityGuardian.GuardianTargetSelector(this)));
		this.moveHelper = new EntityGuardian.GuardianMoveHelper(this);
		this.field_175484_c = this.field_175482_b = this.rand.nextFloat();
	}

	/**
	 * + Causes this Entity to drop a random item.
	 */
	@Override
	protected void addRandomDrop() {
		ItemStack itemstack = ((WeightedRandomFishable) WeightedRandom.getRandomItem(this.rand,
				EntityFishHook.func_174855_j())).getItemStack(this.rand);
		this.entityDropItem(itemstack, 1.0F);
	}

	@Override
	protected void applyEntityAttributes() {
		super.applyEntityAttributes();
		this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(6.0D);
		this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.5D);
		this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(16.0D);
		this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(30.0D);
	}

	/**
	 * + Called when the entity is attacked.
	 */
	@Override
	public boolean attackEntityFrom(DamageSource damagesource, float f) {
		if (!this.func_175472_n() && !damagesource.isMagicDamage()
				&& damagesource.getSourceOfDamage() instanceof EntityLivingBase) {
			EntityLivingBase entitylivingbase = (EntityLivingBase) damagesource.getSourceOfDamage();
			if (!damagesource.isExplosion()) {
				entitylivingbase.attackEntityFrom(DamageSource.causeThornsDamage(this), 2.0F);
				entitylivingbase.playSound("damage.thorns", 0.5F, 1.0F);
			}
		}

		this.wander.makeUpdate();
		return super.attackEntityFrom(damagesource, f);
	}

	/**
	 * + returns if this entity triggers Block.onEntityWalking on the blocks they
	 * walk on. used for spiders and wolves to prevent them from trampling crops
	 */
	@Override
	protected boolean canTriggerWalking() {
		return false;
	}

	/**
	 * + Drop 0-2 items of this living's type
	 */
	@Override
	protected void dropFewItems(boolean flag, int i) {
		int j = this.rand.nextInt(3) + this.rand.nextInt(i + 1);
		if (j > 0) {
			this.entityDropItem(new ItemStack(Items.prismarine_shard, j, 0), 1.0F);
		}

		if (this.rand.nextInt(3 + i) > 1) {
			this.entityDropItem(new ItemStack(Items.fish, 1, ItemFishFood.FishType.COD.getMetadata()), 1.0F);
		} else if (this.rand.nextInt(3 + i) > 1) {
			this.entityDropItem(new ItemStack(Items.prismarine_crystals, 1, 0), 1.0F);
		}

		if (flag && this.isElder()) {
			this.entityDropItem(new ItemStack(Blocks.sponge, 1, 1), 1.0F);
		}

	}

	@Override
	protected void entityInit() {
		super.entityInit();
		this.dataWatcher.addObject(16, Integer.valueOf(0));
		this.dataWatcher.addObject(17, Integer.valueOf(0));
	}

	public int func_175464_ck() {
		return this.isElder() ? 60 : 80;
	}

	public float func_175469_o(float parFloat1) {
		return this.field_175486_bm + (this.field_175485_bl - this.field_175486_bm) * parFloat1;
	}

	public float func_175471_a(float parFloat1) {
		return this.field_175484_c + (this.field_175482_b - this.field_175484_c) * parFloat1;
	}

	public boolean func_175472_n() {
		return this.isSyncedFlagSet(2);
	}

	private void func_175476_l(boolean parFlag) {
		this.setSyncedFlag(2, parFlag);
	}

	public float func_175477_p(float parFloat1) {
		return ((float) this.field_175479_bo + parFloat1) / (float) this.func_175464_ck();
	}

	@Override
	public float getBlockPathWeight(BlockPos blockpos) {
		return this.worldObj.getBlockState(blockpos).getBlock().getMaterial() == Material.water
				? 10.0F + this.worldObj.getLightBrightness(blockpos) - 0.5F
				: super.getBlockPathWeight(blockpos);
	}

	/**
	 * + Checks if the entity's current position is a valid location to spawn this
	 * entity.
	 */
	@Override
	public boolean getCanSpawnHere() {
		return (this.rand.nextInt(20) == 0 || !this.worldObj.canBlockSeeSky(new BlockPos(this)))
				&& super.getCanSpawnHere();
	}

	/**
	 * + Returns the sound this mob makes on death.
	 */
	@Override
	protected String getDeathSound() {
		return !this.isInWater() ? "mob.guardian.land.death"
				: (this.isElder() ? "mob.guardian.elder.death" : "mob.guardian.death");
	}

	@Override
	public float getEyeHeight() {
		return this.height * 0.5F;
	}

	/**
	 * + Returns the sound this mob makes when it is hurt.
	 */
	@Override
	protected String getHurtSound() {
		return !this.isInWater() ? "mob.guardian.land.hit"
				: (this.isElder() ? "mob.guardian.elder.hit" : "mob.guardian.hit");
	}

	/**
	 * + Returns the sound this mob makes while it's alive.
	 */
	@Override
	protected String getLivingSound() {
		return !this.isInWater() ? "mob.guardian.land.idle"
				: (this.isElder() ? "mob.guardian.elder.idle" : "mob.guardian.idle");
	}

	/**
	 * + Returns new PathNavigateGround instance
	 */
	@Override
	protected PathNavigate getNewNavigator(World world) {
		return new PathNavigateSwimmer(this, world);
	}

	/**
	 * + Get number of ticks, at least during which the living entity will be
	 * silent.
	 */
	@Override
	public int getTalkInterval() {
		return 160;
	}

	public EntityLivingBase getTargetedEntity() {
		if (!this.hasTargetedEntity()) {
			return null;
		} else if (this.worldObj.isRemote) {
			if (this.targetedEntity != null) {
				return this.targetedEntity;
			} else {
				Entity entity = this.worldObj.getEntityByID(this.dataWatcher.getWatchableObjectInt(17));
				if (entity instanceof EntityLivingBase) {
					this.targetedEntity = (EntityLivingBase) entity;
					return this.targetedEntity;
				} else {
					return null;
				}
			}
		} else {
			return this.getAttackTarget();
		}
	}

	/**
	 * + The speed it takes to move the entityliving's rotationPitch through the
	 * faceEntity method. This is only currently use in wolves.
	 */
	@Override
	public int getVerticalFaceSpeed() {
		return 180;
	}

	public boolean hasTargetedEntity() {
		return this.dataWatcher.getWatchableObjectInt(17) != 0;
	}

	public boolean isElder() {
		return this.isSyncedFlagSet(4);
	}

	/**
	 * + Checks that the entity is not colliding with any blocks / liquids
	 */
	@Override
	public boolean isNotColliding() {
		return this.worldObj.checkNoEntityCollision(this.getEntityBoundingBox(), this)
				&& this.worldObj.getCollidingBoundingBoxes(this, this.getEntityBoundingBox()).isEmpty();
	}

	/**
	 * + Returns true if given flag is set
	 */
	private boolean isSyncedFlagSet(int flagId) {
		return (this.dataWatcher.getWatchableObjectInt(16) & flagId) != 0;
	}

	/**
	 * + Checks to make sure the light is not too bright where the mob is spawning
	 */
	@Override
	protected boolean isValidLightLevel() {
		return true;
	}

	/**
	 * + Moves the entity based on the specified heading. Args: strafe, forward
	 */
	@Override
	public void moveEntityWithHeading(float f, float f1) {
		if (this.isServerWorld()) {
			if (this.isInWater()) {
				this.moveFlying(f, f1, 0.1F);
				this.moveEntity(this.motionX, this.motionY, this.motionZ);
				this.motionX *= 0.8999999761581421D;
				this.motionY *= 0.8999999761581421D;
				this.motionZ *= 0.8999999761581421D;
				if (!this.func_175472_n() && this.getAttackTarget() == null) {
					this.motionY -= 0.005D;
				}
			} else {
				super.moveEntityWithHeading(f, f1);
			}
		} else {
			super.moveEntityWithHeading(f, f1);
		}

	}

	@Override
	public void onDataWatcherUpdate(int i) {
		super.onDataWatcherUpdate(i);
		if (i == 16) {
			if (this.isElder() && this.width < 1.0F) {
				this.setSize(1.9975F, 1.9975F);
			}
		} else if (i == 17) {
			this.field_175479_bo = 0;
			this.targetedEntity = null;
		}

	}

	/**
	 * + Called frequently so the entity can update its state every tick as
	 * required. For example, zombies and skeletons use this to react to sunlight
	 * and start to burn.
	 */
	@Override
	public void onLivingUpdate() {
		if (this.worldObj.isRemote) {
			this.field_175484_c = this.field_175482_b;
			if (!this.isInWater()) {
				this.field_175483_bk = 2.0F;
				if (this.motionY > 0.0D && this.field_175480_bp && !this.isSilent()) {
					this.worldObj.playSound(this.posX, this.posY, this.posZ, "mob.guardian.flop", 1.0F, 1.0F, false);
				}

				this.field_175480_bp = this.motionY < 0.0D
						&& this.worldObj.isBlockNormalCube((new BlockPos(this)).down(), false);
			} else if (this.func_175472_n()) {
				if (this.field_175483_bk < 0.5F) {
					this.field_175483_bk = 4.0F;
				} else {
					this.field_175483_bk += (0.5F - this.field_175483_bk) * 0.1F;
				}
			} else {
				this.field_175483_bk += (0.125F - this.field_175483_bk) * 0.2F;
			}

			this.field_175482_b += this.field_175483_bk;
			this.field_175486_bm = this.field_175485_bl;
			if (!this.isInWater()) {
				this.field_175485_bl = this.rand.nextFloat();
			} else if (this.func_175472_n()) {
				this.field_175485_bl += (0.0F - this.field_175485_bl) * 0.25F;
			} else {
				this.field_175485_bl += (1.0F - this.field_175485_bl) * 0.06F;
			}

			if (this.func_175472_n() && this.isInWater()) {
				Vec3 vec3 = this.getLook(0.0F);

				for (int i = 0; i < 2; ++i) {
					this.worldObj.spawnParticle(EnumParticleTypes.WATER_BUBBLE,
							this.posX + (this.rand.nextDouble() - 0.5D) * (double) this.width - vec3.xCoord * 1.5D,
							this.posY + this.rand.nextDouble() * (double) this.height - vec3.yCoord * 1.5D,
							this.posZ + (this.rand.nextDouble() - 0.5D) * (double) this.width - vec3.zCoord * 1.5D,
							0.0D, 0.0D, 0.0D, new int[0]);
				}
			}

			if (this.hasTargetedEntity()) {
				if (this.field_175479_bo < this.func_175464_ck()) {
					++this.field_175479_bo;
				}

				EntityLivingBase entitylivingbase = this.getTargetedEntity();
				if (entitylivingbase != null) {
					this.getLookHelper().setLookPositionWithEntity(entitylivingbase, 90.0F, 90.0F);
					this.getLookHelper().onUpdateLook();
					double d5 = (double) this.func_175477_p(0.0F);
					double d0 = entitylivingbase.posX - this.posX;
					double d1 = entitylivingbase.posY + (double) (entitylivingbase.height * 0.5F)
							- (this.posY + (double) this.getEyeHeight());
					double d2 = entitylivingbase.posZ - this.posZ;
					double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
					d0 = d0 / d3;
					d1 = d1 / d3;
					d2 = d2 / d3;
					double d4 = this.rand.nextDouble();

					while (d4 < d3) {
						d4 += 1.8D - d5 + this.rand.nextDouble() * (1.7D - d5);
						this.worldObj.spawnParticle(EnumParticleTypes.WATER_BUBBLE, this.posX + d0 * d4,
								this.posY + d1 * d4 + (double) this.getEyeHeight(), this.posZ + d2 * d4, 0.0D, 0.0D,
								0.0D, new int[0]);
					}
				}
			}
		}

		if (this.inWater) {
			this.setAir(300);
		} else if (this.onGround) {
			this.motionY += 0.5D;
			this.motionX += (double) ((this.rand.nextFloat() * 2.0F - 1.0F) * 0.4F);
			this.motionZ += (double) ((this.rand.nextFloat() * 2.0F - 1.0F) * 0.4F);
			this.rotationYaw = this.rand.nextFloat() * 360.0F;
			this.onGround = false;
			this.isAirBorne = true;
		}

		if (this.hasTargetedEntity()) {
			this.rotationYaw = this.rotationYawHead;
		}

		super.onLivingUpdate();
	}

	/**
	 * + (abstract) Protected helper method to read subclass entity data from NBT.
	 */
	@Override
	public void readEntityFromNBT(NBTTagCompound nbttagcompound) {
		super.readEntityFromNBT(nbttagcompound);
		this.setElder(nbttagcompound.getBoolean("Elder"));
	}

	/**
	 * + Sets this Guardian to be an elder or not.
	 */
	public void setElder() {
		this.setElder(true);
		this.field_175486_bm = this.field_175485_bl = 1.0F;
	}

	/**
	 * + Sets this Guardian to be an elder or not.
	 */
	public void setElder(boolean elder) {
		this.setSyncedFlag(4, elder);
		if (elder) {
			this.setSize(1.9975F, 1.9975F);
			this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.30000001192092896D);
			this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(8.0D);
			this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(80.0D);
			this.enablePersistence();
			this.wander.setExecutionChance(400);
		}

	}

	/**
	 * + Sets a flag state "on/off" on both sides (client/server) by using
	 * DataWatcher
	 */
	private void setSyncedFlag(int flagId, boolean state) {
		int i = this.dataWatcher.getWatchableObjectInt(16);
		if (state) {
			this.dataWatcher.updateObject(16, Integer.valueOf(i | flagId));
		} else {
			this.dataWatcher.updateObject(16, Integer.valueOf(i & ~flagId));
		}

	}

	private void setTargetedEntity(int entityId) {
		this.dataWatcher.updateObject(17, Integer.valueOf(entityId));
	}

	@Override
	protected void updateAITasks() {
		super.updateAITasks();
		if (this.isElder()) {
			boolean flag = true;
			boolean flag1 = true;
			boolean flag2 = true;
			boolean flag3 = true;
			if ((this.ticksExisted + this.getEntityId()) % 1200 == 0) {
				Potion potion = Potion.digSlowdown;

				List<EntityPlayerMP> lst = this.worldObj.getPlayers(EntityPlayerMP.class,
						new Predicate<EntityPlayerMP>() {
							@Override
							public boolean apply(EntityPlayerMP entityplayermp1) {
								return EntityGuardian.this.getDistanceSqToEntity(entityplayermp1) < 2500.0D
										&& entityplayermp1.theItemInWorldManager.survivalOrAdventure();
							}
						});
				for (int i = 0, l = lst.size(); i < l; ++i) {
					EntityPlayerMP entityplayermp = lst.get(i);
					if (!entityplayermp.isPotionActive(potion)
							|| entityplayermp.getActivePotionEffect(potion).getAmplifier() < 2
							|| entityplayermp.getActivePotionEffect(potion).getDuration() < 1200) {
						entityplayermp.playerNetServerHandler.sendPacket(new S2BPacketChangeGameState(10, 0.0F));
						entityplayermp.addPotionEffect(new PotionEffect(potion.id, 6000, 2));
					}
				}
			}

			if (!this.hasHome()) {
				this.setHomePosAndDistance(new BlockPos(this), 16);
			}
		}

	}

	/**
	 * + (abstract) Protected helper method to write subclass entity data to NBT.
	 */
	@Override
	public void writeEntityToNBT(NBTTagCompound nbttagcompound) {
		super.writeEntityToNBT(nbttagcompound);
		nbttagcompound.setBoolean("Elder", this.isElder());
	}
}
