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.List; 006 import net.minecraft.client.Minecraft; 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 private Slot field_85051_p = null; 037 private boolean field_90018_r = false; 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.openContainer = 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 114 if (this.field_85050_q != null && this.field_90018_r) 115 { 116 var16 = var16.copy(); 117 var16.stackSize = MathHelper.ceiling_float_int((float)var16.stackSize / 2.0F); 118 } 119 120 this.func_85044_b(var16, par1 - var4 - var8, par2 - var5 - var8); 121 } 122 123 if (this.field_85045_v != null) 124 { 125 float var17 = (float)(Minecraft.getSystemTime() - this.field_85046_u) / 100.0F; 126 127 if (var17 >= 1.0F) 128 { 129 var17 = 1.0F; 130 this.field_85045_v = null; 131 } 132 133 var9 = this.field_85047_t.xDisplayPosition - this.field_85049_r; 134 int var10 = this.field_85047_t.yDisplayPosition - this.field_85048_s; 135 int var11 = this.field_85049_r + (int)((float)var9 * var17); 136 int var12 = this.field_85048_s + (int)((float)var10 * var17); 137 this.func_85044_b(this.field_85045_v, var11, var12); 138 } 139 140 if (var15.getItemStack() == null && this.theSlot != null && this.theSlot.getHasStack()) 141 { 142 ItemStack var18 = this.theSlot.getStack(); 143 this.func_74184_a(var18, par1 - var4 + 8, par2 - var5 + 8); 144 } 145 146 GL11.glPopMatrix(); 147 GL11.glEnable(GL11.GL_LIGHTING); 148 GL11.glEnable(GL11.GL_DEPTH_TEST); 149 RenderHelper.enableStandardItemLighting(); 150 } 151 152 private void func_85044_b(ItemStack par1ItemStack, int par2, int par3) 153 { 154 GL11.glTranslatef(0.0F, 0.0F, 32.0F); 155 this.zLevel = 200.0F; 156 itemRenderer.zLevel = 200.0F; 157 itemRenderer.renderItemAndEffectIntoGUI(this.fontRenderer, this.mc.renderEngine, par1ItemStack, par2, par3); 158 itemRenderer.renderItemOverlayIntoGUI(this.fontRenderer, this.mc.renderEngine, par1ItemStack, par2, par3); 159 this.zLevel = 0.0F; 160 itemRenderer.zLevel = 0.0F; 161 } 162 163 protected void func_74184_a(ItemStack par1ItemStack, int par2, int par3) 164 { 165 GL11.glDisable(GL12.GL_RESCALE_NORMAL); 166 RenderHelper.disableStandardItemLighting(); 167 GL11.glDisable(GL11.GL_LIGHTING); 168 GL11.glDisable(GL11.GL_DEPTH_TEST); 169 List var4 = par1ItemStack.getTooltip(this.mc.thePlayer, this.mc.gameSettings.advancedItemTooltips); 170 171 if (!var4.isEmpty()) 172 { 173 int var5 = 0; 174 int var6; 175 int var7; 176 177 for (var6 = 0; var6 < var4.size(); ++var6) 178 { 179 var7 = this.fontRenderer.getStringWidth((String)var4.get(var6)); 180 181 if (var7 > var5) 182 { 183 var5 = var7; 184 } 185 } 186 187 var6 = par2 + 12; 188 var7 = par3 - 12; 189 int var9 = 8; 190 191 if (var4.size() > 1) 192 { 193 var9 += 2 + (var4.size() - 1) * 10; 194 } 195 196 this.zLevel = 300.0F; 197 itemRenderer.zLevel = 300.0F; 198 int var10 = -267386864; 199 this.drawGradientRect(var6 - 3, var7 - 4, var6 + var5 + 3, var7 - 3, var10, var10); 200 this.drawGradientRect(var6 - 3, var7 + var9 + 3, var6 + var5 + 3, var7 + var9 + 4, var10, var10); 201 this.drawGradientRect(var6 - 3, var7 - 3, var6 + var5 + 3, var7 + var9 + 3, var10, var10); 202 this.drawGradientRect(var6 - 4, var7 - 3, var6 - 3, var7 + var9 + 3, var10, var10); 203 this.drawGradientRect(var6 + var5 + 3, var7 - 3, var6 + var5 + 4, var7 + var9 + 3, var10, var10); 204 int var11 = 1347420415; 205 int var12 = (var11 & 16711422) >> 1 | var11 & -16777216; 206 this.drawGradientRect(var6 - 3, var7 - 3 + 1, var6 - 3 + 1, var7 + var9 + 3 - 1, var11, var12); 207 this.drawGradientRect(var6 + var5 + 2, var7 - 3 + 1, var6 + var5 + 3, var7 + var9 + 3 - 1, var11, var12); 208 this.drawGradientRect(var6 - 3, var7 - 3, var6 + var5 + 3, var7 - 3 + 1, var11, var11); 209 this.drawGradientRect(var6 - 3, var7 + var9 + 2, var6 + var5 + 3, var7 + var9 + 3, var12, var12); 210 211 for (int var13 = 0; var13 < var4.size(); ++var13) 212 { 213 String var14 = (String)var4.get(var13); 214 215 if (var13 == 0) 216 { 217 var14 = "\u00a7" + Integer.toHexString(par1ItemStack.getRarity().rarityColor) + var14; 218 } 219 else 220 { 221 var14 = "\u00a77" + var14; 222 } 223 224 this.fontRenderer.drawStringWithShadow(var14, var6, var7, -1); 225 226 if (var13 == 0) 227 { 228 var7 += 2; 229 } 230 231 var7 += 10; 232 } 233 234 this.zLevel = 0.0F; 235 itemRenderer.zLevel = 0.0F; 236 } 237 } 238 239 /** 240 * Draws the text when mouse is over creative inventory tab. Params: current creative tab to be checked, current 241 * mouse x position, current mouse y position. 242 */ 243 protected void drawCreativeTabHoveringText(String par1Str, int par2, int par3) 244 { 245 GL11.glDisable(GL12.GL_RESCALE_NORMAL); 246 RenderHelper.disableStandardItemLighting(); 247 GL11.glDisable(GL11.GL_LIGHTING); 248 GL11.glDisable(GL11.GL_DEPTH_TEST); 249 int var4 = this.fontRenderer.getStringWidth(par1Str); 250 int var5 = par2 + 12; 251 int var6 = par3 - 12; 252 byte var8 = 8; 253 this.zLevel = 300.0F; 254 itemRenderer.zLevel = 300.0F; 255 int var9 = -267386864; 256 this.drawGradientRect(var5 - 3, var6 - 4, var5 + var4 + 3, var6 - 3, var9, var9); 257 this.drawGradientRect(var5 - 3, var6 + var8 + 3, var5 + var4 + 3, var6 + var8 + 4, var9, var9); 258 this.drawGradientRect(var5 - 3, var6 - 3, var5 + var4 + 3, var6 + var8 + 3, var9, var9); 259 this.drawGradientRect(var5 - 4, var6 - 3, var5 - 3, var6 + var8 + 3, var9, var9); 260 this.drawGradientRect(var5 + var4 + 3, var6 - 3, var5 + var4 + 4, var6 + var8 + 3, var9, var9); 261 int var10 = 1347420415; 262 int var11 = (var10 & 16711422) >> 1 | var10 & -16777216; 263 this.drawGradientRect(var5 - 3, var6 - 3 + 1, var5 - 3 + 1, var6 + var8 + 3 - 1, var10, var11); 264 this.drawGradientRect(var5 + var4 + 2, var6 - 3 + 1, var5 + var4 + 3, var6 + var8 + 3 - 1, var10, var11); 265 this.drawGradientRect(var5 - 3, var6 - 3, var5 + var4 + 3, var6 - 3 + 1, var10, var10); 266 this.drawGradientRect(var5 - 3, var6 + var8 + 2, var5 + var4 + 3, var6 + var8 + 3, var11, var11); 267 this.fontRenderer.drawStringWithShadow(par1Str, var5, var6, -1); 268 this.zLevel = 0.0F; 269 itemRenderer.zLevel = 0.0F; 270 GL11.glEnable(GL11.GL_LIGHTING); 271 GL11.glEnable(GL11.GL_DEPTH_TEST); 272 RenderHelper.enableStandardItemLighting(); 273 GL11.glEnable(GL12.GL_RESCALE_NORMAL); 274 } 275 276 /** 277 * Draw the foreground layer for the GuiContainer (everything in front of the items) 278 */ 279 protected void drawGuiContainerForegroundLayer(int par1, int par2) {} 280 281 /** 282 * Draw the background layer for the GuiContainer (everything behind the items) 283 */ 284 protected abstract void drawGuiContainerBackgroundLayer(float var1, int var2, int var3); 285 286 /** 287 * Draws an inventory slot 288 */ 289 protected void drawSlotInventory(Slot par1Slot) 290 { 291 int var2 = par1Slot.xDisplayPosition; 292 int var3 = par1Slot.yDisplayPosition; 293 ItemStack var4 = par1Slot.getStack(); 294 boolean var5 = par1Slot == this.field_85051_p && this.field_85050_q != null && !this.field_90018_r; 295 296 if (par1Slot == this.field_85051_p && this.field_85050_q != null && this.field_90018_r && var4 != null) 297 { 298 var4 = var4.copy(); 299 var4.stackSize /= 2; 300 } 301 302 this.zLevel = 100.0F; 303 itemRenderer.zLevel = 100.0F; 304 305 if (var4 == null) 306 { 307 int var6 = par1Slot.getBackgroundIconIndex(); 308 309 if (var6 >= 0) 310 { 311 GL11.glDisable(GL11.GL_LIGHTING); 312 this.mc.renderEngine.bindTexture(this.mc.renderEngine.getTexture(par1Slot.getBackgroundIconTexture())); 313 this.drawTexturedModalRect(var2, var3, var6 % 16 * 16, var6 / 16 * 16, 16, 16); 314 GL11.glEnable(GL11.GL_LIGHTING); 315 var5 = true; 316 } 317 } 318 319 if (!var5) 320 { 321 GL11.glEnable(GL11.GL_DEPTH_TEST); 322 itemRenderer.renderItemAndEffectIntoGUI(this.fontRenderer, this.mc.renderEngine, var4, var2, var3); 323 itemRenderer.renderItemOverlayIntoGUI(this.fontRenderer, this.mc.renderEngine, var4, var2, var3); 324 } 325 326 itemRenderer.zLevel = 0.0F; 327 this.zLevel = 0.0F; 328 } 329 330 /** 331 * Returns the slot at the given coordinates or null if there is none. 332 */ 333 private Slot getSlotAtPosition(int par1, int par2) 334 { 335 for (int var3 = 0; var3 < this.inventorySlots.inventorySlots.size(); ++var3) 336 { 337 Slot var4 = (Slot)this.inventorySlots.inventorySlots.get(var3); 338 339 if (this.isMouseOverSlot(var4, par1, par2)) 340 { 341 return var4; 342 } 343 } 344 345 return null; 346 } 347 348 /** 349 * Called when the mouse is clicked. 350 */ 351 protected void mouseClicked(int par1, int par2, int par3) 352 { 353 super.mouseClicked(par1, par2, par3); 354 boolean var4 = par3 == this.mc.gameSettings.keyBindPickBlock.keyCode + 100; 355 356 if (par3 == 0 || par3 == 1 || var4) 357 { 358 Slot var5 = this.getSlotAtPosition(par1, par2); 359 int var6 = this.guiLeft; 360 int var7 = this.guiTop; 361 boolean var8 = par1 < var6 || par2 < var7 || par1 >= var6 + this.xSize || par2 >= var7 + this.ySize; 362 int var9 = -1; 363 364 if (var5 != null) 365 { 366 var9 = var5.slotNumber; 367 } 368 369 if (var8) 370 { 371 var9 = -999; 372 } 373 374 if (this.mc.gameSettings.field_85185_A && var8 && this.mc.thePlayer.inventory.getItemStack() == null) 375 { 376 this.mc.displayGuiScreen((GuiScreen)null); 377 return; 378 } 379 380 if (var9 != -1) 381 { 382 if (this.mc.gameSettings.field_85185_A) 383 { 384 if (var5 != null && var5.getHasStack()) 385 { 386 this.field_85051_p = var5; 387 this.field_85050_q = null; 388 this.field_90018_r = par3 == 1; 389 } 390 else 391 { 392 this.field_85051_p = null; 393 } 394 } 395 else if (var4) 396 { 397 this.handleMouseClick(var5, var9, par3, 3); 398 } 399 else 400 { 401 boolean var10 = var9 != -999 && (Keyboard.isKeyDown(42) || Keyboard.isKeyDown(54)); 402 this.handleMouseClick(var5, var9, par3, var10 ? 1 : 0); 403 } 404 } 405 } 406 } 407 408 protected void func_85041_a(int par1, int par2, int par3, long par4) 409 { 410 if (this.field_85051_p != null && this.mc.gameSettings.field_85185_A && this.field_85050_q == null) 411 { 412 if (par3 == 0 || par3 == 1) 413 { 414 Slot var6 = this.getSlotAtPosition(par1, par2); 415 416 if (var6 != this.field_85051_p) 417 { 418 this.field_85050_q = this.field_85051_p.getStack(); 419 } 420 } 421 } 422 } 423 424 /** 425 * Called when the mouse is moved or a mouse button is released. Signature: (mouseX, mouseY, which) which==-1 is 426 * mouseMove, which==0 or which==1 is mouseUp 427 */ 428 protected void mouseMovedOrUp(int par1, int par2, int par3) 429 { 430 if (this.field_85051_p != null && this.mc.gameSettings.field_85185_A) 431 { 432 if (par3 == 0 || par3 == 1) 433 { 434 Slot var4 = this.getSlotAtPosition(par1, par2); 435 int var5 = this.guiLeft; 436 int var6 = this.guiTop; 437 boolean var7 = par1 < var5 || par2 < var6 || par1 >= var5 + this.xSize || par2 >= var6 + this.ySize; 438 int var8 = -1; 439 440 if (var4 != null) 441 { 442 var8 = var4.slotNumber; 443 } 444 445 if (var7) 446 { 447 var8 = -999; 448 } 449 450 if (this.field_85050_q == null && var4 != this.field_85051_p) 451 { 452 this.field_85050_q = this.field_85051_p.getStack(); 453 } 454 455 boolean var9 = var4 == null || !var4.getHasStack(); 456 457 if (var4 != null && var4.getHasStack() && this.field_85050_q != null && ItemStack.areItemStackTagsEqual(var4.getStack(), this.field_85050_q)) 458 { 459 var9 |= var4.getStack().stackSize + this.field_85050_q.stackSize <= this.field_85050_q.getMaxStackSize(); 460 } 461 462 if (var8 != -1 && this.field_85050_q != null && var9) 463 { 464 this.handleMouseClick(this.field_85051_p, this.field_85051_p.slotNumber, par3, 0); 465 this.handleMouseClick(var4, var8, 0, 0); 466 467 if (this.mc.thePlayer.inventory.getItemStack() != null) 468 { 469 this.handleMouseClick(this.field_85051_p, this.field_85051_p.slotNumber, par3, 0); 470 this.field_85049_r = par1 - var5; 471 this.field_85048_s = par2 - var6; 472 this.field_85047_t = this.field_85051_p; 473 this.field_85045_v = this.field_85050_q; 474 this.field_85046_u = Minecraft.getSystemTime(); 475 } 476 else 477 { 478 this.field_85045_v = null; 479 } 480 } 481 else if (this.field_85050_q != null) 482 { 483 this.field_85049_r = par1 - var5; 484 this.field_85048_s = par2 - var6; 485 this.field_85047_t = this.field_85051_p; 486 this.field_85045_v = this.field_85050_q; 487 this.field_85046_u = Minecraft.getSystemTime(); 488 } 489 490 this.field_85050_q = null; 491 this.field_85051_p = null; 492 } 493 } 494 } 495 496 /** 497 * Returns if the passed mouse position is over the specified slot. 498 */ 499 private boolean isMouseOverSlot(Slot par1Slot, int par2, int par3) 500 { 501 return this.func_74188_c(par1Slot.xDisplayPosition, par1Slot.yDisplayPosition, 16, 16, par2, par3); 502 } 503 504 protected boolean func_74188_c(int par1, int par2, int par3, int par4, int par5, int par6) 505 { 506 int var7 = this.guiLeft; 507 int var8 = this.guiTop; 508 par5 -= var7; 509 par6 -= var8; 510 return par5 >= par1 - 1 && par5 < par1 + par3 + 1 && par6 >= par2 - 1 && par6 < par2 + par4 + 1; 511 } 512 513 protected void handleMouseClick(Slot par1Slot, int par2, int par3, int par4) 514 { 515 if (par1Slot != null) 516 { 517 par2 = par1Slot.slotNumber; 518 } 519 520 this.mc.playerController.windowClick(this.inventorySlots.windowId, par2, par3, par4, this.mc.thePlayer); 521 } 522 523 /** 524 * Fired when a key is typed. This is the equivalent of KeyListener.keyTyped(KeyEvent e). 525 */ 526 protected void keyTyped(char par1, int par2) 527 { 528 if (par2 == 1 || par2 == this.mc.gameSettings.keyBindInventory.keyCode) 529 { 530 this.mc.thePlayer.closeScreen(); 531 } 532 533 this.func_82319_a(par2); 534 535 if (par2 == this.mc.gameSettings.keyBindPickBlock.keyCode && this.theSlot != null && this.theSlot.getHasStack()) 536 { 537 this.handleMouseClick(this.theSlot, this.theSlot.slotNumber, this.ySize, 3); 538 } 539 } 540 541 protected boolean func_82319_a(int par1) 542 { 543 if (this.mc.thePlayer.inventory.getItemStack() == null && this.theSlot != null) 544 { 545 for (int var2 = 0; var2 < 9; ++var2) 546 { 547 if (par1 == 2 + var2) 548 { 549 this.handleMouseClick(this.theSlot, this.theSlot.slotNumber, var2, 2); 550 return true; 551 } 552 } 553 } 554 555 return false; 556 } 557 558 /** 559 * Called when the screen is unloaded. Used to disable keyboard repeat events 560 */ 561 public void onGuiClosed() 562 { 563 if (this.mc.thePlayer != null) 564 { 565 this.inventorySlots.onCraftGuiClosed(this.mc.thePlayer); 566 } 567 } 568 569 /** 570 * Returns true if this GUI should pause the game when it is displayed in single-player 571 */ 572 public boolean doesGuiPauseGame() 573 { 574 return false; 575 } 576 577 /** 578 * Called from the main game loop to update the screen. 579 */ 580 public void updateScreen() 581 { 582 super.updateScreen(); 583 584 if (!this.mc.thePlayer.isEntityAlive() || this.mc.thePlayer.isDead) 585 { 586 this.mc.thePlayer.closeScreen(); 587 } 588 } 589 }