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