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 protected String field_94050_c; 019 020 /** 021 * Returns the number of slots in the inventory. 022 */ 023 public int getSizeInventory() 024 { 025 return 9; 026 } 027 028 /** 029 * Returns the stack in slot i 030 */ 031 public ItemStack getStackInSlot(int par1) 032 { 033 return this.dispenserContents[par1]; 034 } 035 036 /** 037 * Removes from an inventory slot (first arg) up to a specified number (second arg) of items and returns them in a 038 * new stack. 039 */ 040 public ItemStack decrStackSize(int par1, int par2) 041 { 042 if (this.dispenserContents[par1] != null) 043 { 044 ItemStack itemstack; 045 046 if (this.dispenserContents[par1].stackSize <= par2) 047 { 048 itemstack = this.dispenserContents[par1]; 049 this.dispenserContents[par1] = null; 050 this.onInventoryChanged(); 051 return itemstack; 052 } 053 else 054 { 055 itemstack = this.dispenserContents[par1].splitStack(par2); 056 057 if (this.dispenserContents[par1].stackSize == 0) 058 { 059 this.dispenserContents[par1] = null; 060 } 061 062 this.onInventoryChanged(); 063 return itemstack; 064 } 065 } 066 else 067 { 068 return null; 069 } 070 } 071 072 /** 073 * When some containers are closed they call this on each slot, then drop whatever it returns as an EntityItem - 074 * like when you close a workbench GUI. 075 */ 076 public ItemStack getStackInSlotOnClosing(int par1) 077 { 078 if (this.dispenserContents[par1] != null) 079 { 080 ItemStack itemstack = this.dispenserContents[par1]; 081 this.dispenserContents[par1] = null; 082 return itemstack; 083 } 084 else 085 { 086 return null; 087 } 088 } 089 090 public int getRandomStackFromInventory() 091 { 092 int i = -1; 093 int j = 1; 094 095 for (int k = 0; k < this.dispenserContents.length; ++k) 096 { 097 if (this.dispenserContents[k] != null && this.dispenserRandom.nextInt(j++) == 0) 098 { 099 i = k; 100 } 101 } 102 103 return i; 104 } 105 106 /** 107 * Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections). 108 */ 109 public void setInventorySlotContents(int par1, ItemStack par2ItemStack) 110 { 111 this.dispenserContents[par1] = par2ItemStack; 112 113 if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit()) 114 { 115 par2ItemStack.stackSize = this.getInventoryStackLimit(); 116 } 117 118 this.onInventoryChanged(); 119 } 120 121 /** 122 * Add item stack in first available inventory slot 123 */ 124 public int addItem(ItemStack par1ItemStack) 125 { 126 for (int i = 0; i < this.dispenserContents.length; ++i) 127 { 128 if (this.dispenserContents[i] == null || this.dispenserContents[i].itemID == 0) 129 { 130 this.setInventorySlotContents(i, par1ItemStack); 131 return i; 132 } 133 } 134 135 return -1; 136 } 137 138 /** 139 * Returns the name of the inventory. 140 */ 141 public String getInvName() 142 { 143 return this.func_94042_c() ? this.field_94050_c : "container.dispenser"; 144 } 145 146 public void func_94049_a(String par1Str) 147 { 148 this.field_94050_c = par1Str; 149 } 150 151 public boolean func_94042_c() 152 { 153 return this.field_94050_c != null; 154 } 155 156 /** 157 * Reads a tile entity from NBT. 158 */ 159 public void readFromNBT(NBTTagCompound par1NBTTagCompound) 160 { 161 super.readFromNBT(par1NBTTagCompound); 162 NBTTagList nbttaglist = par1NBTTagCompound.getTagList("Items"); 163 this.dispenserContents = new ItemStack[this.getSizeInventory()]; 164 165 for (int i = 0; i < nbttaglist.tagCount(); ++i) 166 { 167 NBTTagCompound nbttagcompound1 = (NBTTagCompound)nbttaglist.tagAt(i); 168 int j = nbttagcompound1.getByte("Slot") & 255; 169 170 if (j >= 0 && j < this.dispenserContents.length) 171 { 172 this.dispenserContents[j] = ItemStack.loadItemStackFromNBT(nbttagcompound1); 173 } 174 } 175 176 if (par1NBTTagCompound.hasKey("CustomName")) 177 { 178 this.field_94050_c = par1NBTTagCompound.getString("CustomName"); 179 } 180 } 181 182 /** 183 * Writes a tile entity to NBT. 184 */ 185 public void writeToNBT(NBTTagCompound par1NBTTagCompound) 186 { 187 super.writeToNBT(par1NBTTagCompound); 188 NBTTagList nbttaglist = new NBTTagList(); 189 190 for (int i = 0; i < this.dispenserContents.length; ++i) 191 { 192 if (this.dispenserContents[i] != null) 193 { 194 NBTTagCompound nbttagcompound1 = new NBTTagCompound(); 195 nbttagcompound1.setByte("Slot", (byte)i); 196 this.dispenserContents[i].writeToNBT(nbttagcompound1); 197 nbttaglist.appendTag(nbttagcompound1); 198 } 199 } 200 201 par1NBTTagCompound.setTag("Items", nbttaglist); 202 203 if (this.func_94042_c()) 204 { 205 par1NBTTagCompound.setString("CustomName", this.field_94050_c); 206 } 207 } 208 209 /** 210 * Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended. *Isn't 211 * this more of a set than a get?* 212 */ 213 public int getInventoryStackLimit() 214 { 215 return 64; 216 } 217 218 /** 219 * Do not make give this method the name canInteractWith because it clashes with Container 220 */ 221 public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) 222 { 223 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; 224 } 225 226 public void openChest() {} 227 228 public void closeChest() {} 229 230 public boolean func_94041_b(int par1, ItemStack par2ItemStack) 231 { 232 return true; 233 } 234}