    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}