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