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 }