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 }