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