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