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    }