001package net.minecraft.entity.item; 002 003import cpw.mods.fml.relauncher.Side; 004import cpw.mods.fml.relauncher.SideOnly; 005import net.minecraft.entity.Entity; 006import net.minecraft.item.ItemStack; 007import net.minecraft.nbt.NBTTagCompound; 008import net.minecraft.util.MathHelper; 009import net.minecraft.world.World; 010 011public class EntityFireworkRocket extends Entity 012{ 013 /** The age of the firework in ticks. */ 014 private int fireworkAge; 015 016 /** 017 * The lifetime of the firework in ticks. When the age reaches the lifetime the firework explodes. 018 */ 019 private int lifetime; 020 021 public EntityFireworkRocket(World par1World) 022 { 023 super(par1World); 024 this.setSize(0.25F, 0.25F); 025 } 026 027 protected void entityInit() 028 { 029 this.dataWatcher.addObjectByDataType(8, 5); 030 } 031 032 @SideOnly(Side.CLIENT) 033 034 /** 035 * Checks if the entity is in range to render by using the past in distance and comparing it to its average edge 036 * length * 64 * renderDistanceWeight Args: distance 037 */ 038 public boolean isInRangeToRenderDist(double par1) 039 { 040 return par1 < 4096.0D; 041 } 042 043 public EntityFireworkRocket(World par1World, double par2, double par4, double par6, ItemStack par8ItemStack) 044 { 045 super(par1World); 046 this.fireworkAge = 0; 047 this.setSize(0.25F, 0.25F); 048 this.setPosition(par2, par4, par6); 049 this.yOffset = 0.0F; 050 int var9 = 1; 051 052 if (par8ItemStack != null && par8ItemStack.hasTagCompound()) 053 { 054 this.dataWatcher.updateObject(8, par8ItemStack); 055 NBTTagCompound var10 = par8ItemStack.getTagCompound(); 056 NBTTagCompound var11 = var10.getCompoundTag("Fireworks"); 057 058 if (var11 != null) 059 { 060 var9 += var11.getByte("Flight"); 061 } 062 } 063 064 this.motionX = this.rand.nextGaussian() * 0.001D; 065 this.motionZ = this.rand.nextGaussian() * 0.001D; 066 this.motionY = 0.05D; 067 this.lifetime = 10 * var9 + this.rand.nextInt(6) + this.rand.nextInt(7); 068 } 069 070 @SideOnly(Side.CLIENT) 071 072 /** 073 * Sets the velocity to the args. Args: x, y, z 074 */ 075 public void setVelocity(double par1, double par3, double par5) 076 { 077 this.motionX = par1; 078 this.motionY = par3; 079 this.motionZ = par5; 080 081 if (this.prevRotationPitch == 0.0F && this.prevRotationYaw == 0.0F) 082 { 083 float var7 = MathHelper.sqrt_double(par1 * par1 + par5 * par5); 084 this.prevRotationYaw = this.rotationYaw = (float)(Math.atan2(par1, par5) * 180.0D / Math.PI); 085 this.prevRotationPitch = this.rotationPitch = (float)(Math.atan2(par3, (double)var7) * 180.0D / Math.PI); 086 } 087 } 088 089 /** 090 * Called to update the entity's position/logic. 091 */ 092 public void onUpdate() 093 { 094 this.lastTickPosX = this.posX; 095 this.lastTickPosY = this.posY; 096 this.lastTickPosZ = this.posZ; 097 super.onUpdate(); 098 this.motionX *= 1.15D; 099 this.motionZ *= 1.15D; 100 this.motionY += 0.04D; 101 this.moveEntity(this.motionX, this.motionY, this.motionZ); 102 float var1 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); 103 this.rotationYaw = (float)(Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI); 104 105 for (this.rotationPitch = (float)(Math.atan2(this.motionY, (double)var1) * 180.0D / Math.PI); this.rotationPitch - this.prevRotationPitch < -180.0F; this.prevRotationPitch -= 360.0F) 106 { 107 ; 108 } 109 110 while (this.rotationPitch - this.prevRotationPitch >= 180.0F) 111 { 112 this.prevRotationPitch += 360.0F; 113 } 114 115 while (this.rotationYaw - this.prevRotationYaw < -180.0F) 116 { 117 this.prevRotationYaw -= 360.0F; 118 } 119 120 while (this.rotationYaw - this.prevRotationYaw >= 180.0F) 121 { 122 this.prevRotationYaw += 360.0F; 123 } 124 125 this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F; 126 this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F; 127 128 if (this.fireworkAge == 0) 129 { 130 this.worldObj.playSoundAtEntity(this, "fireworks.launch", 3.0F, 1.0F); 131 } 132 133 ++this.fireworkAge; 134 135 if (this.worldObj.isRemote && this.fireworkAge % 2 < 2) 136 { 137 this.worldObj.spawnParticle("fireworksSpark", this.posX, this.posY - 0.3D, this.posZ, this.rand.nextGaussian() * 0.05D, -this.motionY * 0.5D, this.rand.nextGaussian() * 0.05D); 138 } 139 140 if (!this.worldObj.isRemote && this.fireworkAge > this.lifetime) 141 { 142 this.worldObj.setEntityState(this, (byte)17); 143 this.setDead(); 144 } 145 } 146 147 @SideOnly(Side.CLIENT) 148 public void handleHealthUpdate(byte par1) 149 { 150 if (par1 == 17 && this.worldObj.isRemote) 151 { 152 ItemStack var2 = this.dataWatcher.getWatchableObjectItemStack(8); 153 NBTTagCompound var3 = null; 154 155 if (var2 != null && var2.hasTagCompound()) 156 { 157 var3 = var2.getTagCompound().getCompoundTag("Fireworks"); 158 } 159 160 this.worldObj.func_92088_a(this.posX, this.posY, this.posZ, this.motionX, this.motionY, this.motionZ, var3); 161 } 162 163 super.handleHealthUpdate(par1); 164 } 165 166 /** 167 * (abstract) Protected helper method to write subclass entity data to NBT. 168 */ 169 public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) 170 { 171 par1NBTTagCompound.setInteger("Life", this.fireworkAge); 172 par1NBTTagCompound.setInteger("LifeTime", this.lifetime); 173 ItemStack var2 = this.dataWatcher.getWatchableObjectItemStack(8); 174 175 if (var2 != null) 176 { 177 NBTTagCompound var3 = new NBTTagCompound(); 178 var2.writeToNBT(var3); 179 par1NBTTagCompound.setCompoundTag("FireworksItem", var3); 180 } 181 } 182 183 /** 184 * (abstract) Protected helper method to read subclass entity data from NBT. 185 */ 186 public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) 187 { 188 this.fireworkAge = par1NBTTagCompound.getInteger("Life"); 189 this.lifetime = par1NBTTagCompound.getInteger("LifeTime"); 190 NBTTagCompound var2 = par1NBTTagCompound.getCompoundTag("FireworksItem"); 191 192 if (var2 != null) 193 { 194 ItemStack var3 = ItemStack.loadItemStackFromNBT(var2); 195 196 if (var3 != null) 197 { 198 this.dataWatcher.updateObject(8, var3); 199 } 200 } 201 } 202 203 @SideOnly(Side.CLIENT) 204 public float getShadowSize() 205 { 206 return 0.0F; 207 } 208 209 /** 210 * Gets how bright this entity is. 211 */ 212 public float getBrightness(float par1) 213 { 214 return super.getBrightness(par1); 215 } 216 217 @SideOnly(Side.CLIENT) 218 public int getBrightnessForRender(float par1) 219 { 220 return super.getBrightnessForRender(par1); 221 } 222 223 /** 224 * If returns false, the item will not inflict any damage against entities. 225 */ 226 public boolean canAttackWithItem() 227 { 228 return false; 229 } 230}