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.areItemStackTagsEqual(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 /** 182 * Clear this player's inventory, using the specified ID and metadata as filters or -1 for no filter. 183 */ 184 public int clearInventory(int par1, int par2) 185 { 186 int var3 = 0; 187 int var4; 188 ItemStack var5; 189 190 for (var4 = 0; var4 < this.mainInventory.length; ++var4) 191 { 192 var5 = this.mainInventory[var4]; 193 194 if (var5 != null && (par1 <= -1 || var5.itemID == par1) && (par2 <= -1 || var5.getItemDamage() == par2)) 195 { 196 var3 += var5.stackSize; 197 this.mainInventory[var4] = null; 198 } 199 } 200 201 for (var4 = 0; var4 < this.armorInventory.length; ++var4) 202 { 203 var5 = this.armorInventory[var4]; 204 205 if (var5 != null && (par1 <= -1 || var5.itemID == par1) && (par2 <= -1 || var5.getItemDamage() == par2)) 206 { 207 var3 += var5.stackSize; 208 this.armorInventory[var4] = null; 209 } 210 } 211 212 return var3; 213 } 214 215 @SideOnly(Side.CLIENT) 216 public void func_70439_a(Item par1Item, int par2) 217 { 218 if (par1Item != null) 219 { 220 int var3 = this.getInventorySlotContainItemAndDamage(par1Item.shiftedIndex, par2); 221 222 if (var3 >= 0) 223 { 224 this.mainInventory[var3] = this.mainInventory[this.currentItem]; 225 } 226 227 if (this.currentItemStack != null && this.currentItemStack.isItemEnchantable() && this.getInventorySlotContainItemAndDamage(this.currentItemStack.itemID, this.currentItemStack.getItemDamageForDisplay()) == this.currentItem) 228 { 229 return; 230 } 231 232 this.mainInventory[this.currentItem] = new ItemStack(Item.itemsList[par1Item.shiftedIndex], 1, par2); 233 } 234 } 235 236 /** 237 * This function stores as many items of an ItemStack as possible in a matching slot and returns the quantity of 238 * left over items. 239 */ 240 private int storePartialItemStack(ItemStack par1ItemStack) 241 { 242 int var2 = par1ItemStack.itemID; 243 int var3 = par1ItemStack.stackSize; 244 int var4; 245 246 if (par1ItemStack.getMaxStackSize() == 1) 247 { 248 var4 = this.getFirstEmptyStack(); 249 250 if (var4 < 0) 251 { 252 return var3; 253 } 254 else 255 { 256 if (this.mainInventory[var4] == null) 257 { 258 this.mainInventory[var4] = ItemStack.copyItemStack(par1ItemStack); 259 } 260 261 return 0; 262 } 263 } 264 else 265 { 266 var4 = this.storeItemStack(par1ItemStack); 267 268 if (var4 < 0) 269 { 270 var4 = this.getFirstEmptyStack(); 271 } 272 273 if (var4 < 0) 274 { 275 return var3; 276 } 277 else 278 { 279 if (this.mainInventory[var4] == null) 280 { 281 this.mainInventory[var4] = new ItemStack(var2, 0, par1ItemStack.getItemDamage()); 282 283 if (par1ItemStack.hasTagCompound()) 284 { 285 this.mainInventory[var4].setTagCompound((NBTTagCompound)par1ItemStack.getTagCompound().copy()); 286 } 287 } 288 289 int var5 = var3; 290 291 if (var3 > this.mainInventory[var4].getMaxStackSize() - this.mainInventory[var4].stackSize) 292 { 293 var5 = this.mainInventory[var4].getMaxStackSize() - this.mainInventory[var4].stackSize; 294 } 295 296 if (var5 > this.getInventoryStackLimit() - this.mainInventory[var4].stackSize) 297 { 298 var5 = this.getInventoryStackLimit() - this.mainInventory[var4].stackSize; 299 } 300 301 if (var5 == 0) 302 { 303 return var3; 304 } 305 else 306 { 307 var3 -= var5; 308 this.mainInventory[var4].stackSize += var5; 309 this.mainInventory[var4].animationsToGo = 5; 310 return var3; 311 } 312 } 313 } 314 } 315 316 /** 317 * Decrement the number of animations remaining. Only called on client side. This is used to handle the animation of 318 * receiving a block. 319 */ 320 public void decrementAnimations() 321 { 322 for (int var1 = 0; var1 < this.mainInventory.length; ++var1) 323 { 324 if (this.mainInventory[var1] != null) 325 { 326 this.mainInventory[var1].updateAnimation(this.player.worldObj, this.player, var1, this.currentItem == var1); 327 } 328 } 329 } 330 331 /** 332 * removed one item of specified itemID from inventory (if it is in a stack, the stack size will reduce with 1) 333 */ 334 public boolean consumeInventoryItem(int par1) 335 { 336 int var2 = this.getInventorySlotContainItem(par1); 337 338 if (var2 < 0) 339 { 340 return false; 341 } 342 else 343 { 344 if (--this.mainInventory[var2].stackSize <= 0) 345 { 346 this.mainInventory[var2] = null; 347 } 348 349 return true; 350 } 351 } 352 353 /** 354 * Get if a specifiied item id is inside the inventory. 355 */ 356 public boolean hasItem(int par1) 357 { 358 int var2 = this.getInventorySlotContainItem(par1); 359 return var2 >= 0; 360 } 361 362 /** 363 * Adds the item stack to the inventory, returns false if it is impossible. 364 */ 365 public boolean addItemStackToInventory(ItemStack par1ItemStack) 366 { 367 int var2; 368 369 if (par1ItemStack.isItemDamaged()) 370 { 371 var2 = this.getFirstEmptyStack(); 372 373 if (var2 >= 0) 374 { 375 this.mainInventory[var2] = ItemStack.copyItemStack(par1ItemStack); 376 this.mainInventory[var2].animationsToGo = 5; 377 par1ItemStack.stackSize = 0; 378 return true; 379 } 380 else if (this.player.capabilities.isCreativeMode) 381 { 382 par1ItemStack.stackSize = 0; 383 return true; 384 } 385 else 386 { 387 return false; 388 } 389 } 390 else 391 { 392 do 393 { 394 var2 = par1ItemStack.stackSize; 395 par1ItemStack.stackSize = this.storePartialItemStack(par1ItemStack); 396 } 397 while (par1ItemStack.stackSize > 0 && par1ItemStack.stackSize < var2); 398 399 if (par1ItemStack.stackSize == var2 && this.player.capabilities.isCreativeMode) 400 { 401 par1ItemStack.stackSize = 0; 402 return true; 403 } 404 else 405 { 406 return par1ItemStack.stackSize < var2; 407 } 408 } 409 } 410 411 /** 412 * Removes from an inventory slot (first arg) up to a specified number (second arg) of items and returns them in a 413 * new stack. 414 */ 415 public ItemStack decrStackSize(int par1, int par2) 416 { 417 ItemStack[] var3 = this.mainInventory; 418 419 if (par1 >= this.mainInventory.length) 420 { 421 var3 = this.armorInventory; 422 par1 -= this.mainInventory.length; 423 } 424 425 if (var3[par1] != null) 426 { 427 ItemStack var4; 428 429 if (var3[par1].stackSize <= par2) 430 { 431 var4 = var3[par1]; 432 var3[par1] = null; 433 return var4; 434 } 435 else 436 { 437 var4 = var3[par1].splitStack(par2); 438 439 if (var3[par1].stackSize == 0) 440 { 441 var3[par1] = null; 442 } 443 444 return var4; 445 } 446 } 447 else 448 { 449 return null; 450 } 451 } 452 453 /** 454 * When some containers are closed they call this on each slot, then drop whatever it returns as an EntityItem - 455 * like when you close a workbench GUI. 456 */ 457 public ItemStack getStackInSlotOnClosing(int par1) 458 { 459 ItemStack[] var2 = this.mainInventory; 460 461 if (par1 >= this.mainInventory.length) 462 { 463 var2 = this.armorInventory; 464 par1 -= this.mainInventory.length; 465 } 466 467 if (var2[par1] != null) 468 { 469 ItemStack var3 = var2[par1]; 470 var2[par1] = null; 471 return var3; 472 } 473 else 474 { 475 return null; 476 } 477 } 478 479 /** 480 * Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections). 481 */ 482 public void setInventorySlotContents(int par1, ItemStack par2ItemStack) 483 { 484 ItemStack[] var3 = this.mainInventory; 485 486 if (par1 >= var3.length) 487 { 488 par1 -= var3.length; 489 var3 = this.armorInventory; 490 } 491 492 var3[par1] = par2ItemStack; 493 } 494 495 /** 496 * Gets the strength of the current item (tool) against the specified block, 1.0f if not holding anything. 497 */ 498 public float getStrVsBlock(Block par1Block) 499 { 500 float var2 = 1.0F; 501 502 if (this.mainInventory[this.currentItem] != null) 503 { 504 var2 *= this.mainInventory[this.currentItem].getStrVsBlock(par1Block); 505 } 506 507 return var2; 508 } 509 510 /** 511 * Writes the inventory out as a list of compound tags. This is where the slot indices are used (+100 for armor, +80 512 * for crafting). 513 */ 514 public NBTTagList writeToNBT(NBTTagList par1NBTTagList) 515 { 516 int var2; 517 NBTTagCompound var3; 518 519 for (var2 = 0; var2 < this.mainInventory.length; ++var2) 520 { 521 if (this.mainInventory[var2] != null) 522 { 523 var3 = new NBTTagCompound(); 524 var3.setByte("Slot", (byte)var2); 525 this.mainInventory[var2].writeToNBT(var3); 526 par1NBTTagList.appendTag(var3); 527 } 528 } 529 530 for (var2 = 0; var2 < this.armorInventory.length; ++var2) 531 { 532 if (this.armorInventory[var2] != null) 533 { 534 var3 = new NBTTagCompound(); 535 var3.setByte("Slot", (byte)(var2 + 100)); 536 this.armorInventory[var2].writeToNBT(var3); 537 par1NBTTagList.appendTag(var3); 538 } 539 } 540 541 return par1NBTTagList; 542 } 543 544 /** 545 * Reads from the given tag list and fills the slots in the inventory with the correct items. 546 */ 547 public void readFromNBT(NBTTagList par1NBTTagList) 548 { 549 this.mainInventory = new ItemStack[36]; 550 this.armorInventory = new ItemStack[4]; 551 552 for (int var2 = 0; var2 < par1NBTTagList.tagCount(); ++var2) 553 { 554 NBTTagCompound var3 = (NBTTagCompound)par1NBTTagList.tagAt(var2); 555 int var4 = var3.getByte("Slot") & 255; 556 ItemStack var5 = ItemStack.loadItemStackFromNBT(var3); 557 558 if (var5 != null) 559 { 560 if (var4 >= 0 && var4 < this.mainInventory.length) 561 { 562 this.mainInventory[var4] = var5; 563 } 564 565 if (var4 >= 100 && var4 < this.armorInventory.length + 100) 566 { 567 this.armorInventory[var4 - 100] = var5; 568 } 569 } 570 } 571 } 572 573 /** 574 * Returns the number of slots in the inventory. 575 */ 576 public int getSizeInventory() 577 { 578 return this.mainInventory.length + 4; 579 } 580 581 /** 582 * Returns the stack in slot i 583 */ 584 public ItemStack getStackInSlot(int par1) 585 { 586 ItemStack[] var2 = this.mainInventory; 587 588 if (par1 >= var2.length) 589 { 590 par1 -= var2.length; 591 var2 = this.armorInventory; 592 } 593 594 return var2[par1]; 595 } 596 597 /** 598 * Returns the name of the inventory. 599 */ 600 public String getInvName() 601 { 602 return "container.inventory"; 603 } 604 605 /** 606 * Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended. *Isn't 607 * this more of a set than a get?* 608 */ 609 public int getInventoryStackLimit() 610 { 611 return 64; 612 } 613 614 /** 615 * Return damage vs an entity done by the current held weapon, or 1 if nothing is held 616 */ 617 public int getDamageVsEntity(Entity par1Entity) 618 { 619 ItemStack var2 = this.getStackInSlot(this.currentItem); 620 return var2 != null ? var2.getDamageVsEntity(par1Entity) : 1; 621 } 622 623 /** 624 * Returns whether the current item (tool) can harvest from the specified block (actually get a result). 625 */ 626 public boolean canHarvestBlock(Block par1Block) 627 { 628 if (par1Block.blockMaterial.isHarvestable()) 629 { 630 return true; 631 } 632 else 633 { 634 ItemStack var2 = this.getStackInSlot(this.currentItem); 635 return var2 != null ? var2.canHarvestBlock(par1Block) : false; 636 } 637 } 638 639 /** 640 * returns a player armor item (as itemstack) contained in specified armor slot. 641 */ 642 public ItemStack armorItemInSlot(int par1) 643 { 644 return this.armorInventory[par1]; 645 } 646 647 /** 648 * Based on the damage values and maximum damage values of each armor item, returns the current armor value. 649 */ 650 public int getTotalArmorValue() 651 { 652 int var1 = 0; 653 654 for (int var2 = 0; var2 < this.armorInventory.length; ++var2) 655 { 656 if (this.armorInventory[var2] != null && this.armorInventory[var2].getItem() instanceof ItemArmor) 657 { 658 int var3 = ((ItemArmor)this.armorInventory[var2].getItem()).damageReduceAmount; 659 var1 += var3; 660 } 661 } 662 663 return var1; 664 } 665 666 /** 667 * Damages armor in each slot by the specified amount. 668 */ 669 public void damageArmor(int par1) 670 { 671 par1 /= 4; 672 673 if (par1 < 1) 674 { 675 par1 = 1; 676 } 677 678 for (int var2 = 0; var2 < this.armorInventory.length; ++var2) 679 { 680 if (this.armorInventory[var2] != null && this.armorInventory[var2].getItem() instanceof ItemArmor) 681 { 682 this.armorInventory[var2].damageItem(par1, this.player); 683 684 if (this.armorInventory[var2].stackSize == 0) 685 { 686 this.armorInventory[var2] = null; 687 } 688 } 689 } 690 } 691 692 /** 693 * Drop all armor and main inventory items. 694 */ 695 public void dropAllItems() 696 { 697 int var1; 698 699 for (var1 = 0; var1 < this.mainInventory.length; ++var1) 700 { 701 if (this.mainInventory[var1] != null) 702 { 703 this.player.dropPlayerItemWithRandomChoice(this.mainInventory[var1], true); 704 this.mainInventory[var1] = null; 705 } 706 } 707 708 for (var1 = 0; var1 < this.armorInventory.length; ++var1) 709 { 710 if (this.armorInventory[var1] != null) 711 { 712 this.player.dropPlayerItemWithRandomChoice(this.armorInventory[var1], true); 713 this.armorInventory[var1] = null; 714 } 715 } 716 } 717 718 /** 719 * Called when an the contents of an Inventory change, usually 720 */ 721 public void onInventoryChanged() 722 { 723 this.inventoryChanged = true; 724 } 725 726 public void setItemStack(ItemStack par1ItemStack) 727 { 728 this.itemStack = par1ItemStack; 729 } 730 731 public ItemStack getItemStack() 732 { 733 return this.itemStack; 734 } 735 736 /** 737 * Do not make give this method the name canInteractWith because it clashes with Container 738 */ 739 public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) 740 { 741 return this.player.isDead ? false : par1EntityPlayer.getDistanceSqToEntity(this.player) <= 64.0D; 742 } 743 744 /** 745 * Returns true if the specified ItemStack exists in the inventory. 746 */ 747 public boolean hasItemStack(ItemStack par1ItemStack) 748 { 749 int var2; 750 751 for (var2 = 0; var2 < this.armorInventory.length; ++var2) 752 { 753 if (this.armorInventory[var2] != null && this.armorInventory[var2].isItemEqual(par1ItemStack)) 754 { 755 return true; 756 } 757 } 758 759 for (var2 = 0; var2 < this.mainInventory.length; ++var2) 760 { 761 if (this.mainInventory[var2] != null && this.mainInventory[var2].isItemEqual(par1ItemStack)) 762 { 763 return true; 764 } 765 } 766 767 return false; 768 } 769 770 public void openChest() {} 771 772 public void closeChest() {} 773 774 /** 775 * Copy the ItemStack contents from another InventoryPlayer instance 776 */ 777 public void copyInventory(InventoryPlayer par1InventoryPlayer) 778 { 779 int var2; 780 781 for (var2 = 0; var2 < this.mainInventory.length; ++var2) 782 { 783 this.mainInventory[var2] = ItemStack.copyItemStack(par1InventoryPlayer.mainInventory[var2]); 784 } 785 786 for (var2 = 0; var2 < this.armorInventory.length; ++var2) 787 { 788 this.armorInventory[var2] = ItemStack.copyItemStack(par1InventoryPlayer.armorInventory[var2]); 789 } 790 } 791 }