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