001package net.minecraft.tileentity;
002
003import net.minecraft.block.Block;
004import net.minecraft.entity.player.EntityPlayer;
005
006public class TileEntityEnderChest extends TileEntity
007{
008    /** The current angle of the chest lid (between 0 and 1) */
009    public float lidAngle;
010
011    /** The angle of the chest lid last tick */
012    public float prevLidAngle;
013
014    /** The number of players currently using this ender chest. */
015    public int numUsingPlayers;
016
017    /** Server sync counter (once per 20 ticks) */
018    private int ticksSinceSync;
019
020    /**
021     * Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count
022     * ticks and creates a new spawn inside its implementation.
023     */
024    public void updateEntity()
025    {
026        super.updateEntity();
027
028        if (++this.ticksSinceSync % 20 * 4 == 0)
029        {
030            this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, Block.enderChest.blockID, 1, this.numUsingPlayers);
031        }
032
033        this.prevLidAngle = this.lidAngle;
034        float f = 0.1F;
035        double d0;
036
037        if (this.numUsingPlayers > 0 && this.lidAngle == 0.0F)
038        {
039            double d1 = (double)this.xCoord + 0.5D;
040            d0 = (double)this.zCoord + 0.5D;
041            this.worldObj.playSoundEffect(d1, (double)this.yCoord + 0.5D, d0, "random.chestopen", 0.5F, this.worldObj.rand.nextFloat() * 0.1F + 0.9F);
042        }
043
044        if (this.numUsingPlayers == 0 && this.lidAngle > 0.0F || this.numUsingPlayers > 0 && this.lidAngle < 1.0F)
045        {
046            float f1 = this.lidAngle;
047
048            if (this.numUsingPlayers > 0)
049            {
050                this.lidAngle += f;
051            }
052            else
053            {
054                this.lidAngle -= f;
055            }
056
057            if (this.lidAngle > 1.0F)
058            {
059                this.lidAngle = 1.0F;
060            }
061
062            float f2 = 0.5F;
063
064            if (this.lidAngle < f2 && f1 >= f2)
065            {
066                d0 = (double)this.xCoord + 0.5D;
067                double d2 = (double)this.zCoord + 0.5D;
068                this.worldObj.playSoundEffect(d0, (double)this.yCoord + 0.5D, d2, "random.chestclosed", 0.5F, this.worldObj.rand.nextFloat() * 0.1F + 0.9F);
069            }
070
071            if (this.lidAngle < 0.0F)
072            {
073                this.lidAngle = 0.0F;
074            }
075        }
076    }
077
078    /**
079     * Called when a client event is received with the event number and argument, see World.sendClientEvent
080     */
081    public boolean receiveClientEvent(int par1, int par2)
082    {
083        if (par1 == 1)
084        {
085            this.numUsingPlayers = par2;
086            return true;
087        }
088        else
089        {
090            return super.receiveClientEvent(par1, par2);
091        }
092    }
093
094    /**
095     * invalidates a tile entity
096     */
097    public void invalidate()
098    {
099        this.updateContainingBlockInfo();
100        super.invalidate();
101    }
102
103    public void openChest()
104    {
105        ++this.numUsingPlayers;
106        this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, Block.enderChest.blockID, 1, this.numUsingPlayers);
107    }
108
109    public void closeChest()
110    {
111        --this.numUsingPlayers;
112        this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, Block.enderChest.blockID, 1, this.numUsingPlayers);
113    }
114
115    public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer)
116    {
117        return this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false : par1EntityPlayer.getDistanceSq((double)this.xCoord + 0.5D, (double)this.yCoord + 0.5D, (double)this.zCoord + 0.5D) <= 64.0D;
118    }
119}