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.player.EntityPlayer;
007    import net.minecraft.entity.projectile.EntitySmallFireball;
008    import net.minecraft.item.Item;
009    import net.minecraft.util.DamageSource;
010    import net.minecraft.util.MathHelper;
011    import net.minecraft.world.World;
012    
013    public class EntityBlaze extends EntityMob
014    {
015        /** Random offset used in floating behaviour */
016        private float heightOffset = 0.5F;
017    
018        /** ticks until heightOffset is randomized */
019        private int heightOffsetUpdateTime;
020        private int field_70846_g;
021    
022        public EntityBlaze(World par1World)
023        {
024            super(par1World);
025            this.texture = "/mob/fire.png";
026            this.isImmuneToFire = true;
027            this.experienceValue = 10;
028        }
029    
030        public int getMaxHealth()
031        {
032            return 20;
033        }
034    
035        protected void entityInit()
036        {
037            super.entityInit();
038            this.dataWatcher.addObject(16, new Byte((byte)0));
039        }
040    
041        /**
042         * Returns the sound this mob makes while it's alive.
043         */
044        protected String getLivingSound()
045        {
046            return "mob.blaze.breathe";
047        }
048    
049        /**
050         * Returns the sound this mob makes when it is hurt.
051         */
052        protected String getHurtSound()
053        {
054            return "mob.blaze.hit";
055        }
056    
057        /**
058         * Returns the sound this mob makes on death.
059         */
060        protected String getDeathSound()
061        {
062            return "mob.blaze.death";
063        }
064    
065        @SideOnly(Side.CLIENT)
066        public int getBrightnessForRender(float par1)
067        {
068            return 15728880;
069        }
070    
071        /**
072         * Gets how bright this entity is.
073         */
074        public float getBrightness(float par1)
075        {
076            return 1.0F;
077        }
078    
079        /**
080         * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
081         * use this to react to sunlight and start to burn.
082         */
083        public void onLivingUpdate()
084        {
085            if (!this.worldObj.isRemote)
086            {
087                if (this.isWet())
088                {
089                    this.attackEntityFrom(DamageSource.drown, 1);
090                }
091    
092                --this.heightOffsetUpdateTime;
093    
094                if (this.heightOffsetUpdateTime <= 0)
095                {
096                    this.heightOffsetUpdateTime = 100;
097                    this.heightOffset = 0.5F + (float)this.rand.nextGaussian() * 3.0F;
098                }
099    
100                if (this.getEntityToAttack() != null && this.getEntityToAttack().posY + (double)this.getEntityToAttack().getEyeHeight() > this.posY + (double)this.getEyeHeight() + (double)this.heightOffset)
101                {
102                    this.motionY += (0.30000001192092896D - this.motionY) * 0.30000001192092896D;
103                }
104            }
105    
106            if (this.rand.nextInt(24) == 0)
107            {
108                this.worldObj.playSoundEffect(this.posX + 0.5D, this.posY + 0.5D, this.posZ + 0.5D, "fire.fire", 1.0F + this.rand.nextFloat(), this.rand.nextFloat() * 0.7F + 0.3F);
109            }
110    
111            if (!this.onGround && this.motionY < 0.0D)
112            {
113                this.motionY *= 0.6D;
114            }
115    
116            for (int var1 = 0; var1 < 2; ++var1)
117            {
118                this.worldObj.spawnParticle("largesmoke", this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0.0D, 0.0D, 0.0D);
119            }
120    
121            super.onLivingUpdate();
122        }
123    
124        /**
125         * Basic mob attack. Default to touch of death in EntityCreature. Overridden by each mob to define their attack.
126         */
127        protected void attackEntity(Entity par1Entity, float par2)
128        {
129            if (this.attackTime <= 0 && par2 < 2.0F && par1Entity.boundingBox.maxY > this.boundingBox.minY && par1Entity.boundingBox.minY < this.boundingBox.maxY)
130            {
131                this.attackTime = 20;
132                this.attackEntityAsMob(par1Entity);
133            }
134            else if (par2 < 30.0F)
135            {
136                double var3 = par1Entity.posX - this.posX;
137                double var5 = par1Entity.boundingBox.minY + (double)(par1Entity.height / 2.0F) - (this.posY + (double)(this.height / 2.0F));
138                double var7 = par1Entity.posZ - this.posZ;
139    
140                if (this.attackTime == 0)
141                {
142                    ++this.field_70846_g;
143    
144                    if (this.field_70846_g == 1)
145                    {
146                        this.attackTime = 60;
147                        this.func_70844_e(true);
148                    }
149                    else if (this.field_70846_g <= 4)
150                    {
151                        this.attackTime = 6;
152                    }
153                    else
154                    {
155                        this.attackTime = 100;
156                        this.field_70846_g = 0;
157                        this.func_70844_e(false);
158                    }
159    
160                    if (this.field_70846_g > 1)
161                    {
162                        float var9 = MathHelper.sqrt_float(par2) * 0.5F;
163                        this.worldObj.playAuxSFXAtEntity((EntityPlayer)null, 1009, (int)this.posX, (int)this.posY, (int)this.posZ, 0);
164    
165                        for (int var10 = 0; var10 < 1; ++var10)
166                        {
167                            EntitySmallFireball var11 = new EntitySmallFireball(this.worldObj, this, var3 + this.rand.nextGaussian() * (double)var9, var5, var7 + this.rand.nextGaussian() * (double)var9);
168                            var11.posY = this.posY + (double)(this.height / 2.0F) + 0.5D;
169                            this.worldObj.spawnEntityInWorld(var11);
170                        }
171                    }
172                }
173    
174                this.rotationYaw = (float)(Math.atan2(var7, var3) * 180.0D / Math.PI) - 90.0F;
175                this.hasAttacked = true;
176            }
177        }
178    
179        /**
180         * Called when the mob is falling. Calculates and applies fall damage.
181         */
182        protected void fall(float par1) {}
183    
184        /**
185         * Returns the item ID for the item the mob drops on death.
186         */
187        protected int getDropItemId()
188        {
189            return Item.blazeRod.itemID;
190        }
191    
192        /**
193         * Returns true if the entity is on fire. Used by render to add the fire effect on rendering.
194         */
195        public boolean isBurning()
196        {
197            return this.func_70845_n();
198        }
199    
200        /**
201         * Drop 0-2 items of this living's type. @param par1 - Whether this entity has recently been hit by a player. @param
202         * par2 - Level of Looting used to kill this mob.
203         */
204        protected void dropFewItems(boolean par1, int par2)
205        {
206            if (par1)
207            {
208                int var3 = this.rand.nextInt(2 + par2);
209    
210                for (int var4 = 0; var4 < var3; ++var4)
211                {
212                    this.dropItem(Item.blazeRod.itemID, 1);
213                }
214            }
215        }
216    
217        public boolean func_70845_n()
218        {
219            return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0;
220        }
221    
222        public void func_70844_e(boolean par1)
223        {
224            byte var2 = this.dataWatcher.getWatchableObjectByte(16);
225    
226            if (par1)
227            {
228                var2 = (byte)(var2 | 1);
229            }
230            else
231            {
232                var2 &= -2;
233            }
234    
235            this.dataWatcher.updateObject(16, Byte.valueOf(var2));
236        }
237    
238        /**
239         * Checks to make sure the light is not too bright where the mob is spawning
240         */
241        protected boolean isValidLightLevel()
242        {
243            return true;
244        }
245    
246        /**
247         * Returns the amount of damage a mob should deal.
248         */
249        public int getAttackStrength(Entity par1Entity)
250        {
251            return 6;
252        }
253    }