001package net.minecraft.entity.item;
002
003import cpw.mods.fml.relauncher.Side;
004import cpw.mods.fml.relauncher.SideOnly;
005import net.minecraft.block.Block;
006import net.minecraft.block.BlockRailBase;
007import net.minecraft.item.ItemStack;
008import net.minecraft.nbt.NBTTagCompound;
009import net.minecraft.util.DamageSource;
010import net.minecraft.world.Explosion;
011import net.minecraft.world.World;
012
013public class EntityMinecartTNT extends EntityMinecart
014{
015    private int minecartTNTFuse = -1;
016
017    public EntityMinecartTNT(World par1)
018    {
019        super(par1);
020    }
021
022    public EntityMinecartTNT(World par1, double par2, double par4, double par6)
023    {
024        super(par1, par2, par4, par6);
025    }
026
027    public int getMinecartType()
028    {
029        return 3;
030    }
031
032    public Block getDefaultDisplayTile()
033    {
034        return Block.tnt;
035    }
036
037    /**
038     * Called to update the entity's position/logic.
039     */
040    public void onUpdate()
041    {
042        super.onUpdate();
043
044        if (this.minecartTNTFuse > 0)
045        {
046            --this.minecartTNTFuse;
047            this.worldObj.spawnParticle("smoke", this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, 0.0D);
048        }
049        else if (this.minecartTNTFuse == 0)
050        {
051            this.explodeCart(this.motionX * this.motionX + this.motionZ * this.motionZ);
052        }
053
054        if (this.isCollidedHorizontally)
055        {
056            double d0 = this.motionX * this.motionX + this.motionZ * this.motionZ;
057
058            if (d0 >= 0.009999999776482582D)
059            {
060                this.explodeCart(d0);
061            }
062        }
063    }
064
065    public void killMinecart(DamageSource par1DamageSource)
066    {
067        super.killMinecart(par1DamageSource);
068        double d0 = this.motionX * this.motionX + this.motionZ * this.motionZ;
069
070        if (!par1DamageSource.isExplosion())
071        {
072            this.entityDropItem(new ItemStack(Block.tnt, 1), 0.0F);
073        }
074
075        if (par1DamageSource.isFireDamage() || par1DamageSource.isExplosion() || d0 >= 0.009999999776482582D)
076        {
077            this.explodeCart(d0);
078        }
079    }
080
081    /**
082     * Makes the minecart explode.
083     */
084    protected void explodeCart(double par1)
085    {
086        if (!this.worldObj.isRemote)
087        {
088            double d1 = Math.sqrt(par1);
089
090            if (d1 > 5.0D)
091            {
092                d1 = 5.0D;
093            }
094
095            this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float)(4.0D + this.rand.nextDouble() * 1.5D * d1), true);
096            this.setDead();
097        }
098    }
099
100    /**
101     * Called when the mob is falling. Calculates and applies fall damage.
102     */
103    protected void fall(float par1)
104    {
105        if (par1 >= 3.0F)
106        {
107            float f1 = par1 / 10.0F;
108            this.explodeCart((double)(f1 * f1));
109        }
110
111        super.fall(par1);
112    }
113
114    /**
115     * Called every tick the minecart is on an activator rail.
116     */
117    public void onActivatorRailPass(int par1, int par2, int par3, boolean par4)
118    {
119        if (par4 && this.minecartTNTFuse < 0)
120        {
121            this.ignite();
122        }
123    }
124
125    @SideOnly(Side.CLIENT)
126    public void handleHealthUpdate(byte par1)
127    {
128        if (par1 == 10)
129        {
130            this.ignite();
131        }
132        else
133        {
134            super.handleHealthUpdate(par1);
135        }
136    }
137
138    /**
139     * Ignites this TNT cart.
140     */
141    public void ignite()
142    {
143        this.minecartTNTFuse = 80;
144
145        if (!this.worldObj.isRemote)
146        {
147            this.worldObj.setEntityState(this, (byte)10);
148            this.worldObj.playSoundAtEntity(this, "random.fuse", 1.0F, 1.0F);
149        }
150    }
151
152    @SideOnly(Side.CLIENT)
153    public int func_94104_d()
154    {
155        return this.minecartTNTFuse;
156    }
157
158    public boolean func_96096_ay()
159    {
160        return this.minecartTNTFuse > -1;
161    }
162
163    public float func_82146_a(Explosion par1Explosion, World par2World, int par3, int par4, int par5, Block par6Block)
164    {
165        return this.func_96096_ay() && (BlockRailBase.isRailBlock(par6Block.blockID) || BlockRailBase.isRailBlockAt(par2World, par3, par4 + 1, par5)) ? 0.0F : super.func_82146_a(par1Explosion, par2World, par3, par4, par5, par6Block);
166    }
167
168    public boolean func_96091_a(Explosion par1Explosion, World par2World, int par3, int par4, int par5, int par6, float par7)
169    {
170        return this.func_96096_ay() && (BlockRailBase.isRailBlock(par6) || BlockRailBase.isRailBlockAt(par2World, par3, par4 + 1, par5)) ? false : super.func_96091_a(par1Explosion, par2World, par3, par4, par5, par6, par7);
171    }
172
173    /**
174     * (abstract) Protected helper method to read subclass entity data from NBT.
175     */
176    protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
177    {
178        super.readEntityFromNBT(par1NBTTagCompound);
179
180        if (par1NBTTagCompound.hasKey("TNTFuse"))
181        {
182            this.minecartTNTFuse = par1NBTTagCompound.getInteger("TNTFuse");
183        }
184    }
185
186    /**
187     * (abstract) Protected helper method to write subclass entity data to NBT.
188     */
189    protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
190    {
191        super.writeEntityToNBT(par1NBTTagCompound);
192        par1NBTTagCompound.setInteger("TNTFuse", this.minecartTNTFuse);
193    }
194}