001package net.minecraft.entity.item;
002
003import net.minecraft.block.Block;
004import net.minecraft.entity.player.EntityPlayer;
005import net.minecraft.item.Item;
006import net.minecraft.item.ItemStack;
007import net.minecraft.nbt.NBTTagCompound;
008import net.minecraft.util.DamageSource;
009import net.minecraft.util.MathHelper;
010import net.minecraft.world.World;
011import net.minecraftforge.common.MinecraftForge;
012import net.minecraftforge.event.entity.minecart.MinecartInteractEvent;
013
014public class EntityMinecartFurnace extends EntityMinecart
015{
016    private int fuel = 0;
017    public double pushX;
018    public double pushZ;
019
020    public EntityMinecartFurnace(World par1World)
021    {
022        super(par1World);
023    }
024
025    public EntityMinecartFurnace(World par1World, double par2, double par4, double par6)
026    {
027        super(par1World, par2, par4, par6);
028    }
029
030    public int getMinecartType()
031    {
032        return 2;
033    }
034
035    protected void entityInit()
036    {
037        super.entityInit();
038        this.dataWatcher.addObject(16, new Byte((byte)0));
039    }
040
041    /**
042     * Called to update the entity's position/logic.
043     */
044    public void onUpdate()
045    {
046        super.onUpdate();
047
048        if (this.fuel > 0)
049        {
050            --this.fuel;
051        }
052
053        if (this.fuel <= 0)
054        {
055            this.pushX = this.pushZ = 0.0D;
056        }
057
058        this.setMinecartPowered(this.fuel > 0);
059
060        if (this.isMinecartPowered() && this.rand.nextInt(4) == 0)
061        {
062            this.worldObj.spawnParticle("largesmoke", this.posX, this.posY + 0.8D, this.posZ, 0.0D, 0.0D, 0.0D);
063        }
064    }
065
066    public void killMinecart(DamageSource par1DamageSource)
067    {
068        super.killMinecart(par1DamageSource);
069
070        if (!par1DamageSource.isExplosion())
071        {
072            this.entityDropItem(new ItemStack(Block.furnaceIdle, 1), 0.0F);
073        }
074    }
075
076    protected void updateOnTrack(int par1, int par2, int par3, double par4, double par6, int par8, int par9)
077    {
078        super.updateOnTrack(par1, par2, par3, par4, par6, par8, par9);
079        double d2 = this.pushX * this.pushX + this.pushZ * this.pushZ;
080
081        if (d2 > 1.0E-4D && this.motionX * this.motionX + this.motionZ * this.motionZ > 0.001D)
082        {
083            d2 = (double)MathHelper.sqrt_double(d2);
084            this.pushX /= d2;
085            this.pushZ /= d2;
086
087            if (this.pushX * this.motionX + this.pushZ * this.motionZ < 0.0D)
088            {
089                this.pushX = 0.0D;
090                this.pushZ = 0.0D;
091            }
092            else
093            {
094                this.pushX = this.motionX;
095                this.pushZ = this.motionZ;
096            }
097        }
098    }
099
100    protected void applyDrag()
101    {
102        double d0 = this.pushX * this.pushX + this.pushZ * this.pushZ;
103
104        if (d0 > 1.0E-4D)
105        {
106            d0 = (double)MathHelper.sqrt_double(d0);
107            this.pushX /= d0;
108            this.pushZ /= d0;
109            double d1 = 0.05D;
110            this.motionX *= 0.800000011920929D;
111            this.motionY *= 0.0D;
112            this.motionZ *= 0.800000011920929D;
113            this.motionX += this.pushX * d1;
114            this.motionZ += this.pushZ * d1;
115        }
116        else
117        {
118            this.motionX *= 0.9800000190734863D;
119            this.motionY *= 0.0D;
120            this.motionZ *= 0.9800000190734863D;
121        }
122
123        super.applyDrag();
124    }
125
126    /**
127     * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
128     */
129    public boolean interact(EntityPlayer par1EntityPlayer)
130    {
131        if(MinecraftForge.EVENT_BUS.post(new MinecartInteractEvent(this, par1EntityPlayer))) 
132        {
133            return true;
134        }
135        ItemStack itemstack = par1EntityPlayer.inventory.getCurrentItem();
136
137        if (itemstack != null && itemstack.itemID == Item.coal.itemID)
138        {
139            if (--itemstack.stackSize == 0)
140            {
141                par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack)null);
142            }
143
144            this.fuel += 3600;
145        }
146
147        this.pushX = this.posX - par1EntityPlayer.posX;
148        this.pushZ = this.posZ - par1EntityPlayer.posZ;
149        return true;
150    }
151
152    /**
153     * (abstract) Protected helper method to write subclass entity data to NBT.
154     */
155    protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
156    {
157        super.writeEntityToNBT(par1NBTTagCompound);
158        par1NBTTagCompound.setDouble("PushX", this.pushX);
159        par1NBTTagCompound.setDouble("PushZ", this.pushZ);
160        par1NBTTagCompound.setShort("Fuel", (short)this.fuel);
161    }
162
163    /**
164     * (abstract) Protected helper method to read subclass entity data from NBT.
165     */
166    protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
167    {
168        super.readEntityFromNBT(par1NBTTagCompound);
169        this.pushX = par1NBTTagCompound.getDouble("PushX");
170        this.pushZ = par1NBTTagCompound.getDouble("PushZ");
171        this.fuel = par1NBTTagCompound.getShort("Fuel");
172    }
173
174    protected boolean isMinecartPowered()
175    {
176        return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0;
177    }
178
179    protected void setMinecartPowered(boolean par1)
180    {
181        if (par1)
182        {
183            this.dataWatcher.updateObject(16, Byte.valueOf((byte)(this.dataWatcher.getWatchableObjectByte(16) | 1)));
184        }
185        else
186        {
187            this.dataWatcher.updateObject(16, Byte.valueOf((byte)(this.dataWatcher.getWatchableObjectByte(16) & -2)));
188        }
189    }
190
191    public Block getDefaultDisplayTile()
192    {
193        return Block.furnaceBurning;
194    }
195
196    public int getDefaultDisplayTileData()
197    {
198        return 2;
199    }
200}