001 package net.minecraft.client.gui.achievement;
002
003 import cpw.mods.fml.relauncher.Side;
004 import cpw.mods.fml.relauncher.SideOnly;
005
006 import java.util.LinkedList;
007 import java.util.List;
008 import java.util.Random;
009 import net.minecraft.block.Block;
010 import net.minecraft.client.Minecraft;
011 import net.minecraft.client.gui.GuiButton;
012 import net.minecraft.client.gui.GuiScreen;
013 import net.minecraft.client.gui.GuiSmallButton;
014 import net.minecraft.client.renderer.RenderHelper;
015 import net.minecraft.client.renderer.entity.RenderItem;
016 import net.minecraft.stats.Achievement;
017 import net.minecraft.stats.AchievementList;
018 import net.minecraft.stats.StatFileWriter;
019 import net.minecraft.util.MathHelper;
020 import net.minecraft.util.StatCollector;
021 import org.lwjgl.input.Mouse;
022 import org.lwjgl.opengl.GL11;
023 import org.lwjgl.opengl.GL12;
024
025 import net.minecraftforge.common.AchievementPage;
026
027 @SideOnly(Side.CLIENT)
028 public class GuiAchievements extends GuiScreen
029 {
030 /** The top x coordinate of the achievement map */
031 private static final int guiMapTop = AchievementList.minDisplayColumn * 24 - 112;
032
033 /** The left y coordinate of the achievement map */
034 private static final int guiMapLeft = AchievementList.minDisplayRow * 24 - 112;
035
036 /** The bottom x coordinate of the achievement map */
037 private static final int guiMapBottom = AchievementList.maxDisplayColumn * 24 - 77;
038
039 /** The right y coordinate of the achievement map */
040 private static final int guiMapRight = AchievementList.maxDisplayRow * 24 - 77;
041 protected int achievementsPaneWidth = 256;
042 protected int achievementsPaneHeight = 202;
043
044 /** The current mouse x coordinate */
045 protected int mouseX = 0;
046
047 /** The current mouse y coordinate */
048 protected int mouseY = 0;
049 protected double field_74117_m;
050 protected double field_74115_n;
051
052 /** The x position of the achievement map */
053 protected double guiMapX;
054
055 /** The y position of the achievement map */
056 protected double guiMapY;
057 protected double field_74124_q;
058 protected double field_74123_r;
059
060 /** Whether the Mouse Button is down or not */
061 private int isMouseButtonDown = 0;
062 private StatFileWriter statFileWriter;
063
064 private int currentPage = -1;
065 private GuiSmallButton button;
066 private LinkedList<Achievement> minecraftAchievements = new LinkedList<Achievement>();
067
068 public GuiAchievements(StatFileWriter par1StatFileWriter)
069 {
070 this.statFileWriter = par1StatFileWriter;
071 short var2 = 141;
072 short var3 = 141;
073 this.field_74117_m = this.guiMapX = this.field_74124_q = (double)(AchievementList.openInventory.displayColumn * 24 - var2 / 2 - 12);
074 this.field_74115_n = this.guiMapY = this.field_74123_r = (double)(AchievementList.openInventory.displayRow * 24 - var3 / 2);
075 minecraftAchievements.clear();
076 for (Object achievement : AchievementList.achievementList)
077 {
078 if (!AchievementPage.isAchievementInPages((Achievement)achievement))
079 {
080 minecraftAchievements.add((Achievement)achievement);
081 }
082 }
083 }
084
085 /**
086 * Adds the buttons (and other controls) to the screen in question.
087 */
088 public void initGui()
089 {
090 this.controlList.clear();
091 this.controlList.add(new GuiSmallButton(1, this.width / 2 + 24, this.height / 2 + 74, 80, 20, StatCollector.translateToLocal("gui.done")));
092 this.controlList.add(button = new GuiSmallButton(2, (width - achievementsPaneWidth) / 2 + 24, height / 2 + 74, 125, 20, AchievementPage.getTitle(currentPage)));
093 }
094
095 /**
096 * Fired when a control is clicked. This is the equivalent of ActionListener.actionPerformed(ActionEvent e).
097 */
098 protected void actionPerformed(GuiButton par1GuiButton)
099 {
100 if (par1GuiButton.id == 1)
101 {
102 this.mc.displayGuiScreen((GuiScreen)null);
103 this.mc.setIngameFocus();
104 }
105
106 if (par1GuiButton.id == 2)
107 {
108 currentPage++;
109 if (currentPage >= AchievementPage.getAchievementPages().size())
110 {
111 currentPage = -1;
112 }
113 button.displayString = AchievementPage.getTitle(currentPage);
114 }
115
116 super.actionPerformed(par1GuiButton);
117 }
118
119 /**
120 * Fired when a key is typed. This is the equivalent of KeyListener.keyTyped(KeyEvent e).
121 */
122 protected void keyTyped(char par1, int par2)
123 {
124 if (par2 == this.mc.gameSettings.keyBindInventory.keyCode)
125 {
126 this.mc.displayGuiScreen((GuiScreen)null);
127 this.mc.setIngameFocus();
128 }
129 else
130 {
131 super.keyTyped(par1, par2);
132 }
133 }
134
135 /**
136 * Draws the screen and all the components in it.
137 */
138 public void drawScreen(int par1, int par2, float par3)
139 {
140 if (Mouse.isButtonDown(0))
141 {
142 int var4 = (this.width - this.achievementsPaneWidth) / 2;
143 int var5 = (this.height - this.achievementsPaneHeight) / 2;
144 int var6 = var4 + 8;
145 int var7 = var5 + 17;
146
147 if ((this.isMouseButtonDown == 0 || this.isMouseButtonDown == 1) && par1 >= var6 && par1 < var6 + 224 && par2 >= var7 && par2 < var7 + 155)
148 {
149 if (this.isMouseButtonDown == 0)
150 {
151 this.isMouseButtonDown = 1;
152 }
153 else
154 {
155 this.guiMapX -= (double)(par1 - this.mouseX);
156 this.guiMapY -= (double)(par2 - this.mouseY);
157 this.field_74124_q = this.field_74117_m = this.guiMapX;
158 this.field_74123_r = this.field_74115_n = this.guiMapY;
159 }
160
161 this.mouseX = par1;
162 this.mouseY = par2;
163 }
164
165 if (this.field_74124_q < (double)guiMapTop)
166 {
167 this.field_74124_q = (double)guiMapTop;
168 }
169
170 if (this.field_74123_r < (double)guiMapLeft)
171 {
172 this.field_74123_r = (double)guiMapLeft;
173 }
174
175 if (this.field_74124_q >= (double)guiMapBottom)
176 {
177 this.field_74124_q = (double)(guiMapBottom - 1);
178 }
179
180 if (this.field_74123_r >= (double)guiMapRight)
181 {
182 this.field_74123_r = (double)(guiMapRight - 1);
183 }
184 }
185 else
186 {
187 this.isMouseButtonDown = 0;
188 }
189
190 this.drawDefaultBackground();
191 this.genAchievementBackground(par1, par2, par3);
192 GL11.glDisable(GL11.GL_LIGHTING);
193 GL11.glDisable(GL11.GL_DEPTH_TEST);
194 this.drawTitle();
195 GL11.glEnable(GL11.GL_LIGHTING);
196 GL11.glEnable(GL11.GL_DEPTH_TEST);
197 }
198
199 /**
200 * Called from the main game loop to update the screen.
201 */
202 public void updateScreen()
203 {
204 this.field_74117_m = this.guiMapX;
205 this.field_74115_n = this.guiMapY;
206 double var1 = this.field_74124_q - this.guiMapX;
207 double var3 = this.field_74123_r - this.guiMapY;
208
209 if (var1 * var1 + var3 * var3 < 4.0D)
210 {
211 this.guiMapX += var1;
212 this.guiMapY += var3;
213 }
214 else
215 {
216 this.guiMapX += var1 * 0.85D;
217 this.guiMapY += var3 * 0.85D;
218 }
219 }
220
221 /**
222 * Draws the "Achievements" title at the top of the GUI.
223 */
224 protected void drawTitle()
225 {
226 int var1 = (this.width - this.achievementsPaneWidth) / 2;
227 int var2 = (this.height - this.achievementsPaneHeight) / 2;
228 this.fontRenderer.drawString("Achievements", var1 + 15, var2 + 5, 4210752);
229 }
230
231 protected void genAchievementBackground(int par1, int par2, float par3)
232 {
233 int var4 = MathHelper.floor_double(this.field_74117_m + (this.guiMapX - this.field_74117_m) * (double)par3);
234 int var5 = MathHelper.floor_double(this.field_74115_n + (this.guiMapY - this.field_74115_n) * (double)par3);
235
236 if (var4 < guiMapTop)
237 {
238 var4 = guiMapTop;
239 }
240
241 if (var5 < guiMapLeft)
242 {
243 var5 = guiMapLeft;
244 }
245
246 if (var4 >= guiMapBottom)
247 {
248 var4 = guiMapBottom - 1;
249 }
250
251 if (var5 >= guiMapRight)
252 {
253 var5 = guiMapRight - 1;
254 }
255
256 int var6 = this.mc.renderEngine.getTexture("/terrain.png");
257 int var7 = this.mc.renderEngine.getTexture("/achievement/bg.png");
258 int var8 = (this.width - this.achievementsPaneWidth) / 2;
259 int var9 = (this.height - this.achievementsPaneHeight) / 2;
260 int var10 = var8 + 16;
261 int var11 = var9 + 17;
262 this.zLevel = 0.0F;
263 GL11.glDepthFunc(GL11.GL_GEQUAL);
264 GL11.glPushMatrix();
265 GL11.glTranslatef(0.0F, 0.0F, -200.0F);
266 GL11.glEnable(GL11.GL_TEXTURE_2D);
267 GL11.glDisable(GL11.GL_LIGHTING);
268 GL11.glEnable(GL12.GL_RESCALE_NORMAL);
269 GL11.glEnable(GL11.GL_COLOR_MATERIAL);
270 this.mc.renderEngine.bindTexture(var6);
271 int var12 = var4 + 288 >> 4;
272 int var13 = var5 + 288 >> 4;
273 int var14 = (var4 + 288) % 16;
274 int var15 = (var5 + 288) % 16;
275 Random var21 = new Random();
276 int var22;
277 int var25;
278 int var24;
279 int var26;
280
281 for (var22 = 0; var22 * 16 - var15 < 155; ++var22)
282 {
283 float var23 = 0.6F - (float)(var13 + var22) / 25.0F * 0.3F;
284 GL11.glColor4f(var23, var23, var23, 1.0F);
285
286 for (var24 = 0; var24 * 16 - var14 < 224; ++var24)
287 {
288 var21.setSeed((long)(1234 + var12 + var24));
289 var21.nextInt();
290 var25 = var21.nextInt(1 + var13 + var22) + (var13 + var22) / 2;
291 var26 = Block.sand.blockIndexInTexture;
292
293 if (var25 <= 37 && var13 + var22 != 35)
294 {
295 if (var25 == 22)
296 {
297 if (var21.nextInt(2) == 0)
298 {
299 var26 = Block.oreDiamond.blockIndexInTexture;
300 }
301 else
302 {
303 var26 = Block.oreRedstone.blockIndexInTexture;
304 }
305 }
306 else if (var25 == 10)
307 {
308 var26 = Block.oreIron.blockIndexInTexture;
309 }
310 else if (var25 == 8)
311 {
312 var26 = Block.oreCoal.blockIndexInTexture;
313 }
314 else if (var25 > 4)
315 {
316 var26 = Block.stone.blockIndexInTexture;
317 }
318 else if (var25 > 0)
319 {
320 var26 = Block.dirt.blockIndexInTexture;
321 }
322 }
323 else
324 {
325 var26 = Block.bedrock.blockIndexInTexture;
326 }
327
328 this.drawTexturedModalRect(var10 + var24 * 16 - var14, var11 + var22 * 16 - var15, var26 % 16 << 4, var26 >> 4 << 4, 16, 16);
329 }
330 }
331
332 GL11.glEnable(GL11.GL_DEPTH_TEST);
333 GL11.glDepthFunc(GL11.GL_LEQUAL);
334 GL11.glDisable(GL11.GL_TEXTURE_2D);
335 int var27;
336 int var30;
337
338 List<Achievement> achievementList = (currentPage == -1 ? minecraftAchievements : AchievementPage.getAchievementPage(currentPage).getAchievements());
339 for (var22 = 0; var22 < achievementList.size(); ++var22)
340 {
341 Achievement var33 = achievementList.get(var22);
342
343 if (var33.parentAchievement != null && achievementList.contains(var33.parentAchievement))
344 {
345 var24 = var33.displayColumn * 24 - var4 + 11 + var10;
346 var25 = var33.displayRow * 24 - var5 + 11 + var11;
347 var26 = var33.parentAchievement.displayColumn * 24 - var4 + 11 + var10;
348 var27 = var33.parentAchievement.displayRow * 24 - var5 + 11 + var11;
349 boolean var28 = this.statFileWriter.hasAchievementUnlocked(var33);
350 boolean var29 = this.statFileWriter.canUnlockAchievement(var33);
351 var30 = Math.sin((double)(Minecraft.getSystemTime() % 600L) / 600.0D * Math.PI * 2.0D) > 0.6D ? 255 : 130;
352 int var31 = -16777216;
353
354 if (var28)
355 {
356 var31 = -9408400;
357 }
358 else if (var29)
359 {
360 var31 = 65280 + (var30 << 24);
361 }
362
363 this.drawHorizontalLine(var24, var26, var25, var31);
364 this.drawVerticalLine(var26, var25, var27, var31);
365 }
366 }
367
368 Achievement var32 = null;
369 RenderItem var37 = new RenderItem();
370 RenderHelper.enableGUIStandardItemLighting();
371 GL11.glDisable(GL11.GL_LIGHTING);
372 GL11.glEnable(GL12.GL_RESCALE_NORMAL);
373 GL11.glEnable(GL11.GL_COLOR_MATERIAL);
374 int var42;
375 int var41;
376
377 for (var24 = 0; var24 < achievementList.size(); ++var24)
378 {
379 Achievement var35 = achievementList.get(var24);
380 var26 = var35.displayColumn * 24 - var4;
381 var27 = var35.displayRow * 24 - var5;
382
383 if (var26 >= -24 && var27 >= -24 && var26 <= 224 && var27 <= 155)
384 {
385 float var38;
386
387 if (this.statFileWriter.hasAchievementUnlocked(var35))
388 {
389 var38 = 1.0F;
390 GL11.glColor4f(var38, var38, var38, 1.0F);
391 }
392 else if (this.statFileWriter.canUnlockAchievement(var35))
393 {
394 var38 = Math.sin((double)(Minecraft.getSystemTime() % 600L) / 600.0D * Math.PI * 2.0D) < 0.6D ? 0.6F : 0.8F;
395 GL11.glColor4f(var38, var38, var38, 1.0F);
396 }
397 else
398 {
399 var38 = 0.3F;
400 GL11.glColor4f(var38, var38, var38, 1.0F);
401 }
402
403 this.mc.renderEngine.bindTexture(var7);
404 var42 = var10 + var26;
405 var41 = var11 + var27;
406
407 if (var35.getSpecial())
408 {
409 this.drawTexturedModalRect(var42 - 2, var41 - 2, 26, 202, 26, 26);
410 }
411 else
412 {
413 this.drawTexturedModalRect(var42 - 2, var41 - 2, 0, 202, 26, 26);
414 }
415
416 if (!this.statFileWriter.canUnlockAchievement(var35))
417 {
418 float var40 = 0.1F;
419 GL11.glColor4f(var40, var40, var40, 1.0F);
420 var37.field_77024_a = false;
421 }
422
423 GL11.glEnable(GL11.GL_LIGHTING);
424 GL11.glEnable(GL11.GL_CULL_FACE);
425 var37.renderItemAndEffectIntoGUI(this.mc.fontRenderer, this.mc.renderEngine, var35.theItemStack, var42 + 3, var41 + 3);
426 GL11.glDisable(GL11.GL_LIGHTING);
427
428 if (!this.statFileWriter.canUnlockAchievement(var35))
429 {
430 var37.field_77024_a = true;
431 }
432
433 GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
434
435 if (par1 >= var10 && par2 >= var11 && par1 < var10 + 224 && par2 < var11 + 155 && par1 >= var42 && par1 <= var42 + 22 && par2 >= var41 && par2 <= var41 + 22)
436 {
437 var32 = var35;
438 }
439 }
440 }
441
442 GL11.glDisable(GL11.GL_DEPTH_TEST);
443 GL11.glEnable(GL11.GL_BLEND);
444 GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
445 this.mc.renderEngine.bindTexture(var7);
446 this.drawTexturedModalRect(var8, var9, 0, 0, this.achievementsPaneWidth, this.achievementsPaneHeight);
447 GL11.glPopMatrix();
448 this.zLevel = 0.0F;
449 GL11.glDepthFunc(GL11.GL_LEQUAL);
450 GL11.glDisable(GL11.GL_DEPTH_TEST);
451 GL11.glEnable(GL11.GL_TEXTURE_2D);
452 super.drawScreen(par1, par2, par3);
453
454 if (var32 != null)
455 {
456 String var34 = StatCollector.translateToLocal(var32.getName());
457 String var36 = var32.getDescription();
458 var26 = par1 + 12;
459 var27 = par2 - 4;
460
461 if (this.statFileWriter.canUnlockAchievement(var32))
462 {
463 var42 = Math.max(this.fontRenderer.getStringWidth(var34), 120);
464 var41 = this.fontRenderer.splitStringWidth(var36, var42);
465
466 if (this.statFileWriter.hasAchievementUnlocked(var32))
467 {
468 var41 += 12;
469 }
470
471 this.drawGradientRect(var26 - 3, var27 - 3, var26 + var42 + 3, var27 + var41 + 3 + 12, -1073741824, -1073741824);
472 this.fontRenderer.drawSplitString(var36, var26, var27 + 12, var42, -6250336);
473
474 if (this.statFileWriter.hasAchievementUnlocked(var32))
475 {
476 this.fontRenderer.drawStringWithShadow(StatCollector.translateToLocal("achievement.taken"), var26, var27 + var41 + 4, -7302913);
477 }
478 }
479 else
480 {
481 var42 = Math.max(this.fontRenderer.getStringWidth(var34), 120);
482 String var39 = StatCollector.translateToLocalFormatted("achievement.requires", new Object[] {StatCollector.translateToLocal(var32.parentAchievement.getName())});
483 var30 = this.fontRenderer.splitStringWidth(var39, var42);
484 this.drawGradientRect(var26 - 3, var27 - 3, var26 + var42 + 3, var27 + var30 + 12 + 3, -1073741824, -1073741824);
485 this.fontRenderer.drawSplitString(var39, var26, var27 + 12, var42, -9416624);
486 }
487
488 this.fontRenderer.drawStringWithShadow(var34, var26, var27, this.statFileWriter.canUnlockAchievement(var32) ? (var32.getSpecial() ? -128 : -1) : (var32.getSpecial() ? -8355776 : -8355712));
489 }
490
491 GL11.glEnable(GL11.GL_DEPTH_TEST);
492 GL11.glEnable(GL11.GL_LIGHTING);
493 RenderHelper.disableStandardItemLighting();
494 }
495
496 /**
497 * Returns true if this GUI should pause the game when it is displayed in single-player
498 */
499 public boolean doesGuiPauseGame()
500 {
501 return true;
502 }
503 }