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