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.ArrayList;
006 import java.util.HashSet;
007 import java.util.Iterator;
008 import java.util.List;
009 import java.util.Set;
010
011 public abstract class Container
012 {
013 /** the list of all items(stacks) for the corresponding slot */
014 public List inventoryItemStacks = new ArrayList();
015
016 /** the list of all slots in the inventory */
017 public List inventorySlots = new ArrayList();
018 public int windowId = 0;
019 private short transactionID = 0;
020
021 /**
022 * list of all people that need to be notified when this craftinventory changes
023 */
024 protected List crafters = new ArrayList();
025 private Set playerList = new HashSet();
026
027 /**
028 * the slot is assumed empty
029 */
030 protected Slot addSlotToContainer(Slot par1Slot)
031 {
032 par1Slot.slotNumber = this.inventorySlots.size();
033 this.inventorySlots.add(par1Slot);
034 this.inventoryItemStacks.add((Object)null);
035 return par1Slot;
036 }
037
038 public void addCraftingToCrafters(ICrafting par1ICrafting)
039 {
040 if (this.crafters.contains(par1ICrafting))
041 {
042 throw new IllegalArgumentException("Listener already listening");
043 }
044 else
045 {
046 this.crafters.add(par1ICrafting);
047 par1ICrafting.sendContainerAndContentsToPlayer(this, this.getInventory());
048 this.updateCraftingResults();
049 }
050 }
051
052 /**
053 * returns a list if itemStacks, for each slot.
054 */
055 public List getInventory()
056 {
057 ArrayList var1 = new ArrayList();
058 Iterator var2 = this.inventorySlots.iterator();
059
060 while (var2.hasNext())
061 {
062 Slot var3 = (Slot)var2.next();
063 var1.add(var3.getStack());
064 }
065
066 return var1;
067 }
068
069 /**
070 * Updates crafting matrix; called from onCraftMatrixChanged. Args: none
071 */
072 public void updateCraftingResults()
073 {
074 for (int var1 = 0; var1 < this.inventorySlots.size(); ++var1)
075 {
076 ItemStack var2 = ((Slot)this.inventorySlots.get(var1)).getStack();
077 ItemStack var3 = (ItemStack)this.inventoryItemStacks.get(var1);
078
079 if (!ItemStack.areItemStacksEqual(var3, var2))
080 {
081 var3 = var2 == null ? null : var2.copy();
082 this.inventoryItemStacks.set(var1, var3);
083 Iterator var4 = this.crafters.iterator();
084
085 while (var4.hasNext())
086 {
087 ICrafting var5 = (ICrafting)var4.next();
088 var5.updateCraftingInventorySlot(this, var1, var3);
089 }
090 }
091 }
092 }
093
094 /**
095 * enchants the item on the table using the specified slot; also deducts XP from player
096 */
097 public boolean enchantItem(EntityPlayer par1EntityPlayer, int par2)
098 {
099 return false;
100 }
101
102 public Slot getSlotFromInventory(IInventory par1IInventory, int par2)
103 {
104 Iterator var3 = this.inventorySlots.iterator();
105 Slot var4;
106
107 do
108 {
109 if (!var3.hasNext())
110 {
111 return null;
112 }
113
114 var4 = (Slot)var3.next();
115 }
116 while (!var4.isSlotInInventory(par1IInventory, par2));
117
118 return var4;
119 }
120
121 public Slot getSlot(int par1)
122 {
123 return (Slot)this.inventorySlots.get(par1);
124 }
125
126 /**
127 * Called to transfer a stack from one inventory to the other eg. when shift clicking.
128 */
129 public ItemStack transferStackInSlot(int par1)
130 {
131 Slot var2 = (Slot)this.inventorySlots.get(par1);
132 return var2 != null ? var2.getStack() : null;
133 }
134
135 public ItemStack slotClick(int par1, int par2, boolean par3, EntityPlayer par4EntityPlayer)
136 {
137 ItemStack var5 = null;
138
139 if (par2 > 1)
140 {
141 return null;
142 }
143 else
144 {
145 if (par2 == 0 || par2 == 1)
146 {
147 InventoryPlayer var6 = par4EntityPlayer.inventory;
148
149 if (par1 == -999)
150 {
151 if (var6.getItemStack() != null && par1 == -999)
152 {
153 if (par2 == 0)
154 {
155 par4EntityPlayer.dropPlayerItem(var6.getItemStack());
156 var6.setItemStack((ItemStack)null);
157 }
158
159 if (par2 == 1)
160 {
161 par4EntityPlayer.dropPlayerItem(var6.getItemStack().splitStack(1));
162
163 if (var6.getItemStack().stackSize == 0)
164 {
165 var6.setItemStack((ItemStack)null);
166 }
167 }
168 }
169 }
170 else if (par3)
171 {
172 ItemStack var7 = this.transferStackInSlot(par1);
173
174 if (var7 != null)
175 {
176 int var8 = var7.itemID;
177 var5 = var7.copy();
178 Slot var9 = (Slot)this.inventorySlots.get(par1);
179
180 if (var9 != null && var9.getStack() != null && var9.getStack().itemID == var8)
181 {
182 this.retrySlotClick(par1, par2, par3, par4EntityPlayer);
183 }
184 }
185 }
186 else
187 {
188 if (par1 < 0)
189 {
190 return null;
191 }
192
193 Slot var12 = (Slot)this.inventorySlots.get(par1);
194
195 if (var12 != null)
196 {
197 ItemStack var13 = var12.getStack();
198 ItemStack var14 = var6.getItemStack();
199
200 if (var13 != null)
201 {
202 var5 = var13.copy();
203 }
204
205 int var10;
206
207 if (var13 == null)
208 {
209 if (var14 != null && var12.isItemValid(var14))
210 {
211 var10 = par2 == 0 ? var14.stackSize : 1;
212
213 if (var10 > var12.getSlotStackLimit())
214 {
215 var10 = var12.getSlotStackLimit();
216 }
217
218 var12.putStack(var14.splitStack(var10));
219
220 if (var14.stackSize == 0)
221 {
222 var6.setItemStack((ItemStack)null);
223 }
224 }
225 }
226 else if (var14 == null)
227 {
228 var10 = par2 == 0 ? var13.stackSize : (var13.stackSize + 1) / 2;
229 ItemStack var11 = var12.decrStackSize(var10);
230 var6.setItemStack(var11);
231
232 if (var13.stackSize == 0)
233 {
234 var12.putStack((ItemStack)null);
235 }
236
237 var12.onPickupFromSlot(var6.getItemStack());
238 }
239 else if (var12.isItemValid(var14))
240 {
241 if (var13.itemID == var14.itemID && (!var13.getHasSubtypes() || var13.getItemDamage() == var14.getItemDamage()) && ItemStack.func_77970_a(var13, var14))
242 {
243 var10 = par2 == 0 ? var14.stackSize : 1;
244
245 if (var10 > var12.getSlotStackLimit() - var13.stackSize)
246 {
247 var10 = var12.getSlotStackLimit() - var13.stackSize;
248 }
249
250 if (var10 > var14.getMaxStackSize() - var13.stackSize)
251 {
252 var10 = var14.getMaxStackSize() - var13.stackSize;
253 }
254
255 var14.splitStack(var10);
256
257 if (var14.stackSize == 0)
258 {
259 var6.setItemStack((ItemStack)null);
260 }
261
262 var13.stackSize += var10;
263 }
264 else if (var14.stackSize <= var12.getSlotStackLimit())
265 {
266 var12.putStack(var14);
267 var6.setItemStack(var13);
268 }
269 }
270 else if (var13.itemID == var14.itemID && var14.getMaxStackSize() > 1 && (!var13.getHasSubtypes() || var13.getItemDamage() == var14.getItemDamage()) && ItemStack.func_77970_a(var13, var14))
271 {
272 var10 = var13.stackSize;
273
274 if (var10 > 0 && var10 + var14.stackSize <= var14.getMaxStackSize())
275 {
276 var14.stackSize += var10;
277 var13 = var12.decrStackSize(var10);
278
279 if (var13.stackSize == 0)
280 {
281 var12.putStack((ItemStack)null);
282 }
283
284 var12.onPickupFromSlot(var6.getItemStack());
285 }
286 }
287
288 var12.onSlotChanged();
289 }
290 }
291 }
292
293 return var5;
294 }
295 }
296
297 protected void retrySlotClick(int par1, int par2, boolean par3, EntityPlayer par4EntityPlayer)
298 {
299 this.slotClick(par1, par2, par3, par4EntityPlayer);
300 }
301
302 /**
303 * Callback for when the crafting gui is closed.
304 */
305 public void onCraftGuiClosed(EntityPlayer par1EntityPlayer)
306 {
307 InventoryPlayer var2 = par1EntityPlayer.inventory;
308
309 if (var2.getItemStack() != null)
310 {
311 par1EntityPlayer.dropPlayerItem(var2.getItemStack());
312 var2.setItemStack((ItemStack)null);
313 }
314 }
315
316 /**
317 * Callback for when the crafting matrix is changed.
318 */
319 public void onCraftMatrixChanged(IInventory par1IInventory)
320 {
321 this.updateCraftingResults();
322 }
323
324 /**
325 * args: slotID, itemStack to put in slot
326 */
327 public void putStackInSlot(int par1, ItemStack par2ItemStack)
328 {
329 this.getSlot(par1).putStack(par2ItemStack);
330 }
331
332 @SideOnly(Side.CLIENT)
333
334 /**
335 * places itemstacks in first x slots, x being aitemstack.lenght
336 */
337 public void putStacksInSlots(ItemStack[] par1ArrayOfItemStack)
338 {
339 for (int var2 = 0; var2 < par1ArrayOfItemStack.length; ++var2)
340 {
341 this.getSlot(var2).putStack(par1ArrayOfItemStack[var2]);
342 }
343 }
344
345 @SideOnly(Side.CLIENT)
346 public void updateProgressBar(int par1, int par2) {}
347
348 /**
349 * NotUsing because adding a player twice is an error
350 */
351 public boolean isPlayerNotUsingContainer(EntityPlayer par1EntityPlayer)
352 {
353 return !this.playerList.contains(par1EntityPlayer);
354 }
355
356 @SideOnly(Side.CLIENT)
357
358 /**
359 * Gets a unique transaction ID. Parameter is unused.
360 */
361 public short getNextTransactionID(InventoryPlayer par1InventoryPlayer)
362 {
363 ++this.transactionID;
364 return this.transactionID;
365 }
366
367 /**
368 * adds or removes the player from the container based on par2
369 */
370 public void setPlayerIsPresent(EntityPlayer par1EntityPlayer, boolean par2)
371 {
372 if (par2)
373 {
374 this.playerList.remove(par1EntityPlayer);
375 }
376 else
377 {
378 this.playerList.add(par1EntityPlayer);
379 }
380 }
381
382 public abstract boolean canInteractWith(EntityPlayer var1);
383
384 /**
385 * merges provided ItemStack with the first avaliable one in the container/player inventory
386 */
387 protected boolean mergeItemStack(ItemStack par1ItemStack, int par2, int par3, boolean par4)
388 {
389 boolean var5 = false;
390 int var6 = par2;
391
392 if (par4)
393 {
394 var6 = par3 - 1;
395 }
396
397 Slot var7;
398 ItemStack var8;
399
400 if (par1ItemStack.isStackable())
401 {
402 while (par1ItemStack.stackSize > 0 && (!par4 && var6 < par3 || par4 && var6 >= par2))
403 {
404 var7 = (Slot)this.inventorySlots.get(var6);
405 var8 = var7.getStack();
406
407 if (var8 != null && var8.itemID == par1ItemStack.itemID && (!par1ItemStack.getHasSubtypes() || par1ItemStack.getItemDamage() == var8.getItemDamage()) && ItemStack.func_77970_a(par1ItemStack, var8))
408 {
409 int var9 = var8.stackSize + par1ItemStack.stackSize;
410
411 if (var9 <= par1ItemStack.getMaxStackSize())
412 {
413 par1ItemStack.stackSize = 0;
414 var8.stackSize = var9;
415 var7.onSlotChanged();
416 var5 = true;
417 }
418 else if (var8.stackSize < par1ItemStack.getMaxStackSize())
419 {
420 par1ItemStack.stackSize -= par1ItemStack.getMaxStackSize() - var8.stackSize;
421 var8.stackSize = par1ItemStack.getMaxStackSize();
422 var7.onSlotChanged();
423 var5 = true;
424 }
425 }
426
427 if (par4)
428 {
429 --var6;
430 }
431 else
432 {
433 ++var6;
434 }
435 }
436 }
437
438 if (par1ItemStack.stackSize > 0)
439 {
440 if (par4)
441 {
442 var6 = par3 - 1;
443 }
444 else
445 {
446 var6 = par2;
447 }
448
449 while (!par4 && var6 < par3 || par4 && var6 >= par2)
450 {
451 var7 = (Slot)this.inventorySlots.get(var6);
452 var8 = var7.getStack();
453
454 if (var8 == null)
455 {
456 var7.putStack(par1ItemStack.copy());
457 var7.onSlotChanged();
458 par1ItemStack.stackSize = 0;
459 var5 = true;
460 break;
461 }
462
463 if (par4)
464 {
465 --var6;
466 }
467 else
468 {
469 ++var6;
470 }
471 }
472 }
473
474 return var5;
475 }
476 }