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 @SideOnly(Side.CLIENT) 070 071 /** 072 * Remove this crafting listener from the listener list. 073 */ 074 public void removeCraftingFromCrafters(ICrafting par1ICrafting) 075 { 076 this.crafters.remove(par1ICrafting); 077 } 078 079 /** 080 * Updates crafting matrix; called from onCraftMatrixChanged. Args: none 081 */ 082 public void updateCraftingResults() 083 { 084 for (int var1 = 0; var1 < this.inventorySlots.size(); ++var1) 085 { 086 ItemStack var2 = ((Slot)this.inventorySlots.get(var1)).getStack(); 087 ItemStack var3 = (ItemStack)this.inventoryItemStacks.get(var1); 088 089 if (!ItemStack.areItemStacksEqual(var3, var2)) 090 { 091 var3 = var2 == null ? null : var2.copy(); 092 this.inventoryItemStacks.set(var1, var3); 093 Iterator var4 = this.crafters.iterator(); 094 095 while (var4.hasNext()) 096 { 097 ICrafting var5 = (ICrafting)var4.next(); 098 var5.updateCraftingInventorySlot(this, var1, var3); 099 } 100 } 101 } 102 } 103 104 /** 105 * enchants the item on the table using the specified slot; also deducts XP from player 106 */ 107 public boolean enchantItem(EntityPlayer par1EntityPlayer, int par2) 108 { 109 return false; 110 } 111 112 public Slot getSlotFromInventory(IInventory par1IInventory, int par2) 113 { 114 Iterator var3 = this.inventorySlots.iterator(); 115 Slot var4; 116 117 do 118 { 119 if (!var3.hasNext()) 120 { 121 return null; 122 } 123 124 var4 = (Slot)var3.next(); 125 } 126 while (!var4.isSlotInInventory(par1IInventory, par2)); 127 128 return var4; 129 } 130 131 public Slot getSlot(int par1) 132 { 133 return (Slot)this.inventorySlots.get(par1); 134 } 135 136 /** 137 * Called when a player shift-clicks on a slot. You must override this or you will crash when someone does that. 138 */ 139 public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) 140 { 141 Slot var3 = (Slot)this.inventorySlots.get(par2); 142 return var3 != null ? var3.getStack() : null; 143 } 144 145 public ItemStack slotClick(int par1, int par2, int par3, EntityPlayer par4EntityPlayer) 146 { 147 ItemStack var5 = null; 148 InventoryPlayer var6 = par4EntityPlayer.inventory; 149 Slot var7; 150 ItemStack var8; 151 int var10; 152 ItemStack var11; 153 154 if ((par3 == 0 || par3 == 1) && (par2 == 0 || par2 == 1)) 155 { 156 if (par1 == -999) 157 { 158 if (var6.getItemStack() != null && par1 == -999) 159 { 160 if (par2 == 0) 161 { 162 par4EntityPlayer.dropPlayerItem(var6.getItemStack()); 163 var6.setItemStack((ItemStack)null); 164 } 165 166 if (par2 == 1) 167 { 168 par4EntityPlayer.dropPlayerItem(var6.getItemStack().splitStack(1)); 169 170 if (var6.getItemStack().stackSize == 0) 171 { 172 var6.setItemStack((ItemStack)null); 173 } 174 } 175 } 176 } 177 else if (par3 == 1) 178 { 179 var7 = (Slot)this.inventorySlots.get(par1); 180 181 if (var7 != null && var7.canTakeStack(par4EntityPlayer)) 182 { 183 var8 = this.transferStackInSlot(par4EntityPlayer, par1); 184 185 if (var8 != null) 186 { 187 int var12 = var8.itemID; 188 var5 = var8.copy(); 189 190 if (var7 != null && var7.getStack() != null && var7.getStack().itemID == var12) 191 { 192 this.retrySlotClick(par1, par2, true, par4EntityPlayer); 193 } 194 } 195 } 196 } 197 else 198 { 199 if (par1 < 0) 200 { 201 return null; 202 } 203 204 var7 = (Slot)this.inventorySlots.get(par1); 205 206 if (var7 != null) 207 { 208 var8 = var7.getStack(); 209 ItemStack var13 = var6.getItemStack(); 210 211 if (var8 != null) 212 { 213 var5 = var8.copy(); 214 } 215 216 if (var8 == null) 217 { 218 if (var13 != null && var7.isItemValid(var13)) 219 { 220 var10 = par2 == 0 ? var13.stackSize : 1; 221 222 if (var10 > var7.getSlotStackLimit()) 223 { 224 var10 = var7.getSlotStackLimit(); 225 } 226 227 var7.putStack(var13.splitStack(var10)); 228 229 if (var13.stackSize == 0) 230 { 231 var6.setItemStack((ItemStack)null); 232 } 233 } 234 } 235 else if (var7.canTakeStack(par4EntityPlayer)) 236 { 237 if (var13 == null) 238 { 239 var10 = par2 == 0 ? var8.stackSize : (var8.stackSize + 1) / 2; 240 var11 = var7.decrStackSize(var10); 241 var6.setItemStack(var11); 242 243 if (var8.stackSize == 0) 244 { 245 var7.putStack((ItemStack)null); 246 } 247 248 var7.onPickupFromSlot(par4EntityPlayer, var6.getItemStack()); 249 } 250 else if (var7.isItemValid(var13)) 251 { 252 if (var8.itemID == var13.itemID && (!var8.getHasSubtypes() || var8.getItemDamage() == var13.getItemDamage()) && ItemStack.areItemStackTagsEqual(var8, var13)) 253 { 254 var10 = par2 == 0 ? var13.stackSize : 1; 255 256 if (var10 > var7.getSlotStackLimit() - var8.stackSize) 257 { 258 var10 = var7.getSlotStackLimit() - var8.stackSize; 259 } 260 261 if (var10 > var13.getMaxStackSize() - var8.stackSize) 262 { 263 var10 = var13.getMaxStackSize() - var8.stackSize; 264 } 265 266 var13.splitStack(var10); 267 268 if (var13.stackSize == 0) 269 { 270 var6.setItemStack((ItemStack)null); 271 } 272 273 var8.stackSize += var10; 274 } 275 else if (var13.stackSize <= var7.getSlotStackLimit()) 276 { 277 var7.putStack(var13); 278 var6.setItemStack(var8); 279 } 280 } 281 else if (var8.itemID == var13.itemID && var13.getMaxStackSize() > 1 && (!var8.getHasSubtypes() || var8.getItemDamage() == var13.getItemDamage()) && ItemStack.areItemStackTagsEqual(var8, var13)) 282 { 283 var10 = var8.stackSize; 284 285 if (var10 > 0 && var10 + var13.stackSize <= var13.getMaxStackSize()) 286 { 287 var13.stackSize += var10; 288 var8 = var7.decrStackSize(var10); 289 290 if (var8.stackSize == 0) 291 { 292 var7.putStack((ItemStack)null); 293 } 294 295 var7.onPickupFromSlot(par4EntityPlayer, var6.getItemStack()); 296 } 297 } 298 } 299 300 var7.onSlotChanged(); 301 } 302 } 303 } 304 else if (par3 == 2 && par2 >= 0 && par2 < 9) 305 { 306 var7 = (Slot)this.inventorySlots.get(par1); 307 308 if (var7.canTakeStack(par4EntityPlayer)) 309 { 310 var8 = var6.getStackInSlot(par2); 311 boolean var9 = var8 == null || var7.inventory == var6 && var7.isItemValid(var8); 312 var10 = -1; 313 314 if (!var9) 315 { 316 var10 = var6.getFirstEmptyStack(); 317 var9 |= var10 > -1; 318 } 319 320 if (var7.getHasStack() && var9) 321 { 322 var11 = var7.getStack(); 323 var6.setInventorySlotContents(par2, var11); 324 325 if ((var7.inventory != var6 || !var7.isItemValid(var8)) && var8 != null) 326 { 327 if (var10 > -1) 328 { 329 var6.addItemStackToInventory(var8); 330 var7.putStack((ItemStack)null); 331 var7.onPickupFromSlot(par4EntityPlayer, var11); 332 } 333 } 334 else 335 { 336 var7.putStack(var8); 337 var7.onPickupFromSlot(par4EntityPlayer, var11); 338 } 339 } 340 else if (!var7.getHasStack() && var8 != null && var7.isItemValid(var8)) 341 { 342 var6.setInventorySlotContents(par2, (ItemStack)null); 343 var7.putStack(var8); 344 } 345 } 346 } 347 else if (par3 == 3 && par4EntityPlayer.capabilities.isCreativeMode && var6.getItemStack() == null && par1 >= 0) 348 { 349 var7 = (Slot)this.inventorySlots.get(par1); 350 351 if (var7 != null && var7.getHasStack()) 352 { 353 var8 = var7.getStack().copy(); 354 var8.stackSize = var8.getMaxStackSize(); 355 var6.setItemStack(var8); 356 } 357 } 358 359 return var5; 360 } 361 362 protected void retrySlotClick(int par1, int par2, boolean par3, EntityPlayer par4EntityPlayer) 363 { 364 this.slotClick(par1, par2, 1, par4EntityPlayer); 365 } 366 367 /** 368 * Callback for when the crafting gui is closed. 369 */ 370 public void onCraftGuiClosed(EntityPlayer par1EntityPlayer) 371 { 372 InventoryPlayer var2 = par1EntityPlayer.inventory; 373 374 if (var2.getItemStack() != null) 375 { 376 par1EntityPlayer.dropPlayerItem(var2.getItemStack()); 377 var2.setItemStack((ItemStack)null); 378 } 379 } 380 381 /** 382 * Callback for when the crafting matrix is changed. 383 */ 384 public void onCraftMatrixChanged(IInventory par1IInventory) 385 { 386 this.updateCraftingResults(); 387 } 388 389 /** 390 * args: slotID, itemStack to put in slot 391 */ 392 public void putStackInSlot(int par1, ItemStack par2ItemStack) 393 { 394 this.getSlot(par1).putStack(par2ItemStack); 395 } 396 397 @SideOnly(Side.CLIENT) 398 399 /** 400 * places itemstacks in first x slots, x being aitemstack.lenght 401 */ 402 public void putStacksInSlots(ItemStack[] par1ArrayOfItemStack) 403 { 404 for (int var2 = 0; var2 < par1ArrayOfItemStack.length; ++var2) 405 { 406 this.getSlot(var2).putStack(par1ArrayOfItemStack[var2]); 407 } 408 } 409 410 @SideOnly(Side.CLIENT) 411 public void updateProgressBar(int par1, int par2) {} 412 413 @SideOnly(Side.CLIENT) 414 415 /** 416 * Gets a unique transaction ID. Parameter is unused. 417 */ 418 public short getNextTransactionID(InventoryPlayer par1InventoryPlayer) 419 { 420 ++this.transactionID; 421 return this.transactionID; 422 } 423 424 /** 425 * NotUsing because adding a player twice is an error 426 */ 427 public boolean isPlayerNotUsingContainer(EntityPlayer par1EntityPlayer) 428 { 429 return !this.playerList.contains(par1EntityPlayer); 430 } 431 432 /** 433 * adds or removes the player from the container based on par2 434 */ 435 public void setPlayerIsPresent(EntityPlayer par1EntityPlayer, boolean par2) 436 { 437 if (par2) 438 { 439 this.playerList.remove(par1EntityPlayer); 440 } 441 else 442 { 443 this.playerList.add(par1EntityPlayer); 444 } 445 } 446 447 public abstract boolean canInteractWith(EntityPlayer var1); 448 449 /** 450 * merges provided ItemStack with the first avaliable one in the container/player inventory 451 */ 452 protected boolean mergeItemStack(ItemStack par1ItemStack, int par2, int par3, boolean par4) 453 { 454 boolean var5 = false; 455 int var6 = par2; 456 457 if (par4) 458 { 459 var6 = par3 - 1; 460 } 461 462 Slot var7; 463 ItemStack var8; 464 465 if (par1ItemStack.isStackable()) 466 { 467 while (par1ItemStack.stackSize > 0 && (!par4 && var6 < par3 || par4 && var6 >= par2)) 468 { 469 var7 = (Slot)this.inventorySlots.get(var6); 470 var8 = var7.getStack(); 471 472 if (var8 != null && var8.itemID == par1ItemStack.itemID && (!par1ItemStack.getHasSubtypes() || par1ItemStack.getItemDamage() == var8.getItemDamage()) && ItemStack.areItemStackTagsEqual(par1ItemStack, var8)) 473 { 474 int var9 = var8.stackSize + par1ItemStack.stackSize; 475 476 if (var9 <= par1ItemStack.getMaxStackSize()) 477 { 478 par1ItemStack.stackSize = 0; 479 var8.stackSize = var9; 480 var7.onSlotChanged(); 481 var5 = true; 482 } 483 else if (var8.stackSize < par1ItemStack.getMaxStackSize()) 484 { 485 par1ItemStack.stackSize -= par1ItemStack.getMaxStackSize() - var8.stackSize; 486 var8.stackSize = par1ItemStack.getMaxStackSize(); 487 var7.onSlotChanged(); 488 var5 = true; 489 } 490 } 491 492 if (par4) 493 { 494 --var6; 495 } 496 else 497 { 498 ++var6; 499 } 500 } 501 } 502 503 if (par1ItemStack.stackSize > 0) 504 { 505 if (par4) 506 { 507 var6 = par3 - 1; 508 } 509 else 510 { 511 var6 = par2; 512 } 513 514 while (!par4 && var6 < par3 || par4 && var6 >= par2) 515 { 516 var7 = (Slot)this.inventorySlots.get(var6); 517 var8 = var7.getStack(); 518 519 if (var8 == null) 520 { 521 var7.putStack(par1ItemStack.copy()); 522 var7.onSlotChanged(); 523 par1ItemStack.stackSize = 0; 524 var5 = true; 525 break; 526 } 527 528 if (par4) 529 { 530 --var6; 531 } 532 else 533 { 534 ++var6; 535 } 536 } 537 } 538 539 return var5; 540 } 541 }