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 }