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 field_82320_o;
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.field_82320_o = 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.field_82320_o = 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.func_82406_b(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.field_82320_o != null && this.field_82320_o.getHasStack())
111            {
112                ItemStack var13 = this.field_82320_o.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.func_82840_a(this.mc.thePlayer, this.mc.gameSettings.field_82882_x);
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.func_82406_b(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.field_82320_o != null && this.field_82320_o.getHasStack())
377            {
378                this.handleMouseClick(this.field_82320_o, this.field_82320_o.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.field_82320_o != null)
385            {
386                for (int var2 = 0; var2 < 9; ++var2)
387                {
388                    if (par1 == 2 + var2)
389                    {
390                        this.handleMouseClick(this.field_82320_o, this.field_82320_o.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    }