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}