    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}