001    package net.minecraft.entity.monster;
002    
003    import cpw.mods.fml.relauncher.Side;
004    import cpw.mods.fml.relauncher.SideOnly;
005    import net.minecraft.entity.Entity;
006    import net.minecraft.entity.EnumCreatureAttribute;
007    import net.minecraft.item.Item;
008    import net.minecraft.potion.Potion;
009    import net.minecraft.potion.PotionEffect;
010    import net.minecraft.util.MathHelper;
011    import net.minecraft.world.World;
012    
013    public class EntitySpider extends EntityMob
014    {
015        public EntitySpider(World par1World)
016        {
017            super(par1World);
018            this.texture = "/mob/spider.png";
019            this.setSize(1.4F, 0.9F);
020            this.moveSpeed = 0.8F;
021        }
022    
023        protected void entityInit()
024        {
025            super.entityInit();
026            this.dataWatcher.addObject(16, new Byte((byte)0));
027        }
028    
029        /**
030         * Called to update the entity's position/logic.
031         */
032        public void onUpdate()
033        {
034            super.onUpdate();
035    
036            if (!this.worldObj.isRemote)
037            {
038                this.setBesideClimbableBlock(this.isCollidedHorizontally);
039            }
040        }
041    
042        public int getMaxHealth()
043        {
044            return 16;
045        }
046    
047        /**
048         * Returns the Y offset from the entity's position for any entity riding this one.
049         */
050        public double getMountedYOffset()
051        {
052            return (double)this.height * 0.75D - 0.5D;
053        }
054    
055        /**
056         * Finds the closest player within 16 blocks to attack, or null if this Entity isn't interested in attacking
057         * (Animals, Spiders at day, peaceful PigZombies).
058         */
059        protected Entity findPlayerToAttack()
060        {
061            float var1 = this.getBrightness(1.0F);
062    
063            if (var1 < 0.5F)
064            {
065                double var2 = 16.0D;
066                return this.worldObj.getClosestVulnerablePlayerToEntity(this, var2);
067            }
068            else
069            {
070                return null;
071            }
072        }
073    
074        /**
075         * Returns the sound this mob makes while it's alive.
076         */
077        protected String getLivingSound()
078        {
079            return "mob.spider.say";
080        }
081    
082        /**
083         * Returns the sound this mob makes when it is hurt.
084         */
085        protected String getHurtSound()
086        {
087            return "mob.spider.say";
088        }
089    
090        /**
091         * Returns the sound this mob makes on death.
092         */
093        protected String getDeathSound()
094        {
095            return "mob.spider.death";
096        }
097    
098        /**
099         * Plays step sound at given x, y, z for the entity
100         */
101        protected void playStepSound(int par1, int par2, int par3, int par4)
102        {
103            this.playSound("mob.spider.step", 0.15F, 1.0F);
104        }
105    
106        /**
107         * Basic mob attack. Default to touch of death in EntityCreature. Overridden by each mob to define their attack.
108         */
109        protected void attackEntity(Entity par1Entity, float par2)
110        {
111            float var3 = this.getBrightness(1.0F);
112    
113            if (var3 > 0.5F && this.rand.nextInt(100) == 0)
114            {
115                this.entityToAttack = null;
116            }
117            else
118            {
119                if (par2 > 2.0F && par2 < 6.0F && this.rand.nextInt(10) == 0)
120                {
121                    if (this.onGround)
122                    {
123                        double var4 = par1Entity.posX - this.posX;
124                        double var6 = par1Entity.posZ - this.posZ;
125                        float var8 = MathHelper.sqrt_double(var4 * var4 + var6 * var6);
126                        this.motionX = var4 / (double)var8 * 0.5D * 0.800000011920929D + this.motionX * 0.20000000298023224D;
127                        this.motionZ = var6 / (double)var8 * 0.5D * 0.800000011920929D + this.motionZ * 0.20000000298023224D;
128                        this.motionY = 0.4000000059604645D;
129                    }
130                }
131                else
132                {
133                    super.attackEntity(par1Entity, par2);
134                }
135            }
136        }
137    
138        /**
139         * Returns the item ID for the item the mob drops on death.
140         */
141        protected int getDropItemId()
142        {
143            return Item.silk.itemID;
144        }
145    
146        /**
147         * Drop 0-2 items of this living's type. @param par1 - Whether this entity has recently been hit by a player. @param
148         * par2 - Level of Looting used to kill this mob.
149         */
150        protected void dropFewItems(boolean par1, int par2)
151        {
152            super.dropFewItems(par1, par2);
153    
154            if (par1 && (this.rand.nextInt(3) == 0 || this.rand.nextInt(1 + par2) > 0))
155            {
156                this.dropItem(Item.spiderEye.itemID, 1);
157            }
158        }
159    
160        /**
161         * returns true if this entity is by a ladder, false otherwise
162         */
163        public boolean isOnLadder()
164        {
165            return this.isBesideClimbableBlock();
166        }
167    
168        /**
169         * Sets the Entity inside a web block.
170         */
171        public void setInWeb() {}
172    
173        @SideOnly(Side.CLIENT)
174    
175        /**
176         * How large the spider should be scaled.
177         */
178        public float spiderScaleAmount()
179        {
180            return 1.0F;
181        }
182    
183        /**
184         * Get this Entity's EnumCreatureAttribute
185         */
186        public EnumCreatureAttribute getCreatureAttribute()
187        {
188            return EnumCreatureAttribute.ARTHROPOD;
189        }
190    
191        public boolean isPotionApplicable(PotionEffect par1PotionEffect)
192        {
193            return par1PotionEffect.getPotionID() == Potion.poison.id ? false : super.isPotionApplicable(par1PotionEffect);
194        }
195    
196        /**
197         * Returns true if the WatchableObject (Byte) is 0x01 otherwise returns false. The WatchableObject is updated using
198         * setBesideClimableBlock.
199         */
200        public boolean isBesideClimbableBlock()
201        {
202            return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0;
203        }
204    
205        /**
206         * Updates the WatchableObject (Byte) created in entityInit(), setting it to 0x01 if par1 is true or 0x00 if it is
207         * false.
208         */
209        public void setBesideClimbableBlock(boolean par1)
210        {
211            byte var2 = this.dataWatcher.getWatchableObjectByte(16);
212    
213            if (par1)
214            {
215                var2 = (byte)(var2 | 1);
216            }
217            else
218            {
219                var2 &= -2;
220            }
221    
222            this.dataWatcher.updateObject(16, Byte.valueOf(var2));
223        }
224    
225        /**
226         * Initialize this creature.
227         */
228        public void initCreature()
229        {
230            if (this.worldObj.rand.nextInt(100) == 0)
231            {
232                EntitySkeleton var1 = new EntitySkeleton(this.worldObj);
233                var1.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, 0.0F);
234                var1.initCreature();
235                this.worldObj.spawnEntityInWorld(var1);
236                var1.mountEntity(this);
237            }
238        }
239    }