001 package net.minecraft.tileentity;
002
003 import net.minecraft.block.Block;
004 import net.minecraft.entity.player.EntityPlayer;
005
006 public 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 var1 = 0.1F;
035 double var4;
036
037 if (this.numUsingPlayers > 0 && this.lidAngle == 0.0F)
038 {
039 double var2 = (double)this.xCoord + 0.5D;
040 var4 = (double)this.zCoord + 0.5D;
041 this.worldObj.playSoundEffect(var2, (double)this.yCoord + 0.5D, var4, "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 var8 = this.lidAngle;
047
048 if (this.numUsingPlayers > 0)
049 {
050 this.lidAngle += var1;
051 }
052 else
053 {
054 this.lidAngle -= var1;
055 }
056
057 if (this.lidAngle > 1.0F)
058 {
059 this.lidAngle = 1.0F;
060 }
061
062 float var3 = 0.5F;
063
064 if (this.lidAngle < var3 && var8 >= var3)
065 {
066 var4 = (double)this.xCoord + 0.5D;
067 double var6 = (double)this.zCoord + 0.5D;
068 this.worldObj.playSoundEffect(var4, (double)this.yCoord + 0.5D, var6, "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 void receiveClientEvent(int par1, int par2)
082 {
083 if (par1 == 1)
084 {
085 this.numUsingPlayers = par2;
086 }
087 }
088
089 /**
090 * invalidates a tile entity
091 */
092 public void invalidate()
093 {
094 this.updateContainingBlockInfo();
095 super.invalidate();
096 }
097
098 public void openChest()
099 {
100 ++this.numUsingPlayers;
101 this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, Block.enderChest.blockID, 1, this.numUsingPlayers);
102 }
103
104 public void closeChest()
105 {
106 --this.numUsingPlayers;
107 this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, Block.enderChest.blockID, 1, this.numUsingPlayers);
108 }
109
110 public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer)
111 {
112 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;
113 }
114 }