    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        @SideOnly(Side.CLIENT)
    070        public void func_82847_b(ICrafting par1ICrafting)
    071        {
    072            this.crafters.remove(par1ICrafting);
    073        }
    074
    075        /**
    076         * Updates crafting matrix; called from onCraftMatrixChanged. Args: none
    077         */
    078        public void updateCraftingResults()
    079        {
    080            for (int var1 = 0; var1 < this.inventorySlots.size(); ++var1)
    081            {
    082                ItemStack var2 = ((Slot)this.inventorySlots.get(var1)).getStack();
    083                ItemStack var3 = (ItemStack)this.inventoryItemStacks.get(var1);
    084
    085                if (!ItemStack.areItemStacksEqual(var3, var2))
    086                {
    087                    var3 = var2 == null ? null : var2.copy();
    088                    this.inventoryItemStacks.set(var1, var3);
    089                    Iterator var4 = this.crafters.iterator();
    090
    091                    while (var4.hasNext())
    092                    {
    093                        ICrafting var5 = (ICrafting)var4.next();
    094                        var5.updateCraftingInventorySlot(this, var1, var3);
    095                    }
    096                }
    097            }
    098        }
    099
    100        /**
    101         * enchants the item on the table using the specified slot; also deducts XP from player
    102         */
    103        public boolean enchantItem(EntityPlayer par1EntityPlayer, int par2)
    104        {
    105            return false;
    106        }
    107
    108        public Slot getSlotFromInventory(IInventory par1IInventory, int par2)
    109        {
    110            Iterator var3 = this.inventorySlots.iterator();
    111            Slot var4;
    112
    113            do
    114            {
    115                if (!var3.hasNext())
    116                {
    117                    return null;
    118                }
    119
    120                var4 = (Slot)var3.next();
    121            }
    122            while (!var4.isSlotInInventory(par1IInventory, par2));
    123
    124            return var4;
    125        }
    126
    127        public Slot getSlot(int par1)
    128        {
    129            return (Slot)this.inventorySlots.get(par1);
    130        }
    131
    132        public ItemStack func_82846_b(EntityPlayer par1EntityPlayer, int par2)
    133        {
    134            Slot var3 = (Slot)this.inventorySlots.get(par2);
    135            return var3 != null ? var3.getStack() : null;
    136        }
    137
    138        public ItemStack slotClick(int par1, int par2, int par3, EntityPlayer par4EntityPlayer)
    139        {
    140            ItemStack var5 = null;
    141            InventoryPlayer var6 = par4EntityPlayer.inventory;
    142            Slot var7;
    143            ItemStack var8;
    144            int var10;
    145            ItemStack var11;
    146
    147            if ((par3 == 0 || par3 == 1) && (par2 == 0 || par2 == 1))
    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 == 1)
    171                {
    172                    var7 = (Slot)this.inventorySlots.get(par1);
    173
    174                    if (var7 != null && var7.func_82869_a(par4EntityPlayer))
    175                    {
    176                        var8 = this.func_82846_b(par4EntityPlayer, par1);
    177
    178                        if (var8 != null)
    179                        {
    180                            int var12 = var8.itemID;
    181                            var5 = var8.copy();
    182
    183                            if (var7 != null && var7.getStack() != null && var7.getStack().itemID == var12)
    184                            {
    185                                this.retrySlotClick(par1, par2, true, par4EntityPlayer);
    186                            }
    187                        }
    188                    }
    189                }
    190                else
    191                {
    192                    if (par1 < 0)
    193                    {
    194                        return null;
    195                    }
    196
    197                    var7 = (Slot)this.inventorySlots.get(par1);
    198
    199                    if (var7 != null)
    200                    {
    201                        var8 = var7.getStack();
    202                        ItemStack var13 = var6.getItemStack();
    203
    204                        if (var8 != null)
    205                        {
    206                            var5 = var8.copy();
    207                        }
    208
    209                        if (var8 == null)
    210                        {
    211                            if (var13 != null && var7.isItemValid(var13))
    212                            {
    213                                var10 = par2 == 0 ? var13.stackSize : 1;
    214
    215                                if (var10 > var7.getSlotStackLimit())
    216                                {
    217                                    var10 = var7.getSlotStackLimit();
    218                                }
    219
    220                                var7.putStack(var13.splitStack(var10));
    221
    222                                if (var13.stackSize == 0)
    223                                {
    224                                    var6.setItemStack((ItemStack)null);
    225                                }
    226                            }
    227                        }
    228                        else if (var7.func_82869_a(par4EntityPlayer))
    229                        {
    230                            if (var13 == null)
    231                            {
    232                                var10 = par2 == 0 ? var8.stackSize : (var8.stackSize + 1) / 2;
    233                                var11 = var7.decrStackSize(var10);
    234                                var6.setItemStack(var11);
    235
    236                                if (var8.stackSize == 0)
    237                                {
    238                                    var7.putStack((ItemStack)null);
    239                                }
    240
    241                                var7.func_82870_a(par4EntityPlayer, var6.getItemStack());
    242                            }
    243                            else if (var7.isItemValid(var13))
    244                            {
    245                                if (var8.itemID == var13.itemID && (!var8.getHasSubtypes() || var8.getItemDamage() == var13.getItemDamage()) && ItemStack.func_77970_a(var8, var13))
    246                                {
    247                                    var10 = par2 == 0 ? var13.stackSize : 1;
    248
    249                                    if (var10 > var7.getSlotStackLimit() - var8.stackSize)
    250                                    {
    251                                        var10 = var7.getSlotStackLimit() - var8.stackSize;
    252                                    }
    253
    254                                    if (var10 > var13.getMaxStackSize() - var8.stackSize)
    255                                    {
    256                                        var10 = var13.getMaxStackSize() - var8.stackSize;
    257                                    }
    258
    259                                    var13.splitStack(var10);
    260
    261                                    if (var13.stackSize == 0)
    262                                    {
    263                                        var6.setItemStack((ItemStack)null);
    264                                    }
    265
    266                                    var8.stackSize += var10;
    267                                }
    268                                else if (var13.stackSize <= var7.getSlotStackLimit())
    269                                {
    270                                    var7.putStack(var13);
    271                                    var6.setItemStack(var8);
    272                                }
    273                            }
    274                            else if (var8.itemID == var13.itemID && var13.getMaxStackSize() > 1 && (!var8.getHasSubtypes() || var8.getItemDamage() == var13.getItemDamage()) && ItemStack.func_77970_a(var8, var13))
    275                            {
    276                                var10 = var8.stackSize;
    277
    278                                if (var10 > 0 && var10 + var13.stackSize <= var13.getMaxStackSize())
    279                                {
    280                                    var13.stackSize += var10;
    281                                    var8 = var7.decrStackSize(var10);
    282
    283                                    if (var8.stackSize == 0)
    284                                    {
    285                                        var7.putStack((ItemStack)null);
    286                                    }
    287
    288                                    var7.func_82870_a(par4EntityPlayer, var6.getItemStack());
    289                                }
    290                            }
    291                        }
    292
    293                        var7.onSlotChanged();
    294                    }
    295                }
    296            }
    297            else if (par3 == 2 && par2 >= 0 && par2 < 9)
    298            {
    299                var7 = (Slot)this.inventorySlots.get(par1);
    300
    301                if (var7.func_82869_a(par4EntityPlayer))
    302                {
    303                    var8 = var6.getStackInSlot(par2);
    304                    boolean var9 = var8 == null || var7.inventory == var6 && var7.isItemValid(var8);
    305                    var10 = -1;
    306
    307                    if (!var9)
    308                    {
    309                        var10 = var6.getFirstEmptyStack();
    310                        var9 |= var10 > -1;
    311                    }
    312
    313                    if (var7.getHasStack() && var9)
    314                    {
    315                        var11 = var7.getStack();
    316                        var6.setInventorySlotContents(par2, var11);
    317
    318                        if ((var7.inventory != var6 || !var7.isItemValid(var8)) && var8 != null)
    319                        {
    320                            if (var10 > -1)
    321                            {
    322                                var6.addItemStackToInventory(var8);
    323                                var7.putStack((ItemStack)null);
    324                                var7.func_82870_a(par4EntityPlayer, var11);
    325                            }
    326                        }
    327                        else
    328                        {
    329                            var7.putStack(var8);
    330                            var7.func_82870_a(par4EntityPlayer, var11);
    331                        }
    332                    }
    333                    else if (!var7.getHasStack() && var8 != null && var7.isItemValid(var8))
    334                    {
    335                        var6.setInventorySlotContents(par2, (ItemStack)null);
    336                        var7.putStack(var8);
    337                    }
    338                }
    339            }
    340            else if (par3 == 3 && par4EntityPlayer.capabilities.isCreativeMode && var6.getItemStack() == null && par1 > 0)
    341            {
    342                var7 = (Slot)this.inventorySlots.get(par1);
    343
    344                if (var7 != null && var7.getHasStack())
    345                {
    346                    var8 = var7.getStack().copy();
    347                    var8.stackSize = var8.getMaxStackSize();
    348                    var6.setItemStack(var8);
    349                }
    350            }
    351
    352            return var5;
    353        }
    354
    355        protected void retrySlotClick(int par1, int par2, boolean par3, EntityPlayer par4EntityPlayer)
    356        {
    357            this.slotClick(par1, par2, 1, par4EntityPlayer);
    358        }
    359
    360        /**
    361         * Callback for when the crafting gui is closed.
    362         */
    363        public void onCraftGuiClosed(EntityPlayer par1EntityPlayer)
    364        {
    365            InventoryPlayer var2 = par1EntityPlayer.inventory;
    366
    367            if (var2.getItemStack() != null)
    368            {
    369                par1EntityPlayer.dropPlayerItem(var2.getItemStack());
    370                var2.setItemStack((ItemStack)null);
    371            }
    372        }
    373
    374        /**
    375         * Callback for when the crafting matrix is changed.
    376         */
    377        public void onCraftMatrixChanged(IInventory par1IInventory)
    378        {
    379            this.updateCraftingResults();
    380        }
    381
    382        /**
    383         * args: slotID, itemStack to put in slot
    384         */
    385        public void putStackInSlot(int par1, ItemStack par2ItemStack)
    386        {
    387            this.getSlot(par1).putStack(par2ItemStack);
    388        }
    389
    390        /**
    391         * NotUsing because adding a player twice is an error
    392         */
    393        public boolean isPlayerNotUsingContainer(EntityPlayer par1EntityPlayer)
    394        {
    395            return !this.playerList.contains(par1EntityPlayer);
    396        }
    397
    398        @SideOnly(Side.CLIENT)
    399
    400        /**
    401         * places itemstacks in first x slots, x being aitemstack.lenght
    402         */
    403        public void putStacksInSlots(ItemStack[] par1ArrayOfItemStack)
    404        {
    405            for (int var2 = 0; var2 < par1ArrayOfItemStack.length; ++var2)
    406            {
    407                this.getSlot(var2).putStack(par1ArrayOfItemStack[var2]);
    408            }
    409        }
    410
    411        /**
    412         * adds or removes the player from the container based on par2
    413         */
    414        public void setPlayerIsPresent(EntityPlayer par1EntityPlayer, boolean par2)
    415        {
    416            if (par2)
    417            {
    418                this.playerList.remove(par1EntityPlayer);
    419            }
    420            else
    421            {
    422                this.playerList.add(par1EntityPlayer);
    423            }
    424        }
    425
    426        @SideOnly(Side.CLIENT)
    427        public void updateProgressBar(int par1, int par2) {}
    428
    429        @SideOnly(Side.CLIENT)
    430
    431        /**
    432         * Gets a unique transaction ID. Parameter is unused.
    433         */
    434        public short getNextTransactionID(InventoryPlayer par1InventoryPlayer)
    435        {
    436            ++this.transactionID;
    437            return this.transactionID;
    438        }
    439
    440        public abstract boolean canInteractWith(EntityPlayer var1);
    441
    442        /**
    443         * merges provided ItemStack with the first avaliable one in the container/player inventory
    444         */
    445        protected boolean mergeItemStack(ItemStack par1ItemStack, int par2, int par3, boolean par4)
    446        {
    447            boolean var5 = false;
    448            int var6 = par2;
    449
    450            if (par4)
    451            {
    452                var6 = par3 - 1;
    453            }
    454
    455            Slot var7;
    456            ItemStack var8;
    457
    458            if (par1ItemStack.isStackable())
    459            {
    460                while (par1ItemStack.stackSize > 0 && (!par4 && var6 < par3 || par4 && var6 >= par2))
    461                {
    462                    var7 = (Slot)this.inventorySlots.get(var6);
    463                    var8 = var7.getStack();
    464
    465                    if (var8 != null && var8.itemID == par1ItemStack.itemID && (!par1ItemStack.getHasSubtypes() || par1ItemStack.getItemDamage() == var8.getItemDamage()) && ItemStack.func_77970_a(par1ItemStack, var8))
    466                    {
    467                        int var9 = var8.stackSize + par1ItemStack.stackSize;
    468
    469                        if (var9 <= par1ItemStack.getMaxStackSize())
    470                        {
    471                            par1ItemStack.stackSize = 0;
    472                            var8.stackSize = var9;
    473                            var7.onSlotChanged();
    474                            var5 = true;
    475                        }
    476                        else if (var8.stackSize < par1ItemStack.getMaxStackSize())
    477                        {
    478                            par1ItemStack.stackSize -= par1ItemStack.getMaxStackSize() - var8.stackSize;
    479                            var8.stackSize = par1ItemStack.getMaxStackSize();
    480                            var7.onSlotChanged();
    481                            var5 = true;
    482                        }
    483                    }
    484
    485                    if (par4)
    486                    {
    487                        --var6;
    488                    }
    489                    else
    490                    {
    491                        ++var6;
    492                    }
    493                }
    494            }
    495
    496            if (par1ItemStack.stackSize > 0)
    497            {
    498                if (par4)
    499                {
    500                    var6 = par3 - 1;
    501                }
    502                else
    503                {
    504                    var6 = par2;
    505                }
    506
    507                while (!par4 && var6 < par3 || par4 && var6 >= par2)
    508                {
    509                    var7 = (Slot)this.inventorySlots.get(var6);
    510                    var8 = var7.getStack();
    511
    512                    if (var8 == null)
    513                    {
    514                        var7.putStack(par1ItemStack.copy());
    515                        var7.onSlotChanged();
    516                        par1ItemStack.stackSize = 0;
    517                        var5 = true;
    518                        break;
    519                    }
    520
    521                    if (par4)
    522                    {
    523                        --var6;
    524                    }
    525                    else
    526                    {
    527                        ++var6;
    528                    }
    529                }
    530            }
    531
    532            return var5;
    533        }
    534    }