    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 org.lwjgl.input.Keyboard;
    008    import org.lwjgl.opengl.GL11;
    009    import org.lwjgl.opengl.GL12;
    010
    011    @SideOnly(Side.CLIENT)
    012    public abstract class GuiContainer extends GuiScreen
    013    {
    014        /** Stacks renderer. Icons, stack size, health, etc... */
    015        protected static RenderItem itemRenderer = new RenderItem();
    016
    017        /** The X size of the inventory window in pixels. */
    018        protected int xSize = 176;
    019
    020        /** The Y size of the inventory window in pixels. */
    021        protected int ySize = 166;
    022
    023        /** A list of the players inventory slots. */
    024        public Container inventorySlots;
    025
    026        /**
    027         * Starting X position for the Gui. Inconsistent use for Gui backgrounds.
    028         */
    029        protected int guiLeft;
    030
    031        /**
    032         * Starting Y position for the Gui. Inconsistent use for Gui backgrounds.
    033         */
    034        protected int guiTop;
    035        private Slot theSlot;
    036
    037        public GuiContainer(Container par1Container)
    038        {
    039            this.inventorySlots = par1Container;
    040        }
    041
    042        /**
    043         * Adds the buttons (and other controls) to the screen in question.
    044         */
    045        public void initGui()
    046        {
    047            super.initGui();
    048            this.mc.thePlayer.craftingInventory = this.inventorySlots;
    049            this.guiLeft = (this.width - this.xSize) / 2;
    050            this.guiTop = (this.height - this.ySize) / 2;
    051        }
    052
    053        /**
    054         * Draws the screen and all the components in it.
    055         */
    056        public void drawScreen(int par1, int par2, float par3)
    057        {
    058            this.drawDefaultBackground();
    059            int var4 = this.guiLeft;
    060            int var5 = this.guiTop;
    061            this.drawGuiContainerBackgroundLayer(par3, par1, par2);
    062            GL11.glDisable(GL12.GL_RESCALE_NORMAL);
    063            RenderHelper.disableStandardItemLighting();
    064            GL11.glDisable(GL11.GL_LIGHTING);
    065            GL11.glDisable(GL11.GL_DEPTH_TEST);
    066            super.drawScreen(par1, par2, par3);
    067            RenderHelper.enableGUIStandardItemLighting();
    068            GL11.glPushMatrix();
    069            GL11.glTranslatef((float)var4, (float)var5, 0.0F);
    070            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    071            GL11.glEnable(GL12.GL_RESCALE_NORMAL);
    072            this.theSlot = null;
    073            short var6 = 240;
    074            short var7 = 240;
    075            OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)var6 / 1.0F, (float)var7 / 1.0F);
    076            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    077
    078            for (int var10 = 0; var10 < this.inventorySlots.inventorySlots.size(); ++var10)
    079            {
    080                Slot var11 = (Slot)this.inventorySlots.inventorySlots.get(var10);
    081                this.drawSlotInventory(var11);
    082
    083                if (this.isMouseOverSlot(var11, par1, par2))
    084                {
    085                    this.theSlot = var11;
    086                    GL11.glDisable(GL11.GL_LIGHTING);
    087                    GL11.glDisable(GL11.GL_DEPTH_TEST);
    088                    int var8 = var11.xDisplayPosition;
    089                    int var9 = var11.yDisplayPosition;
    090                    this.drawGradientRect(var8, var9, var8 + 16, var9 + 16, -2130706433, -2130706433);
    091                    GL11.glEnable(GL11.GL_LIGHTING);
    092                    GL11.glEnable(GL11.GL_DEPTH_TEST);
    093                }
    094            }
    095
    096            this.drawGuiContainerForegroundLayer(par1, par2);
    097            InventoryPlayer var12 = this.mc.thePlayer.inventory;
    098
    099            if (var12.getItemStack() != null)
    100            {
    101                GL11.glTranslatef(0.0F, 0.0F, 32.0F);
    102                this.zLevel = 200.0F;
    103                itemRenderer.zLevel = 200.0F;
    104                itemRenderer.renderItemAndEffectIntoGUI(this.fontRenderer, this.mc.renderEngine, var12.getItemStack(), par1 - var4 - 8, par2 - var5 - 8);
    105                itemRenderer.renderItemOverlayIntoGUI(this.fontRenderer, this.mc.renderEngine, var12.getItemStack(), par1 - var4 - 8, par2 - var5 - 8);
    106                this.zLevel = 0.0F;
    107                itemRenderer.zLevel = 0.0F;
    108            }
    109
    110            if (var12.getItemStack() == null && this.theSlot != null && this.theSlot.getHasStack())
    111            {
    112                ItemStack var13 = this.theSlot.getStack();
    113                this.func_74184_a(var13, par1 - var4, par2 - var5);
    114            }
    115
    116            GL11.glPopMatrix();
    117            GL11.glEnable(GL11.GL_LIGHTING);
    118            GL11.glEnable(GL11.GL_DEPTH_TEST);
    119            RenderHelper.enableStandardItemLighting();
    120        }
    121
    122        protected void func_74184_a(ItemStack par1ItemStack, int par2, int par3)
    123        {
    124            GL11.glDisable(GL12.GL_RESCALE_NORMAL);
    125            RenderHelper.disableStandardItemLighting();
    126            GL11.glDisable(GL11.GL_LIGHTING);
    127            GL11.glDisable(GL11.GL_DEPTH_TEST);
    128            List var4 = par1ItemStack.getTooltip(this.mc.thePlayer, this.mc.gameSettings.advancedItemTooltips);
    129
    130            if (!var4.isEmpty())
    131            {
    132                int var5 = 0;
    133                Iterator var6 = var4.iterator();
    134
    135                while (var6.hasNext())
    136                {
    137                    String var7 = (String)var6.next();
    138                    int var8 = this.fontRenderer.getStringWidth(var7);
    139
    140                    if (var8 > var5)
    141                    {
    142                        var5 = var8;
    143                    }
    144                }
    145
    146                int var15 = par2 + 12;
    147                int var16 = par3 - 12;
    148                int var9 = 8;
    149
    150                if (var4.size() > 1)
    151                {
    152                    var9 += 2 + (var4.size() - 1) * 10;
    153                }
    154
    155                this.zLevel = 300.0F;
    156                itemRenderer.zLevel = 300.0F;
    157                int var10 = -267386864;
    158                this.drawGradientRect(var15 - 3, var16 - 4, var15 + var5 + 3, var16 - 3, var10, var10);
    159                this.drawGradientRect(var15 - 3, var16 + var9 + 3, var15 + var5 + 3, var16 + var9 + 4, var10, var10);
    160                this.drawGradientRect(var15 - 3, var16 - 3, var15 + var5 + 3, var16 + var9 + 3, var10, var10);
    161                this.drawGradientRect(var15 - 4, var16 - 3, var15 - 3, var16 + var9 + 3, var10, var10);
    162                this.drawGradientRect(var15 + var5 + 3, var16 - 3, var15 + var5 + 4, var16 + var9 + 3, var10, var10);
    163                int var11 = 1347420415;
    164                int var12 = (var11 & 16711422) >> 1 | var11 & -16777216;
    165                this.drawGradientRect(var15 - 3, var16 - 3 + 1, var15 - 3 + 1, var16 + var9 + 3 - 1, var11, var12);
    166                this.drawGradientRect(var15 + var5 + 2, var16 - 3 + 1, var15 + var5 + 3, var16 + var9 + 3 - 1, var11, var12);
    167                this.drawGradientRect(var15 - 3, var16 - 3, var15 + var5 + 3, var16 - 3 + 1, var11, var11);
    168                this.drawGradientRect(var15 - 3, var16 + var9 + 2, var15 + var5 + 3, var16 + var9 + 3, var12, var12);
    169
    170                for (int var13 = 0; var13 < var4.size(); ++var13)
    171                {
    172                    String var14 = (String)var4.get(var13);
    173
    174                    if (var13 == 0)
    175                    {
    176                        var14 = "\u00a7" + Integer.toHexString(par1ItemStack.getRarity().rarityColor) + var14;
    177                    }
    178                    else
    179                    {
    180                        var14 = "\u00a77" + var14;
    181                    }
    182
    183                    this.fontRenderer.drawStringWithShadow(var14, var15, var16, -1);
    184
    185                    if (var13 == 0)
    186                    {
    187                        var16 += 2;
    188                    }
    189
    190                    var16 += 10;
    191                }
    192
    193                this.zLevel = 0.0F;
    194                itemRenderer.zLevel = 0.0F;
    195            }
    196        }
    197
    198        /**
    199         * Draws the text when mouse is over creative inventory tab. Params: current creative tab to be checked, current
    200         * mouse x position, current mouse y position.
    201         */
    202        protected void drawCreativeTabHoveringText(String par1Str, int par2, int par3)
    203        {
    204            GL11.glDisable(GL12.GL_RESCALE_NORMAL);
    205            RenderHelper.disableStandardItemLighting();
    206            GL11.glDisable(GL11.GL_LIGHTING);
    207            GL11.glDisable(GL11.GL_DEPTH_TEST);
    208            int var4 = this.fontRenderer.getStringWidth(par1Str);
    209            int var5 = par2 + 12;
    210            int var6 = par3 - 12;
    211            byte var8 = 8;
    212            this.zLevel = 300.0F;
    213            itemRenderer.zLevel = 300.0F;
    214            int var9 = -267386864;
    215            this.drawGradientRect(var5 - 3, var6 - 4, var5 + var4 + 3, var6 - 3, var9, var9);
    216            this.drawGradientRect(var5 - 3, var6 + var8 + 3, var5 + var4 + 3, var6 + var8 + 4, var9, var9);
    217            this.drawGradientRect(var5 - 3, var6 - 3, var5 + var4 + 3, var6 + var8 + 3, var9, var9);
    218            this.drawGradientRect(var5 - 4, var6 - 3, var5 - 3, var6 + var8 + 3, var9, var9);
    219            this.drawGradientRect(var5 + var4 + 3, var6 - 3, var5 + var4 + 4, var6 + var8 + 3, var9, var9);
    220            int var10 = 1347420415;
    221            int var11 = (var10 & 16711422) >> 1 | var10 & -16777216;
    222            this.drawGradientRect(var5 - 3, var6 - 3 + 1, var5 - 3 + 1, var6 + var8 + 3 - 1, var10, var11);
    223            this.drawGradientRect(var5 + var4 + 2, var6 - 3 + 1, var5 + var4 + 3, var6 + var8 + 3 - 1, var10, var11);
    224            this.drawGradientRect(var5 - 3, var6 - 3, var5 + var4 + 3, var6 - 3 + 1, var10, var10);
    225            this.drawGradientRect(var5 - 3, var6 + var8 + 2, var5 + var4 + 3, var6 + var8 + 3, var11, var11);
    226            this.fontRenderer.drawStringWithShadow(par1Str, var5, var6, -1);
    227            this.zLevel = 0.0F;
    228            itemRenderer.zLevel = 0.0F;
    229        }
    230
    231        /**
    232         * Draw the foreground layer for the GuiContainer (everything in front of the items)
    233         */
    234        protected void drawGuiContainerForegroundLayer(int par1, int par2) {}
    235
    236        /**
    237         * Draw the background layer for the GuiContainer (everything behind the items)
    238         */
    239        protected abstract void drawGuiContainerBackgroundLayer(float var1, int var2, int var3);
    240
    241        /**
    242         * Draws an inventory slot
    243         */
    244        private void drawSlotInventory(Slot par1Slot)
    245        {
    246            int var2 = par1Slot.xDisplayPosition;
    247            int var3 = par1Slot.yDisplayPosition;
    248            ItemStack var4 = par1Slot.getStack();
    249            boolean var5 = false;
    250            this.zLevel = 100.0F;
    251            itemRenderer.zLevel = 100.0F;
    252
    253            if (var4 == null)
    254            {
    255                int var6 = par1Slot.getBackgroundIconIndex();
    256
    257                if (var6 >= 0)
    258                {
    259                    GL11.glDisable(GL11.GL_LIGHTING);
    260                    this.mc.renderEngine.bindTexture(this.mc.renderEngine.getTexture("/gui/items.png"));
    261                    this.drawTexturedModalRect(var2, var3, var6 % 16 * 16, var6 / 16 * 16, 16, 16);
    262                    GL11.glEnable(GL11.GL_LIGHTING);
    263                    var5 = true;
    264                }
    265            }
    266
    267            if (!var5)
    268            {
    269                GL11.glEnable(GL11.GL_DEPTH_TEST);
    270                itemRenderer.renderItemAndEffectIntoGUI(this.fontRenderer, this.mc.renderEngine, var4, var2, var3);
    271                itemRenderer.renderItemOverlayIntoGUI(this.fontRenderer, this.mc.renderEngine, var4, var2, var3);
    272            }
    273
    274            itemRenderer.zLevel = 0.0F;
    275            this.zLevel = 0.0F;
    276        }
    277
    278        /**
    279         * Returns the slot at the given coordinates or null if there is none.
    280         */
    281        private Slot getSlotAtPosition(int par1, int par2)
    282        {
    283            for (int var3 = 0; var3 < this.inventorySlots.inventorySlots.size(); ++var3)
    284            {
    285                Slot var4 = (Slot)this.inventorySlots.inventorySlots.get(var3);
    286
    287                if (this.isMouseOverSlot(var4, par1, par2))
    288                {
    289                    return var4;
    290                }
    291            }
    292
    293            return null;
    294        }
    295
    296        /**
    297         * Called when the mouse is clicked.
    298         */
    299        protected void mouseClicked(int par1, int par2, int par3)
    300        {
    301            super.mouseClicked(par1, par2, par3);
    302            boolean var4 = par3 == this.mc.gameSettings.keyBindPickBlock.keyCode + 100;
    303
    304            if (par3 == 0 || par3 == 1 || var4)
    305            {
    306                Slot var5 = this.getSlotAtPosition(par1, par2);
    307                int var6 = this.guiLeft;
    308                int var7 = this.guiTop;
    309                boolean var8 = par1 < var6 || par2 < var7 || par1 >= var6 + this.xSize || par2 >= var7 + this.ySize;
    310                int var9 = -1;
    311
    312                if (var5 != null)
    313                {
    314                    var9 = var5.slotNumber;
    315                }
    316
    317                if (var8)
    318                {
    319                    var9 = -999;
    320                }
    321
    322                if (var9 != -1)
    323                {
    324                    if (var4)
    325                    {
    326                        this.handleMouseClick(var5, var9, par3, 3);
    327                    }
    328                    else
    329                    {
    330                        boolean var10 = var9 != -999 && (Keyboard.isKeyDown(42) || Keyboard.isKeyDown(54));
    331                        this.handleMouseClick(var5, var9, par3, var10 ? 1 : 0);
    332                    }
    333                }
    334            }
    335        }
    336
    337        /**
    338         * Returns if the passed mouse position is over the specified slot.
    339         */
    340        private boolean isMouseOverSlot(Slot par1Slot, int par2, int par3)
    341        {
    342            return this.func_74188_c(par1Slot.xDisplayPosition, par1Slot.yDisplayPosition, 16, 16, par2, par3);
    343        }
    344
    345        protected boolean func_74188_c(int par1, int par2, int par3, int par4, int par5, int par6)
    346        {
    347            int var7 = this.guiLeft;
    348            int var8 = this.guiTop;
    349            par5 -= var7;
    350            par6 -= var8;
    351            return par5 >= par1 - 1 && par5 < par1 + par3 + 1 && par6 >= par2 - 1 && par6 < par2 + par4 + 1;
    352        }
    353
    354        protected void handleMouseClick(Slot par1Slot, int par2, int par3, int par4)
    355        {
    356            if (par1Slot != null)
    357            {
    358                par2 = par1Slot.slotNumber;
    359            }
    360
    361            this.mc.playerController.windowClick(this.inventorySlots.windowId, par2, par3, par4, this.mc.thePlayer);
    362        }
    363
    364        /**
    365         * Fired when a key is typed. This is the equivalent of KeyListener.keyTyped(KeyEvent e).
    366         */
    367        protected void keyTyped(char par1, int par2)
    368        {
    369            if (par2 == 1 || par2 == this.mc.gameSettings.keyBindInventory.keyCode)
    370            {
    371                this.mc.thePlayer.closeScreen();
    372            }
    373
    374            this.func_82319_a(par2);
    375
    376            if (par2 == this.mc.gameSettings.keyBindPickBlock.keyCode && this.theSlot != null && this.theSlot.getHasStack())
    377            {
    378                this.handleMouseClick(this.theSlot, this.theSlot.slotNumber, this.ySize, 3);
    379            }
    380        }
    381
    382        protected boolean func_82319_a(int par1)
    383        {
    384            if (this.mc.thePlayer.inventory.getItemStack() == null && this.theSlot != null)
    385            {
    386                for (int var2 = 0; var2 < 9; ++var2)
    387                {
    388                    if (par1 == 2 + var2)
    389                    {
    390                        this.handleMouseClick(this.theSlot, this.theSlot.slotNumber, var2, 2);
    391                        return true;
    392                    }
    393                }
    394            }
    395
    396            return false;
    397        }
    398
    399        /**
    400         * Called when the screen is unloaded. Used to disable keyboard repeat events
    401         */
    402        public void onGuiClosed()
    403        {
    404            if (this.mc.thePlayer != null)
    405            {
    406                this.inventorySlots.onCraftGuiClosed(this.mc.thePlayer);
    407            }
    408        }
    409
    410        /**
    411         * Returns true if this GUI should pause the game when it is displayed in single-player
    412         */
    413        public boolean doesGuiPauseGame()
    414        {
    415            return false;
    416        }
    417
    418        /**
    419         * Called from the main game loop to update the screen.
    420         */
    421        public void updateScreen()
    422        {
    423            super.updateScreen();
    424
    425            if (!this.mc.thePlayer.isEntityAlive() || this.mc.thePlayer.isDead)
    426            {
    427                this.mc.thePlayer.closeScreen();
    428            }
    429        }
    430    }