    001package net.minecraft.client.gui.inventory;
    002
    003import cpw.mods.fml.relauncher.Side;
    004import cpw.mods.fml.relauncher.SideOnly;
    005import java.util.HashSet;
    006import java.util.Iterator;
    007import java.util.List;
    008import java.util.Set;
    009import net.minecraft.client.Minecraft;
    010import net.minecraft.client.gui.GuiScreen;
    011import net.minecraft.client.renderer.OpenGlHelper;
    012import net.minecraft.client.renderer.RenderHelper;
    013import net.minecraft.client.renderer.entity.RenderItem;
    014import net.minecraft.entity.player.InventoryPlayer;
    015import net.minecraft.inventory.Container;
    016import net.minecraft.inventory.Slot;
    017import net.minecraft.item.ItemStack;
    018import net.minecraft.util.EnumChatFormatting;
    019import net.minecraft.util.Icon;
    020import net.minecraft.util.MathHelper;
    021import org.lwjgl.input.Keyboard;
    022import org.lwjgl.opengl.GL11;
    023import org.lwjgl.opengl.GL12;
    024
    025@SideOnly(Side.CLIENT)
    026public abstract class GuiContainer extends GuiScreen
    027{
    028    /** Stacks renderer. Icons, stack size, health, etc... */
    029    protected static RenderItem itemRenderer = new RenderItem();
    030
    031    /** The X size of the inventory window in pixels. */
    032    protected int xSize = 176;
    033
    034    /** The Y size of the inventory window in pixels. */
    035    protected int ySize = 166;
    036
    037    /** A list of the players inventory slots. */
    038    public Container inventorySlots;
    039
    040    /**
    041     * Starting X position for the Gui. Inconsistent use for Gui backgrounds.
    042     */
    043    protected int guiLeft;
    044
    045    /**
    046     * Starting Y position for the Gui. Inconsistent use for Gui backgrounds.
    047     */
    048    protected int guiTop;
    049    private Slot theSlot;
    050
    051    /** Used when touchscreen is enabled */
    052    private Slot clickedSlot = null;
    053
    054    /** Used when touchscreen is enabled */
    055    private boolean isRightMouseClick = false;
    056
    057    /** Used when touchscreen is enabled */
    058    private ItemStack draggedStack = null;
    059    private int field_85049_r = 0;
    060    private int field_85048_s = 0;
    061    private Slot returningStackDestSlot = null;
    062    private long returningStackTime = 0L;
    063
    064    /** Used when touchscreen is enabled */
    065    private ItemStack returningStack = null;
    066    private Slot field_92033_y = null;
    067    private long field_92032_z = 0L;
    068    protected final Set field_94077_p = new HashSet();
    069    protected boolean field_94076_q;
    070    private int field_94071_C = 0;
    071    private int field_94067_D = 0;
    072    private boolean field_94068_E = false;
    073    private int field_94069_F;
    074    private long field_94070_G = 0L;
    075    private Slot field_94072_H = null;
    076    private int field_94073_I = 0;
    077    private boolean field_94074_J;
    078    private ItemStack field_94075_K = null;
    079
    080    public GuiContainer(Container par1Container)
    081    {
    082        this.inventorySlots = par1Container;
    083        this.field_94068_E = true;
    084    }
    085
    086    /**
    087     * Adds the buttons (and other controls) to the screen in question.
    088     */
    089    public void initGui()
    090    {
    091        super.initGui();
    092        this.mc.thePlayer.openContainer = this.inventorySlots;
    093        this.guiLeft = (this.width - this.xSize) / 2;
    094        this.guiTop = (this.height - this.ySize) / 2;
    095    }
    096
    097    /**
    098     * Draws the screen and all the components in it.
    099     */
    100    public void drawScreen(int par1, int par2, float par3)
    101    {
    102        this.drawDefaultBackground();
    103        int k = this.guiLeft;
    104        int l = this.guiTop;
    105        this.drawGuiContainerBackgroundLayer(par3, par1, par2);
    106        GL11.glDisable(GL12.GL_RESCALE_NORMAL);
    107        RenderHelper.disableStandardItemLighting();
    108        GL11.glDisable(GL11.GL_LIGHTING);
    109        GL11.glDisable(GL11.GL_DEPTH_TEST);
    110        super.drawScreen(par1, par2, par3);
    111        RenderHelper.enableGUIStandardItemLighting();
    112        GL11.glPushMatrix();
    113        GL11.glTranslatef((float)k, (float)l, 0.0F);
    114        GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    115        GL11.glEnable(GL12.GL_RESCALE_NORMAL);
    116        this.theSlot = null;
    117        short short1 = 240;
    118        short short2 = 240;
    119        OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)short1 / 1.0F, (float)short2 / 1.0F);
    120        GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    121        int i1;
    122
    123        for (int j1 = 0; j1 < this.inventorySlots.inventorySlots.size(); ++j1)
    124        {
    125            Slot slot = (Slot)this.inventorySlots.inventorySlots.get(j1);
    126            this.drawSlotInventory(slot);
    127
    128            if (this.isMouseOverSlot(slot, par1, par2))
    129            {
    130                this.theSlot = slot;
    131                GL11.glDisable(GL11.GL_LIGHTING);
    132                GL11.glDisable(GL11.GL_DEPTH_TEST);
    133                int k1 = slot.xDisplayPosition;
    134                i1 = slot.yDisplayPosition;
    135                this.drawGradientRect(k1, i1, k1 + 16, i1 + 16, -2130706433, -2130706433);
    136                GL11.glEnable(GL11.GL_LIGHTING);
    137                GL11.glEnable(GL11.GL_DEPTH_TEST);
    138            }
    139        }
    140
    141        this.drawGuiContainerForegroundLayer(par1, par2);
    142        InventoryPlayer inventoryplayer = this.mc.thePlayer.inventory;
    143        ItemStack itemstack = this.draggedStack == null ? inventoryplayer.getItemStack() : this.draggedStack;
    144
    145        if (itemstack != null)
    146        {
    147            byte b0 = 8;
    148            i1 = this.draggedStack == null ? 8 : 16;
    149            String s = null;
    150
    151            if (this.draggedStack != null && this.isRightMouseClick)
    152            {
    153                itemstack = itemstack.copy();
    154                itemstack.stackSize = MathHelper.ceiling_float_int((float)itemstack.stackSize / 2.0F);
    155            }
    156            else if (this.field_94076_q && this.field_94077_p.size() > 1)
    157            {
    158                itemstack = itemstack.copy();
    159                itemstack.stackSize = this.field_94069_F;
    160
    161                if (itemstack.stackSize == 0)
    162                {
    163                    s = "" + EnumChatFormatting.YELLOW + "0";
    164                }
    165            }
    166
    167            this.drawItemStack(itemstack, par1 - k - b0, par2 - l - i1, s);
    168        }
    169
    170        if (this.returningStack != null)
    171        {
    172            float f1 = (float)(Minecraft.getSystemTime() - this.returningStackTime) / 100.0F;
    173
    174            if (f1 >= 1.0F)
    175            {
    176                f1 = 1.0F;
    177                this.returningStack = null;
    178            }
    179
    180            i1 = this.returningStackDestSlot.xDisplayPosition - this.field_85049_r;
    181            int l1 = this.returningStackDestSlot.yDisplayPosition - this.field_85048_s;
    182            int i2 = this.field_85049_r + (int)((float)i1 * f1);
    183            int j2 = this.field_85048_s + (int)((float)l1 * f1);
    184            this.drawItemStack(this.returningStack, i2, j2, (String)null);
    185        }
    186
    187        if (inventoryplayer.getItemStack() == null && this.theSlot != null && this.theSlot.getHasStack())
    188        {
    189            ItemStack itemstack1 = this.theSlot.getStack();
    190            this.drawItemStackTooltip(itemstack1, par1 - k + 8, par2 - l + 8);
    191        }
    192
    193        GL11.glPopMatrix();
    194        GL11.glEnable(GL11.GL_LIGHTING);
    195        GL11.glEnable(GL11.GL_DEPTH_TEST);
    196        RenderHelper.enableStandardItemLighting();
    197    }
    198
    199    private void drawItemStack(ItemStack par1ItemStack, int par2, int par3, String par4Str)
    200    {
    201        GL11.glTranslatef(0.0F, 0.0F, 32.0F);
    202        this.zLevel = 200.0F;
    203        itemRenderer.zLevel = 200.0F;
    204        itemRenderer.renderItemAndEffectIntoGUI(this.fontRenderer, this.mc.renderEngine, par1ItemStack, par2, par3);
    205        itemRenderer.func_94148_a(this.fontRenderer, this.mc.renderEngine, par1ItemStack, par2, par3 - (this.draggedStack == null ? 0 : 8), par4Str);
    206        this.zLevel = 0.0F;
    207        itemRenderer.zLevel = 0.0F;
    208    }
    209
    210    protected void drawItemStackTooltip(ItemStack par1ItemStack, int par2, int par3)
    211    {
    212        GL11.glDisable(GL12.GL_RESCALE_NORMAL);
    213        RenderHelper.disableStandardItemLighting();
    214        GL11.glDisable(GL11.GL_LIGHTING);
    215        GL11.glDisable(GL11.GL_DEPTH_TEST);
    216        List list = par1ItemStack.getTooltip(this.mc.thePlayer, this.mc.gameSettings.advancedItemTooltips);
    217
    218        if (!list.isEmpty())
    219        {
    220            int k = 0;
    221            int l;
    222            int i1;
    223
    224            for (l = 0; l < list.size(); ++l)
    225            {
    226                i1 = this.fontRenderer.getStringWidth((String)list.get(l));
    227
    228                if (i1 > k)
    229                {
    230                    k = i1;
    231                }
    232            }
    233
    234            l = par2 + 12;
    235            i1 = par3 - 12;
    236            int j1 = 8;
    237
    238            if (list.size() > 1)
    239            {
    240                j1 += 2 + (list.size() - 1) * 10;
    241            }
    242
    243            if (this.guiTop + i1 + j1 + 6 > this.height)
    244            {
    245                i1 = this.height - j1 - this.guiTop - 6;
    246            }
    247
    248            this.zLevel = 300.0F;
    249            itemRenderer.zLevel = 300.0F;
    250            int k1 = -267386864;
    251            this.drawGradientRect(l - 3, i1 - 4, l + k + 3, i1 - 3, k1, k1);
    252            this.drawGradientRect(l - 3, i1 + j1 + 3, l + k + 3, i1 + j1 + 4, k1, k1);
    253            this.drawGradientRect(l - 3, i1 - 3, l + k + 3, i1 + j1 + 3, k1, k1);
    254            this.drawGradientRect(l - 4, i1 - 3, l - 3, i1 + j1 + 3, k1, k1);
    255            this.drawGradientRect(l + k + 3, i1 - 3, l + k + 4, i1 + j1 + 3, k1, k1);
    256            int l1 = 1347420415;
    257            int i2 = (l1 & 16711422) >> 1 | l1 & -16777216;
    258            this.drawGradientRect(l - 3, i1 - 3 + 1, l - 3 + 1, i1 + j1 + 3 - 1, l1, i2);
    259            this.drawGradientRect(l + k + 2, i1 - 3 + 1, l + k + 3, i1 + j1 + 3 - 1, l1, i2);
    260            this.drawGradientRect(l - 3, i1 - 3, l + k + 3, i1 - 3 + 1, l1, l1);
    261            this.drawGradientRect(l - 3, i1 + j1 + 2, l + k + 3, i1 + j1 + 3, i2, i2);
    262
    263            for (int j2 = 0; j2 < list.size(); ++j2)
    264            {
    265                String s = (String)list.get(j2);
    266
    267                if (j2 == 0)
    268                {
    269                    s = "\u00a7" + Integer.toHexString(par1ItemStack.getRarity().rarityColor) + s;
    270                }
    271                else
    272                {
    273                    s = EnumChatFormatting.GRAY + s;
    274                }
    275
    276                this.fontRenderer.drawStringWithShadow(s, l, i1, -1);
    277
    278                if (j2 == 0)
    279                {
    280                    i1 += 2;
    281                }
    282
    283                i1 += 10;
    284            }
    285
    286            this.zLevel = 0.0F;
    287            itemRenderer.zLevel = 0.0F;
    288        }
    289    }
    290
    291    /**
    292     * Draws the text when mouse is over creative inventory tab. Params: current creative tab to be checked, current
    293     * mouse x position, current mouse y position.
    294     */
    295    protected void drawCreativeTabHoveringText(String par1Str, int par2, int par3)
    296    {
    297        GL11.glDisable(GL12.GL_RESCALE_NORMAL);
    298        RenderHelper.disableStandardItemLighting();
    299        GL11.glDisable(GL11.GL_LIGHTING);
    300        GL11.glDisable(GL11.GL_DEPTH_TEST);
    301        int k = this.fontRenderer.getStringWidth(par1Str);
    302        int l = par2 + 12;
    303        int i1 = par3 - 12;
    304        byte b0 = 8;
    305        this.zLevel = 300.0F;
    306        itemRenderer.zLevel = 300.0F;
    307        int j1 = -267386864;
    308        this.drawGradientRect(l - 3, i1 - 4, l + k + 3, i1 - 3, j1, j1);
    309        this.drawGradientRect(l - 3, i1 + b0 + 3, l + k + 3, i1 + b0 + 4, j1, j1);
    310        this.drawGradientRect(l - 3, i1 - 3, l + k + 3, i1 + b0 + 3, j1, j1);
    311        this.drawGradientRect(l - 4, i1 - 3, l - 3, i1 + b0 + 3, j1, j1);
    312        this.drawGradientRect(l + k + 3, i1 - 3, l + k + 4, i1 + b0 + 3, j1, j1);
    313        int k1 = 1347420415;
    314        int l1 = (k1 & 16711422) >> 1 | k1 & -16777216;
    315        this.drawGradientRect(l - 3, i1 - 3 + 1, l - 3 + 1, i1 + b0 + 3 - 1, k1, l1);
    316        this.drawGradientRect(l + k + 2, i1 - 3 + 1, l + k + 3, i1 + b0 + 3 - 1, k1, l1);
    317        this.drawGradientRect(l - 3, i1 - 3, l + k + 3, i1 - 3 + 1, k1, k1);
    318        this.drawGradientRect(l - 3, i1 + b0 + 2, l + k + 3, i1 + b0 + 3, l1, l1);
    319        this.fontRenderer.drawStringWithShadow(par1Str, l, i1, -1);
    320        this.zLevel = 0.0F;
    321        itemRenderer.zLevel = 0.0F;
    322        GL11.glEnable(GL11.GL_LIGHTING);
    323        GL11.glEnable(GL11.GL_DEPTH_TEST);
    324        RenderHelper.enableStandardItemLighting();
    325        GL11.glEnable(GL12.GL_RESCALE_NORMAL);
    326    }
    327
    328    /**
    329     * Draw the foreground layer for the GuiContainer (everything in front of the items)
    330     */
    331    protected void drawGuiContainerForegroundLayer(int par1, int par2) {}
    332
    333    /**
    334     * Draw the background layer for the GuiContainer (everything behind the items)
    335     */
    336    protected abstract void drawGuiContainerBackgroundLayer(float f, int i, int j);
    337
    338    /**
    339     * Draws an inventory slot
    340     */
    341    protected void drawSlotInventory(Slot par1Slot)
    342    {
    343        int i = par1Slot.xDisplayPosition;
    344        int j = par1Slot.yDisplayPosition;
    345        ItemStack itemstack = par1Slot.getStack();
    346        boolean flag = false;
    347        boolean flag1 = par1Slot == this.clickedSlot && this.draggedStack != null && !this.isRightMouseClick;
    348        ItemStack itemstack1 = this.mc.thePlayer.inventory.getItemStack();
    349        String s = null;
    350
    351        if (par1Slot == this.clickedSlot && this.draggedStack != null && this.isRightMouseClick && itemstack != null)
    352        {
    353            itemstack = itemstack.copy();
    354            itemstack.stackSize /= 2;
    355        }
    356        else if (this.field_94076_q && this.field_94077_p.contains(par1Slot) && itemstack1 != null)
    357        {
    358            if (this.field_94077_p.size() == 1)
    359            {
    360                return;
    361            }
    362
    363            if (Container.func_94527_a(par1Slot, itemstack1, true) && this.inventorySlots.func_94531_b(par1Slot))
    364            {
    365                itemstack = itemstack1.copy();
    366                flag = true;
    367                Container.func_94525_a(this.field_94077_p, this.field_94071_C, itemstack, par1Slot.getStack() == null ? 0 : par1Slot.getStack().stackSize);
    368
    369                if (itemstack.stackSize > itemstack.getMaxStackSize())
    370                {
    371                    s = EnumChatFormatting.YELLOW + "" + itemstack.getMaxStackSize();
    372                    itemstack.stackSize = itemstack.getMaxStackSize();
    373                }
    374
    375                if (itemstack.stackSize > par1Slot.getSlotStackLimit())
    376                {
    377                    s = EnumChatFormatting.YELLOW + "" + par1Slot.getSlotStackLimit();
    378                    itemstack.stackSize = par1Slot.getSlotStackLimit();
    379                }
    380            }
    381            else
    382            {
    383                this.field_94077_p.remove(par1Slot);
    384                this.func_94066_g();
    385            }
    386        }
    387
    388        this.zLevel = 100.0F;
    389        itemRenderer.zLevel = 100.0F;
    390
    391        if (itemstack == null)
    392        {
    393            Icon icon = par1Slot.getBackgroundIconIndex();
    394
    395            if (icon != null)
    396            {
    397                GL11.glDisable(GL11.GL_LIGHTING);
    398                this.mc.renderEngine.func_98187_b("/gui/items.png");
    399                this.func_94065_a(i, j, icon, 16, 16);
    400                GL11.glEnable(GL11.GL_LIGHTING);
    401                flag1 = true;
    402            }
    403        }
    404
    405        if (!flag1)
    406        {
    407            if (flag)
    408            {
    409                drawRect(i, j, i + 16, j + 16, -2130706433);
    410            }
    411
    412            GL11.glEnable(GL11.GL_DEPTH_TEST);
    413            itemRenderer.renderItemAndEffectIntoGUI(this.fontRenderer, this.mc.renderEngine, itemstack, i, j);
    414            itemRenderer.func_94148_a(this.fontRenderer, this.mc.renderEngine, itemstack, i, j, s);
    415        }
    416
    417        itemRenderer.zLevel = 0.0F;
    418        this.zLevel = 0.0F;
    419    }
    420
    421    private void func_94066_g()
    422    {
    423        ItemStack itemstack = this.mc.thePlayer.inventory.getItemStack();
    424
    425        if (itemstack != null && this.field_94076_q)
    426        {
    427            this.field_94069_F = itemstack.stackSize;
    428            ItemStack itemstack1;
    429            int i;
    430
    431            for (Iterator iterator = this.field_94077_p.iterator(); iterator.hasNext(); this.field_94069_F -= itemstack1.stackSize - i)
    432            {
    433                Slot slot = (Slot)iterator.next();
    434                itemstack1 = itemstack.copy();
    435                i = slot.getStack() == null ? 0 : slot.getStack().stackSize;
    436                Container.func_94525_a(this.field_94077_p, this.field_94071_C, itemstack1, i);
    437
    438                if (itemstack1.stackSize > itemstack1.getMaxStackSize())
    439                {
    440                    itemstack1.stackSize = itemstack1.getMaxStackSize();
    441                }
    442
    443                if (itemstack1.stackSize > slot.getSlotStackLimit())
    444                {
    445                    itemstack1.stackSize = slot.getSlotStackLimit();
    446                }
    447            }
    448        }
    449    }
    450
    451    /**
    452     * Returns the slot at the given coordinates or null if there is none.
    453     */
    454    private Slot getSlotAtPosition(int par1, int par2)
    455    {
    456        for (int k = 0; k < this.inventorySlots.inventorySlots.size(); ++k)
    457        {
    458            Slot slot = (Slot)this.inventorySlots.inventorySlots.get(k);
    459
    460            if (this.isMouseOverSlot(slot, par1, par2))
    461            {
    462                return slot;
    463            }
    464        }
    465
    466        return null;
    467    }
    468
    469    /**
    470     * Called when the mouse is clicked.
    471     */
    472    protected void mouseClicked(int par1, int par2, int par3)
    473    {
    474        super.mouseClicked(par1, par2, par3);
    475        boolean flag = par3 == this.mc.gameSettings.keyBindPickBlock.keyCode + 100;
    476        Slot slot = this.getSlotAtPosition(par1, par2);
    477        long l = Minecraft.getSystemTime();
    478        this.field_94074_J = this.field_94072_H == slot && l - this.field_94070_G < 250L && this.field_94073_I == par3;
    479        this.field_94068_E = false;
    480
    481        if (par3 == 0 || par3 == 1 || flag)
    482        {
    483            int i1 = this.guiLeft;
    484            int j1 = this.guiTop;
    485            boolean flag1 = par1 < i1 || par2 < j1 || par1 >= i1 + this.xSize || par2 >= j1 + this.ySize;
    486            int k1 = -1;
    487
    488            if (slot != null)
    489            {
    490                k1 = slot.slotNumber;
    491            }
    492
    493            if (flag1)
    494            {
    495                k1 = -999;
    496            }
    497
    498            if (this.mc.gameSettings.touchscreen && flag1 && this.mc.thePlayer.inventory.getItemStack() == null)
    499            {
    500                this.mc.displayGuiScreen((GuiScreen)null);
    501                return;
    502            }
    503
    504            if (k1 != -1)
    505            {
    506                if (this.mc.gameSettings.touchscreen)
    507                {
    508                    if (slot != null && slot.getHasStack())
    509                    {
    510                        this.clickedSlot = slot;
    511                        this.draggedStack = null;
    512                        this.isRightMouseClick = par3 == 1;
    513                    }
    514                    else
    515                    {
    516                        this.clickedSlot = null;
    517                    }
    518                }
    519                else if (!this.field_94076_q)
    520                {
    521                    if (this.mc.thePlayer.inventory.getItemStack() == null)
    522                    {
    523                        if (par3 == this.mc.gameSettings.keyBindPickBlock.keyCode + 100)
    524                        {
    525                            this.handleMouseClick(slot, k1, par3, 3);
    526                        }
    527                        else
    528                        {
    529                            boolean flag2 = k1 != -999 && (Keyboard.isKeyDown(42) || Keyboard.isKeyDown(54));
    530                            byte b0 = 0;
    531
    532                            if (flag2)
    533                            {
    534                                this.field_94075_K = slot != null && slot.getHasStack() ? slot.getStack() : null;
    535                                b0 = 1;
    536                            }
    537                            else if (k1 == -999)
    538                            {
    539                                b0 = 4;
    540                            }
    541
    542                            this.handleMouseClick(slot, k1, par3, b0);
    543                        }
    544
    545                        this.field_94068_E = true;
    546                    }
    547                    else
    548                    {
    549                        this.field_94076_q = true;
    550                        this.field_94067_D = par3;
    551                        this.field_94077_p.clear();
    552
    553                        if (par3 == 0)
    554                        {
    555                            this.field_94071_C = 0;
    556                        }
    557                        else if (par3 == 1)
    558                        {
    559                            this.field_94071_C = 1;
    560                        }
    561                    }
    562                }
    563            }
    564        }
    565
    566        this.field_94072_H = slot;
    567        this.field_94070_G = l;
    568        this.field_94073_I = par3;
    569    }
    570
    571    protected void func_85041_a(int par1, int par2, int par3, long par4)
    572    {
    573        Slot slot = this.getSlotAtPosition(par1, par2);
    574        ItemStack itemstack = this.mc.thePlayer.inventory.getItemStack();
    575
    576        if (this.clickedSlot != null && this.mc.gameSettings.touchscreen)
    577        {
    578            if (par3 == 0 || par3 == 1)
    579            {
    580                if (this.draggedStack == null)
    581                {
    582                    if (slot != this.clickedSlot)
    583                    {
    584                        this.draggedStack = this.clickedSlot.getStack().copy();
    585                    }
    586                }
    587                else if (this.draggedStack.stackSize > 1 && slot != null && Container.func_94527_a(slot, this.draggedStack, false))
    588                {
    589                    long i1 = Minecraft.getSystemTime();
    590
    591                    if (this.field_92033_y == slot)
    592                    {
    593                        if (i1 - this.field_92032_z > 500L)
    594                        {
    595                            this.handleMouseClick(this.clickedSlot, this.clickedSlot.slotNumber, 0, 0);
    596                            this.handleMouseClick(slot, slot.slotNumber, 1, 0);
    597                            this.handleMouseClick(this.clickedSlot, this.clickedSlot.slotNumber, 0, 0);
    598                            this.field_92032_z = i1 + 750L;
    599                            --this.draggedStack.stackSize;
    600                        }
    601                    }
    602                    else
    603                    {
    604                        this.field_92033_y = slot;
    605                        this.field_92032_z = i1;
    606                    }
    607                }
    608            }
    609        }
    610        else if (this.field_94076_q && slot != null && itemstack != null && itemstack.stackSize > this.field_94077_p.size() && Container.func_94527_a(slot, itemstack, true) && slot.isItemValid(itemstack) && this.inventorySlots.func_94531_b(slot))
    611        {
    612            this.field_94077_p.add(slot);
    613            this.func_94066_g();
    614        }
    615    }
    616
    617    /**
    618     * Called when the mouse is moved or a mouse button is released.  Signature: (mouseX, mouseY, which) which==-1 is
    619     * mouseMove, which==0 or which==1 is mouseUp
    620     */
    621    protected void mouseMovedOrUp(int par1, int par2, int par3)
    622    {
    623        Slot slot = this.getSlotAtPosition(par1, par2);
    624        int l = this.guiLeft;
    625        int i1 = this.guiTop;
    626        boolean flag = par1 < l || par2 < i1 || par1 >= l + this.xSize || par2 >= i1 + this.ySize;
    627        int j1 = -1;
    628
    629        if (slot != null)
    630        {
    631            j1 = slot.slotNumber;
    632        }
    633
    634        if (flag)
    635        {
    636            j1 = -999;
    637        }
    638
    639        Slot slot1;
    640        Iterator iterator;
    641
    642        if (this.field_94074_J && slot != null && par3 == 0 && this.inventorySlots.func_94530_a((ItemStack)null, slot))
    643        {
    644            if (isShiftKeyDown())
    645            {
    646                if (slot != null && slot.inventory != null && this.field_94075_K != null)
    647                {
    648                    iterator = this.inventorySlots.inventorySlots.iterator();
    649
    650                    while (iterator.hasNext())
    651                    {
    652                        slot1 = (Slot)iterator.next();
    653
    654                        if (slot1 != null && slot1.canTakeStack(this.mc.thePlayer) && slot1.getHasStack() && slot1.inventory == slot.inventory && Container.func_94527_a(slot1, this.field_94075_K, true))
    655                        {
    656                            this.handleMouseClick(slot1, slot1.slotNumber, par3, 1);
    657                        }
    658                    }
    659                }
    660            }
    661            else
    662            {
    663                this.handleMouseClick(slot, j1, par3, 6);
    664            }
    665
    666            this.field_94074_J = false;
    667            this.field_94070_G = 0L;
    668        }
    669        else
    670        {
    671            if (this.field_94076_q && this.field_94067_D != par3)
    672            {
    673                this.field_94076_q = false;
    674                this.field_94077_p.clear();
    675                this.field_94068_E = true;
    676                return;
    677            }
    678
    679            if (this.field_94068_E)
    680            {
    681                this.field_94068_E = false;
    682                return;
    683            }
    684
    685            boolean flag1;
    686
    687            if (this.clickedSlot != null && this.mc.gameSettings.touchscreen)
    688            {
    689                if (par3 == 0 || par3 == 1)
    690                {
    691                    if (this.draggedStack == null && slot != this.clickedSlot)
    692                    {
    693                        this.draggedStack = this.clickedSlot.getStack();
    694                    }
    695
    696                    flag1 = Container.func_94527_a(slot, this.draggedStack, false);
    697
    698                    if (j1 != -1 && this.draggedStack != null && flag1)
    699                    {
    700                        this.handleMouseClick(this.clickedSlot, this.clickedSlot.slotNumber, par3, 0);
    701                        this.handleMouseClick(slot, j1, 0, 0);
    702
    703                        if (this.mc.thePlayer.inventory.getItemStack() != null)
    704                        {
    705                            this.handleMouseClick(this.clickedSlot, this.clickedSlot.slotNumber, par3, 0);
    706                            this.field_85049_r = par1 - l;
    707                            this.field_85048_s = par2 - i1;
    708                            this.returningStackDestSlot = this.clickedSlot;
    709                            this.returningStack = this.draggedStack;
    710                            this.returningStackTime = Minecraft.getSystemTime();
    711                        }
    712                        else
    713                        {
    714                            this.returningStack = null;
    715                        }
    716                    }
    717                    else if (this.draggedStack != null)
    718                    {
    719                        this.field_85049_r = par1 - l;
    720                        this.field_85048_s = par2 - i1;
    721                        this.returningStackDestSlot = this.clickedSlot;
    722                        this.returningStack = this.draggedStack;
    723                        this.returningStackTime = Minecraft.getSystemTime();
    724                    }
    725
    726                    this.draggedStack = null;
    727                    this.clickedSlot = null;
    728                }
    729            }
    730            else if (this.field_94076_q && !this.field_94077_p.isEmpty())
    731            {
    732                this.handleMouseClick((Slot)null, -999, Container.func_94534_d(0, this.field_94071_C), 5);
    733                iterator = this.field_94077_p.iterator();
    734
    735                while (iterator.hasNext())
    736                {
    737                    slot1 = (Slot)iterator.next();
    738                    this.handleMouseClick(slot1, slot1.slotNumber, Container.func_94534_d(1, this.field_94071_C), 5);
    739                }
    740
    741                this.handleMouseClick((Slot)null, -999, Container.func_94534_d(2, this.field_94071_C), 5);
    742            }
    743            else if (this.mc.thePlayer.inventory.getItemStack() != null)
    744            {
    745                if (par3 == this.mc.gameSettings.keyBindPickBlock.keyCode + 100)
    746                {
    747                    this.handleMouseClick(slot, j1, par3, 3);
    748                }
    749                else
    750                {
    751                    flag1 = j1 != -999 && (Keyboard.isKeyDown(42) || Keyboard.isKeyDown(54));
    752
    753                    if (flag1)
    754                    {
    755                        this.field_94075_K = slot != null && slot.getHasStack() ? slot.getStack() : null;
    756                    }
    757
    758                    this.handleMouseClick(slot, j1, par3, flag1 ? 1 : 0);
    759                }
    760            }
    761        }
    762
    763        if (this.mc.thePlayer.inventory.getItemStack() == null)
    764        {
    765            this.field_94070_G = 0L;
    766        }
    767
    768        this.field_94076_q = false;
    769    }
    770
    771    /**
    772     * Returns if the passed mouse position is over the specified slot.
    773     */
    774    private boolean isMouseOverSlot(Slot par1Slot, int par2, int par3)
    775    {
    776        return this.isPointInRegion(par1Slot.xDisplayPosition, par1Slot.yDisplayPosition, 16, 16, par2, par3);
    777    }
    778
    779    /**
    780     * Args: left, top, width, height, pointX, pointY. Note: left, top are local to Gui, pointX, pointY are local to
    781     * screen
    782     */
    783    protected boolean isPointInRegion(int par1, int par2, int par3, int par4, int par5, int par6)
    784    {
    785        int k1 = this.guiLeft;
    786        int l1 = this.guiTop;
    787        par5 -= k1;
    788        par6 -= l1;
    789        return par5 >= par1 - 1 && par5 < par1 + par3 + 1 && par6 >= par2 - 1 && par6 < par2 + par4 + 1;
    790    }
    791
    792    protected void handleMouseClick(Slot par1Slot, int par2, int par3, int par4)
    793    {
    794        if (par1Slot != null)
    795        {
    796            par2 = par1Slot.slotNumber;
    797        }
    798
    799        this.mc.playerController.windowClick(this.inventorySlots.windowId, par2, par3, par4, this.mc.thePlayer);
    800    }
    801
    802    /**
    803     * Fired when a key is typed. This is the equivalent of KeyListener.keyTyped(KeyEvent e).
    804     */
    805    protected void keyTyped(char par1, int par2)
    806    {
    807        if (par2 == 1 || par2 == this.mc.gameSettings.keyBindInventory.keyCode)
    808        {
    809            this.mc.thePlayer.closeScreen();
    810        }
    811
    812        this.checkHotbarKeys(par2);
    813
    814        if (this.theSlot != null && this.theSlot.getHasStack())
    815        {
    816            if (par2 == this.mc.gameSettings.keyBindPickBlock.keyCode)
    817            {
    818                this.handleMouseClick(this.theSlot, this.theSlot.slotNumber, 0, 3);
    819            }
    820            else if (par2 == this.mc.gameSettings.keyBindDrop.keyCode)
    821            {
    822                this.handleMouseClick(this.theSlot, this.theSlot.slotNumber, isCtrlKeyDown() ? 1 : 0, 4);
    823            }
    824        }
    825    }
    826
    827    /**
    828     * This function is what controls the hotbar shortcut check when you press a number key when hovering a stack.
    829     */
    830    protected boolean checkHotbarKeys(int par1)
    831    {
    832        if (this.mc.thePlayer.inventory.getItemStack() == null && this.theSlot != null)
    833        {
    834            for (int j = 0; j < 9; ++j)
    835            {
    836                if (par1 == 2 + j)
    837                {
    838                    this.handleMouseClick(this.theSlot, this.theSlot.slotNumber, j, 2);
    839                    return true;
    840                }
    841            }
    842        }
    843
    844        return false;
    845    }
    846
    847    /**
    848     * Called when the screen is unloaded. Used to disable keyboard repeat events
    849     */
    850    public void onGuiClosed()
    851    {
    852        if (this.mc.thePlayer != null)
    853        {
    854            this.inventorySlots.onCraftGuiClosed(this.mc.thePlayer);
    855        }
    856    }
    857
    858    /**
    859     * Returns true if this GUI should pause the game when it is displayed in single-player
    860     */
    861    public boolean doesGuiPauseGame()
    862    {
    863        return false;
    864    }
    865
    866    /**
    867     * Called from the main game loop to update the screen.
    868     */
    869    public void updateScreen()
    870    {
    871        super.updateScreen();
    872
    873        if (!this.mc.thePlayer.isEntityAlive() || this.mc.thePlayer.isDead)
    874        {
    875            this.mc.thePlayer.closeScreen();
    876        }
    877    }
    878}