001 package net.minecraft.src; 002 003 import cpw.mods.fml.common.Side; 004 import cpw.mods.fml.common.asm.SideOnly; 005 import java.util.List; 006 007 import net.minecraftforge.common.ISidedInventory; 008 import net.minecraftforge.common.ForgeDirection; 009 010 public class TileEntityBrewingStand extends TileEntity implements IInventory, ISidedInventory 011 { 012 /** The itemstacks currently placed in the slots of the brewing stand */ 013 private ItemStack[] brewingItemStacks = new ItemStack[4]; 014 private int brewTime; 015 016 /** 017 * an integer with each bit specifying whether that slot of the stand contains a potion 018 */ 019 private int filledSlots; 020 private int ingredientID; 021 022 /** 023 * Returns the name of the inventory. 024 */ 025 public String getInvName() 026 { 027 return "container.brewing"; 028 } 029 030 /** 031 * Returns the number of slots in the inventory. 032 */ 033 public int getSizeInventory() 034 { 035 return this.brewingItemStacks.length; 036 } 037 038 /** 039 * Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count 040 * ticks and creates a new spawn inside its implementation. 041 */ 042 public void updateEntity() 043 { 044 if (this.brewTime > 0) 045 { 046 --this.brewTime; 047 048 if (this.brewTime == 0) 049 { 050 this.brewPotions(); 051 this.onInventoryChanged(); 052 } 053 else if (!this.canBrew()) 054 { 055 this.brewTime = 0; 056 this.onInventoryChanged(); 057 } 058 else if (this.ingredientID != this.brewingItemStacks[3].itemID) 059 { 060 this.brewTime = 0; 061 this.onInventoryChanged(); 062 } 063 } 064 else if (this.canBrew()) 065 { 066 this.brewTime = 400; 067 this.ingredientID = this.brewingItemStacks[3].itemID; 068 } 069 070 int var1 = this.getFilledSlots(); 071 072 if (var1 != this.filledSlots) 073 { 074 this.filledSlots = var1; 075 this.worldObj.setBlockMetadataWithNotify(this.xCoord, this.yCoord, this.zCoord, var1); 076 } 077 078 super.updateEntity(); 079 } 080 081 public int getBrewTime() 082 { 083 return this.brewTime; 084 } 085 086 private boolean canBrew() 087 { 088 if (this.brewingItemStacks[3] != null && this.brewingItemStacks[3].stackSize > 0) 089 { 090 ItemStack var1 = this.brewingItemStacks[3]; 091 092 if (!Item.itemsList[var1.itemID].isPotionIngredient()) 093 { 094 return false; 095 } 096 else 097 { 098 boolean var2 = false; 099 100 for (int var3 = 0; var3 < 3; ++var3) 101 { 102 if (this.brewingItemStacks[var3] != null && this.brewingItemStacks[var3].itemID == Item.potion.shiftedIndex) 103 { 104 int var4 = this.brewingItemStacks[var3].getItemDamage(); 105 int var5 = this.getPotionResult(var4, var1); 106 107 if (!ItemPotion.isSplash(var4) && ItemPotion.isSplash(var5)) 108 { 109 var2 = true; 110 break; 111 } 112 113 List var6 = Item.potion.getEffects(var4); 114 List var7 = Item.potion.getEffects(var5); 115 116 if ((var4 <= 0 || var6 != var7) && (var6 == null || !var6.equals(var7) && var7 != null) && var4 != var5) 117 { 118 var2 = true; 119 break; 120 } 121 } 122 } 123 124 return var2; 125 } 126 } 127 else 128 { 129 return false; 130 } 131 } 132 133 private void brewPotions() 134 { 135 if (this.canBrew()) 136 { 137 ItemStack var1 = this.brewingItemStacks[3]; 138 139 for (int var2 = 0; var2 < 3; ++var2) 140 { 141 if (this.brewingItemStacks[var2] != null && this.brewingItemStacks[var2].itemID == Item.potion.shiftedIndex) 142 { 143 int var3 = this.brewingItemStacks[var2].getItemDamage(); 144 int var4 = this.getPotionResult(var3, var1); 145 List var5 = Item.potion.getEffects(var3); 146 List var6 = Item.potion.getEffects(var4); 147 148 if ((var3 <= 0 || var5 != var6) && (var5 == null || !var5.equals(var6) && var6 != null)) 149 { 150 if (var3 != var4) 151 { 152 this.brewingItemStacks[var2].setItemDamage(var4); 153 } 154 } 155 else if (!ItemPotion.isSplash(var3) && ItemPotion.isSplash(var4)) 156 { 157 this.brewingItemStacks[var2].setItemDamage(var4); 158 } 159 } 160 } 161 162 if (Item.itemsList[var1.itemID].hasContainerItem()) 163 { 164 this.brewingItemStacks[3] = Item.itemsList[var1.itemID].getContainerItemStack(brewingItemStacks[3]); 165 } 166 else 167 { 168 --this.brewingItemStacks[3].stackSize; 169 170 if (this.brewingItemStacks[3].stackSize <= 0) 171 { 172 this.brewingItemStacks[3] = null; 173 } 174 } 175 } 176 } 177 178 /** 179 * The result of brewing a potion of the specified damage value with an ingredient itemstack. 180 */ 181 private int getPotionResult(int par1, ItemStack par2ItemStack) 182 { 183 return par2ItemStack == null ? par1 : (Item.itemsList[par2ItemStack.itemID].isPotionIngredient() ? PotionHelper.applyIngredient(par1, Item.itemsList[par2ItemStack.itemID].getPotionEffect()) : par1); 184 } 185 186 /** 187 * Reads a tile entity from NBT. 188 */ 189 public void readFromNBT(NBTTagCompound par1NBTTagCompound) 190 { 191 super.readFromNBT(par1NBTTagCompound); 192 NBTTagList var2 = par1NBTTagCompound.getTagList("Items"); 193 this.brewingItemStacks = new ItemStack[this.getSizeInventory()]; 194 195 for (int var3 = 0; var3 < var2.tagCount(); ++var3) 196 { 197 NBTTagCompound var4 = (NBTTagCompound)var2.tagAt(var3); 198 byte var5 = var4.getByte("Slot"); 199 200 if (var5 >= 0 && var5 < this.brewingItemStacks.length) 201 { 202 this.brewingItemStacks[var5] = ItemStack.loadItemStackFromNBT(var4); 203 } 204 } 205 206 this.brewTime = par1NBTTagCompound.getShort("BrewTime"); 207 } 208 209 /** 210 * Writes a tile entity to NBT. 211 */ 212 public void writeToNBT(NBTTagCompound par1NBTTagCompound) 213 { 214 super.writeToNBT(par1NBTTagCompound); 215 par1NBTTagCompound.setShort("BrewTime", (short)this.brewTime); 216 NBTTagList var2 = new NBTTagList(); 217 218 for (int var3 = 0; var3 < this.brewingItemStacks.length; ++var3) 219 { 220 if (this.brewingItemStacks[var3] != null) 221 { 222 NBTTagCompound var4 = new NBTTagCompound(); 223 var4.setByte("Slot", (byte)var3); 224 this.brewingItemStacks[var3].writeToNBT(var4); 225 var2.appendTag(var4); 226 } 227 } 228 229 par1NBTTagCompound.setTag("Items", var2); 230 } 231 232 /** 233 * Returns the stack in slot i 234 */ 235 public ItemStack getStackInSlot(int par1) 236 { 237 return par1 >= 0 && par1 < this.brewingItemStacks.length ? this.brewingItemStacks[par1] : null; 238 } 239 240 /** 241 * Removes from an inventory slot (first arg) up to a specified number (second arg) of items and returns them in a 242 * new stack. 243 */ 244 public ItemStack decrStackSize(int par1, int par2) 245 { 246 if (par1 >= 0 && par1 < this.brewingItemStacks.length) 247 { 248 ItemStack var3 = this.brewingItemStacks[par1]; 249 this.brewingItemStacks[par1] = null; 250 return var3; 251 } 252 else 253 { 254 return null; 255 } 256 } 257 258 /** 259 * When some containers are closed they call this on each slot, then drop whatever it returns as an EntityItem - 260 * like when you close a workbench GUI. 261 */ 262 public ItemStack getStackInSlotOnClosing(int par1) 263 { 264 if (par1 >= 0 && par1 < this.brewingItemStacks.length) 265 { 266 ItemStack var2 = this.brewingItemStacks[par1]; 267 this.brewingItemStacks[par1] = null; 268 return var2; 269 } 270 else 271 { 272 return null; 273 } 274 } 275 276 /** 277 * Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections). 278 */ 279 public void setInventorySlotContents(int par1, ItemStack par2ItemStack) 280 { 281 if (par1 >= 0 && par1 < this.brewingItemStacks.length) 282 { 283 this.brewingItemStacks[par1] = par2ItemStack; 284 } 285 } 286 287 /** 288 * Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended. *Isn't 289 * this more of a set than a get?* 290 */ 291 public int getInventoryStackLimit() 292 { 293 return 1; 294 } 295 296 /** 297 * Do not make give this method the name canInteractWith because it clashes with Container 298 */ 299 public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) 300 { 301 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; 302 } 303 304 public void openChest() {} 305 306 public void closeChest() {} 307 308 @SideOnly(Side.CLIENT) 309 public void setBrewTime(int par1) 310 { 311 this.brewTime = par1; 312 } 313 314 /** 315 * returns an integer with each bit specifying wether that slot of the stand contains a potion 316 */ 317 public int getFilledSlots() 318 { 319 int var1 = 0; 320 321 for (int var2 = 0; var2 < 3; ++var2) 322 { 323 if (this.brewingItemStacks[var2] != null) 324 { 325 var1 |= 1 << var2; 326 } 327 } 328 329 return var1; 330 } 331 332 @Override 333 public int getStartInventorySide(ForgeDirection side) 334 { 335 return (side == ForgeDirection.UP ? 3 : 0); 336 } 337 338 @Override 339 public int getSizeInventorySide(ForgeDirection side) 340 { 341 return (side == ForgeDirection.UP ? 1 : 3); 342 } 343 }