001    package net.minecraft.src;
002    
003    import cpw.mods.fml.common.Side;
004    import cpw.mods.fml.common.asm.SideOnly;
005    
006    public class EntitySkeleton extends EntityMob
007    {
008        /** The ItemStack that any Skeleton holds (a bow). */
009        private static final ItemStack defaultHeldItem = new ItemStack(Item.bow, 1);
010    
011        public EntitySkeleton(World par1World)
012        {
013            super(par1World);
014            this.texture = "/mob/skeleton.png";
015            this.moveSpeed = 0.25F;
016            this.tasks.addTask(1, new EntityAISwimming(this));
017            this.tasks.addTask(2, new EntityAIRestrictSun(this));
018            this.tasks.addTask(3, new EntityAIFleeSun(this, this.moveSpeed));
019            this.tasks.addTask(4, new EntityAIArrowAttack(this, this.moveSpeed, 1, 60));
020            this.tasks.addTask(5, new EntityAIWander(this, this.moveSpeed));
021            this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
022            this.tasks.addTask(6, new EntityAILookIdle(this));
023            this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false));
024            this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 16.0F, 0, true));
025        }
026    
027        /**
028         * Returns true if the newer Entity AI code should be run
029         */
030        public boolean isAIEnabled()
031        {
032            return true;
033        }
034    
035        public int getMaxHealth()
036        {
037            return 20;
038        }
039    
040        /**
041         * Returns the sound this mob makes while it's alive.
042         */
043        protected String getLivingSound()
044        {
045            return "mob.skeleton";
046        }
047    
048        /**
049         * Returns the sound this mob makes when it is hurt.
050         */
051        protected String getHurtSound()
052        {
053            return "mob.skeletonhurt";
054        }
055    
056        /**
057         * Returns the sound this mob makes on death.
058         */
059        protected String getDeathSound()
060        {
061            return "mob.skeletonhurt";
062        }
063    
064        @SideOnly(Side.CLIENT)
065    
066        /**
067         * Returns the item that this EntityLiving is holding, if any.
068         */
069        public ItemStack getHeldItem()
070        {
071            return defaultHeldItem;
072        }
073    
074        /**
075         * Get this Entity's EnumCreatureAttribute
076         */
077        public EnumCreatureAttribute getCreatureAttribute()
078        {
079            return EnumCreatureAttribute.UNDEAD;
080        }
081    
082        /**
083         * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
084         * use this to react to sunlight and start to burn.
085         */
086        public void onLivingUpdate()
087        {
088            if (this.worldObj.isDaytime() && !this.worldObj.isRemote)
089            {
090                float var1 = this.getBrightness(1.0F);
091    
092                if (var1 > 0.5F && this.worldObj.canBlockSeeTheSky(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)) && this.rand.nextFloat() * 30.0F < (var1 - 0.4F) * 2.0F)
093                {
094                    this.setFire(8);
095                }
096            }
097    
098            super.onLivingUpdate();
099        }
100    
101        /**
102         * Called when the mob's health reaches 0.
103         */
104        public void onDeath(DamageSource par1DamageSource)
105        {
106            super.onDeath(par1DamageSource);
107    
108            if (par1DamageSource.getSourceOfDamage() instanceof EntityArrow && par1DamageSource.getEntity() instanceof EntityPlayer)
109            {
110                EntityPlayer var2 = (EntityPlayer)par1DamageSource.getEntity();
111                double var3 = var2.posX - this.posX;
112                double var5 = var2.posZ - this.posZ;
113    
114                if (var3 * var3 + var5 * var5 >= 2500.0D)
115                {
116                    var2.triggerAchievement(AchievementList.snipeSkeleton);
117                }
118            }
119        }
120    
121        /**
122         * Returns the item ID for the item the mob drops on death.
123         */
124        protected int getDropItemId()
125        {
126            return Item.arrow.shiftedIndex;
127        }
128    
129        /**
130         * Drop 0-2 items of this living's type
131         */
132        protected void dropFewItems(boolean par1, int par2)
133        {
134            int var3 = this.rand.nextInt(3 + par2);
135            int var4;
136    
137            for (var4 = 0; var4 < var3; ++var4)
138            {
139                this.dropItem(Item.arrow.shiftedIndex, 1);
140            }
141    
142            var3 = this.rand.nextInt(3 + par2);
143    
144            for (var4 = 0; var4 < var3; ++var4)
145            {
146                this.dropItem(Item.bone.shiftedIndex, 1);
147            }
148        }
149    
150        protected void dropRareDrop(int par1)
151        {
152            if (par1 > 0)
153            {
154                ItemStack var2 = new ItemStack(Item.bow);
155                EnchantmentHelper.addRandomEnchantment(this.rand, var2, 5);
156                this.entityDropItem(var2, 0.0F);
157            }
158            else
159            {
160                this.dropItem(Item.bow.shiftedIndex, 1);
161            }
162        }
163    }