package net.minecraft.tileentity; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import java.util.List; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.ISidedInventory; import net.minecraft.item.Item; import net.minecraft.item.ItemPotion; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.potion.PotionHelper; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.brewing.PotionBrewedEvent; public class TileEntityBrewingStand extends TileEntity implements ISidedInventory { private static final int[] field_102017_a = new int[] {3}; private static final int[] field_102016_b = new int[] {0, 1, 2}; /** The itemstacks currently placed in the slots of the brewing stand */ private ItemStack[] brewingItemStacks = new ItemStack[4]; private int brewTime; /** * an integer with each bit specifying whether that slot of the stand contains a potion */ private int filledSlots; private int ingredientID; private String field_94132_e; /** * Returns the name of the inventory. */ public String getInvName() { return this.isInvNameLocalized() ? this.field_94132_e : "container.brewing"; } /** * If this returns false, the inventory name will be used as an unlocalized name, and translated into the player's * language. Otherwise it will be used directly. */ public boolean isInvNameLocalized() { return this.field_94132_e != null && this.field_94132_e.length() > 0; } public void func_94131_a(String par1Str) { this.field_94132_e = par1Str; } /** * Returns the number of slots in the inventory. */ public int getSizeInventory() { return this.brewingItemStacks.length; } /** * Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count * ticks and creates a new spawn inside its implementation. */ public void updateEntity() { if (this.brewTime > 0) { --this.brewTime; if (this.brewTime == 0) { this.brewPotions(); this.onInventoryChanged(); } else if (!this.canBrew()) { this.brewTime = 0; this.onInventoryChanged(); } else if (this.ingredientID != this.brewingItemStacks[3].itemID) { this.brewTime = 0; this.onInventoryChanged(); } } else if (this.canBrew()) { this.brewTime = 400; this.ingredientID = this.brewingItemStacks[3].itemID; } int i = this.getFilledSlots(); if (i != this.filledSlots) { this.filledSlots = i; this.worldObj.setBlockMetadataWithNotify(this.xCoord, this.yCoord, this.zCoord, i, 2); } super.updateEntity(); } public int getBrewTime() { return this.brewTime; } private boolean canBrew() { if (this.brewingItemStacks[3] != null && this.brewingItemStacks[3].stackSize > 0) { ItemStack itemstack = this.brewingItemStacks[3]; if (!Item.itemsList[itemstack.itemID].isPotionIngredient()) { return false; } else { boolean flag = false; for (int i = 0; i < 3; ++i) { if (this.brewingItemStacks[i] != null && this.brewingItemStacks[i].getItem() instanceof ItemPotion) { int j = this.brewingItemStacks[i].getItemDamage(); int k = this.getPotionResult(j, itemstack); if (!ItemPotion.isSplash(j) && ItemPotion.isSplash(k)) { flag = true; break; } List list = Item.potion.getEffects(j); List list1 = Item.potion.getEffects(k); if ((j <= 0 || list != list1) && (list == null || !list.equals(list1) && list1 != null) && j != k) { flag = true; break; } } } return flag; } } else { return false; } } private void brewPotions() { if (this.canBrew()) { ItemStack itemstack = this.brewingItemStacks[3]; for (int i = 0; i < 3; ++i) { if (this.brewingItemStacks[i] != null && this.brewingItemStacks[i].getItem() instanceof ItemPotion) { int j = this.brewingItemStacks[i].getItemDamage(); int k = this.getPotionResult(j, itemstack); List list = Item.potion.getEffects(j); List list1 = Item.potion.getEffects(k); if ((j <= 0 || list != list1) && (list == null || !list.equals(list1) && list1 != null)) { if (j != k) { this.brewingItemStacks[i].setItemDamage(k); } } else if (!ItemPotion.isSplash(j) && ItemPotion.isSplash(k)) { this.brewingItemStacks[i].setItemDamage(k); } } } if (Item.itemsList[itemstack.itemID].hasContainerItem()) { this.brewingItemStacks[3] = Item.itemsList[itemstack.itemID].getContainerItemStack(brewingItemStacks[3]); } else { --this.brewingItemStacks[3].stackSize; if (this.brewingItemStacks[3].stackSize <= 0) { this.brewingItemStacks[3] = null; } } MinecraftForge.EVENT_BUS.post(new PotionBrewedEvent(brewingItemStacks)); } } /** * The result of brewing a potion of the specified damage value with an ingredient itemstack. */ private int getPotionResult(int par1, ItemStack par2ItemStack) { return par2ItemStack == null ? par1 : (Item.itemsList[par2ItemStack.itemID].isPotionIngredient() ? PotionHelper.applyIngredient(par1, Item.itemsList[par2ItemStack.itemID].getPotionEffect()) : par1); } /** * Reads a tile entity from NBT. */ public void readFromNBT(NBTTagCompound par1NBTTagCompound) { super.readFromNBT(par1NBTTagCompound); NBTTagList nbttaglist = par1NBTTagCompound.getTagList("Items"); this.brewingItemStacks = new ItemStack[this.getSizeInventory()]; for (int i = 0; i < nbttaglist.tagCount(); ++i) { NBTTagCompound nbttagcompound1 = (NBTTagCompound)nbttaglist.tagAt(i); byte b0 = nbttagcompound1.getByte("Slot"); if (b0 >= 0 && b0 < this.brewingItemStacks.length) { this.brewingItemStacks[b0] = ItemStack.loadItemStackFromNBT(nbttagcompound1); } } this.brewTime = par1NBTTagCompound.getShort("BrewTime"); if (par1NBTTagCompound.hasKey("CustomName")) { this.field_94132_e = par1NBTTagCompound.getString("CustomName"); } } /** * Writes a tile entity to NBT. */ public void writeToNBT(NBTTagCompound par1NBTTagCompound) { super.writeToNBT(par1NBTTagCompound); par1NBTTagCompound.setShort("BrewTime", (short)this.brewTime); NBTTagList nbttaglist = new NBTTagList(); for (int i = 0; i < this.brewingItemStacks.length; ++i) { if (this.brewingItemStacks[i] != null) { NBTTagCompound nbttagcompound1 = new NBTTagCompound(); nbttagcompound1.setByte("Slot", (byte)i); this.brewingItemStacks[i].writeToNBT(nbttagcompound1); nbttaglist.appendTag(nbttagcompound1); } } par1NBTTagCompound.setTag("Items", nbttaglist); if (this.isInvNameLocalized()) { par1NBTTagCompound.setString("CustomName", this.field_94132_e); } } /** * Returns the stack in slot i */ public ItemStack getStackInSlot(int par1) { return par1 >= 0 && par1 < this.brewingItemStacks.length ? this.brewingItemStacks[par1] : null; } /** * Removes from an inventory slot (first arg) up to a specified number (second arg) of items and returns them in a * new stack. */ public ItemStack decrStackSize(int par1, int par2) { if (par1 >= 0 && par1 < this.brewingItemStacks.length) { ItemStack itemstack = this.brewingItemStacks[par1]; this.brewingItemStacks[par1] = null; return itemstack; } else { return null; } } /** * When some containers are closed they call this on each slot, then drop whatever it returns as an EntityItem - * like when you close a workbench GUI. */ public ItemStack getStackInSlotOnClosing(int par1) { if (par1 >= 0 && par1 < this.brewingItemStacks.length) { ItemStack itemstack = this.brewingItemStacks[par1]; this.brewingItemStacks[par1] = null; return itemstack; } else { return null; } } /** * Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections). */ public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { if (par1 >= 0 && par1 < this.brewingItemStacks.length) { this.brewingItemStacks[par1] = par2ItemStack; } } /** * Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended. *Isn't * this more of a set than a get?* */ public int getInventoryStackLimit() { return 64; } /** * Do not make give this method the name canInteractWith because it clashes with Container */ public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { 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; } public void openChest() {} public void closeChest() {} /** * Returns true if automation is allowed to insert the given stack (ignoring stack size) into the given slot. */ public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { return par1 == 3 ? Item.itemsList[par2ItemStack.itemID].isPotionIngredient() : par2ItemStack.getItem() instanceof ItemPotion || par2ItemStack.itemID == Item.glassBottle.itemID; } @SideOnly(Side.CLIENT) public void setBrewTime(int par1) { this.brewTime = par1; } /** * returns an integer with each bit specifying wether that slot of the stand contains a potion */ public int getFilledSlots() { int i = 0; for (int j = 0; j < 3; ++j) { if (this.brewingItemStacks[j] != null) { i |= 1 << j; } } return i; } /** * Returns an array containing the indices of the slots that can be accessed by automation on the given side of this * block. */ public int[] getAccessibleSlotsFromSide(int par1) { return par1 == 1 ? field_102017_a : field_102016_b; } /** * Returns true if automation can insert the given item in the given slot from the given side. Args: Slot, item, * side */ public boolean canInsertItem(int par1, ItemStack par2ItemStack, int par3) { return this.isStackValidForSlot(par1, par2ItemStack); } /** * Returns true if automation can extract the given item in the given slot from the given side. Args: Slot, item, * side */ public boolean canExtractItem(int par1, ItemStack par2ItemStack, int par3) { return true; } }