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 }