001 package net.minecraft.src; 002 003 import cpw.mods.fml.common.Side; 004 import cpw.mods.fml.common.asm.SideOnly; 005 import java.util.Iterator; 006 import java.util.List; 007 008 public class EntityFireball extends Entity 009 { 010 private int xTile = -1; 011 private int yTile = -1; 012 private int zTile = -1; 013 private int inTile = 0; 014 private boolean inGround = false; 015 public EntityLiving shootingEntity; 016 private int ticksAlive; 017 private int ticksInAir = 0; 018 public double accelerationX; 019 public double accelerationY; 020 public double accelerationZ; 021 022 public EntityFireball(World par1World) 023 { 024 super(par1World); 025 this.setSize(1.0F, 1.0F); 026 } 027 028 protected void entityInit() {} 029 030 @SideOnly(Side.CLIENT) 031 032 /** 033 * Checks if the entity is in range to render by using the past in distance and comparing it to its average edge 034 * length * 64 * renderDistanceWeight Args: distance 035 */ 036 public boolean isInRangeToRenderDist(double par1) 037 { 038 double var3 = this.boundingBox.getAverageEdgeLength() * 4.0D; 039 var3 *= 64.0D; 040 return par1 < var3 * var3; 041 } 042 043 public EntityFireball(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) 044 { 045 super(par1World); 046 this.setSize(1.0F, 1.0F); 047 this.setLocationAndAngles(par2, par4, par6, this.rotationYaw, this.rotationPitch); 048 this.setPosition(par2, par4, par6); 049 double var14 = (double)MathHelper.sqrt_double(par8 * par8 + par10 * par10 + par12 * par12); 050 this.accelerationX = par8 / var14 * 0.1D; 051 this.accelerationY = par10 / var14 * 0.1D; 052 this.accelerationZ = par12 / var14 * 0.1D; 053 } 054 055 public EntityFireball(World par1World, EntityLiving par2EntityLiving, double par3, double par5, double par7) 056 { 057 super(par1World); 058 this.shootingEntity = par2EntityLiving; 059 this.setSize(1.0F, 1.0F); 060 this.setLocationAndAngles(par2EntityLiving.posX, par2EntityLiving.posY, par2EntityLiving.posZ, par2EntityLiving.rotationYaw, par2EntityLiving.rotationPitch); 061 this.setPosition(this.posX, this.posY, this.posZ); 062 this.yOffset = 0.0F; 063 this.motionX = this.motionY = this.motionZ = 0.0D; 064 par3 += this.rand.nextGaussian() * 0.4D; 065 par5 += this.rand.nextGaussian() * 0.4D; 066 par7 += this.rand.nextGaussian() * 0.4D; 067 double var9 = (double)MathHelper.sqrt_double(par3 * par3 + par5 * par5 + par7 * par7); 068 this.accelerationX = par3 / var9 * 0.1D; 069 this.accelerationY = par5 / var9 * 0.1D; 070 this.accelerationZ = par7 / var9 * 0.1D; 071 } 072 073 /** 074 * Called to update the entity's position/logic. 075 */ 076 public void onUpdate() 077 { 078 if (!this.worldObj.isRemote && (this.shootingEntity != null && this.shootingEntity.isDead || !this.worldObj.blockExists((int)this.posX, (int)this.posY, (int)this.posZ))) 079 { 080 this.setDead(); 081 } 082 else 083 { 084 super.onUpdate(); 085 this.setFire(1); 086 087 if (this.inGround) 088 { 089 int var1 = this.worldObj.getBlockId(this.xTile, this.yTile, this.zTile); 090 091 if (var1 == this.inTile) 092 { 093 ++this.ticksAlive; 094 095 if (this.ticksAlive == 600) 096 { 097 this.setDead(); 098 } 099 100 return; 101 } 102 103 this.inGround = false; 104 this.motionX *= (double)(this.rand.nextFloat() * 0.2F); 105 this.motionY *= (double)(this.rand.nextFloat() * 0.2F); 106 this.motionZ *= (double)(this.rand.nextFloat() * 0.2F); 107 this.ticksAlive = 0; 108 this.ticksInAir = 0; 109 } 110 else 111 { 112 ++this.ticksInAir; 113 } 114 115 Vec3 var15 = Vec3.getVec3Pool().getVecFromPool(this.posX, this.posY, this.posZ); 116 Vec3 var2 = Vec3.getVec3Pool().getVecFromPool(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ); 117 MovingObjectPosition var3 = this.worldObj.rayTraceBlocks(var15, var2); 118 var15 = Vec3.getVec3Pool().getVecFromPool(this.posX, this.posY, this.posZ); 119 var2 = Vec3.getVec3Pool().getVecFromPool(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ); 120 121 if (var3 != null) 122 { 123 var2 = Vec3.getVec3Pool().getVecFromPool(var3.hitVec.xCoord, var3.hitVec.yCoord, var3.hitVec.zCoord); 124 } 125 126 Entity var4 = null; 127 List var5 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D)); 128 double var6 = 0.0D; 129 Iterator var8 = var5.iterator(); 130 131 while (var8.hasNext()) 132 { 133 Entity var9 = (Entity)var8.next(); 134 135 if (var9.canBeCollidedWith() && (!var9.isEntityEqual(this.shootingEntity) || this.ticksInAir >= 25)) 136 { 137 float var10 = 0.3F; 138 AxisAlignedBB var11 = var9.boundingBox.expand((double)var10, (double)var10, (double)var10); 139 MovingObjectPosition var12 = var11.calculateIntercept(var15, var2); 140 141 if (var12 != null) 142 { 143 double var13 = var15.distanceTo(var12.hitVec); 144 145 if (var13 < var6 || var6 == 0.0D) 146 { 147 var4 = var9; 148 var6 = var13; 149 } 150 } 151 } 152 } 153 154 if (var4 != null) 155 { 156 var3 = new MovingObjectPosition(var4); 157 } 158 159 if (var3 != null) 160 { 161 this.onImpact(var3); 162 } 163 164 this.posX += this.motionX; 165 this.posY += this.motionY; 166 this.posZ += this.motionZ; 167 float var16 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); 168 this.rotationYaw = (float)(Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI); 169 170 for (this.rotationPitch = (float)(Math.atan2(this.motionY, (double)var16) * 180.0D / Math.PI); this.rotationPitch - this.prevRotationPitch < -180.0F; this.prevRotationPitch -= 360.0F) 171 { 172 ; 173 } 174 175 while (this.rotationPitch - this.prevRotationPitch >= 180.0F) 176 { 177 this.prevRotationPitch += 360.0F; 178 } 179 180 while (this.rotationYaw - this.prevRotationYaw < -180.0F) 181 { 182 this.prevRotationYaw -= 360.0F; 183 } 184 185 while (this.rotationYaw - this.prevRotationYaw >= 180.0F) 186 { 187 this.prevRotationYaw += 360.0F; 188 } 189 190 this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F; 191 this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F; 192 float var17 = 0.95F; 193 194 if (this.isInWater()) 195 { 196 for (int var19 = 0; var19 < 4; ++var19) 197 { 198 float var18 = 0.25F; 199 this.worldObj.spawnParticle("bubble", this.posX - this.motionX * (double)var18, this.posY - this.motionY * (double)var18, this.posZ - this.motionZ * (double)var18, this.motionX, this.motionY, this.motionZ); 200 } 201 202 var17 = 0.8F; 203 } 204 205 this.motionX += this.accelerationX; 206 this.motionY += this.accelerationY; 207 this.motionZ += this.accelerationZ; 208 this.motionX *= (double)var17; 209 this.motionY *= (double)var17; 210 this.motionZ *= (double)var17; 211 this.worldObj.spawnParticle("smoke", this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, 0.0D); 212 this.setPosition(this.posX, this.posY, this.posZ); 213 } 214 } 215 216 /** 217 * Called when this EntityFireball hits a block or entity. 218 */ 219 protected void onImpact(MovingObjectPosition par1MovingObjectPosition) 220 { 221 if (!this.worldObj.isRemote) 222 { 223 if (par1MovingObjectPosition.entityHit != null) 224 { 225 par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.causeFireballDamage(this, this.shootingEntity), 6); 226 } 227 228 this.worldObj.newExplosion((Entity)null, this.posX, this.posY, this.posZ, 1.0F, true); 229 this.setDead(); 230 } 231 } 232 233 /** 234 * (abstract) Protected helper method to write subclass entity data to NBT. 235 */ 236 public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) 237 { 238 par1NBTTagCompound.setShort("xTile", (short)this.xTile); 239 par1NBTTagCompound.setShort("yTile", (short)this.yTile); 240 par1NBTTagCompound.setShort("zTile", (short)this.zTile); 241 par1NBTTagCompound.setByte("inTile", (byte)this.inTile); 242 par1NBTTagCompound.setByte("inGround", (byte)(this.inGround ? 1 : 0)); 243 par1NBTTagCompound.setTag("direction", this.newDoubleNBTList(new double[] {this.motionX, this.motionY, this.motionZ})); 244 } 245 246 /** 247 * (abstract) Protected helper method to read subclass entity data from NBT. 248 */ 249 public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) 250 { 251 this.xTile = par1NBTTagCompound.getShort("xTile"); 252 this.yTile = par1NBTTagCompound.getShort("yTile"); 253 this.zTile = par1NBTTagCompound.getShort("zTile"); 254 this.inTile = par1NBTTagCompound.getByte("inTile") & 255; 255 this.inGround = par1NBTTagCompound.getByte("inGround") == 1; 256 257 if (par1NBTTagCompound.hasKey("direction")) 258 { 259 NBTTagList var2 = par1NBTTagCompound.getTagList("direction"); 260 this.motionX = ((NBTTagDouble)var2.tagAt(0)).data; 261 this.motionY = ((NBTTagDouble)var2.tagAt(1)).data; 262 this.motionZ = ((NBTTagDouble)var2.tagAt(2)).data; 263 } 264 else 265 { 266 this.setDead(); 267 } 268 } 269 270 /** 271 * Returns true if other Entities should be prevented from moving through this Entity. 272 */ 273 public boolean canBeCollidedWith() 274 { 275 return true; 276 } 277 278 public float getCollisionBorderSize() 279 { 280 return 1.0F; 281 } 282 283 /** 284 * Called when the entity is attacked. 285 */ 286 public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) 287 { 288 this.setBeenAttacked(); 289 290 if (par1DamageSource.getEntity() != null) 291 { 292 Vec3 var3 = par1DamageSource.getEntity().getLookVec(); 293 294 if (var3 != null) 295 { 296 this.motionX = var3.xCoord; 297 this.motionY = var3.yCoord; 298 this.motionZ = var3.zCoord; 299 this.accelerationX = this.motionX * 0.1D; 300 this.accelerationY = this.motionY * 0.1D; 301 this.accelerationZ = this.motionZ * 0.1D; 302 } 303 304 if (par1DamageSource.getEntity() instanceof EntityLiving) 305 { 306 this.shootingEntity = (EntityLiving)par1DamageSource.getEntity(); 307 } 308 309 return true; 310 } 311 else 312 { 313 return false; 314 } 315 } 316 317 @SideOnly(Side.CLIENT) 318 public float getShadowSize() 319 { 320 return 0.0F; 321 } 322 323 /** 324 * Gets how bright this entity is. 325 */ 326 public float getBrightness(float par1) 327 { 328 return 1.0F; 329 } 330 331 @SideOnly(Side.CLIENT) 332 public int getBrightnessForRender(float par1) 333 { 334 return 15728880; 335 } 336 }