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