package net.minecraft.entity.monster; import net.minecraft.block.material.Material; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.IRangedAttackMob; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.ai.EntityAIArrowAttack; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAIWander; import net.minecraft.entity.ai.EntityAIWatchClosest; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.projectile.EntitySnowball; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.util.DamageSource; import net.minecraft.util.MathHelper; import net.minecraft.world.World; public class EntitySnowman extends EntityGolem implements IRangedAttackMob { private static final String __OBFID = "CL_00001650"; public EntitySnowman(World p_i1692_1_) { super(p_i1692_1_); this.setSize(0.4F, 1.8F); this.getNavigator().setAvoidsWater(true); this.tasks.addTask(1, new EntityAIArrowAttack(this, 1.25D, 20, 10.0F)); this.tasks.addTask(2, new EntityAIWander(this, 1.0D)); this.tasks.addTask(3, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F)); this.tasks.addTask(4, new EntityAILookIdle(this)); this.targetTasks.addTask(1, new EntityAINearestAttackableTarget(this, EntityLiving.class, 0, true, false, IMob.mobSelector)); } /** * Returns true if the newer Entity AI code should be run */ public boolean isAIEnabled() { return true; } protected void applyEntityAttributes() { super.applyEntityAttributes(); this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(4.0D); this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.20000000298023224D); } /** * 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() { super.onLivingUpdate(); int i = MathHelper.floor_double(this.posX); int j = MathHelper.floor_double(this.posY); int k = MathHelper.floor_double(this.posZ); if (this.isWet()) { this.attackEntityFrom(DamageSource.drown, 1.0F); } if (this.worldObj.getBiomeGenForCoords(i, k).getFloatTemperature(i, j, k) > 1.0F) { this.attackEntityFrom(DamageSource.onFire, 1.0F); } for (int l = 0; l < 4; ++l) { i = MathHelper.floor_double(this.posX + (double)((float)(l % 2 * 2 - 1) * 0.25F)); j = MathHelper.floor_double(this.posY); k = MathHelper.floor_double(this.posZ + (double)((float)(l / 2 % 2 * 2 - 1) * 0.25F)); if (this.worldObj.getBlock(i, j, k).getMaterial() == Material.air && this.worldObj.getBiomeGenForCoords(i, k).getFloatTemperature(i, j, k) < 0.8F && Blocks.snow_layer.canPlaceBlockAt(this.worldObj, i, j, k)) { this.worldObj.setBlock(i, j, k, Blocks.snow_layer); } } } protected Item getDropItem() { return Items.snowball; } /** * Drop 0-2 items of this living's type */ protected void dropFewItems(boolean p_70628_1_, int p_70628_2_) { int j = this.rand.nextInt(16); for (int k = 0; k < j; ++k) { this.dropItem(Items.snowball, 1); } } /** * Attack the specified entity using a ranged attack. */ public void attackEntityWithRangedAttack(EntityLivingBase p_82196_1_, float p_82196_2_) { EntitySnowball entitysnowball = new EntitySnowball(this.worldObj, this); double d0 = p_82196_1_.posX - this.posX; double d1 = p_82196_1_.posY + (double)p_82196_1_.getEyeHeight() - 1.100000023841858D - entitysnowball.posY; double d2 = p_82196_1_.posZ - this.posZ; float f1 = MathHelper.sqrt_double(d0 * d0 + d2 * d2) * 0.2F; entitysnowball.setThrowableHeading(d0, d1 + (double)f1, d2, 1.6F, 12.0F); this.playSound("random.bow", 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F)); this.worldObj.spawnEntityInWorld(entitysnowball); } }