    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    }