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        protected void func_74190_a(String par1Str, int par2, int par3)
198        {
199            GL11.glDisable(GL12.GL_RESCALE_NORMAL);
200            RenderHelper.disableStandardItemLighting();
201            GL11.glDisable(GL11.GL_LIGHTING);
202            GL11.glDisable(GL11.GL_DEPTH_TEST);
203            int var4 = this.fontRenderer.getStringWidth(par1Str);
204            int var5 = par2 + 12;
205            int var6 = par3 - 12;
206            byte var8 = 8;
207            this.zLevel = 300.0F;
208            itemRenderer.zLevel = 300.0F;
209            int var9 = -267386864;
210            this.drawGradientRect(var5 - 3, var6 - 4, var5 + var4 + 3, var6 - 3, var9, var9);
211            this.drawGradientRect(var5 - 3, var6 + var8 + 3, var5 + var4 + 3, var6 + var8 + 4, var9, var9);
212            this.drawGradientRect(var5 - 3, var6 - 3, var5 + var4 + 3, var6 + var8 + 3, var9, var9);
213            this.drawGradientRect(var5 - 4, var6 - 3, var5 - 3, var6 + var8 + 3, var9, var9);
214            this.drawGradientRect(var5 + var4 + 3, var6 - 3, var5 + var4 + 4, var6 + var8 + 3, var9, var9);
215            int var10 = 1347420415;
216            int var11 = (var10 & 16711422) >> 1 | var10 & -16777216;
217            this.drawGradientRect(var5 - 3, var6 - 3 + 1, var5 - 3 + 1, var6 + var8 + 3 - 1, var10, var11);
218            this.drawGradientRect(var5 + var4 + 2, var6 - 3 + 1, var5 + var4 + 3, var6 + var8 + 3 - 1, var10, var11);
219            this.drawGradientRect(var5 - 3, var6 - 3, var5 + var4 + 3, var6 - 3 + 1, var10, var10);
220            this.drawGradientRect(var5 - 3, var6 + var8 + 2, var5 + var4 + 3, var6 + var8 + 3, var11, var11);
221            this.fontRenderer.drawStringWithShadow(par1Str, var5, var6, -1);
222            this.zLevel = 0.0F;
223            itemRenderer.zLevel = 0.0F;
224        }
225    
226        /**
227         * Draw the foreground layer for the GuiContainer (everything in front of the items)
228         */
229        protected void drawGuiContainerForegroundLayer() {}
230    
231        /**
232         * Draw the background layer for the GuiContainer (everything behind the items)
233         */
234        protected abstract void drawGuiContainerBackgroundLayer(float var1, int var2, int var3);
235    
236        /**
237         * Draws an inventory slot
238         */
239        private void drawSlotInventory(Slot par1Slot)
240        {
241            int var2 = par1Slot.xDisplayPosition;
242            int var3 = par1Slot.yDisplayPosition;
243            ItemStack var4 = par1Slot.getStack();
244            boolean var5 = false;
245            this.zLevel = 100.0F;
246            itemRenderer.zLevel = 100.0F;
247    
248            if (var4 == null)
249            {
250                int var6 = par1Slot.getBackgroundIconIndex();
251    
252                if (var6 >= 0)
253                {
254                    GL11.glDisable(GL11.GL_LIGHTING);
255                    this.mc.renderEngine.bindTexture(this.mc.renderEngine.getTexture("/gui/items.png"));
256                    this.drawTexturedModalRect(var2, var3, var6 % 16 * 16, var6 / 16 * 16, 16, 16);
257                    GL11.glEnable(GL11.GL_LIGHTING);
258                    var5 = true;
259                }
260            }
261    
262            if (!var5)
263            {
264                GL11.glEnable(GL11.GL_DEPTH_TEST);
265                itemRenderer.renderItemIntoGUI(this.fontRenderer, this.mc.renderEngine, var4, var2, var3);
266                itemRenderer.renderItemOverlayIntoGUI(this.fontRenderer, this.mc.renderEngine, var4, var2, var3);
267            }
268    
269            itemRenderer.zLevel = 0.0F;
270            this.zLevel = 0.0F;
271        }
272    
273        /**
274         * Returns the slot at the given coordinates or null if there is none.
275         */
276        private Slot getSlotAtPosition(int par1, int par2)
277        {
278            for (int var3 = 0; var3 < this.inventorySlots.inventorySlots.size(); ++var3)
279            {
280                Slot var4 = (Slot)this.inventorySlots.inventorySlots.get(var3);
281    
282                if (this.isMouseOverSlot(var4, par1, par2))
283                {
284                    return var4;
285                }
286            }
287    
288            return null;
289        }
290    
291        /**
292         * Called when the mouse is clicked.
293         */
294        protected void mouseClicked(int par1, int par2, int par3)
295        {
296            super.mouseClicked(par1, par2, par3);
297    
298            if (par3 == 0 || par3 == 1)
299            {
300                Slot var4 = this.getSlotAtPosition(par1, par2);
301                int var5 = this.guiLeft;
302                int var6 = this.guiTop;
303                boolean var7 = par1 < var5 || par2 < var6 || par1 >= var5 + this.xSize || par2 >= var6 + this.ySize;
304                int var8 = -1;
305    
306                if (var4 != null)
307                {
308                    var8 = var4.slotNumber;
309                }
310    
311                if (var7)
312                {
313                    var8 = -999;
314                }
315    
316                if (var8 != -1)
317                {
318                    boolean var9 = var8 != -999 && (Keyboard.isKeyDown(42) || Keyboard.isKeyDown(54));
319                    this.handleMouseClick(var4, var8, par3, var9);
320                }
321            }
322        }
323    
324        /**
325         * Returns if the passed mouse position is over the specified slot.
326         */
327        private boolean isMouseOverSlot(Slot par1Slot, int par2, int par3)
328        {
329            return this.func_74188_c(par1Slot.xDisplayPosition, par1Slot.yDisplayPosition, 16, 16, par2, par3);
330        }
331    
332        protected boolean func_74188_c(int par1, int par2, int par3, int par4, int par5, int par6)
333        {
334            int var7 = this.guiLeft;
335            int var8 = this.guiTop;
336            par5 -= var7;
337            par6 -= var8;
338            return par5 >= par1 - 1 && par5 < par1 + par3 + 1 && par6 >= par2 - 1 && par6 < par2 + par4 + 1;
339        }
340    
341        protected void handleMouseClick(Slot par1Slot, int par2, int par3, boolean par4)
342        {
343            if (par1Slot != null)
344            {
345                par2 = par1Slot.slotNumber;
346            }
347    
348            this.mc.playerController.windowClick(this.inventorySlots.windowId, par2, par3, par4, this.mc.thePlayer);
349        }
350    
351        /**
352         * Fired when a key is typed. This is the equivalent of KeyListener.keyTyped(KeyEvent e).
353         */
354        protected void keyTyped(char par1, int par2)
355        {
356            if (par2 == 1 || par2 == this.mc.gameSettings.keyBindInventory.keyCode)
357            {
358                this.mc.thePlayer.closeScreen();
359            }
360        }
361    
362        /**
363         * Called when the screen is unloaded. Used to disable keyboard repeat events
364         */
365        public void onGuiClosed()
366        {
367            if (this.mc.thePlayer != null)
368            {
369                this.inventorySlots.onCraftGuiClosed(this.mc.thePlayer);
370            }
371        }
372    
373        /**
374         * Returns true if this GUI should pause the game when it is displayed in single-player
375         */
376        public boolean doesGuiPauseGame()
377        {
378            return false;
379        }
380    
381        /**
382         * Called from the main game loop to update the screen.
383         */
384        public void updateScreen()
385        {
386            super.updateScreen();
387    
388            if (!this.mc.thePlayer.isEntityAlive() || this.mc.thePlayer.isDead)
389            {
390                this.mc.thePlayer.closeScreen();
391            }
392        }
393    }