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    }