001    package net.minecraft.src;
002    
003    import cpw.mods.fml.common.Side;
004    import cpw.mods.fml.common.asm.SideOnly;
005    import java.util.Iterator;
006    import java.util.List;
007    
008    public class EntityLightningBolt extends EntityWeatherEffect
009    {
010        /**
011         * Declares which state the lightning bolt is in. Whether it's in the air, hit the ground, etc.
012         */
013        private int lightningState;
014    
015        /**
016         * A random long that is used to change the vertex of the lightning rendered in RenderLightningBolt
017         */
018        public long boltVertex = 0L;
019    
020        /**
021         * Determines the time before the EntityLightningBolt is destroyed. It is a random integer decremented over time.
022         */
023        private int boltLivingTime;
024    
025        public EntityLightningBolt(World par1World, double par2, double par4, double par6)
026        {
027            super(par1World);
028            this.setLocationAndAngles(par2, par4, par6, 0.0F, 0.0F);
029            this.lightningState = 2;
030            this.boltVertex = this.rand.nextLong();
031            this.boltLivingTime = this.rand.nextInt(3) + 1;
032    
033            if (par1World.difficultySetting >= 2 && par1World.doChunksNearChunkExist(MathHelper.floor_double(par2), MathHelper.floor_double(par4), MathHelper.floor_double(par6), 10))
034            {
035                int var8 = MathHelper.floor_double(par2);
036                int var9 = MathHelper.floor_double(par4);
037                int var10 = MathHelper.floor_double(par6);
038    
039                if (par1World.getBlockId(var8, var9, var10) == 0 && Block.fire.canPlaceBlockAt(par1World, var8, var9, var10))
040                {
041                    par1World.setBlockWithNotify(var8, var9, var10, Block.fire.blockID);
042                }
043    
044                for (var8 = 0; var8 < 4; ++var8)
045                {
046                    var9 = MathHelper.floor_double(par2) + this.rand.nextInt(3) - 1;
047                    var10 = MathHelper.floor_double(par4) + this.rand.nextInt(3) - 1;
048                    int var11 = MathHelper.floor_double(par6) + this.rand.nextInt(3) - 1;
049    
050                    if (par1World.getBlockId(var9, var10, var11) == 0 && Block.fire.canPlaceBlockAt(par1World, var9, var10, var11))
051                    {
052                        par1World.setBlockWithNotify(var9, var10, var11, Block.fire.blockID);
053                    }
054                }
055            }
056        }
057    
058        /**
059         * Called to update the entity's position/logic.
060         */
061        public void onUpdate()
062        {
063            super.onUpdate();
064    
065            if (this.lightningState == 2)
066            {
067                this.worldObj.playSoundEffect(this.posX, this.posY, this.posZ, "ambient.weather.thunder", 10000.0F, 0.8F + this.rand.nextFloat() * 0.2F);
068                this.worldObj.playSoundEffect(this.posX, this.posY, this.posZ, "random.explode", 2.0F, 0.5F + this.rand.nextFloat() * 0.2F);
069            }
070    
071            --this.lightningState;
072    
073            if (this.lightningState < 0)
074            {
075                if (this.boltLivingTime == 0)
076                {
077                    this.setDead();
078                }
079                else if (this.lightningState < -this.rand.nextInt(10))
080                {
081                    --this.boltLivingTime;
082                    this.lightningState = 1;
083                    this.boltVertex = this.rand.nextLong();
084    
085                    if (this.worldObj.doChunksNearChunkExist(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ), 10))
086                    {
087                        int var1 = MathHelper.floor_double(this.posX);
088                        int var2 = MathHelper.floor_double(this.posY);
089                        int var3 = MathHelper.floor_double(this.posZ);
090    
091                        if (this.worldObj.getBlockId(var1, var2, var3) == 0 && Block.fire.canPlaceBlockAt(this.worldObj, var1, var2, var3))
092                        {
093                            this.worldObj.setBlockWithNotify(var1, var2, var3, Block.fire.blockID);
094                        }
095                    }
096                }
097            }
098    
099            if (this.lightningState >= 0)
100            {
101                double var6 = 3.0D;
102                List var7 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, AxisAlignedBB.getAABBPool().addOrModifyAABBInPool(this.posX - var6, this.posY - var6, this.posZ - var6, this.posX + var6, this.posY + 6.0D + var6, this.posZ + var6));
103                Iterator var4 = var7.iterator();
104    
105                while (var4.hasNext())
106                {
107                    Entity var5 = (Entity)var4.next();
108                    var5.onStruckByLightning(this);
109                }
110    
111                this.worldObj.lightningFlash = 2;
112            }
113        }
114    
115        protected void entityInit() {}
116    
117        /**
118         * (abstract) Protected helper method to read subclass entity data from NBT.
119         */
120        protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) {}
121    
122        /**
123         * (abstract) Protected helper method to write subclass entity data to NBT.
124         */
125        protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) {}
126    
127        @SideOnly(Side.CLIENT)
128    
129        /**
130         * Checks using a Vec3d to determine if this entity is within range of that vector to be rendered. Args: vec3D
131         */
132        public boolean isInRangeToRenderVec3D(Vec3 par1Vec3)
133        {
134            return this.lightningState >= 0;
135        }
136    }