001package net.minecraft.client.gui.achievement;
002
003import cpw.mods.fml.relauncher.Side;
004import cpw.mods.fml.relauncher.SideOnly;
005
006import java.util.LinkedList;
007import java.util.List;
008import java.util.Random;
009import net.minecraft.block.Block;
010import net.minecraft.client.Minecraft;
011import net.minecraft.client.gui.GuiButton;
012import net.minecraft.client.gui.GuiScreen;
013import net.minecraft.client.gui.GuiSmallButton;
014import net.minecraft.client.renderer.RenderHelper;
015import net.minecraft.client.renderer.entity.RenderItem;
016import net.minecraft.stats.Achievement;
017import net.minecraft.stats.AchievementList;
018import net.minecraft.stats.StatFileWriter;
019import net.minecraft.util.MathHelper;
020import net.minecraft.util.StatCollector;
021import org.lwjgl.input.Mouse;
022import org.lwjgl.opengl.GL11;
023import org.lwjgl.opengl.GL12;
024
025import net.minecraftforge.common.AchievementPage;
026
027@SideOnly(Side.CLIENT)
028public 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}