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