    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    }