001 package net.minecraft.src; 002 003 import cpw.mods.fml.common.Side; 004 import cpw.mods.fml.common.asm.SideOnly; 005 006 public class InventoryPlayer implements IInventory 007 { 008 /** 009 * An array of 36 item stacks indicating the main player inventory (including the visible bar). 010 */ 011 public ItemStack[] mainInventory = new ItemStack[36]; 012 013 /** An array of 4 item stacks containing the currently worn armor pieces. */ 014 public ItemStack[] armorInventory = new ItemStack[4]; 015 016 /** The index of the currently held item (0-8). */ 017 public int currentItem = 0; 018 @SideOnly(Side.CLIENT) 019 020 /** The current ItemStack. */ 021 private ItemStack currentItemStack; 022 023 /** The player whose inventory this is. */ 024 public EntityPlayer player; 025 private ItemStack itemStack; 026 027 /** 028 * Set true whenever the inventory changes. Nothing sets it false so you will have to write your own code to check 029 * it and reset the value. 030 */ 031 public boolean inventoryChanged = false; 032 033 public InventoryPlayer(EntityPlayer par1EntityPlayer) 034 { 035 this.player = par1EntityPlayer; 036 } 037 038 /** 039 * Returns the item stack currently held by the player. 040 */ 041 public ItemStack getCurrentItem() 042 { 043 return this.currentItem < 9 && this.currentItem >= 0 ? this.mainInventory[this.currentItem] : null; 044 } 045 046 public static int func_70451_h() 047 { 048 return 9; 049 } 050 051 /** 052 * Returns a slot index in main inventory containing a specific itemID 053 */ 054 private int getInventorySlotContainItem(int par1) 055 { 056 for (int var2 = 0; var2 < this.mainInventory.length; ++var2) 057 { 058 if (this.mainInventory[var2] != null && this.mainInventory[var2].itemID == par1) 059 { 060 return var2; 061 } 062 } 063 064 return -1; 065 } 066 067 @SideOnly(Side.CLIENT) 068 private int getInventorySlotContainItemAndDamage(int par1, int par2) 069 { 070 for (int var3 = 0; var3 < this.mainInventory.length; ++var3) 071 { 072 if (this.mainInventory[var3] != null && this.mainInventory[var3].itemID == par1 && this.mainInventory[var3].getItemDamage() == par2) 073 { 074 return var3; 075 } 076 } 077 078 return -1; 079 } 080 081 /** 082 * stores an itemstack in the users inventory 083 */ 084 private int storeItemStack(ItemStack par1ItemStack) 085 { 086 for (int var2 = 0; var2 < this.mainInventory.length; ++var2) 087 { 088 if (this.mainInventory[var2] != null && this.mainInventory[var2].itemID == par1ItemStack.itemID && this.mainInventory[var2].isStackable() && this.mainInventory[var2].stackSize < this.mainInventory[var2].getMaxStackSize() && this.mainInventory[var2].stackSize < this.getInventoryStackLimit() && (!this.mainInventory[var2].getHasSubtypes() || this.mainInventory[var2].getItemDamage() == par1ItemStack.getItemDamage()) && ItemStack.func_77970_a(this.mainInventory[var2], par1ItemStack)) 089 { 090 return var2; 091 } 092 } 093 094 return -1; 095 } 096 097 /** 098 * Returns the first item stack that is empty. 099 */ 100 public int getFirstEmptyStack() 101 { 102 for (int var1 = 0; var1 < this.mainInventory.length; ++var1) 103 { 104 if (this.mainInventory[var1] == null) 105 { 106 return var1; 107 } 108 } 109 110 return -1; 111 } 112 113 @SideOnly(Side.CLIENT) 114 115 /** 116 * Sets a specific itemID as the current item being held (only if it exists on the hotbar) 117 */ 118 public void setCurrentItem(int par1, int par2, boolean par3, boolean par4) 119 { 120 boolean var5 = true; 121 this.currentItemStack = this.getCurrentItem(); 122 int var7; 123 124 if (par3) 125 { 126 var7 = this.getInventorySlotContainItemAndDamage(par1, par2); 127 } 128 else 129 { 130 var7 = this.getInventorySlotContainItem(par1); 131 } 132 133 if (var7 >= 0 && var7 < 9) 134 { 135 this.currentItem = var7; 136 } 137 else 138 { 139 if (par4 && par1 > 0) 140 { 141 int var6 = this.getFirstEmptyStack(); 142 143 if (var6 >= 0 && var6 < 9) 144 { 145 this.currentItem = var6; 146 } 147 148 this.func_70439_a(Item.itemsList[par1], par2); 149 } 150 } 151 } 152 153 @SideOnly(Side.CLIENT) 154 155 /** 156 * Switch the current item to the next one or the previous one 157 */ 158 public void changeCurrentItem(int par1) 159 { 160 if (par1 > 0) 161 { 162 par1 = 1; 163 } 164 165 if (par1 < 0) 166 { 167 par1 = -1; 168 } 169 170 for (this.currentItem -= par1; this.currentItem < 0; this.currentItem += 9) 171 { 172 ; 173 } 174 175 while (this.currentItem >= 9) 176 { 177 this.currentItem -= 9; 178 } 179 } 180 181 public int func_82347_b(int par1, int par2) 182 { 183 int var3 = 0; 184 int var4; 185 ItemStack var5; 186 187 for (var4 = 0; var4 < this.mainInventory.length; ++var4) 188 { 189 var5 = this.mainInventory[var4]; 190 191 if (var5 != null && (par1 <= -1 || var5.itemID == par1) && (par2 <= -1 || var5.getItemDamage() == par2)) 192 { 193 var3 += var5.stackSize; 194 this.mainInventory[var4] = null; 195 } 196 } 197 198 for (var4 = 0; var4 < this.armorInventory.length; ++var4) 199 { 200 var5 = this.armorInventory[var4]; 201 202 if (var5 != null && (par1 <= -1 || var5.itemID == par1) && (par2 <= -1 || var5.getItemDamage() == par2)) 203 { 204 var3 += var5.stackSize; 205 this.armorInventory[var4] = null; 206 } 207 } 208 209 return var3; 210 } 211 212 @SideOnly(Side.CLIENT) 213 public void func_70439_a(Item par1Item, int par2) 214 { 215 if (par1Item != null) 216 { 217 int var3 = this.getInventorySlotContainItemAndDamage(par1Item.shiftedIndex, par2); 218 219 if (var3 >= 0) 220 { 221 this.mainInventory[var3] = this.mainInventory[this.currentItem]; 222 } 223 224 if (this.currentItemStack != null && this.currentItemStack.isItemEnchantable() && this.getInventorySlotContainItemAndDamage(this.currentItemStack.itemID, this.currentItemStack.getItemDamageForDisplay()) == this.currentItem) 225 { 226 return; 227 } 228 229 this.mainInventory[this.currentItem] = new ItemStack(Item.itemsList[par1Item.shiftedIndex], 1, par2); 230 } 231 } 232 233 /** 234 * This function stores as many items of an ItemStack as possible in a matching slot and returns the quantity of 235 * left over items. 236 */ 237 private int storePartialItemStack(ItemStack par1ItemStack) 238 { 239 int var2 = par1ItemStack.itemID; 240 int var3 = par1ItemStack.stackSize; 241 int var4; 242 243 if (par1ItemStack.getMaxStackSize() == 1) 244 { 245 var4 = this.getFirstEmptyStack(); 246 247 if (var4 < 0) 248 { 249 return var3; 250 } 251 else 252 { 253 if (this.mainInventory[var4] == null) 254 { 255 this.mainInventory[var4] = ItemStack.copyItemStack(par1ItemStack); 256 } 257 258 return 0; 259 } 260 } 261 else 262 { 263 var4 = this.storeItemStack(par1ItemStack); 264 265 if (var4 < 0) 266 { 267 var4 = this.getFirstEmptyStack(); 268 } 269 270 if (var4 < 0) 271 { 272 return var3; 273 } 274 else 275 { 276 if (this.mainInventory[var4] == null) 277 { 278 this.mainInventory[var4] = new ItemStack(var2, 0, par1ItemStack.getItemDamage()); 279 280 if (par1ItemStack.hasTagCompound()) 281 { 282 this.mainInventory[var4].setTagCompound((NBTTagCompound)par1ItemStack.getTagCompound().copy()); 283 } 284 } 285 286 int var5 = var3; 287 288 if (var3 > this.mainInventory[var4].getMaxStackSize() - this.mainInventory[var4].stackSize) 289 { 290 var5 = this.mainInventory[var4].getMaxStackSize() - this.mainInventory[var4].stackSize; 291 } 292 293 if (var5 > this.getInventoryStackLimit() - this.mainInventory[var4].stackSize) 294 { 295 var5 = this.getInventoryStackLimit() - this.mainInventory[var4].stackSize; 296 } 297 298 if (var5 == 0) 299 { 300 return var3; 301 } 302 else 303 { 304 var3 -= var5; 305 this.mainInventory[var4].stackSize += var5; 306 this.mainInventory[var4].animationsToGo = 5; 307 return var3; 308 } 309 } 310 } 311 } 312 313 /** 314 * Decrement the number of animations remaining. Only called on client side. This is used to handle the animation of 315 * receiving a block. 316 */ 317 public void decrementAnimations() 318 { 319 for (int var1 = 0; var1 < this.mainInventory.length; ++var1) 320 { 321 if (this.mainInventory[var1] != null) 322 { 323 this.mainInventory[var1].updateAnimation(this.player.worldObj, this.player, var1, this.currentItem == var1); 324 } 325 } 326 } 327 328 /** 329 * removed one item of specified itemID from inventory (if it is in a stack, the stack size will reduce with 1) 330 */ 331 public boolean consumeInventoryItem(int par1) 332 { 333 int var2 = this.getInventorySlotContainItem(par1); 334 335 if (var2 < 0) 336 { 337 return false; 338 } 339 else 340 { 341 if (--this.mainInventory[var2].stackSize <= 0) 342 { 343 this.mainInventory[var2] = null; 344 } 345 346 return true; 347 } 348 } 349 350 /** 351 * Get if a specifiied item id is inside the inventory. 352 */ 353 public boolean hasItem(int par1) 354 { 355 int var2 = this.getInventorySlotContainItem(par1); 356 return var2 >= 0; 357 } 358 359 /** 360 * Adds the item stack to the inventory, returns false if it is impossible. 361 */ 362 public boolean addItemStackToInventory(ItemStack par1ItemStack) 363 { 364 int var2; 365 366 if (par1ItemStack.isItemDamaged()) 367 { 368 var2 = this.getFirstEmptyStack(); 369 370 if (var2 >= 0) 371 { 372 this.mainInventory[var2] = ItemStack.copyItemStack(par1ItemStack); 373 this.mainInventory[var2].animationsToGo = 5; 374 par1ItemStack.stackSize = 0; 375 return true; 376 } 377 else if (this.player.capabilities.isCreativeMode) 378 { 379 par1ItemStack.stackSize = 0; 380 return true; 381 } 382 else 383 { 384 return false; 385 } 386 } 387 else 388 { 389 do 390 { 391 var2 = par1ItemStack.stackSize; 392 par1ItemStack.stackSize = this.storePartialItemStack(par1ItemStack); 393 } 394 while (par1ItemStack.stackSize > 0 && par1ItemStack.stackSize < var2); 395 396 if (par1ItemStack.stackSize == var2 && this.player.capabilities.isCreativeMode) 397 { 398 par1ItemStack.stackSize = 0; 399 return true; 400 } 401 else 402 { 403 return par1ItemStack.stackSize < var2; 404 } 405 } 406 } 407 408 /** 409 * Removes from an inventory slot (first arg) up to a specified number (second arg) of items and returns them in a 410 * new stack. 411 */ 412 public ItemStack decrStackSize(int par1, int par2) 413 { 414 ItemStack[] var3 = this.mainInventory; 415 416 if (par1 >= this.mainInventory.length) 417 { 418 var3 = this.armorInventory; 419 par1 -= this.mainInventory.length; 420 } 421 422 if (var3[par1] != null) 423 { 424 ItemStack var4; 425 426 if (var3[par1].stackSize <= par2) 427 { 428 var4 = var3[par1]; 429 var3[par1] = null; 430 return var4; 431 } 432 else 433 { 434 var4 = var3[par1].splitStack(par2); 435 436 if (var3[par1].stackSize == 0) 437 { 438 var3[par1] = null; 439 } 440 441 return var4; 442 } 443 } 444 else 445 { 446 return null; 447 } 448 } 449 450 /** 451 * When some containers are closed they call this on each slot, then drop whatever it returns as an EntityItem - 452 * like when you close a workbench GUI. 453 */ 454 public ItemStack getStackInSlotOnClosing(int par1) 455 { 456 ItemStack[] var2 = this.mainInventory; 457 458 if (par1 >= this.mainInventory.length) 459 { 460 var2 = this.armorInventory; 461 par1 -= this.mainInventory.length; 462 } 463 464 if (var2[par1] != null) 465 { 466 ItemStack var3 = var2[par1]; 467 var2[par1] = null; 468 return var3; 469 } 470 else 471 { 472 return null; 473 } 474 } 475 476 /** 477 * Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections). 478 */ 479 public void setInventorySlotContents(int par1, ItemStack par2ItemStack) 480 { 481 ItemStack[] var3 = this.mainInventory; 482 483 if (par1 >= var3.length) 484 { 485 par1 -= var3.length; 486 var3 = this.armorInventory; 487 } 488 489 var3[par1] = par2ItemStack; 490 } 491 492 /** 493 * Gets the strength of the current item (tool) against the specified block, 1.0f if not holding anything. 494 */ 495 public float getStrVsBlock(Block par1Block) 496 { 497 float var2 = 1.0F; 498 499 if (this.mainInventory[this.currentItem] != null) 500 { 501 var2 *= this.mainInventory[this.currentItem].getStrVsBlock(par1Block); 502 } 503 504 return var2; 505 } 506 507 /** 508 * Writes the inventory out as a list of compound tags. This is where the slot indices are used (+100 for armor, +80 509 * for crafting). 510 */ 511 public NBTTagList writeToNBT(NBTTagList par1NBTTagList) 512 { 513 int var2; 514 NBTTagCompound var3; 515 516 for (var2 = 0; var2 < this.mainInventory.length; ++var2) 517 { 518 if (this.mainInventory[var2] != null) 519 { 520 var3 = new NBTTagCompound(); 521 var3.setByte("Slot", (byte)var2); 522 this.mainInventory[var2].writeToNBT(var3); 523 par1NBTTagList.appendTag(var3); 524 } 525 } 526 527 for (var2 = 0; var2 < this.armorInventory.length; ++var2) 528 { 529 if (this.armorInventory[var2] != null) 530 { 531 var3 = new NBTTagCompound(); 532 var3.setByte("Slot", (byte)(var2 + 100)); 533 this.armorInventory[var2].writeToNBT(var3); 534 par1NBTTagList.appendTag(var3); 535 } 536 } 537 538 return par1NBTTagList; 539 } 540 541 /** 542 * Reads from the given tag list and fills the slots in the inventory with the correct items. 543 */ 544 public void readFromNBT(NBTTagList par1NBTTagList) 545 { 546 this.mainInventory = new ItemStack[36]; 547 this.armorInventory = new ItemStack[4]; 548 549 for (int var2 = 0; var2 < par1NBTTagList.tagCount(); ++var2) 550 { 551 NBTTagCompound var3 = (NBTTagCompound)par1NBTTagList.tagAt(var2); 552 int var4 = var3.getByte("Slot") & 255; 553 ItemStack var5 = ItemStack.loadItemStackFromNBT(var3); 554 555 if (var5 != null) 556 { 557 if (var4 >= 0 && var4 < this.mainInventory.length) 558 { 559 this.mainInventory[var4] = var5; 560 } 561 562 if (var4 >= 100 && var4 < this.armorInventory.length + 100) 563 { 564 this.armorInventory[var4 - 100] = var5; 565 } 566 } 567 } 568 } 569 570 /** 571 * Returns the number of slots in the inventory. 572 */ 573 public int getSizeInventory() 574 { 575 return this.mainInventory.length + 4; 576 } 577 578 /** 579 * Returns the stack in slot i 580 */ 581 public ItemStack getStackInSlot(int par1) 582 { 583 ItemStack[] var2 = this.mainInventory; 584 585 if (par1 >= var2.length) 586 { 587 par1 -= var2.length; 588 var2 = this.armorInventory; 589 } 590 591 return var2[par1]; 592 } 593 594 /** 595 * Returns the name of the inventory. 596 */ 597 public String getInvName() 598 { 599 return "container.inventory"; 600 } 601 602 /** 603 * Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended. *Isn't 604 * this more of a set than a get?* 605 */ 606 public int getInventoryStackLimit() 607 { 608 return 64; 609 } 610 611 /** 612 * Return damage vs an entity done by the current held weapon, or 1 if nothing is held 613 */ 614 public int getDamageVsEntity(Entity par1Entity) 615 { 616 ItemStack var2 = this.getStackInSlot(this.currentItem); 617 return var2 != null ? var2.getDamageVsEntity(par1Entity) : 1; 618 } 619 620 /** 621 * Returns whether the current item (tool) can harvest from the specified block (actually get a result). 622 */ 623 public boolean canHarvestBlock(Block par1Block) 624 { 625 if (par1Block.blockMaterial.isHarvestable()) 626 { 627 return true; 628 } 629 else 630 { 631 ItemStack var2 = this.getStackInSlot(this.currentItem); 632 return var2 != null ? var2.canHarvestBlock(par1Block) : false; 633 } 634 } 635 636 /** 637 * returns a player armor item (as itemstack) contained in specified armor slot. 638 */ 639 public ItemStack armorItemInSlot(int par1) 640 { 641 return this.armorInventory[par1]; 642 } 643 644 /** 645 * Based on the damage values and maximum damage values of each armor item, returns the current armor value. 646 */ 647 public int getTotalArmorValue() 648 { 649 int var1 = 0; 650 ItemStack[] var2 = this.armorInventory; 651 int var3 = var2.length; 652 653 for (int var4 = 0; var4 < var3; ++var4) 654 { 655 ItemStack var5 = var2[var4]; 656 657 if (var5 != null && var5.getItem() instanceof ItemArmor) 658 { 659 int var6 = ((ItemArmor)var5.getItem()).damageReduceAmount; 660 var1 += var6; 661 } 662 } 663 664 return var1; 665 } 666 667 /** 668 * Damages armor in each slot by the specified amount. 669 */ 670 public void damageArmor(int par1) 671 { 672 par1 /= 4; 673 674 if (par1 < 1) 675 { 676 par1 = 1; 677 } 678 679 for (int var2 = 0; var2 < this.armorInventory.length; ++var2) 680 { 681 if (this.armorInventory[var2] != null && this.armorInventory[var2].getItem() instanceof ItemArmor) 682 { 683 this.armorInventory[var2].damageItem(par1, this.player); 684 685 if (this.armorInventory[var2].stackSize == 0) 686 { 687 this.armorInventory[var2] = null; 688 } 689 } 690 } 691 } 692 693 /** 694 * Drop all armor and main inventory items. 695 */ 696 public void dropAllItems() 697 { 698 int var1; 699 700 for (var1 = 0; var1 < this.mainInventory.length; ++var1) 701 { 702 if (this.mainInventory[var1] != null) 703 { 704 this.player.dropPlayerItemWithRandomChoice(this.mainInventory[var1], true); 705 this.mainInventory[var1] = null; 706 } 707 } 708 709 for (var1 = 0; var1 < this.armorInventory.length; ++var1) 710 { 711 if (this.armorInventory[var1] != null) 712 { 713 this.player.dropPlayerItemWithRandomChoice(this.armorInventory[var1], true); 714 this.armorInventory[var1] = null; 715 } 716 } 717 } 718 719 /** 720 * Called when an the contents of an Inventory change, usually 721 */ 722 public void onInventoryChanged() 723 { 724 this.inventoryChanged = true; 725 } 726 727 public void setItemStack(ItemStack par1ItemStack) 728 { 729 this.itemStack = par1ItemStack; 730 } 731 732 public ItemStack getItemStack() 733 { 734 return this.itemStack; 735 } 736 737 /** 738 * Do not make give this method the name canInteractWith because it clashes with Container 739 */ 740 public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) 741 { 742 return this.player.isDead ? false : par1EntityPlayer.getDistanceSqToEntity(this.player) <= 64.0D; 743 } 744 745 /** 746 * Returns true if the specified ItemStack exists in the inventory. 747 */ 748 public boolean hasItemStack(ItemStack par1ItemStack) 749 { 750 ItemStack[] var2 = this.armorInventory; 751 int var3 = var2.length; 752 int var4; 753 ItemStack var5; 754 755 for (var4 = 0; var4 < var3; ++var4) 756 { 757 var5 = var2[var4]; 758 759 if (var5 != null && var5.isItemEqual(par1ItemStack)) 760 { 761 return true; 762 } 763 } 764 765 var2 = this.mainInventory; 766 var3 = var2.length; 767 768 for (var4 = 0; var4 < var3; ++var4) 769 { 770 var5 = var2[var4]; 771 772 if (var5 != null && var5.isItemEqual(par1ItemStack)) 773 { 774 return true; 775 } 776 } 777 778 return false; 779 } 780 781 public void openChest() {} 782 783 public void closeChest() {} 784 785 /** 786 * Copy the ItemStack contents from another InventoryPlayer instance 787 */ 788 public void copyInventory(InventoryPlayer par1InventoryPlayer) 789 { 790 int var2; 791 792 for (var2 = 0; var2 < this.mainInventory.length; ++var2) 793 { 794 this.mainInventory[var2] = ItemStack.copyItemStack(par1InventoryPlayer.mainInventory[var2]); 795 } 796 797 for (var2 = 0; var2 < this.armorInventory.length; ++var2) 798 { 799 this.armorInventory[var2] = ItemStack.copyItemStack(par1InventoryPlayer.armorInventory[var2]); 800 } 801 } 802 }