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 net.minecraft.client.Minecraft; 008 import org.lwjgl.input.Keyboard; 009 import org.lwjgl.opengl.GL11; 010 import org.lwjgl.opengl.GL12; 011 012 @SideOnly(Side.CLIENT) 013 public abstract class GuiContainer extends GuiScreen 014 { 015 /** Stacks renderer. Icons, stack size, health, etc... */ 016 protected static RenderItem itemRenderer = new RenderItem(); 017 018 /** The X size of the inventory window in pixels. */ 019 protected int xSize = 176; 020 021 /** The Y size of the inventory window in pixels. */ 022 protected int ySize = 166; 023 024 /** A list of the players inventory slots. */ 025 public Container inventorySlots; 026 027 /** 028 * Starting X position for the Gui. Inconsistent use for Gui backgrounds. 029 */ 030 protected int guiLeft; 031 032 /** 033 * Starting Y position for the Gui. Inconsistent use for Gui backgrounds. 034 */ 035 protected int guiTop; 036 private Slot theSlot; 037 private Slot field_85051_p = null; 038 private ItemStack field_85050_q = null; 039 private int field_85049_r = 0; 040 private int field_85048_s = 0; 041 private Slot field_85047_t = null; 042 private long field_85046_u = 0L; 043 private ItemStack field_85045_v = null; 044 045 public GuiContainer(Container par1Container) 046 { 047 this.inventorySlots = par1Container; 048 } 049 050 /** 051 * Adds the buttons (and other controls) to the screen in question. 052 */ 053 public void initGui() 054 { 055 super.initGui(); 056 this.mc.thePlayer.craftingInventory = this.inventorySlots; 057 this.guiLeft = (this.width - this.xSize) / 2; 058 this.guiTop = (this.height - this.ySize) / 2; 059 } 060 061 /** 062 * Draws the screen and all the components in it. 063 */ 064 public void drawScreen(int par1, int par2, float par3) 065 { 066 this.drawDefaultBackground(); 067 int var4 = this.guiLeft; 068 int var5 = this.guiTop; 069 this.drawGuiContainerBackgroundLayer(par3, par1, par2); 070 GL11.glDisable(GL12.GL_RESCALE_NORMAL); 071 RenderHelper.disableStandardItemLighting(); 072 GL11.glDisable(GL11.GL_LIGHTING); 073 GL11.glDisable(GL11.GL_DEPTH_TEST); 074 super.drawScreen(par1, par2, par3); 075 RenderHelper.enableGUIStandardItemLighting(); 076 GL11.glPushMatrix(); 077 GL11.glTranslatef((float)var4, (float)var5, 0.0F); 078 GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); 079 GL11.glEnable(GL12.GL_RESCALE_NORMAL); 080 this.theSlot = null; 081 short var6 = 240; 082 short var7 = 240; 083 OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)var6 / 1.0F, (float)var7 / 1.0F); 084 GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); 085 int var8; 086 int var9; 087 088 for (int var13 = 0; var13 < this.inventorySlots.inventorySlots.size(); ++var13) 089 { 090 Slot var14 = (Slot)this.inventorySlots.inventorySlots.get(var13); 091 this.drawSlotInventory(var14); 092 093 if (this.isMouseOverSlot(var14, par1, par2)) 094 { 095 this.theSlot = var14; 096 GL11.glDisable(GL11.GL_LIGHTING); 097 GL11.glDisable(GL11.GL_DEPTH_TEST); 098 var8 = var14.xDisplayPosition; 099 var9 = var14.yDisplayPosition; 100 this.drawGradientRect(var8, var9, var8 + 16, var9 + 16, -2130706433, -2130706433); 101 GL11.glEnable(GL11.GL_LIGHTING); 102 GL11.glEnable(GL11.GL_DEPTH_TEST); 103 } 104 } 105 106 this.drawGuiContainerForegroundLayer(par1, par2); 107 InventoryPlayer var15 = this.mc.thePlayer.inventory; 108 ItemStack var16 = this.field_85050_q == null ? var15.getItemStack() : this.field_85050_q; 109 110 if (var16 != null) 111 { 112 var8 = this.field_85050_q == null ? 8 : 0; 113 this.func_85044_b(var16, par1 - var4 - var8, par2 - var5 - var8); 114 } 115 116 if (this.field_85045_v != null) 117 { 118 float var17 = (float)(Minecraft.getSystemTime() - this.field_85046_u) / 100.0F; 119 120 if (var17 >= 1.0F) 121 { 122 var17 = 1.0F; 123 this.field_85045_v = null; 124 } 125 126 var9 = this.field_85047_t.xDisplayPosition - this.field_85049_r; 127 int var10 = this.field_85047_t.yDisplayPosition - this.field_85048_s; 128 int var11 = this.field_85049_r + (int)((float)var9 * var17); 129 int var12 = this.field_85048_s + (int)((float)var10 * var17); 130 this.func_85044_b(this.field_85045_v, var11, var12); 131 } 132 133 if (var15.getItemStack() == null && this.theSlot != null && this.theSlot.getHasStack()) 134 { 135 ItemStack var18 = this.theSlot.getStack(); 136 this.func_74184_a(var18, par1 - var4 + 8, par2 - var5 + 8); 137 } 138 139 GL11.glPopMatrix(); 140 GL11.glEnable(GL11.GL_LIGHTING); 141 GL11.glEnable(GL11.GL_DEPTH_TEST); 142 RenderHelper.enableStandardItemLighting(); 143 } 144 145 private void func_85044_b(ItemStack par1ItemStack, int par2, int par3) 146 { 147 GL11.glTranslatef(0.0F, 0.0F, 32.0F); 148 this.zLevel = 200.0F; 149 itemRenderer.zLevel = 200.0F; 150 itemRenderer.renderItemAndEffectIntoGUI(this.fontRenderer, this.mc.renderEngine, par1ItemStack, par2, par3); 151 itemRenderer.renderItemOverlayIntoGUI(this.fontRenderer, this.mc.renderEngine, par1ItemStack, par2, par3); 152 this.zLevel = 0.0F; 153 itemRenderer.zLevel = 0.0F; 154 } 155 156 protected void func_74184_a(ItemStack par1ItemStack, int par2, int par3) 157 { 158 GL11.glDisable(GL12.GL_RESCALE_NORMAL); 159 RenderHelper.disableStandardItemLighting(); 160 GL11.glDisable(GL11.GL_LIGHTING); 161 GL11.glDisable(GL11.GL_DEPTH_TEST); 162 List var4 = par1ItemStack.getTooltip(this.mc.thePlayer, this.mc.gameSettings.advancedItemTooltips); 163 164 if (!var4.isEmpty()) 165 { 166 int var5 = 0; 167 Iterator var6 = var4.iterator(); 168 169 while (var6.hasNext()) 170 { 171 String var7 = (String)var6.next(); 172 int var8 = this.fontRenderer.getStringWidth(var7); 173 174 if (var8 > var5) 175 { 176 var5 = var8; 177 } 178 } 179 180 int var15 = par2 + 12; 181 int var16 = par3 - 12; 182 int var9 = 8; 183 184 if (var4.size() > 1) 185 { 186 var9 += 2 + (var4.size() - 1) * 10; 187 } 188 189 this.zLevel = 300.0F; 190 itemRenderer.zLevel = 300.0F; 191 int var10 = -267386864; 192 this.drawGradientRect(var15 - 3, var16 - 4, var15 + var5 + 3, var16 - 3, var10, var10); 193 this.drawGradientRect(var15 - 3, var16 + var9 + 3, var15 + var5 + 3, var16 + var9 + 4, var10, var10); 194 this.drawGradientRect(var15 - 3, var16 - 3, var15 + var5 + 3, var16 + var9 + 3, var10, var10); 195 this.drawGradientRect(var15 - 4, var16 - 3, var15 - 3, var16 + var9 + 3, var10, var10); 196 this.drawGradientRect(var15 + var5 + 3, var16 - 3, var15 + var5 + 4, var16 + var9 + 3, var10, var10); 197 int var11 = 1347420415; 198 int var12 = (var11 & 16711422) >> 1 | var11 & -16777216; 199 this.drawGradientRect(var15 - 3, var16 - 3 + 1, var15 - 3 + 1, var16 + var9 + 3 - 1, var11, var12); 200 this.drawGradientRect(var15 + var5 + 2, var16 - 3 + 1, var15 + var5 + 3, var16 + var9 + 3 - 1, var11, var12); 201 this.drawGradientRect(var15 - 3, var16 - 3, var15 + var5 + 3, var16 - 3 + 1, var11, var11); 202 this.drawGradientRect(var15 - 3, var16 + var9 + 2, var15 + var5 + 3, var16 + var9 + 3, var12, var12); 203 204 for (int var13 = 0; var13 < var4.size(); ++var13) 205 { 206 String var14 = (String)var4.get(var13); 207 208 if (var13 == 0) 209 { 210 var14 = "\u00a7" + Integer.toHexString(par1ItemStack.getRarity().rarityColor) + var14; 211 } 212 else 213 { 214 var14 = "\u00a77" + var14; 215 } 216 217 this.fontRenderer.drawStringWithShadow(var14, var15, var16, -1); 218 219 if (var13 == 0) 220 { 221 var16 += 2; 222 } 223 224 var16 += 10; 225 } 226 227 this.zLevel = 0.0F; 228 itemRenderer.zLevel = 0.0F; 229 } 230 } 231 232 /** 233 * Draws the text when mouse is over creative inventory tab. Params: current creative tab to be checked, current 234 * mouse x position, current mouse y position. 235 */ 236 protected void drawCreativeTabHoveringText(String par1Str, int par2, int par3) 237 { 238 GL11.glDisable(GL12.GL_RESCALE_NORMAL); 239 RenderHelper.disableStandardItemLighting(); 240 GL11.glDisable(GL11.GL_LIGHTING); 241 GL11.glDisable(GL11.GL_DEPTH_TEST); 242 int var4 = this.fontRenderer.getStringWidth(par1Str); 243 int var5 = par2 + 12; 244 int var6 = par3 - 12; 245 byte var8 = 8; 246 this.zLevel = 300.0F; 247 itemRenderer.zLevel = 300.0F; 248 int var9 = -267386864; 249 this.drawGradientRect(var5 - 3, var6 - 4, var5 + var4 + 3, var6 - 3, var9, var9); 250 this.drawGradientRect(var5 - 3, var6 + var8 + 3, var5 + var4 + 3, var6 + var8 + 4, var9, var9); 251 this.drawGradientRect(var5 - 3, var6 - 3, var5 + var4 + 3, var6 + var8 + 3, var9, var9); 252 this.drawGradientRect(var5 - 4, var6 - 3, var5 - 3, var6 + var8 + 3, var9, var9); 253 this.drawGradientRect(var5 + var4 + 3, var6 - 3, var5 + var4 + 4, var6 + var8 + 3, var9, var9); 254 int var10 = 1347420415; 255 int var11 = (var10 & 16711422) >> 1 | var10 & -16777216; 256 this.drawGradientRect(var5 - 3, var6 - 3 + 1, var5 - 3 + 1, var6 + var8 + 3 - 1, var10, var11); 257 this.drawGradientRect(var5 + var4 + 2, var6 - 3 + 1, var5 + var4 + 3, var6 + var8 + 3 - 1, var10, var11); 258 this.drawGradientRect(var5 - 3, var6 - 3, var5 + var4 + 3, var6 - 3 + 1, var10, var10); 259 this.drawGradientRect(var5 - 3, var6 + var8 + 2, var5 + var4 + 3, var6 + var8 + 3, var11, var11); 260 this.fontRenderer.drawStringWithShadow(par1Str, var5, var6, -1); 261 this.zLevel = 0.0F; 262 itemRenderer.zLevel = 0.0F; 263 GL11.glEnable(GL11.GL_LIGHTING); 264 GL11.glEnable(GL11.GL_DEPTH_TEST); 265 RenderHelper.enableStandardItemLighting(); 266 GL11.glEnable(GL12.GL_RESCALE_NORMAL); 267 } 268 269 /** 270 * Draw the foreground layer for the GuiContainer (everything in front of the items) 271 */ 272 protected void drawGuiContainerForegroundLayer(int par1, int par2) {} 273 274 /** 275 * Draw the background layer for the GuiContainer (everything behind the items) 276 */ 277 protected abstract void drawGuiContainerBackgroundLayer(float var1, int var2, int var3); 278 279 /** 280 * Draws an inventory slot 281 */ 282 private void drawSlotInventory(Slot par1Slot) 283 { 284 int var2 = par1Slot.xDisplayPosition; 285 int var3 = par1Slot.yDisplayPosition; 286 ItemStack var4 = par1Slot.getStack(); 287 boolean var5 = par1Slot == this.field_85051_p && this.field_85050_q != null; 288 this.zLevel = 100.0F; 289 itemRenderer.zLevel = 100.0F; 290 291 if (var4 == null) 292 { 293 int var6 = par1Slot.getBackgroundIconIndex(); 294 295 if (var6 >= 0) 296 { 297 GL11.glDisable(GL11.GL_LIGHTING); 298 this.mc.renderEngine.bindTexture(this.mc.renderEngine.getTexture("/gui/items.png")); 299 this.drawTexturedModalRect(var2, var3, var6 % 16 * 16, var6 / 16 * 16, 16, 16); 300 GL11.glEnable(GL11.GL_LIGHTING); 301 var5 = true; 302 } 303 } 304 305 if (!var5) 306 { 307 GL11.glEnable(GL11.GL_DEPTH_TEST); 308 itemRenderer.renderItemAndEffectIntoGUI(this.fontRenderer, this.mc.renderEngine, var4, var2, var3); 309 itemRenderer.renderItemOverlayIntoGUI(this.fontRenderer, this.mc.renderEngine, var4, var2, var3); 310 } 311 312 itemRenderer.zLevel = 0.0F; 313 this.zLevel = 0.0F; 314 } 315 316 /** 317 * Returns the slot at the given coordinates or null if there is none. 318 */ 319 private Slot getSlotAtPosition(int par1, int par2) 320 { 321 for (int var3 = 0; var3 < this.inventorySlots.inventorySlots.size(); ++var3) 322 { 323 Slot var4 = (Slot)this.inventorySlots.inventorySlots.get(var3); 324 325 if (this.isMouseOverSlot(var4, par1, par2)) 326 { 327 return var4; 328 } 329 } 330 331 return null; 332 } 333 334 /** 335 * Called when the mouse is clicked. 336 */ 337 protected void mouseClicked(int par1, int par2, int par3) 338 { 339 super.mouseClicked(par1, par2, par3); 340 boolean var4 = par3 == this.mc.gameSettings.keyBindPickBlock.keyCode + 100; 341 342 if (par3 == 0 || par3 == 1 || var4) 343 { 344 Slot var5 = this.getSlotAtPosition(par1, par2); 345 int var6 = this.guiLeft; 346 int var7 = this.guiTop; 347 boolean var8 = par1 < var6 || par2 < var7 || par1 >= var6 + this.xSize || par2 >= var7 + this.ySize; 348 int var9 = -1; 349 350 if (var5 != null) 351 { 352 var9 = var5.slotNumber; 353 } 354 355 if (var8) 356 { 357 var9 = -999; 358 } 359 360 if (this.mc.gameSettings.field_85185_A && var8 && this.mc.thePlayer.inventory.getItemStack() == null) 361 { 362 this.mc.displayGuiScreen((GuiScreen)null); 363 return; 364 } 365 366 if (var9 != -1) 367 { 368 if (this.mc.gameSettings.field_85185_A) 369 { 370 if (var5 != null && var5.getHasStack()) 371 { 372 this.field_85051_p = var5; 373 this.field_85050_q = null; 374 } 375 else 376 { 377 this.field_85051_p = null; 378 } 379 } 380 else if (var4) 381 { 382 this.handleMouseClick(var5, var9, par3, 3); 383 } 384 else 385 { 386 boolean var10 = var9 != -999 && (Keyboard.isKeyDown(42) || Keyboard.isKeyDown(54)); 387 this.handleMouseClick(var5, var9, par3, var10 ? 1 : 0); 388 } 389 } 390 } 391 } 392 393 protected void func_85041_a(int par1, int par2, int par3, long par4) 394 { 395 if (this.field_85051_p != null && this.mc.gameSettings.field_85185_A && this.field_85050_q == null) 396 { 397 if (par3 == 0 || par3 == 1) 398 { 399 Slot var6 = this.getSlotAtPosition(par1, par2); 400 401 if (var6 != this.field_85051_p) 402 { 403 this.field_85050_q = this.field_85051_p.getStack(); 404 } 405 } 406 } 407 } 408 409 /** 410 * Called when the mouse is moved or a mouse button is released. Signature: (mouseX, mouseY, which) which==-1 is 411 * mouseMove, which==0 or which==1 is mouseUp 412 */ 413 protected void mouseMovedOrUp(int par1, int par2, int par3) 414 { 415 if (this.field_85051_p != null && this.mc.gameSettings.field_85185_A) 416 { 417 if (par3 == 0 || par3 == 1) 418 { 419 Slot var4 = this.getSlotAtPosition(par1, par2); 420 int var5 = this.guiLeft; 421 int var6 = this.guiTop; 422 boolean var7 = par1 < var5 || par2 < var6 || par1 >= var5 + this.xSize || par2 >= var6 + this.ySize; 423 int var8 = -1; 424 425 if (var4 != null) 426 { 427 var8 = var4.slotNumber; 428 } 429 430 if (var7) 431 { 432 var8 = -999; 433 } 434 435 if (this.field_85050_q == null && var4 != this.field_85051_p) 436 { 437 this.field_85050_q = this.field_85051_p.getStack(); 438 } 439 440 boolean var9 = var4 == null || !var4.getHasStack(); 441 442 if (var4 != null && var4.getHasStack() && this.field_85050_q != null && ItemStack.areItemStackTagsEqual(var4.getStack(), this.field_85050_q)) 443 { 444 var9 |= var4.getStack().stackSize + this.field_85050_q.stackSize <= this.field_85050_q.getMaxStackSize(); 445 } 446 447 if (var8 != -1 && this.field_85050_q != null && var9) 448 { 449 this.handleMouseClick(this.field_85051_p, this.field_85051_p.slotNumber, par3, 0); 450 this.handleMouseClick(var4, var8, 0, 0); 451 452 if (this.mc.thePlayer.inventory.getItemStack() != null) 453 { 454 this.handleMouseClick(this.field_85051_p, this.field_85051_p.slotNumber, par3, 0); 455 this.field_85049_r = par1 - var5; 456 this.field_85048_s = par2 - var6; 457 this.field_85047_t = this.field_85051_p; 458 this.field_85045_v = this.field_85050_q; 459 this.field_85046_u = Minecraft.getSystemTime(); 460 } 461 else 462 { 463 this.field_85045_v = null; 464 } 465 } 466 else if (this.field_85050_q != null) 467 { 468 this.field_85049_r = par1 - var5; 469 this.field_85048_s = par2 - var6; 470 this.field_85047_t = this.field_85051_p; 471 this.field_85045_v = this.field_85050_q; 472 this.field_85046_u = Minecraft.getSystemTime(); 473 } 474 475 this.field_85050_q = null; 476 this.field_85051_p = null; 477 } 478 } 479 } 480 481 /** 482 * Returns if the passed mouse position is over the specified slot. 483 */ 484 private boolean isMouseOverSlot(Slot par1Slot, int par2, int par3) 485 { 486 return this.func_74188_c(par1Slot.xDisplayPosition, par1Slot.yDisplayPosition, 16, 16, par2, par3); 487 } 488 489 protected boolean func_74188_c(int par1, int par2, int par3, int par4, int par5, int par6) 490 { 491 int var7 = this.guiLeft; 492 int var8 = this.guiTop; 493 par5 -= var7; 494 par6 -= var8; 495 return par5 >= par1 - 1 && par5 < par1 + par3 + 1 && par6 >= par2 - 1 && par6 < par2 + par4 + 1; 496 } 497 498 protected void handleMouseClick(Slot par1Slot, int par2, int par3, int par4) 499 { 500 if (par1Slot != null) 501 { 502 par2 = par1Slot.slotNumber; 503 } 504 505 this.mc.playerController.windowClick(this.inventorySlots.windowId, par2, par3, par4, this.mc.thePlayer); 506 } 507 508 /** 509 * Fired when a key is typed. This is the equivalent of KeyListener.keyTyped(KeyEvent e). 510 */ 511 protected void keyTyped(char par1, int par2) 512 { 513 if (par2 == 1 || par2 == this.mc.gameSettings.keyBindInventory.keyCode) 514 { 515 this.mc.thePlayer.closeScreen(); 516 } 517 518 this.func_82319_a(par2); 519 520 if (par2 == this.mc.gameSettings.keyBindPickBlock.keyCode && this.theSlot != null && this.theSlot.getHasStack()) 521 { 522 this.handleMouseClick(this.theSlot, this.theSlot.slotNumber, this.ySize, 3); 523 } 524 } 525 526 protected boolean func_82319_a(int par1) 527 { 528 if (this.mc.thePlayer.inventory.getItemStack() == null && this.theSlot != null) 529 { 530 for (int var2 = 0; var2 < 9; ++var2) 531 { 532 if (par1 == 2 + var2) 533 { 534 this.handleMouseClick(this.theSlot, this.theSlot.slotNumber, var2, 2); 535 return true; 536 } 537 } 538 } 539 540 return false; 541 } 542 543 /** 544 * Called when the screen is unloaded. Used to disable keyboard repeat events 545 */ 546 public void onGuiClosed() 547 { 548 if (this.mc.thePlayer != null) 549 { 550 this.inventorySlots.onCraftGuiClosed(this.mc.thePlayer); 551 } 552 } 553 554 /** 555 * Returns true if this GUI should pause the game when it is displayed in single-player 556 */ 557 public boolean doesGuiPauseGame() 558 { 559 return false; 560 } 561 562 /** 563 * Called from the main game loop to update the screen. 564 */ 565 public void updateScreen() 566 { 567 super.updateScreen(); 568 569 if (!this.mc.thePlayer.isEntityAlive() || this.mc.thePlayer.isDead) 570 { 571 this.mc.thePlayer.closeScreen(); 572 } 573 } 574 }