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 }