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