package net.minecraft.entity.monster;
import com.google.common.base.Predicate;
import com.google.common.collect.Sets;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAIAttackOnCollide;
import net.minecraft.entity.ai.EntityAIBase;
import net.minecraft.entity.ai.EntityAIHurtByTarget;
import net.minecraft.entity.ai.EntityAILookIdle;
import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
import net.minecraft.entity.ai.EntityAISwimming;
import net.minecraft.entity.ai.EntityAIWander;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.ai.attributes.AttributeModifier;
import net.minecraft.entity.ai.attributes.IAttributeInstance;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.BlockPos;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EntityDamageSource;
import net.minecraft.util.EntityDamageSourceIndirect;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.MathHelper;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
public class EntityEnderman extends EntityMob
{
private static final UUID attackingSpeedBoostModifierUUID = UUID.fromString("020E0DFB-87AE-4653-9556-831010E291A0");
private static final AttributeModifier attackingSpeedBoostModifier = (new AttributeModifier(attackingSpeedBoostModifierUUID, "Attacking speed boost", 0.15000000596046448D, 0)).setSaved(false);
private static final Set carriableBlocks = Sets.newIdentityHashSet();
private boolean isAggressive;
private static final String __OBFID = "CL_00001685";
public EntityEnderman(World worldIn)
{
super(worldIn);
this.setSize(0.6F, 2.9F);
this.stepHeight = 1.0F;
this.tasks.addTask(0, new EntityAISwimming(this));
this.tasks.addTask(2, new EntityAIAttackOnCollide(this, 1.0D, false));
this.tasks.addTask(7, new EntityAIWander(this, 1.0D));
this.tasks.addTask(8, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
this.tasks.addTask(8, new EntityAILookIdle(this));
this.tasks.addTask(10, new EntityEnderman.AIPlaceBlock());
this.tasks.addTask(11, new EntityEnderman.AITakeBlock());
this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false, new Class[0]));
this.targetTasks.addTask(2, new EntityEnderman.AIFindPlayer());
this.targetTasks.addTask(3, new EntityAINearestAttackableTarget(this, EntityEndermite.class, 10, true, false, new Predicate()
{
private static final String __OBFID = "CL_00002223";
public boolean func_179948_a(EntityEndermite p_179948_1_)
{
return p_179948_1_.isSpawnedByPlayer();
}
public boolean apply(Object p_apply_1_)
{
return this.func_179948_a((EntityEndermite)p_apply_1_);
}
}));
}
protected void applyEntityAttributes()
{
super.applyEntityAttributes();
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(40.0D);
this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.30000001192092896D);
this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(7.0D);
this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(64.0D);
}
protected void entityInit()
{
super.entityInit();
this.dataWatcher.addObject(16, new Short((short)0));
this.dataWatcher.addObject(17, new Byte((byte)0));
this.dataWatcher.addObject(18, new Byte((byte)0));
}
/**
* (abstract) Protected helper method to write subclass entity data to NBT.
*/
public void writeEntityToNBT(NBTTagCompound tagCompound)
{
super.writeEntityToNBT(tagCompound);
IBlockState var2 = this.func_175489_ck();
tagCompound.setShort("carried", (short)Block.getIdFromBlock(var2.getBlock()));
tagCompound.setShort("carriedData", (short)var2.getBlock().getMetaFromState(var2));
}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
public void readEntityFromNBT(NBTTagCompound tagCompund)
{
super.readEntityFromNBT(tagCompund);
IBlockState var2;
if (tagCompund.hasKey("carried", 8))
{
var2 = Block.getBlockFromName(tagCompund.getString("carried")).getStateFromMeta(tagCompund.getShort("carriedData") & 65535);
}
else
{
var2 = Block.getBlockById(tagCompund.getShort("carried")).getStateFromMeta(tagCompund.getShort("carriedData") & 65535);
}
this.func_175490_a(var2);
}
/**
* Checks to see if this enderman should be attacking this player
*/
private boolean shouldAttackPlayer(EntityPlayer p_70821_1_)
{
ItemStack var2 = p_70821_1_.inventory.armorInventory[3];
if (var2 != null && var2.getItem() == Item.getItemFromBlock(Blocks.pumpkin))
{
return false;
}
else
{
Vec3 var3 = p_70821_1_.getLook(1.0F).normalize();
Vec3 var4 = new Vec3(this.posX - p_70821_1_.posX, this.getEntityBoundingBox().minY + (double)(this.height / 2.0F) - (p_70821_1_.posY + (double)p_70821_1_.getEyeHeight()), this.posZ - p_70821_1_.posZ);
double var5 = var4.lengthVector();
var4 = var4.normalize();
double var7 = var3.dotProduct(var4);
return var7 > 1.0D - 0.025D / var5 ? p_70821_1_.canEntityBeSeen(this) : false;
}
}
public float getEyeHeight()
{
return 2.55F;
}
/**
* 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.
*/
public void onLivingUpdate()
{
if (this.worldObj.isRemote)
{
for (int var1 = 0; var1 < 2; ++var1)
{
this.worldObj.spawnParticle(EnumParticleTypes.PORTAL, this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height - 0.25D, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, (this.rand.nextDouble() - 0.5D) * 2.0D, -this.rand.nextDouble(), (this.rand.nextDouble() - 0.5D) * 2.0D, new int[0]);
}
}
this.isJumping = false;
super.onLivingUpdate();
}
protected void updateAITasks()
{
if (this.isWet())
{
this.attackEntityFrom(DamageSource.drown, 1.0F);
}
if (this.isScreaming() && !this.isAggressive && this.rand.nextInt(100) == 0)
{
this.setScreaming(false);
}
if (this.worldObj.isDaytime())
{
float var1 = this.getBrightness(1.0F);
if (var1 > 0.5F && this.worldObj.isAgainstSky(new BlockPos(this)) && this.rand.nextFloat() * 30.0F < (var1 - 0.4F) * 2.0F)
{
this.setAttackTarget((EntityLivingBase)null);
this.setScreaming(false);
this.isAggressive = false;
this.teleportRandomly();
}
}
super.updateAITasks();
}
/**
* Teleport the enderman to a random nearby position
*/
protected boolean teleportRandomly()
{
double var1 = this.posX + (this.rand.nextDouble() - 0.5D) * 64.0D;
double var3 = this.posY + (double)(this.rand.nextInt(64) - 32);
double var5 = this.posZ + (this.rand.nextDouble() - 0.5D) * 64.0D;
return this.teleportTo(var1, var3, var5);
}
/**
* Teleport the enderman to another entity
*/
protected boolean teleportToEntity(Entity p_70816_1_)
{
Vec3 var2 = new Vec3(this.posX - p_70816_1_.posX, this.getEntityBoundingBox().minY + (double)(this.height / 2.0F) - p_70816_1_.posY + (double)p_70816_1_.getEyeHeight(), this.posZ - p_70816_1_.posZ);
var2 = var2.normalize();
double var3 = 16.0D;
double var5 = this.posX + (this.rand.nextDouble() - 0.5D) * 8.0D - var2.xCoord * var3;
double var7 = this.posY + (double)(this.rand.nextInt(16) - 8) - var2.yCoord * var3;
double var9 = this.posZ + (this.rand.nextDouble() - 0.5D) * 8.0D - var2.zCoord * var3;
return this.teleportTo(var5, var7, var9);
}
/**
* Teleport the enderman
*/
protected boolean teleportTo(double p_70825_1_, double p_70825_3_, double p_70825_5_)
{
double var7 = this.posX;
double var9 = this.posY;
double var11 = this.posZ;
this.posX = p_70825_1_;
this.posY = p_70825_3_;
this.posZ = p_70825_5_;
boolean var13 = false;
BlockPos var14 = new BlockPos(this.posX, this.posY, this.posZ);
if (this.worldObj.isBlockLoaded(var14))
{
boolean var15 = false;
while (!var15 && var14.getY() > 0)
{
BlockPos var16 = var14.offsetDown();
Block var17 = this.worldObj.getBlockState(var16).getBlock();
if (var17.getMaterial().blocksMovement())
{
var15 = true;
}
else
{
--this.posY;
var14 = var16;
}
}
if (var15)
{
super.setPositionAndUpdate(this.posX, this.posY, this.posZ);
if (this.worldObj.getCollidingBoundingBoxes(this, this.getEntityBoundingBox()).isEmpty() && !this.worldObj.isAnyLiquid(this.getEntityBoundingBox()))
{
var13 = true;
}
}
}
if (!var13)
{
this.setPosition(var7, var9, var11);
return false;
}
else
{
short var28 = 128;
for (int var29 = 0; var29 < var28; ++var29)
{
double var30 = (double)var29 / ((double)var28 - 1.0D);
float var19 = (this.rand.nextFloat() - 0.5F) * 0.2F;
float var20 = (this.rand.nextFloat() - 0.5F) * 0.2F;
float var21 = (this.rand.nextFloat() - 0.5F) * 0.2F;
double var22 = var7 + (this.posX - var7) * var30 + (this.rand.nextDouble() - 0.5D) * (double)this.width * 2.0D;
double var24 = var9 + (this.posY - var9) * var30 + this.rand.nextDouble() * (double)this.height;
double var26 = var11 + (this.posZ - var11) * var30 + (this.rand.nextDouble() - 0.5D) * (double)this.width * 2.0D;
this.worldObj.spawnParticle(EnumParticleTypes.PORTAL, var22, var24, var26, (double)var19, (double)var20, (double)var21, new int[0]);
}
this.worldObj.playSoundEffect(var7, var9, var11, "mob.endermen.portal", 1.0F, 1.0F);
this.playSound("mob.endermen.portal", 1.0F, 1.0F);
return true;
}
}
/**
* Returns the sound this mob makes while it's alive.
*/
protected String getLivingSound()
{
return this.isScreaming() ? "mob.endermen.scream" : "mob.endermen.idle";
}
/**
* Returns the sound this mob makes when it is hurt.
*/
protected String getHurtSound()
{
return "mob.endermen.hit";
}
/**
* Returns the sound this mob makes on death.
*/
protected String getDeathSound()
{
return "mob.endermen.death";
}
protected Item getDropItem()
{
return Items.ender_pearl;
}
/**
* Drop 0-2 items of this living's type
*/
protected void dropFewItems(boolean p_70628_1_, int p_70628_2_)
{
Item var3 = this.getDropItem();
if (var3 != null)
{
int var4 = this.rand.nextInt(2 + p_70628_2_);
for (int var5 = 0; var5 < var4; ++var5)
{
this.dropItem(var3, 1);
}
}
}
public void func_175490_a(IBlockState p_175490_1_)
{
this.dataWatcher.updateObject(16, Short.valueOf((short)(Block.getStateId(p_175490_1_) & 65535)));
}
public IBlockState func_175489_ck()
{
return Block.getStateById(this.dataWatcher.getWatchableObjectShort(16) & 65535);
}
/**
* Called when the entity is attacked.
*/
public boolean attackEntityFrom(DamageSource source, float amount)
{
if (this.func_180431_b(source))
{
return false;
}
else
{
if (source.getEntity() == null || !(source.getEntity() instanceof EntityEndermite))
{
if (!this.worldObj.isRemote)
{
this.setScreaming(true);
}
if (source instanceof EntityDamageSource && source.getEntity() instanceof EntityPlayer)
{
if (source.getEntity() instanceof EntityPlayerMP && ((EntityPlayerMP)source.getEntity()).theItemInWorldManager.isCreative())
{
this.setScreaming(false);
}
else
{
this.isAggressive = true;
}
}
if (source instanceof EntityDamageSourceIndirect)
{
this.isAggressive = false;
for (int var4 = 0; var4 < 64; ++var4)
{
if (this.teleportRandomly())
{
return true;
}
}
return false;
}
}
boolean var3 = super.attackEntityFrom(source, amount);
if (source.isUnblockable() && this.rand.nextInt(10) != 0)
{
this.teleportRandomly();
}
return var3;
}
}
public boolean isScreaming()
{
return this.dataWatcher.getWatchableObjectByte(18) > 0;
}
public void setScreaming(boolean p_70819_1_)
{
this.dataWatcher.updateObject(18, Byte.valueOf((byte)(p_70819_1_ ? 1 : 0)));
}
static
{
carriableBlocks.add(Blocks.grass);
carriableBlocks.add(Blocks.dirt);
carriableBlocks.add(Blocks.sand);
carriableBlocks.add(Blocks.gravel);
carriableBlocks.add(Blocks.yellow_flower);
carriableBlocks.add(Blocks.red_flower);
carriableBlocks.add(Blocks.brown_mushroom);
carriableBlocks.add(Blocks.red_mushroom);
carriableBlocks.add(Blocks.tnt);
carriableBlocks.add(Blocks.cactus);
carriableBlocks.add(Blocks.clay);
carriableBlocks.add(Blocks.pumpkin);
carriableBlocks.add(Blocks.melon_block);
carriableBlocks.add(Blocks.mycelium);
}
class AIFindPlayer extends EntityAINearestAttackableTarget
{
private EntityPlayer field_179448_g;
private int field_179450_h;
private int field_179451_i;
private EntityEnderman field_179449_j = EntityEnderman.this;
private static final String __OBFID = "CL_00002221";
public AIFindPlayer()
{
super(EntityEnderman.this, EntityPlayer.class, true);
}
public boolean shouldExecute()
{
double var1 = this.getTargetDistance();
List var3 = this.taskOwner.worldObj.func_175647_a(EntityPlayer.class, this.taskOwner.getEntityBoundingBox().expand(var1, 4.0D, var1), this.targetEntitySelector);
Collections.sort(var3, this.theNearestAttackableTargetSorter);
if (var3.isEmpty())
{
return false;
}
else
{
this.field_179448_g = (EntityPlayer)var3.get(0);
return true;
}
}
public void startExecuting()
{
this.field_179450_h = 5;
this.field_179451_i = 0;
}
public void resetTask()
{
this.field_179448_g = null;
this.field_179449_j.setScreaming(false);
IAttributeInstance var1 = this.field_179449_j.getEntityAttribute(SharedMonsterAttributes.movementSpeed);
var1.removeModifier(EntityEnderman.attackingSpeedBoostModifier);
super.resetTask();
}
public boolean continueExecuting()
{
if (this.field_179448_g != null)
{
if (!this.field_179449_j.shouldAttackPlayer(this.field_179448_g))
{
return false;
}
else
{
this.field_179449_j.isAggressive = true;
this.field_179449_j.faceEntity(this.field_179448_g, 10.0F, 10.0F);
return true;
}
}
else
{
return super.continueExecuting();
}
}
public void updateTask()
{
if (this.field_179448_g != null)
{
if (--this.field_179450_h <= 0)
{
this.targetEntity = this.field_179448_g;
this.field_179448_g = null;
super.startExecuting();
this.field_179449_j.playSound("mob.endermen.stare", 1.0F, 1.0F);
this.field_179449_j.setScreaming(true);
IAttributeInstance var1 = this.field_179449_j.getEntityAttribute(SharedMonsterAttributes.movementSpeed);
var1.applyModifier(EntityEnderman.attackingSpeedBoostModifier);
}
}
else
{
if (this.targetEntity != null)
{
if (this.targetEntity instanceof EntityPlayer && this.field_179449_j.shouldAttackPlayer((EntityPlayer)this.targetEntity))
{
if (this.targetEntity.getDistanceSqToEntity(this.field_179449_j) < 16.0D)
{
this.field_179449_j.teleportRandomly();
}
this.field_179451_i = 0;
}
else if (this.targetEntity.getDistanceSqToEntity(this.field_179449_j) > 256.0D && this.field_179451_i++ >= 30 && this.field_179449_j.teleportToEntity(this.targetEntity))
{
this.field_179451_i = 0;
}
}
super.updateTask();
}
}
}
class AIPlaceBlock extends EntityAIBase
{
private EntityEnderman field_179475_a = EntityEnderman.this;
private static final String __OBFID = "CL_00002222";
public boolean shouldExecute()
{
return !this.field_179475_a.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing") ? false : (this.field_179475_a.func_175489_ck().getBlock().getMaterial() == Material.air ? false : this.field_179475_a.getRNG().nextInt(2000) == 0);
}
public void updateTask()
{
Random var1 = this.field_179475_a.getRNG();
World var2 = this.field_179475_a.worldObj;
int var3 = MathHelper.floor_double(this.field_179475_a.posX - 1.0D + var1.nextDouble() * 2.0D);
int var4 = MathHelper.floor_double(this.field_179475_a.posY + var1.nextDouble() * 2.0D);
int var5 = MathHelper.floor_double(this.field_179475_a.posZ - 1.0D + var1.nextDouble() * 2.0D);
BlockPos var6 = new BlockPos(var3, var4, var5);
Block var7 = var2.getBlockState(var6).getBlock();
Block var8 = var2.getBlockState(var6.offsetDown()).getBlock();
if (this.func_179474_a(var2, var6, this.field_179475_a.func_175489_ck().getBlock(), var7, var8))
{
var2.setBlockState(var6, this.field_179475_a.func_175489_ck(), 3);
this.field_179475_a.func_175490_a(Blocks.air.getDefaultState());
}
}
private boolean func_179474_a(World worldIn, BlockPos p_179474_2_, Block p_179474_3_, Block p_179474_4_, Block p_179474_5_)
{
return !p_179474_3_.canPlaceBlockAt(worldIn, p_179474_2_) ? false : (p_179474_4_.getMaterial() != Material.air ? false : (p_179474_5_.getMaterial() == Material.air ? false : p_179474_5_.isFullCube()));
}
}
class AITakeBlock extends EntityAIBase
{
private EntityEnderman field_179473_a = EntityEnderman.this;
private static final String __OBFID = "CL_00002220";
public boolean shouldExecute()
{
return !this.field_179473_a.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing") ? false : (this.field_179473_a.func_175489_ck().getBlock().getMaterial() != Material.air ? false : this.field_179473_a.getRNG().nextInt(20) == 0);
}
public void updateTask()
{
Random var1 = this.field_179473_a.getRNG();
World var2 = this.field_179473_a.worldObj;
int var3 = MathHelper.floor_double(this.field_179473_a.posX - 2.0D + var1.nextDouble() * 4.0D);
int var4 = MathHelper.floor_double(this.field_179473_a.posY + var1.nextDouble() * 3.0D);
int var5 = MathHelper.floor_double(this.field_179473_a.posZ - 2.0D + var1.nextDouble() * 4.0D);
BlockPos var6 = new BlockPos(var3, var4, var5);
IBlockState var7 = var2.getBlockState(var6);
Block var8 = var7.getBlock();
if (EntityEnderman.carriableBlocks.contains(var8))
{
this.field_179473_a.func_175490_a(var7);
var2.setBlockState(var6, Blocks.air.getDefaultState());
}
}
}
}