    001    package net.minecraft.src;
    002
    003    import cpw.mods.fml.common.Side;
    004    import cpw.mods.fml.common.asm.SideOnly;
    005    import java.util.Iterator;
    006    import java.util.List;
    007    import net.minecraft.client.Minecraft;
    008    import org.lwjgl.input.Keyboard;
    009    import org.lwjgl.opengl.GL11;
    010    import org.lwjgl.opengl.GL12;
    011
    012    @SideOnly(Side.CLIENT)
    013    public abstract class GuiContainer extends GuiScreen
    014    {
    015        /** Stacks renderer. Icons, stack size, health, etc... */
    016        protected static RenderItem itemRenderer = new RenderItem();
    017
    018        /** The X size of the inventory window in pixels. */
    019        protected int xSize = 176;
    020
    021        /** The Y size of the inventory window in pixels. */
    022        protected int ySize = 166;
    023
    024        /** A list of the players inventory slots. */
    025        public Container inventorySlots;
    026
    027        /**
    028         * Starting X position for the Gui. Inconsistent use for Gui backgrounds.
    029         */
    030        protected int guiLeft;
    031
    032        /**
    033         * Starting Y position for the Gui. Inconsistent use for Gui backgrounds.
    034         */
    035        protected int guiTop;
    036        private Slot theSlot;
    037        private Slot field_85051_p = null;
    038        private ItemStack field_85050_q = null;
    039        private int field_85049_r = 0;
    040        private int field_85048_s = 0;
    041        private Slot field_85047_t = null;
    042        private long field_85046_u = 0L;
    043        private ItemStack field_85045_v = null;
    044
    045        public GuiContainer(Container par1Container)
    046        {
    047            this.inventorySlots = par1Container;
    048        }
    049
    050        /**
    051         * Adds the buttons (and other controls) to the screen in question.
    052         */
    053        public void initGui()
    054        {
    055            super.initGui();
    056            this.mc.thePlayer.craftingInventory = this.inventorySlots;
    057            this.guiLeft = (this.width - this.xSize) / 2;
    058            this.guiTop = (this.height - this.ySize) / 2;
    059        }
    060
    061        /**
    062         * Draws the screen and all the components in it.
    063         */
    064        public void drawScreen(int par1, int par2, float par3)
    065        {
    066            this.drawDefaultBackground();
    067            int var4 = this.guiLeft;
    068            int var5 = this.guiTop;
    069            this.drawGuiContainerBackgroundLayer(par3, par1, par2);
    070            GL11.glDisable(GL12.GL_RESCALE_NORMAL);
    071            RenderHelper.disableStandardItemLighting();
    072            GL11.glDisable(GL11.GL_LIGHTING);
    073            GL11.glDisable(GL11.GL_DEPTH_TEST);
    074            super.drawScreen(par1, par2, par3);
    075            RenderHelper.enableGUIStandardItemLighting();
    076            GL11.glPushMatrix();
    077            GL11.glTranslatef((float)var4, (float)var5, 0.0F);
    078            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    079            GL11.glEnable(GL12.GL_RESCALE_NORMAL);
    080            this.theSlot = null;
    081            short var6 = 240;
    082            short var7 = 240;
    083            OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)var6 / 1.0F, (float)var7 / 1.0F);
    084            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    085            int var8;
    086            int var9;
    087
    088            for (int var13 = 0; var13 < this.inventorySlots.inventorySlots.size(); ++var13)
    089            {
    090                Slot var14 = (Slot)this.inventorySlots.inventorySlots.get(var13);
    091                this.drawSlotInventory(var14);
    092
    093                if (this.isMouseOverSlot(var14, par1, par2))
    094                {
    095                    this.theSlot = var14;
    096                    GL11.glDisable(GL11.GL_LIGHTING);
    097                    GL11.glDisable(GL11.GL_DEPTH_TEST);
    098                    var8 = var14.xDisplayPosition;
    099                    var9 = var14.yDisplayPosition;
    100                    this.drawGradientRect(var8, var9, var8 + 16, var9 + 16, -2130706433, -2130706433);
    101                    GL11.glEnable(GL11.GL_LIGHTING);
    102                    GL11.glEnable(GL11.GL_DEPTH_TEST);
    103                }
    104            }
    105
    106            this.drawGuiContainerForegroundLayer(par1, par2);
    107            InventoryPlayer var15 = this.mc.thePlayer.inventory;
    108            ItemStack var16 = this.field_85050_q == null ? var15.getItemStack() : this.field_85050_q;
    109
    110            if (var16 != null)
    111            {
    112                var8 = this.field_85050_q == null ? 8 : 0;
    113                this.func_85044_b(var16, par1 - var4 - var8, par2 - var5 - var8);
    114            }
    115
    116            if (this.field_85045_v != null)
    117            {
    118                float var17 = (float)(Minecraft.getSystemTime() - this.field_85046_u) / 100.0F;
    119
    120                if (var17 >= 1.0F)
    121                {
    122                    var17 = 1.0F;
    123                    this.field_85045_v = null;
    124                }
    125
    126                var9 = this.field_85047_t.xDisplayPosition - this.field_85049_r;
    127                int var10 = this.field_85047_t.yDisplayPosition - this.field_85048_s;
    128                int var11 = this.field_85049_r + (int)((float)var9 * var17);
    129                int var12 = this.field_85048_s + (int)((float)var10 * var17);
    130                this.func_85044_b(this.field_85045_v, var11, var12);
    131            }
    132
    133            if (var15.getItemStack() == null && this.theSlot != null && this.theSlot.getHasStack())
    134            {
    135                ItemStack var18 = this.theSlot.getStack();
    136                this.func_74184_a(var18, par1 - var4 + 8, par2 - var5 + 8);
    137            }
    138
    139            GL11.glPopMatrix();
    140            GL11.glEnable(GL11.GL_LIGHTING);
    141            GL11.glEnable(GL11.GL_DEPTH_TEST);
    142            RenderHelper.enableStandardItemLighting();
    143        }
    144
    145        private void func_85044_b(ItemStack par1ItemStack, int par2, int par3)
    146        {
    147            GL11.glTranslatef(0.0F, 0.0F, 32.0F);
    148            this.zLevel = 200.0F;
    149            itemRenderer.zLevel = 200.0F;
    150            itemRenderer.renderItemAndEffectIntoGUI(this.fontRenderer, this.mc.renderEngine, par1ItemStack, par2, par3);
    151            itemRenderer.renderItemOverlayIntoGUI(this.fontRenderer, this.mc.renderEngine, par1ItemStack, par2, par3);
    152            this.zLevel = 0.0F;
    153            itemRenderer.zLevel = 0.0F;
    154        }
    155
    156        protected void func_74184_a(ItemStack par1ItemStack, int par2, int par3)
    157        {
    158            GL11.glDisable(GL12.GL_RESCALE_NORMAL);
    159            RenderHelper.disableStandardItemLighting();
    160            GL11.glDisable(GL11.GL_LIGHTING);
    161            GL11.glDisable(GL11.GL_DEPTH_TEST);
    162            List var4 = par1ItemStack.getTooltip(this.mc.thePlayer, this.mc.gameSettings.advancedItemTooltips);
    163
    164            if (!var4.isEmpty())
    165            {
    166                int var5 = 0;
    167                Iterator var6 = var4.iterator();
    168
    169                while (var6.hasNext())
    170                {
    171                    String var7 = (String)var6.next();
    172                    int var8 = this.fontRenderer.getStringWidth(var7);
    173
    174                    if (var8 > var5)
    175                    {
    176                        var5 = var8;
    177                    }
    178                }
    179
    180                int var15 = par2 + 12;
    181                int var16 = par3 - 12;
    182                int var9 = 8;
    183
    184                if (var4.size() > 1)
    185                {
    186                    var9 += 2 + (var4.size() - 1) * 10;
    187                }
    188
    189                this.zLevel = 300.0F;
    190                itemRenderer.zLevel = 300.0F;
    191                int var10 = -267386864;
    192                this.drawGradientRect(var15 - 3, var16 - 4, var15 + var5 + 3, var16 - 3, var10, var10);
    193                this.drawGradientRect(var15 - 3, var16 + var9 + 3, var15 + var5 + 3, var16 + var9 + 4, var10, var10);
    194                this.drawGradientRect(var15 - 3, var16 - 3, var15 + var5 + 3, var16 + var9 + 3, var10, var10);
    195                this.drawGradientRect(var15 - 4, var16 - 3, var15 - 3, var16 + var9 + 3, var10, var10);
    196                this.drawGradientRect(var15 + var5 + 3, var16 - 3, var15 + var5 + 4, var16 + var9 + 3, var10, var10);
    197                int var11 = 1347420415;
    198                int var12 = (var11 & 16711422) >> 1 | var11 & -16777216;
    199                this.drawGradientRect(var15 - 3, var16 - 3 + 1, var15 - 3 + 1, var16 + var9 + 3 - 1, var11, var12);
    200                this.drawGradientRect(var15 + var5 + 2, var16 - 3 + 1, var15 + var5 + 3, var16 + var9 + 3 - 1, var11, var12);
    201                this.drawGradientRect(var15 - 3, var16 - 3, var15 + var5 + 3, var16 - 3 + 1, var11, var11);
    202                this.drawGradientRect(var15 - 3, var16 + var9 + 2, var15 + var5 + 3, var16 + var9 + 3, var12, var12);
    203
    204                for (int var13 = 0; var13 < var4.size(); ++var13)
    205                {
    206                    String var14 = (String)var4.get(var13);
    207
    208                    if (var13 == 0)
    209                    {
    210                        var14 = "\u00a7" + Integer.toHexString(par1ItemStack.getRarity().rarityColor) + var14;
    211                    }
    212                    else
    213                    {
    214                        var14 = "\u00a77" + var14;
    215                    }
    216
    217                    this.fontRenderer.drawStringWithShadow(var14, var15, var16, -1);
    218
    219                    if (var13 == 0)
    220                    {
    221                        var16 += 2;
    222                    }
    223
    224                    var16 += 10;
    225                }
    226
    227                this.zLevel = 0.0F;
    228                itemRenderer.zLevel = 0.0F;
    229            }
    230        }
    231
    232        /**
    233         * Draws the text when mouse is over creative inventory tab. Params: current creative tab to be checked, current
    234         * mouse x position, current mouse y position.
    235         */
    236        protected void drawCreativeTabHoveringText(String par1Str, int par2, int par3)
    237        {
    238            GL11.glDisable(GL12.GL_RESCALE_NORMAL);
    239            RenderHelper.disableStandardItemLighting();
    240            GL11.glDisable(GL11.GL_LIGHTING);
    241            GL11.glDisable(GL11.GL_DEPTH_TEST);
    242            int var4 = this.fontRenderer.getStringWidth(par1Str);
    243            int var5 = par2 + 12;
    244            int var6 = par3 - 12;
    245            byte var8 = 8;
    246            this.zLevel = 300.0F;
    247            itemRenderer.zLevel = 300.0F;
    248            int var9 = -267386864;
    249            this.drawGradientRect(var5 - 3, var6 - 4, var5 + var4 + 3, var6 - 3, var9, var9);
    250            this.drawGradientRect(var5 - 3, var6 + var8 + 3, var5 + var4 + 3, var6 + var8 + 4, var9, var9);
    251            this.drawGradientRect(var5 - 3, var6 - 3, var5 + var4 + 3, var6 + var8 + 3, var9, var9);
    252            this.drawGradientRect(var5 - 4, var6 - 3, var5 - 3, var6 + var8 + 3, var9, var9);
    253            this.drawGradientRect(var5 + var4 + 3, var6 - 3, var5 + var4 + 4, var6 + var8 + 3, var9, var9);
    254            int var10 = 1347420415;
    255            int var11 = (var10 & 16711422) >> 1 | var10 & -16777216;
    256            this.drawGradientRect(var5 - 3, var6 - 3 + 1, var5 - 3 + 1, var6 + var8 + 3 - 1, var10, var11);
    257            this.drawGradientRect(var5 + var4 + 2, var6 - 3 + 1, var5 + var4 + 3, var6 + var8 + 3 - 1, var10, var11);
    258            this.drawGradientRect(var5 - 3, var6 - 3, var5 + var4 + 3, var6 - 3 + 1, var10, var10);
    259            this.drawGradientRect(var5 - 3, var6 + var8 + 2, var5 + var4 + 3, var6 + var8 + 3, var11, var11);
    260            this.fontRenderer.drawStringWithShadow(par1Str, var5, var6, -1);
    261            this.zLevel = 0.0F;
    262            itemRenderer.zLevel = 0.0F;
    263            GL11.glEnable(GL11.GL_LIGHTING);
    264            GL11.glEnable(GL11.GL_DEPTH_TEST);
    265            RenderHelper.enableStandardItemLighting();
    266            GL11.glEnable(GL12.GL_RESCALE_NORMAL);
    267        }
    268
    269        /**
    270         * Draw the foreground layer for the GuiContainer (everything in front of the items)
    271         */
    272        protected void drawGuiContainerForegroundLayer(int par1, int par2) {}
    273
    274        /**
    275         * Draw the background layer for the GuiContainer (everything behind the items)
    276         */
    277        protected abstract void drawGuiContainerBackgroundLayer(float var1, int var2, int var3);
    278
    279        /**
    280         * Draws an inventory slot
    281         */
    282        private void drawSlotInventory(Slot par1Slot)
    283        {
    284            int var2 = par1Slot.xDisplayPosition;
    285            int var3 = par1Slot.yDisplayPosition;
    286            ItemStack var4 = par1Slot.getStack();
    287            boolean var5 = par1Slot == this.field_85051_p && this.field_85050_q != null;
    288            this.zLevel = 100.0F;
    289            itemRenderer.zLevel = 100.0F;
    290
    291            if (var4 == null)
    292            {
    293                int var6 = par1Slot.getBackgroundIconIndex();
    294
    295                if (var6 >= 0)
    296                {
    297                    GL11.glDisable(GL11.GL_LIGHTING);
    298                    this.mc.renderEngine.bindTexture(this.mc.renderEngine.getTexture("/gui/items.png"));
    299                    this.drawTexturedModalRect(var2, var3, var6 % 16 * 16, var6 / 16 * 16, 16, 16);
    300                    GL11.glEnable(GL11.GL_LIGHTING);
    301                    var5 = true;
    302                }
    303            }
    304
    305            if (!var5)
    306            {
    307                GL11.glEnable(GL11.GL_DEPTH_TEST);
    308                itemRenderer.renderItemAndEffectIntoGUI(this.fontRenderer, this.mc.renderEngine, var4, var2, var3);
    309                itemRenderer.renderItemOverlayIntoGUI(this.fontRenderer, this.mc.renderEngine, var4, var2, var3);
    310            }
    311
    312            itemRenderer.zLevel = 0.0F;
    313            this.zLevel = 0.0F;
    314        }
    315
    316        /**
    317         * Returns the slot at the given coordinates or null if there is none.
    318         */
    319        private Slot getSlotAtPosition(int par1, int par2)
    320        {
    321            for (int var3 = 0; var3 < this.inventorySlots.inventorySlots.size(); ++var3)
    322            {
    323                Slot var4 = (Slot)this.inventorySlots.inventorySlots.get(var3);
    324
    325                if (this.isMouseOverSlot(var4, par1, par2))
    326                {
    327                    return var4;
    328                }
    329            }
    330
    331            return null;
    332        }
    333
    334        /**
    335         * Called when the mouse is clicked.
    336         */
    337        protected void mouseClicked(int par1, int par2, int par3)
    338        {
    339            super.mouseClicked(par1, par2, par3);
    340            boolean var4 = par3 == this.mc.gameSettings.keyBindPickBlock.keyCode + 100;
    341
    342            if (par3 == 0 || par3 == 1 || var4)
    343            {
    344                Slot var5 = this.getSlotAtPosition(par1, par2);
    345                int var6 = this.guiLeft;
    346                int var7 = this.guiTop;
    347                boolean var8 = par1 < var6 || par2 < var7 || par1 >= var6 + this.xSize || par2 >= var7 + this.ySize;
    348                int var9 = -1;
    349
    350                if (var5 != null)
    351                {
    352                    var9 = var5.slotNumber;
    353                }
    354
    355                if (var8)
    356                {
    357                    var9 = -999;
    358                }
    359
    360                if (this.mc.gameSettings.field_85185_A && var8 && this.mc.thePlayer.inventory.getItemStack() == null)
    361                {
    362                    this.mc.displayGuiScreen((GuiScreen)null);
    363                    return;
    364                }
    365
    366                if (var9 != -1)
    367                {
    368                    if (this.mc.gameSettings.field_85185_A)
    369                    {
    370                        if (var5 != null && var5.getHasStack())
    371                        {
    372                            this.field_85051_p = var5;
    373                            this.field_85050_q = null;
    374                        }
    375                        else
    376                        {
    377                            this.field_85051_p = null;
    378                        }
    379                    }
    380                    else if (var4)
    381                    {
    382                        this.handleMouseClick(var5, var9, par3, 3);
    383                    }
    384                    else
    385                    {
    386                        boolean var10 = var9 != -999 && (Keyboard.isKeyDown(42) || Keyboard.isKeyDown(54));
    387                        this.handleMouseClick(var5, var9, par3, var10 ? 1 : 0);
    388                    }
    389                }
    390            }
    391        }
    392
    393        protected void func_85041_a(int par1, int par2, int par3, long par4)
    394        {
    395            if (this.field_85051_p != null && this.mc.gameSettings.field_85185_A && this.field_85050_q == null)
    396            {
    397                if (par3 == 0 || par3 == 1)
    398                {
    399                    Slot var6 = this.getSlotAtPosition(par1, par2);
    400
    401                    if (var6 != this.field_85051_p)
    402                    {
    403                        this.field_85050_q = this.field_85051_p.getStack();
    404                    }
    405                }
    406            }
    407        }
    408
    409        /**
    410         * Called when the mouse is moved or a mouse button is released.  Signature: (mouseX, mouseY, which) which==-1 is
    411         * mouseMove, which==0 or which==1 is mouseUp
    412         */
    413        protected void mouseMovedOrUp(int par1, int par2, int par3)
    414        {
    415            if (this.field_85051_p != null && this.mc.gameSettings.field_85185_A)
    416            {
    417                if (par3 == 0 || par3 == 1)
    418                {
    419                    Slot var4 = this.getSlotAtPosition(par1, par2);
    420                    int var5 = this.guiLeft;
    421                    int var6 = this.guiTop;
    422                    boolean var7 = par1 < var5 || par2 < var6 || par1 >= var5 + this.xSize || par2 >= var6 + this.ySize;
    423                    int var8 = -1;
    424
    425                    if (var4 != null)
    426                    {
    427                        var8 = var4.slotNumber;
    428                    }
    429
    430                    if (var7)
    431                    {
    432                        var8 = -999;
    433                    }
    434
    435                    if (this.field_85050_q == null && var4 != this.field_85051_p)
    436                    {
    437                        this.field_85050_q = this.field_85051_p.getStack();
    438                    }
    439
    440                    boolean var9 = var4 == null || !var4.getHasStack();
    441
    442                    if (var4 != null && var4.getHasStack() && this.field_85050_q != null && ItemStack.areItemStackTagsEqual(var4.getStack(), this.field_85050_q))
    443                    {
    444                        var9 |= var4.getStack().stackSize + this.field_85050_q.stackSize <= this.field_85050_q.getMaxStackSize();
    445                    }
    446
    447                    if (var8 != -1 && this.field_85050_q != null && var9)
    448                    {
    449                        this.handleMouseClick(this.field_85051_p, this.field_85051_p.slotNumber, par3, 0);
    450                        this.handleMouseClick(var4, var8, 0, 0);
    451
    452                        if (this.mc.thePlayer.inventory.getItemStack() != null)
    453                        {
    454                            this.handleMouseClick(this.field_85051_p, this.field_85051_p.slotNumber, par3, 0);
    455                            this.field_85049_r = par1 - var5;
    456                            this.field_85048_s = par2 - var6;
    457                            this.field_85047_t = this.field_85051_p;
    458                            this.field_85045_v = this.field_85050_q;
    459                            this.field_85046_u = Minecraft.getSystemTime();
    460                        }
    461                        else
    462                        {
    463                            this.field_85045_v = null;
    464                        }
    465                    }
    466                    else if (this.field_85050_q != null)
    467                    {
    468                        this.field_85049_r = par1 - var5;
    469                        this.field_85048_s = par2 - var6;
    470                        this.field_85047_t = this.field_85051_p;
    471                        this.field_85045_v = this.field_85050_q;
    472                        this.field_85046_u = Minecraft.getSystemTime();
    473                    }
    474
    475                    this.field_85050_q = null;
    476                    this.field_85051_p = null;
    477                }
    478            }
    479        }
    480
    481        /**
    482         * Returns if the passed mouse position is over the specified slot.
    483         */
    484        private boolean isMouseOverSlot(Slot par1Slot, int par2, int par3)
    485        {
    486            return this.func_74188_c(par1Slot.xDisplayPosition, par1Slot.yDisplayPosition, 16, 16, par2, par3);
    487        }
    488
    489        protected boolean func_74188_c(int par1, int par2, int par3, int par4, int par5, int par6)
    490        {
    491            int var7 = this.guiLeft;
    492            int var8 = this.guiTop;
    493            par5 -= var7;
    494            par6 -= var8;
    495            return par5 >= par1 - 1 && par5 < par1 + par3 + 1 && par6 >= par2 - 1 && par6 < par2 + par4 + 1;
    496        }
    497
    498        protected void handleMouseClick(Slot par1Slot, int par2, int par3, int par4)
    499        {
    500            if (par1Slot != null)
    501            {
    502                par2 = par1Slot.slotNumber;
    503            }
    504
    505            this.mc.playerController.windowClick(this.inventorySlots.windowId, par2, par3, par4, this.mc.thePlayer);
    506        }
    507
    508        /**
    509         * Fired when a key is typed. This is the equivalent of KeyListener.keyTyped(KeyEvent e).
    510         */
    511        protected void keyTyped(char par1, int par2)
    512        {
    513            if (par2 == 1 || par2 == this.mc.gameSettings.keyBindInventory.keyCode)
    514            {
    515                this.mc.thePlayer.closeScreen();
    516            }
    517
    518            this.func_82319_a(par2);
    519
    520            if (par2 == this.mc.gameSettings.keyBindPickBlock.keyCode && this.theSlot != null && this.theSlot.getHasStack())
    521            {
    522                this.handleMouseClick(this.theSlot, this.theSlot.slotNumber, this.ySize, 3);
    523            }
    524        }
    525
    526        protected boolean func_82319_a(int par1)
    527        {
    528            if (this.mc.thePlayer.inventory.getItemStack() == null && this.theSlot != null)
    529            {
    530                for (int var2 = 0; var2 < 9; ++var2)
    531                {
    532                    if (par1 == 2 + var2)
    533                    {
    534                        this.handleMouseClick(this.theSlot, this.theSlot.slotNumber, var2, 2);
    535                        return true;
    536                    }
    537                }
    538            }
    539
    540            return false;
    541        }
    542
    543        /**
    544         * Called when the screen is unloaded. Used to disable keyboard repeat events
    545         */
    546        public void onGuiClosed()
    547        {
    548            if (this.mc.thePlayer != null)
    549            {
    550                this.inventorySlots.onCraftGuiClosed(this.mc.thePlayer);
    551            }
    552        }
    553
    554        /**
    555         * Returns true if this GUI should pause the game when it is displayed in single-player
    556         */
    557        public boolean doesGuiPauseGame()
    558        {
    559            return false;
    560        }
    561
    562        /**
    563         * Called from the main game loop to update the screen.
    564         */
    565        public void updateScreen()
    566        {
    567            super.updateScreen();
    568
    569            if (!this.mc.thePlayer.isEntityAlive() || this.mc.thePlayer.isDead)
    570            {
    571                this.mc.thePlayer.closeScreen();
    572            }
    573        }
    574    }