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