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