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}