    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.func_98187_b("/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.getBlockTextureFromSideAndMetadata(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.getBlockTextureFromSideAndMetadata(0, 0);
    298                        }
    299                        else
    300                        {
    301                            icon = Block.oreRedstone.getBlockTextureFromSideAndMetadata(0, 0);
    302                        }
    303                    }
    304                    else if (j3 == 10)
    305                    {
    306                        icon = Block.oreIron.getBlockTextureFromSideAndMetadata(0, 0);
    307                    }
    308                    else if (j3 == 8)
    309                    {
    310                        icon = Block.oreCoal.getBlockTextureFromSideAndMetadata(0, 0);
    311                    }
    312                    else if (j3 > 4)
    313                    {
    314                        icon = Block.stone.getBlockTextureFromSideAndMetadata(0, 0);
    315                    }
    316                    else if (j3 > 0)
    317                    {
    318                        icon = Block.dirt.getBlockTextureFromSideAndMetadata(0, 0);
    319                    }
    320                }
    321                else
    322                {
    323                    icon = Block.bedrock.getBlockTextureFromSideAndMetadata(0, 0);
    324                }
    325
    326                this.func_94065_a(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.func_98187_b("/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.field_77024_a = 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.field_77024_a = 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.func_98187_b("/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}