001 package net.minecraft.tileentity;
002
003 import java.util.Random;
004 import net.minecraft.entity.player.EntityPlayer;
005 import net.minecraft.inventory.IInventory;
006 import net.minecraft.item.ItemStack;
007 import net.minecraft.nbt.NBTTagCompound;
008 import net.minecraft.nbt.NBTTagList;
009
010 public class TileEntityDispenser extends TileEntity implements IInventory
011 {
012 private ItemStack[] dispenserContents = new ItemStack[9];
013
014 /**
015 * random number generator for instance. Used in random item stack selection.
016 */
017 private Random dispenserRandom = new Random();
018
019 /**
020 * Returns the number of slots in the inventory.
021 */
022 public int getSizeInventory()
023 {
024 return 9;
025 }
026
027 /**
028 * Returns the stack in slot i
029 */
030 public ItemStack getStackInSlot(int par1)
031 {
032 return this.dispenserContents[par1];
033 }
034
035 /**
036 * Removes from an inventory slot (first arg) up to a specified number (second arg) of items and returns them in a
037 * new stack.
038 */
039 public ItemStack decrStackSize(int par1, int par2)
040 {
041 if (this.dispenserContents[par1] != null)
042 {
043 ItemStack var3;
044
045 if (this.dispenserContents[par1].stackSize <= par2)
046 {
047 var3 = this.dispenserContents[par1];
048 this.dispenserContents[par1] = null;
049 this.onInventoryChanged();
050 return var3;
051 }
052 else
053 {
054 var3 = this.dispenserContents[par1].splitStack(par2);
055
056 if (this.dispenserContents[par1].stackSize == 0)
057 {
058 this.dispenserContents[par1] = null;
059 }
060
061 this.onInventoryChanged();
062 return var3;
063 }
064 }
065 else
066 {
067 return null;
068 }
069 }
070
071 /**
072 * When some containers are closed they call this on each slot, then drop whatever it returns as an EntityItem -
073 * like when you close a workbench GUI.
074 */
075 public ItemStack getStackInSlotOnClosing(int par1)
076 {
077 if (this.dispenserContents[par1] != null)
078 {
079 ItemStack var2 = this.dispenserContents[par1];
080 this.dispenserContents[par1] = null;
081 return var2;
082 }
083 else
084 {
085 return null;
086 }
087 }
088
089 public int getRandomStackFromInventory()
090 {
091 int var1 = -1;
092 int var2 = 1;
093
094 for (int var3 = 0; var3 < this.dispenserContents.length; ++var3)
095 {
096 if (this.dispenserContents[var3] != null && this.dispenserRandom.nextInt(var2++) == 0)
097 {
098 var1 = var3;
099 }
100 }
101
102 return var1;
103 }
104
105 /**
106 * Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections).
107 */
108 public void setInventorySlotContents(int par1, ItemStack par2ItemStack)
109 {
110 this.dispenserContents[par1] = par2ItemStack;
111
112 if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit())
113 {
114 par2ItemStack.stackSize = this.getInventoryStackLimit();
115 }
116
117 this.onInventoryChanged();
118 }
119
120 /**
121 * Add item stack in first available inventory slot
122 */
123 public int addItem(ItemStack par1ItemStack)
124 {
125 for (int var2 = 0; var2 < this.dispenserContents.length; ++var2)
126 {
127 if (this.dispenserContents[var2] == null || this.dispenserContents[var2].itemID == 0)
128 {
129 this.dispenserContents[var2] = par1ItemStack;
130 return var2;
131 }
132 }
133
134 return -1;
135 }
136
137 /**
138 * Returns the name of the inventory.
139 */
140 public String getInvName()
141 {
142 return "container.dispenser";
143 }
144
145 /**
146 * Reads a tile entity from NBT.
147 */
148 public void readFromNBT(NBTTagCompound par1NBTTagCompound)
149 {
150 super.readFromNBT(par1NBTTagCompound);
151 NBTTagList var2 = par1NBTTagCompound.getTagList("Items");
152 this.dispenserContents = new ItemStack[this.getSizeInventory()];
153
154 for (int var3 = 0; var3 < var2.tagCount(); ++var3)
155 {
156 NBTTagCompound var4 = (NBTTagCompound)var2.tagAt(var3);
157 int var5 = var4.getByte("Slot") & 255;
158
159 if (var5 >= 0 && var5 < this.dispenserContents.length)
160 {
161 this.dispenserContents[var5] = ItemStack.loadItemStackFromNBT(var4);
162 }
163 }
164 }
165
166 /**
167 * Writes a tile entity to NBT.
168 */
169 public void writeToNBT(NBTTagCompound par1NBTTagCompound)
170 {
171 super.writeToNBT(par1NBTTagCompound);
172 NBTTagList var2 = new NBTTagList();
173
174 for (int var3 = 0; var3 < this.dispenserContents.length; ++var3)
175 {
176 if (this.dispenserContents[var3] != null)
177 {
178 NBTTagCompound var4 = new NBTTagCompound();
179 var4.setByte("Slot", (byte)var3);
180 this.dispenserContents[var3].writeToNBT(var4);
181 var2.appendTag(var4);
182 }
183 }
184
185 par1NBTTagCompound.setTag("Items", var2);
186 }
187
188 /**
189 * Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended. *Isn't
190 * this more of a set than a get?*
191 */
192 public int getInventoryStackLimit()
193 {
194 return 64;
195 }
196
197 /**
198 * Do not make give this method the name canInteractWith because it clashes with Container
199 */
200 public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer)
201 {
202 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;
203 }
204
205 public void openChest() {}
206
207 public void closeChest() {}
208 }