    001    package net.minecraft.src;
    002
    003    import java.util.ArrayList;
    004    import java.util.HashMap;
    005    import java.util.HashSet;
    006    import java.util.Iterator;
    007    import java.util.List;
    008    import java.util.Map;
    009    import java.util.Random;
    010
    011    public class Explosion
    012    {
    013        /** whether or not the explosion sets fire to blocks around it */
    014        public boolean isFlaming = false;
    015        private int field_77289_h = 16;
    016        private Random explosionRNG = new Random();
    017        private World worldObj;
    018        public double explosionX;
    019        public double explosionY;
    020        public double explosionZ;
    021        public Entity exploder;
    022        public float explosionSize;
    023        public List field_77281_g = new ArrayList();
    024        private Map field_77288_k = new HashMap();
    025
    026        public Explosion(World par1World, Entity par2Entity, double par3, double par5, double par7, float par9)
    027        {
    028            this.worldObj = par1World;
    029            this.exploder = par2Entity;
    030            this.explosionSize = par9;
    031            this.explosionX = par3;
    032            this.explosionY = par5;
    033            this.explosionZ = par7;
    034        }
    035
    036        /**
    037         * Does the first part of the explosion (destroy blocks)
    038         */
    039        public void doExplosionA()
    040        {
    041            float var1 = this.explosionSize;
    042            HashSet var2 = new HashSet();
    043            int var3;
    044            int var4;
    045            int var5;
    046            double var15;
    047            double var17;
    048            double var19;
    049
    050            for (var3 = 0; var3 < this.field_77289_h; ++var3)
    051            {
    052                for (var4 = 0; var4 < this.field_77289_h; ++var4)
    053                {
    054                    for (var5 = 0; var5 < this.field_77289_h; ++var5)
    055                    {
    056                        if (var3 == 0 || var3 == this.field_77289_h - 1 || var4 == 0 || var4 == this.field_77289_h - 1 || var5 == 0 || var5 == this.field_77289_h - 1)
    057                        {
    058                            double var6 = (double)((float)var3 / ((float)this.field_77289_h - 1.0F) * 2.0F - 1.0F);
    059                            double var8 = (double)((float)var4 / ((float)this.field_77289_h - 1.0F) * 2.0F - 1.0F);
    060                            double var10 = (double)((float)var5 / ((float)this.field_77289_h - 1.0F) * 2.0F - 1.0F);
    061                            double var12 = Math.sqrt(var6 * var6 + var8 * var8 + var10 * var10);
    062                            var6 /= var12;
    063                            var8 /= var12;
    064                            var10 /= var12;
    065                            float var14 = this.explosionSize * (0.7F + this.worldObj.rand.nextFloat() * 0.6F);
    066                            var15 = this.explosionX;
    067                            var17 = this.explosionY;
    068                            var19 = this.explosionZ;
    069
    070                            for (float var21 = 0.3F; var14 > 0.0F; var14 -= var21 * 0.75F)
    071                            {
    072                                int var22 = MathHelper.floor_double(var15);
    073                                int var23 = MathHelper.floor_double(var17);
    074                                int var24 = MathHelper.floor_double(var19);
    075                                int var25 = this.worldObj.getBlockId(var22, var23, var24);
    076
    077                                if (var25 > 0)
    078                                {
    079                                    var14 -= (Block.blocksList[var25].getExplosionResistance(this.exploder, worldObj, var22, var23, var24, explosionX, explosionY, explosionZ) + 0.3F) * var21;
    080                                }
    081
    082                                if (var14 > 0.0F)
    083                                {
    084                                    var2.add(new ChunkPosition(var22, var23, var24));
    085                                }
    086
    087                                var15 += var6 * (double)var21;
    088                                var17 += var8 * (double)var21;
    089                                var19 += var10 * (double)var21;
    090                            }
    091                        }
    092                    }
    093                }
    094            }
    095
    096            this.field_77281_g.addAll(var2);
    097            this.explosionSize *= 2.0F;
    098            var3 = MathHelper.floor_double(this.explosionX - (double)this.explosionSize - 1.0D);
    099            var4 = MathHelper.floor_double(this.explosionX + (double)this.explosionSize + 1.0D);
    100            var5 = MathHelper.floor_double(this.explosionY - (double)this.explosionSize - 1.0D);
    101            int var27 = MathHelper.floor_double(this.explosionY + (double)this.explosionSize + 1.0D);
    102            int var7 = MathHelper.floor_double(this.explosionZ - (double)this.explosionSize - 1.0D);
    103            int var28 = MathHelper.floor_double(this.explosionZ + (double)this.explosionSize + 1.0D);
    104            List var9 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this.exploder, AxisAlignedBB.getAABBPool().addOrModifyAABBInPool((double)var3, (double)var5, (double)var7, (double)var4, (double)var27, (double)var28));
    105            Vec3 var29 = Vec3.getVec3Pool().getVecFromPool(this.explosionX, this.explosionY, this.explosionZ);
    106
    107            for (int var11 = 0; var11 < var9.size(); ++var11)
    108            {
    109                Entity var30 = (Entity)var9.get(var11);
    110                double var13 = var30.getDistance(this.explosionX, this.explosionY, this.explosionZ) / (double)this.explosionSize;
    111
    112                if (var13 <= 1.0D)
    113                {
    114                    var15 = var30.posX - this.explosionX;
    115                    var17 = var30.posY + (double)var30.getEyeHeight() - this.explosionY;
    116                    var19 = var30.posZ - this.explosionZ;
    117                    double var32 = (double)MathHelper.sqrt_double(var15 * var15 + var17 * var17 + var19 * var19);
    118
    119                    if (var32 != 0.0D)
    120                    {
    121                        var15 /= var32;
    122                        var17 /= var32;
    123                        var19 /= var32;
    124                        double var31 = (double)this.worldObj.getBlockDensity(var29, var30.boundingBox);
    125                        double var33 = (1.0D - var13) * var31;
    126                        var30.attackEntityFrom(DamageSource.explosion, (int)((var33 * var33 + var33) / 2.0D * 8.0D * (double)this.explosionSize + 1.0D));
    127                        var30.motionX += var15 * var33;
    128                        var30.motionY += var17 * var33;
    129                        var30.motionZ += var19 * var33;
    130
    131                        if (var30 instanceof EntityPlayer)
    132                        {
    133                            this.field_77288_k.put((EntityPlayer)var30, Vec3.getVec3Pool().getVecFromPool(var15 * var33, var17 * var33, var19 * var33));
    134                        }
    135                    }
    136                }
    137            }
    138
    139            this.explosionSize = var1;
    140        }
    141
    142        /**
    143         * Does the second part of the explosion (sound, particles, drop spawn)
    144         */
    145        public void doExplosionB(boolean par1)
    146        {
    147            this.worldObj.playSoundEffect(this.explosionX, this.explosionY, this.explosionZ, "random.explode", 4.0F, (1.0F + (this.worldObj.rand.nextFloat() - this.worldObj.rand.nextFloat()) * 0.2F) * 0.7F);
    148            this.worldObj.spawnParticle("hugeexplosion", this.explosionX, this.explosionY, this.explosionZ, 0.0D, 0.0D, 0.0D);
    149            Iterator var2 = this.field_77281_g.iterator();
    150            ChunkPosition var3;
    151            int var4;
    152            int var5;
    153            int var6;
    154            int var7;
    155
    156            while (var2.hasNext())
    157            {
    158                var3 = (ChunkPosition)var2.next();
    159                var4 = var3.x;
    160                var5 = var3.y;
    161                var6 = var3.z;
    162                var7 = this.worldObj.getBlockId(var4, var5, var6);
    163
    164                if (par1)
    165                {
    166                    double var8 = (double)((float)var4 + this.worldObj.rand.nextFloat());
    167                    double var10 = (double)((float)var5 + this.worldObj.rand.nextFloat());
    168                    double var12 = (double)((float)var6 + this.worldObj.rand.nextFloat());
    169                    double var14 = var8 - this.explosionX;
    170                    double var16 = var10 - this.explosionY;
    171                    double var18 = var12 - this.explosionZ;
    172                    double var20 = (double)MathHelper.sqrt_double(var14 * var14 + var16 * var16 + var18 * var18);
    173                    var14 /= var20;
    174                    var16 /= var20;
    175                    var18 /= var20;
    176                    double var22 = 0.5D / (var20 / (double)this.explosionSize + 0.1D);
    177                    var22 *= (double)(this.worldObj.rand.nextFloat() * this.worldObj.rand.nextFloat() + 0.3F);
    178                    var14 *= var22;
    179                    var16 *= var22;
    180                    var18 *= var22;
    181                    this.worldObj.spawnParticle("explode", (var8 + this.explosionX * 1.0D) / 2.0D, (var10 + this.explosionY * 1.0D) / 2.0D, (var12 + this.explosionZ * 1.0D) / 2.0D, var14, var16, var18);
    182                    this.worldObj.spawnParticle("smoke", var8, var10, var12, var14, var16, var18);
    183                }
    184
    185                if (var7 > 0)
    186                {
    187                    Block.blocksList[var7].dropBlockAsItemWithChance(this.worldObj, var4, var5, var6, this.worldObj.getBlockMetadata(var4, var5, var6), 0.3F, 0);
    188
    189                    if (this.worldObj.setBlockAndMetadataWithUpdate(var4, var5, var6, 0, 0, this.worldObj.isRemote))
    190                    {
    191                        this.worldObj.notifyBlocksOfNeighborChange(var4, var5, var6, 0);
    192                    }
    193
    194                    Block.blocksList[var7].onBlockDestroyedByExplosion(this.worldObj, var4, var5, var6);
    195                }
    196            }
    197
    198            if (this.isFlaming)
    199            {
    200                var2 = this.field_77281_g.iterator();
    201
    202                while (var2.hasNext())
    203                {
    204                    var3 = (ChunkPosition)var2.next();
    205                    var4 = var3.x;
    206                    var5 = var3.y;
    207                    var6 = var3.z;
    208                    var7 = this.worldObj.getBlockId(var4, var5, var6);
    209                    int var24 = this.worldObj.getBlockId(var4, var5 - 1, var6);
    210
    211                    if (var7 == 0 && Block.opaqueCubeLookup[var24] && this.explosionRNG.nextInt(3) == 0)
    212                    {
    213                        this.worldObj.setBlockWithNotify(var4, var5, var6, Block.fire.blockID);
    214                    }
    215                }
    216            }
    217        }
    218
    219        public Map func_77277_b()
    220        {
    221            return this.field_77288_k;
    222        }
    223    }