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