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    }