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