001package net.minecraft.client.particle; 002 003import cpw.mods.fml.relauncher.Side; 004import cpw.mods.fml.relauncher.SideOnly; 005import net.minecraft.client.Minecraft; 006import net.minecraft.client.renderer.Tessellator; 007import net.minecraft.nbt.NBTTagCompound; 008import net.minecraft.nbt.NBTTagList; 009import net.minecraft.util.MathHelper; 010import net.minecraft.world.World; 011 012@SideOnly(Side.CLIENT) 013public class EntityFireworkStarterFX extends EntityFX 014{ 015 private int field_92042_ax = 0; 016 private final EffectRenderer field_92040_ay; 017 private NBTTagList fireworkExplosions; 018 boolean field_92041_a; 019 020 public EntityFireworkStarterFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, EffectRenderer par14EffectRenderer, NBTTagCompound par15NBTTagCompound) 021 { 022 super(par1World, par2, par4, par6, 0.0D, 0.0D, 0.0D); 023 this.motionX = par8; 024 this.motionY = par10; 025 this.motionZ = par12; 026 this.field_92040_ay = par14EffectRenderer; 027 this.particleMaxAge = 8; 028 029 if (par15NBTTagCompound != null) 030 { 031 this.fireworkExplosions = par15NBTTagCompound.getTagList("Explosions"); 032 033 if (this.fireworkExplosions != null && this.fireworkExplosions.tagCount() == 0) 034 { 035 this.fireworkExplosions = null; 036 } 037 else if (this.fireworkExplosions != null) 038 { 039 this.particleMaxAge = this.fireworkExplosions.tagCount() * 2 - 1; 040 041 for (int i = 0; i < this.fireworkExplosions.tagCount(); ++i) 042 { 043 NBTTagCompound nbttagcompound1 = (NBTTagCompound)this.fireworkExplosions.tagAt(i); 044 045 if (nbttagcompound1.getBoolean("Flicker")) 046 { 047 this.field_92041_a = true; 048 this.particleMaxAge += 15; 049 break; 050 } 051 } 052 } 053 } 054 } 055 056 public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) {} 057 058 /** 059 * Called to update the entity's position/logic. 060 */ 061 public void onUpdate() 062 { 063 boolean flag; 064 065 if (this.field_92042_ax == 0 && this.fireworkExplosions != null) 066 { 067 flag = this.func_92037_i(); 068 boolean flag1 = false; 069 070 if (this.fireworkExplosions.tagCount() >= 3) 071 { 072 flag1 = true; 073 } 074 else 075 { 076 for (int i = 0; i < this.fireworkExplosions.tagCount(); ++i) 077 { 078 NBTTagCompound nbttagcompound = (NBTTagCompound)this.fireworkExplosions.tagAt(i); 079 080 if (nbttagcompound.getByte("Type") == 1) 081 { 082 flag1 = true; 083 break; 084 } 085 } 086 } 087 088 String s = "fireworks." + (flag1 ? "largeBlast" : "blast") + (flag ? "_far" : ""); 089 this.worldObj.playSound(this.posX, this.posY, this.posZ, s, 20.0F, 0.95F + this.rand.nextFloat() * 0.1F, true); 090 } 091 092 if (this.field_92042_ax % 2 == 0 && this.fireworkExplosions != null && this.field_92042_ax / 2 < this.fireworkExplosions.tagCount()) 093 { 094 int j = this.field_92042_ax / 2; 095 NBTTagCompound nbttagcompound1 = (NBTTagCompound)this.fireworkExplosions.tagAt(j); 096 byte b0 = nbttagcompound1.getByte("Type"); 097 boolean flag2 = nbttagcompound1.getBoolean("Trail"); 098 boolean flag3 = nbttagcompound1.getBoolean("Flicker"); 099 int[] aint = nbttagcompound1.getIntArray("Colors"); 100 int[] aint1 = nbttagcompound1.getIntArray("FadeColors"); 101 102 if (b0 == 1) 103 { 104 this.func_92035_a(0.5D, 4, aint, aint1, flag2, flag3); 105 } 106 else if (b0 == 2) 107 { 108 this.func_92038_a(0.5D, new double[][] {{0.0D, 1.0D}, {0.3455D, 0.309D}, {0.9511D, 0.309D}, {0.3795918367346939D, -0.12653061224489795D}, {0.6122448979591837D, -0.8040816326530612D}, {0.0D, -0.35918367346938773D}}, aint, aint1, flag2, flag3, false); 109 } 110 else if (b0 == 3) 111 { 112 this.func_92038_a(0.5D, new double[][] {{0.0D, 0.2D}, {0.2D, 0.2D}, {0.2D, 0.6D}, {0.6D, 0.6D}, {0.6D, 0.2D}, {0.2D, 0.2D}, {0.2D, 0.0D}, {0.4D, 0.0D}, {0.4D, -0.6D}, {0.2D, -0.6D}, {0.2D, -0.4D}, {0.0D, -0.4D}}, aint, aint1, flag2, flag3, true); 113 } 114 else if (b0 == 4) 115 { 116 this.func_92036_a(aint, aint1, flag2, flag3); 117 } 118 else 119 { 120 this.func_92035_a(0.25D, 2, aint, aint1, flag2, flag3); 121 } 122 123 int k = aint[0]; 124 float f = (float)((k & 16711680) >> 16) / 255.0F; 125 float f1 = (float)((k & 65280) >> 8) / 255.0F; 126 float f2 = (float)((k & 255) >> 0) / 255.0F; 127 EntityFireworkOverlayFX entityfireworkoverlayfx = new EntityFireworkOverlayFX(this.worldObj, this.posX, this.posY, this.posZ); 128 entityfireworkoverlayfx.setRBGColorF(f, f1, f2); 129 this.field_92040_ay.addEffect(entityfireworkoverlayfx); 130 } 131 132 ++this.field_92042_ax; 133 134 if (this.field_92042_ax > this.particleMaxAge) 135 { 136 if (this.field_92041_a) 137 { 138 flag = this.func_92037_i(); 139 String s1 = "fireworks." + (flag ? "twinkle_far" : "twinkle"); 140 this.worldObj.playSound(this.posX, this.posY, this.posZ, s1, 20.0F, 0.9F + this.rand.nextFloat() * 0.15F, true); 141 } 142 143 this.setDead(); 144 } 145 } 146 147 private boolean func_92037_i() 148 { 149 Minecraft minecraft = Minecraft.getMinecraft(); 150 return minecraft == null || minecraft.renderViewEntity == null || minecraft.renderViewEntity.getDistanceSq(this.posX, this.posY, this.posZ) >= 256.0D; 151 } 152 153 private void func_92034_a(double par1, double par3, double par5, double par7, double par9, double par11, int[] par13ArrayOfInteger, int[] par14ArrayOfInteger, boolean par15, boolean par16) 154 { 155 EntityFireworkSparkFX entityfireworksparkfx = new EntityFireworkSparkFX(this.worldObj, par1, par3, par5, par7, par9, par11, this.field_92040_ay); 156 entityfireworksparkfx.func_92045_e(par15); 157 entityfireworksparkfx.func_92043_f(par16); 158 int i = this.rand.nextInt(par13ArrayOfInteger.length); 159 entityfireworksparkfx.func_92044_a(par13ArrayOfInteger[i]); 160 161 if (par14ArrayOfInteger != null && par14ArrayOfInteger.length > 0) 162 { 163 entityfireworksparkfx.func_92046_g(par14ArrayOfInteger[this.rand.nextInt(par14ArrayOfInteger.length)]); 164 } 165 166 this.field_92040_ay.addEffect(entityfireworksparkfx); 167 } 168 169 private void func_92035_a(double par1, int par3, int[] par4ArrayOfInteger, int[] par5ArrayOfInteger, boolean par6, boolean par7) 170 { 171 double d1 = this.posX; 172 double d2 = this.posY; 173 double d3 = this.posZ; 174 175 for (int j = -par3; j <= par3; ++j) 176 { 177 for (int k = -par3; k <= par3; ++k) 178 { 179 for (int l = -par3; l <= par3; ++l) 180 { 181 double d4 = (double)k + (this.rand.nextDouble() - this.rand.nextDouble()) * 0.5D; 182 double d5 = (double)j + (this.rand.nextDouble() - this.rand.nextDouble()) * 0.5D; 183 double d6 = (double)l + (this.rand.nextDouble() - this.rand.nextDouble()) * 0.5D; 184 double d7 = (double)MathHelper.sqrt_double(d4 * d4 + d5 * d5 + d6 * d6) / par1 + this.rand.nextGaussian() * 0.05D; 185 this.func_92034_a(d1, d2, d3, d4 / d7, d5 / d7, d6 / d7, par4ArrayOfInteger, par5ArrayOfInteger, par6, par7); 186 187 if (j != -par3 && j != par3 && k != -par3 && k != par3) 188 { 189 l += par3 * 2 - 1; 190 } 191 } 192 } 193 } 194 } 195 196 private void func_92038_a(double par1, double[][] par3ArrayOfDouble, int[] par4ArrayOfInteger, int[] par5ArrayOfInteger, boolean par6, boolean par7, boolean par8) 197 { 198 double d1 = par3ArrayOfDouble[0][0]; 199 double d2 = par3ArrayOfDouble[0][1]; 200 this.func_92034_a(this.posX, this.posY, this.posZ, d1 * par1, d2 * par1, 0.0D, par4ArrayOfInteger, par5ArrayOfInteger, par6, par7); 201 float f = this.rand.nextFloat() * (float)Math.PI; 202 double d3 = par8 ? 0.034D : 0.34D; 203 204 for (int i = 0; i < 3; ++i) 205 { 206 double d4 = (double)f + (double)((float)i * (float)Math.PI) * d3; 207 double d5 = d1; 208 double d6 = d2; 209 210 for (int j = 1; j < par3ArrayOfDouble.length; ++j) 211 { 212 double d7 = par3ArrayOfDouble[j][0]; 213 double d8 = par3ArrayOfDouble[j][1]; 214 215 for (double d9 = 0.25D; d9 <= 1.0D; d9 += 0.25D) 216 { 217 double d10 = (d5 + (d7 - d5) * d9) * par1; 218 double d11 = (d6 + (d8 - d6) * d9) * par1; 219 double d12 = d10 * Math.sin(d4); 220 d10 *= Math.cos(d4); 221 222 for (double d13 = -1.0D; d13 <= 1.0D; d13 += 2.0D) 223 { 224 this.func_92034_a(this.posX, this.posY, this.posZ, d10 * d13, d11, d12 * d13, par4ArrayOfInteger, par5ArrayOfInteger, par6, par7); 225 } 226 } 227 228 d5 = d7; 229 d6 = d8; 230 } 231 } 232 } 233 234 private void func_92036_a(int[] par1ArrayOfInteger, int[] par2ArrayOfInteger, boolean par3, boolean par4) 235 { 236 double d0 = this.rand.nextGaussian() * 0.05D; 237 double d1 = this.rand.nextGaussian() * 0.05D; 238 239 for (int i = 0; i < 70; ++i) 240 { 241 double d2 = this.motionX * 0.5D + this.rand.nextGaussian() * 0.15D + d0; 242 double d3 = this.motionZ * 0.5D + this.rand.nextGaussian() * 0.15D + d1; 243 double d4 = this.motionY * 0.5D + this.rand.nextDouble() * 0.5D; 244 this.func_92034_a(this.posX, this.posY, this.posZ, d2, d4, d3, par1ArrayOfInteger, par2ArrayOfInteger, par3, par4); 245 } 246 } 247 248 public int getFXLayer() 249 { 250 return 0; 251 } 252}