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 public int func_70360_a(ItemStack par1ItemStack)
121 {
122 for (int var2 = 0; var2 < this.dispenserContents.length; ++var2)
123 {
124 if (this.dispenserContents[var2] == null || this.dispenserContents[var2].itemID == 0)
125 {
126 this.dispenserContents[var2] = par1ItemStack;
127 return var2;
128 }
129 }
130
131 return -1;
132 }
133
134 /**
135 * Returns the name of the inventory.
136 */
137 public String getInvName()
138 {
139 return "container.dispenser";
140 }
141
142 /**
143 * Reads a tile entity from NBT.
144 */
145 public void readFromNBT(NBTTagCompound par1NBTTagCompound)
146 {
147 super.readFromNBT(par1NBTTagCompound);
148 NBTTagList var2 = par1NBTTagCompound.getTagList("Items");
149 this.dispenserContents = new ItemStack[this.getSizeInventory()];
150
151 for (int var3 = 0; var3 < var2.tagCount(); ++var3)
152 {
153 NBTTagCompound var4 = (NBTTagCompound)var2.tagAt(var3);
154 int var5 = var4.getByte("Slot") & 255;
155
156 if (var5 >= 0 && var5 < this.dispenserContents.length)
157 {
158 this.dispenserContents[var5] = ItemStack.loadItemStackFromNBT(var4);
159 }
160 }
161 }
162
163 /**
164 * Writes a tile entity to NBT.
165 */
166 public void writeToNBT(NBTTagCompound par1NBTTagCompound)
167 {
168 super.writeToNBT(par1NBTTagCompound);
169 NBTTagList var2 = new NBTTagList();
170
171 for (int var3 = 0; var3 < this.dispenserContents.length; ++var3)
172 {
173 if (this.dispenserContents[var3] != null)
174 {
175 NBTTagCompound var4 = new NBTTagCompound();
176 var4.setByte("Slot", (byte)var3);
177 this.dispenserContents[var3].writeToNBT(var4);
178 var2.appendTag(var4);
179 }
180 }
181
182 par1NBTTagCompound.setTag("Items", var2);
183 }
184
185 /**
186 * Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended. *Isn't
187 * this more of a set than a get?*
188 */
189 public int getInventoryStackLimit()
190 {
191 return 64;
192 }
193
194 /**
195 * Do not make give this method the name canInteractWith because it clashes with Container
196 */
197 public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer)
198 {
199 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;
200 }
201
202 public void openChest() {}
203
204 public void closeChest() {}
205 }