This project is read-only.

Achievement name

Sep 25, 2011 at 11:18 AM

Hi,

Thnx for a wonderful project!

I am trying to list the 10 latest achievements by name and date for a character.

But I can only find something that looks like the achievement ID in one of the Achievement collections returned from :

api.GetCharacter("xxx", "yyy", true);
Is the achievement name included in the result or am I supposed to get it someway else?
TIA
/cf
Sep 26, 2011 at 1:28 AM
Edited Sep 26, 2011 at 1:31 AM

Hi,

No, the achievement names are not returned by the character API since Blizzard's character APIs don't return achievements. You can get all achievements using the achievements API which is by calling:  api.GetCharacterAchievements(). This method get information about all character acheivements and their categories. description, rewards, etc. The data returned by this function is static and changes only when a new patch is released when Blizzard adds new acheivements to the game and/or change existing achievements. So I recommend that you cache this information at your side and don't call this method everytime you want to get achievement information. The achievements' data returned is also localized using the locale you used to create the ApiClient object. For example a client created with
api = new ApiClient(Region.EU, "de-de") will return achievement information in german.

Below is a code snippet that explains how to use the API to achieve what you want:

 

// the following line will get initialize a new client that will connect to the European battle.net service and get data in English (Great Britain) Locale
ApiClient client = new ApiClient(Region.EU, "en-GB");

// Note that the result from the following two calls is static and only changes with new patches or if you get data using a different language
// Get all character achievements (they are returned in categories and subcategories not as one single array)
AchievementsResponse characterAchievements = client.GetCharacterAchievements();
// Now we call FlatenCharacterAchievements to return all achievements as a single array
Achievement[] flatenedCharacterAchievements = FlatenCharacterAchievements(characterAchievements.Categories).ToArray();
// Add code to cache the above variable here so you don't have to call them everytime you need achievement data. 

var character = client.GetCharacter("doomhammer", "grendizer", true);
// Now we want to sort the achievements using the CompletedDate
// Since the data is returned as to separate arrays we will use the following overload of Array.Sort to sort achievements
// Array.Sort<TKey, TValue> Method (TKey[],TValue[])
// This way while sorting when the achievementDate is positioned, the corresponding achievement ID is also positioned
Array.Sort(character.Achievements.AchievmentsCompletedDatesUtc, character.Achievements.AchievementsCompleted);
int numberOfAchievementsToGet = 10;
// Get the latest 10 achievements (starting index from character.Achievements.AchievementsCompleted.Length - 10)
var latestAchievements = Enumerable.Range(character.Achievements.AchievementsCompleted.Length - numberOfAchievementsToGet, numberOfAchievementsToGet)
    .Select(i => 
        new {
            // lookup the achievements in the flatened achievements
            Achievement = flatenedCharacterAchievements.FirstOrDefault(achievement => achievement.Id == character.Achievements.AchievementsCompleted[i]),
            // lookup the date
            DateCompleted = character.Achievements.AchievmentsCompletedDatesUtc[i]
        }).Reverse().ToArray();

// This enumerator will loop all categories recursively and return all achievements
private static IEnumerable<Achievement> FlatenCharacterAchievements(IEnumerable<AchievementCategory> categories)
{
    if (categories != null)
    {
        // Loop all categories
        foreach (AchievementCategory category in categories)
        {
            // return all achievements
            if (category.Achievements != null)
            {
                foreach (Achievement achievement in category.Achievements)
                {
                    if (achievement != null)
                        yield return achievement;
                }
            }
            if (category.Categories != null)
            {
                // loop all sub categories of the category
                foreach (Achievement achievement in FlatenCharacterAchievements(category.Categories))
                {
                    if (achievement != null)
                        yield return achievement;
                }
            }
        }
    }
}

 

Sep 26, 2011 at 1:35 AM

By the way, I suppose I should make enhance the library to make it easier to get character achievement data without having to do write all the code above. Hopefully I will do this in the near future.

Sep 26, 2011 at 3:19 PM

Perfectly Brilliant!!

Thnx for not only answering but also taking time to create the code example!
It works like a charm :)

/cf