achievement System

Got any custom JavaScript additions/tweaks you think other people would like to see? Post 'em here!
Post Reply
dragon slayer
UOX3 Guru
Posts: 776
Joined: Thu Dec 21, 2006 7:37 am
Has thanked: 4 times
Been thanked: 26 times

achievement System

Post by dragon slayer »

Uox3 first of its kind achievement system.
// achievementGump.js - UOX3 JavaScript

function onUseChecked(pUser, iUsed)
{
    if (!pUser || !ValidateObject(pUser))
        return false;

    var progressMap = LoadAchievements(pUser);
    var achID = 101; // ID for "Skeleton Slayer"
    var current = progressMap[achID] || 0;
    var gain = 5;
    var capped = Math.min(current + gain, 100); // ? Prevent overfilling
    progressMap[achID] = capped;

    // Check for unlock at exact value (and not multiple triggers)
    if (current < 100 && capped == 100)
    {
        pUser.SysMessage("Achievement Unlocked: Skeleton Slayer!");
        // Optionally: ShowAchievementUnlockGump(pUser, achID);
    }

    SaveAchievements(pUser, progressMap);

    ShowAchievementGump(pUser.socket, 1); // Default to category 1
}

function LoadAchievements(pChar)
{
    var mFile = new UOXCFile();
    var accountID = pChar.account.id;
    var fileName = "Achievements_" + accountID + ".jsdata";

    var progressMap = {};
    mFile.Open(fileName, "r", "Achievements");

    if (mFile && mFile.Length() > 0)
    {
        while (!mFile.EOF())
        {
            var line = manualTrim(mFile.ReadUntil("\n"));
            if (!line || line.indexOf(":") == -1)
                continue;

            var parts = line.split(":");
            var id = parseInt(parts[0]);
            var val = parseInt(parts[1]);
            if (!isNaN(id) && !isNaN(val))
                progressMap[id] = val;
        }
        mFile.Close();
        mFile.Free();
    }
    else if (mFile)
    {
        mFile.Free();
    }

    return progressMap;
}

function manualTrim(str)
{
    return str.replace(/^\s+|\s+$/g, "");
}

function SaveAchievements(pChar, progressMap)
{
    var mFile = new UOXCFile();
    var accountID = pChar.account.id;
    var fileName = "Achievements_" + accountID + ".jsdata";

    mFile.Open(fileName, "w", "Achievements"); // Must match a valid [UOX3Directories] entry
    if (mFile)
    {
        for (var key in progressMap)
        {
            if (progressMap.hasOwnProperty(key))
            {
                mFile.Write(key + ":" + progressMap[key] + "\n");
            }
        }
        mFile.Close();
        mFile.Free();
        return true;
    }
    else
    {
        if (mFile) mFile.Free();
        return false;
    }
}



function ShowAchievementGump(pSock, categoryID, page)
{
    if (!pSock || !ValidateObject(pSock.currentChar))
        return;

    var pChar = pSock.currentChar;
    var gump = new Gump; // create a new gump
    //var totalPoints = parseInt(pChar.GetTag("achv_totalpoints")) || 0;
    var progressData = LoadAchievements(pChar);
    var totalPoints = 0;
    for (var key in progressData)
    {
        if (progressData[key] > 0)
            totalPoints += progressData[key]; // Placeholder logic, adjust if points are separate
    }

    var page = parseInt(pChar.GetTag("achvPage")) || 1;

    gump.AddBackground(11, 15, 758, 575, 2600);
    gump.AddBackground(57, 92, 666, 478, 9250);
    gump.AddBackground(321, 104, 386, 453, 9270);
    gump.AddBackground(72, 104, 245, 453, 9270);
    gump.AddBackground(72, 34, 635, 53, 9270);
    gump.AddBackground(327, 0, 133, 41, 9200);
    gump.AddText(330, 52, 68, "Achievement System");
    gump.AddText(360, 11, 82, totalPoints + " Points");
    gump.AddBackground(341, 522, 353, 26, 9200);

    // Categories - sample static list for now
    var categories = [
        { id: 1, name: "Combat", parent: 0 },
        { id: 2, name: "Crafting", parent: 0 },
        { id: 3, name: "Exploration", parent: 0 },
    ];

    var currentCat = categoryID || 1;
    var catCount = 0;

    for (var i = 0; i < categories.length; ++i)
    {
        var cat = categories[i];
        var x = 90;
        var bgID = 9200;

        if (cat.id == currentCat)
            bgID = 5120;

        gump.AddBackground(x, 123 + (catCount * 31), 188, 25, bgID);

        if (cat.id == currentCat)
            gump.AddGump(x + 12, 129 + (catCount * 31), 1210);
        else
            gump.AddButton(x + 12, 129 + (catCount * 31), 1209, 1210, 1, 0, 5000 + cat.id);

        gump.AddText(x + 32, 125 + (catCount * 31), 0, cat.name);
        catCount++;
    }

    var achievements = GetAchievements();

    var achievementsInCategory = achievements.filter(function(ac) { return ac.categoryID == currentCat });
    var totalPages = Math.ceil(achievementsInCategory.length / 4);

    var displayCount = 0;
    for (var j = 0; j < achievements.length; ++j)
    {
        var ac = achievements[j];
        if (ac.categoryID != currentCat)
            continue;

        //var progress = parseInt(pChar.GetTag("achv_" + ac.id)) || 0;
        var progress = progressData[ac.id] || 0;
        var bg = (progress >= ac.total) ? 9300 : 9350;
        var yOffset = 122 + ((displayCount % 4) * 100);
        var pageNum = Math.floor(displayCount / 4) + 1;

        if (pageNum != page)
        {
            displayCount++;
            continue;
        }

        if (page > 1)
            gump.AddButton(345, 524, 4014, 4015, 1, 0,  6000 + (page - 1));
        if (page < totalPages)
            gump.AddButton(658, 524, 4005, 4006, 1, 0, 6100 + (page + 1));
        gump.AddText(484, 526, 32, "Page " + pageNum);

            // ??? Fixed progress bar logic
        var maxWidth = 95;
        var barWidth = Math.floor(Math.min((progress / ac.total) * maxWidth, maxWidth));

        gump.AddBackground(340, yOffset, 347, 97, bg);
        gump.AddText(414, yOffset + 9, 49, ac.title);
        if (ac.icon > 0)
            gump.AddPicture(357, yOffset + 25, ac.icon);
        gump.AddTiledGump(416, yOffset + 81, maxWidth, 9, 9750); // Bar background
        gump.AddTiledGump(416, yOffset + 81, barWidth, 9, 9752);  // Filled progress
        //gump.AddTiledGump(416, yOffset + 81, 95, 9, 9750);
        //gump.AddTiledGump(416, yOffset + 81, Math.min(progress / ac.total * 95, 95), 9, 9752);
        gump.AddText(413, yOffset + 30, 0, ac.desc);
        gump.AddText(522, yOffset + 74, 0, progress + " / " + ac.total);
        gump.AddBackground(628, yOffset + 27, 48, 48, 9200);
        gump.AddText(648, yOffset + 42, 32, ac.points.toString());

        displayCount++;
    }

    gump.Send( pSock );
    gump.Free();
}

function onGumpPress(pSock, pButton, gumpData)
{
    var pUser = pSock.currentChar;

    if (!ValidateObject(pUser))
        return;

    // Handle category switching
    if (pButton >= 5000 && pButton < 6000)
    {
        pUser.SetTag("achvPage", 1); // Reset to page 1 on category switch
        ShowAchievementGump(pSock, pButton - 5000);
        return;
    }

    // Prev page
    if (pButton >= 6000 && pButton < 6100)
    {
        var prevPage = pButton - 6000;
        pUser.SetTag("achvPage", prevPage);
        ShowAchievementGump(pSock);
        return;
    }

    // Next page
    if (pButton >= 6100 && pButton < 6200)
    {
        var nextPage = pButton - 6100;
        pUser.SetTag("achvPage", nextPage);
        ShowAchievementGump(pSock);
        return;
    }
}

function GetAchievements()
{
    return [
        { id: 101, categoryID: 1, title: "Skeleton Slayer", desc: "Kill 100 skeletons.", points: 10, icon: 0x1B7A, total: 100 },
        { id: 102, categoryID: 1, title: "Dragon Slayer", desc: "Kill 100 Dragons.", points: 10, icon: 0x1B7A, total: 100 },
        { id: 103, categoryID: 1, title: "Dragon Slayer", desc: "Kill 100 Dragons.", points: 10, icon: 0x1B7A, total: 100 },
        { id: 104, categoryID: 1, title: "Dragon Slayer", desc: "Kill 100 Dragons.", points: 10, icon: 0x1B7A, total: 100 },
        { id: 105, categoryID: 1, title: "Dragon Slayer", desc: "Kill 100 Dragons.", points: 10, icon: 0x1B7A, total: 100 },
        { id: 106, categoryID: 1, title: "Dragon Slayer", desc: "Kill 100 Dragons.", points: 10, icon: 0x1B7A, total: 100 },
        { id: 107, categoryID: 1, title: "Dragon Slayer", desc: "Kill 100 Dragons.", points: 10, icon: 0x1B7A, total: 100 },
        { id: 202, categoryID: 2, title: "Master Blacksmith", desc: "Reach 100.0 Blacksmithing.", points: 15, icon: 0x13E3, total: 1000 }
    ];
}
at the moment it's just simple script to be able to start making Achievements

I will work on more update version with how to do it with crafting
killing monsters collecting items ect.
Post Reply