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