    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}