001    package net.minecraft.entity.monster;
002    
003    import net.minecraft.block.Block;
004    import net.minecraft.block.BlockSilverfish;
005    import net.minecraft.entity.Entity;
006    import net.minecraft.entity.EnumCreatureAttribute;
007    import net.minecraft.entity.player.EntityPlayer;
008    import net.minecraft.util.DamageSource;
009    import net.minecraft.util.EntityDamageSource;
010    import net.minecraft.util.Facing;
011    import net.minecraft.util.MathHelper;
012    import net.minecraft.world.World;
013    
014    public class EntitySilverfish extends EntityMob
015    {
016        /**
017         * A cooldown before this entity will search for another Silverfish to join them in battle.
018         */
019        private int allySummonCooldown;
020    
021        public EntitySilverfish(World par1World)
022        {
023            super(par1World);
024            this.texture = "/mob/silverfish.png";
025            this.setSize(0.3F, 0.7F);
026            this.moveSpeed = 0.6F;
027        }
028    
029        public int getMaxHealth()
030        {
031            return 8;
032        }
033    
034        /**
035         * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
036         * prevent them from trampling crops
037         */
038        protected boolean canTriggerWalking()
039        {
040            return false;
041        }
042    
043        /**
044         * Finds the closest player within 16 blocks to attack, or null if this Entity isn't interested in attacking
045         * (Animals, Spiders at day, peaceful PigZombies).
046         */
047        protected Entity findPlayerToAttack()
048        {
049            double var1 = 8.0D;
050            return this.worldObj.getClosestVulnerablePlayerToEntity(this, var1);
051        }
052    
053        /**
054         * Returns the sound this mob makes while it's alive.
055         */
056        protected String getLivingSound()
057        {
058            return "mob.silverfish.say";
059        }
060    
061        /**
062         * Returns the sound this mob makes when it is hurt.
063         */
064        protected String getHurtSound()
065        {
066            return "mob.silverfish.hit";
067        }
068    
069        /**
070         * Returns the sound this mob makes on death.
071         */
072        protected String getDeathSound()
073        {
074            return "mob.silverfish.kill";
075        }
076    
077        /**
078         * Called when the entity is attacked.
079         */
080        public boolean attackEntityFrom(DamageSource par1DamageSource, int par2)
081        {
082            if (this.isEntityInvulnerable())
083            {
084                return false;
085            }
086            else
087            {
088                if (this.allySummonCooldown <= 0 && (par1DamageSource instanceof EntityDamageSource || par1DamageSource == DamageSource.magic))
089                {
090                    this.allySummonCooldown = 20;
091                }
092    
093                return super.attackEntityFrom(par1DamageSource, par2);
094            }
095        }
096    
097        /**
098         * Basic mob attack. Default to touch of death in EntityCreature. Overridden by each mob to define their attack.
099         */
100        protected void attackEntity(Entity par1Entity, float par2)
101        {
102            if (this.attackTime <= 0 && par2 < 1.2F && par1Entity.boundingBox.maxY > this.boundingBox.minY && par1Entity.boundingBox.minY < this.boundingBox.maxY)
103            {
104                this.attackTime = 20;
105                this.attackEntityAsMob(par1Entity);
106            }
107        }
108    
109        /**
110         * Plays step sound at given x, y, z for the entity
111         */
112        protected void playStepSound(int par1, int par2, int par3, int par4)
113        {
114            this.playSound("mob.silverfish.step", 0.15F, 1.0F);
115        }
116    
117        /**
118         * Returns the item ID for the item the mob drops on death.
119         */
120        protected int getDropItemId()
121        {
122            return 0;
123        }
124    
125        /**
126         * Called to update the entity's position/logic.
127         */
128        public void onUpdate()
129        {
130            this.renderYawOffset = this.rotationYaw;
131            super.onUpdate();
132        }
133    
134        protected void updateEntityActionState()
135        {
136            super.updateEntityActionState();
137    
138            if (!this.worldObj.isRemote)
139            {
140                int var1;
141                int var2;
142                int var3;
143                int var5;
144    
145                if (this.allySummonCooldown > 0)
146                {
147                    --this.allySummonCooldown;
148    
149                    if (this.allySummonCooldown == 0)
150                    {
151                        var1 = MathHelper.floor_double(this.posX);
152                        var2 = MathHelper.floor_double(this.posY);
153                        var3 = MathHelper.floor_double(this.posZ);
154                        boolean var4 = false;
155    
156                        for (var5 = 0; !var4 && var5 <= 5 && var5 >= -5; var5 = var5 <= 0 ? 1 - var5 : 0 - var5)
157                        {
158                            for (int var6 = 0; !var4 && var6 <= 10 && var6 >= -10; var6 = var6 <= 0 ? 1 - var6 : 0 - var6)
159                            {
160                                for (int var7 = 0; !var4 && var7 <= 10 && var7 >= -10; var7 = var7 <= 0 ? 1 - var7 : 0 - var7)
161                                {
162                                    int var8 = this.worldObj.getBlockId(var1 + var6, var2 + var5, var3 + var7);
163    
164                                    if (var8 == Block.silverfish.blockID)
165                                    {
166                                        this.worldObj.playAuxSFX(2001, var1 + var6, var2 + var5, var3 + var7, Block.silverfish.blockID + (this.worldObj.getBlockMetadata(var1 + var6, var2 + var5, var3 + var7) << 12));
167                                        this.worldObj.setBlockWithNotify(var1 + var6, var2 + var5, var3 + var7, 0);
168                                        Block.silverfish.onBlockDestroyedByPlayer(this.worldObj, var1 + var6, var2 + var5, var3 + var7, 0);
169    
170                                        if (this.rand.nextBoolean())
171                                        {
172                                            var4 = true;
173                                            break;
174                                        }
175                                    }
176                                }
177                            }
178                        }
179                    }
180                }
181    
182                if (this.entityToAttack == null && !this.hasPath())
183                {
184                    var1 = MathHelper.floor_double(this.posX);
185                    var2 = MathHelper.floor_double(this.posY + 0.5D);
186                    var3 = MathHelper.floor_double(this.posZ);
187                    int var9 = this.rand.nextInt(6);
188                    var5 = this.worldObj.getBlockId(var1 + Facing.offsetsXForSide[var9], var2 + Facing.offsetsYForSide[var9], var3 + Facing.offsetsZForSide[var9]);
189    
190                    if (BlockSilverfish.getPosingIdByMetadata(var5))
191                    {
192                        this.worldObj.setBlockAndMetadataWithNotify(var1 + Facing.offsetsXForSide[var9], var2 + Facing.offsetsYForSide[var9], var3 + Facing.offsetsZForSide[var9], Block.silverfish.blockID, BlockSilverfish.getMetadataForBlockType(var5));
193                        this.spawnExplosionParticle();
194                        this.setDead();
195                    }
196                    else
197                    {
198                        this.updateWanderPath();
199                    }
200                }
201                else if (this.entityToAttack != null && !this.hasPath())
202                {
203                    this.entityToAttack = null;
204                }
205            }
206        }
207    
208        /**
209         * Takes a coordinate in and returns a weight to determine how likely this creature will try to path to the block.
210         * Args: x, y, z
211         */
212        public float getBlockPathWeight(int par1, int par2, int par3)
213        {
214            return this.worldObj.getBlockId(par1, par2 - 1, par3) == Block.stone.blockID ? 10.0F : super.getBlockPathWeight(par1, par2, par3);
215        }
216    
217        /**
218         * Checks to make sure the light is not too bright where the mob is spawning
219         */
220        protected boolean isValidLightLevel()
221        {
222            return true;
223        }
224    
225        /**
226         * Checks if the entity's current position is a valid location to spawn this entity.
227         */
228        public boolean getCanSpawnHere()
229        {
230            if (super.getCanSpawnHere())
231            {
232                EntityPlayer var1 = this.worldObj.getClosestPlayerToEntity(this, 5.0D);
233                return var1 == null;
234            }
235            else
236            {
237                return false;
238            }
239        }
240    
241        /**
242         * Returns the amount of damage a mob should deal.
243         */
244        public int getAttackStrength(Entity par1Entity)
245        {
246            return 1;
247        }
248    
249        /**
250         * Get this Entity's EnumCreatureAttribute
251         */
252        public EnumCreatureAttribute getCreatureAttribute()
253        {
254            return EnumCreatureAttribute.ARTHROPOD;
255        }
256    }