001package net.minecraft.tileentity;
002
003import java.util.Random;
004import net.minecraft.entity.player.EntityPlayer;
005import net.minecraft.inventory.IInventory;
006import net.minecraft.item.ItemStack;
007import net.minecraft.nbt.NBTTagCompound;
008import net.minecraft.nbt.NBTTagList;
009
010public 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}