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    }