Achievement System

zerodowned

Moderator
ServUO Developer
Jun 28, 2014
1,770
221
Sorry, can't read what's on the gump. What does the system track?
 

dmurphy

Admin
ServUO Developer
Feb 10, 2014
1,017
233
30
Looks very nice.

I actually have planned an achievement system myself that I will be releasing here once finished (probably after xmas)
 
  • Like
Reactions: Greed

frankieowns

Active Member
Sep 30, 2013
28
1
42
Shard Name
uoadventure
Donate
Donate money to this user
Ive been looking for this all over and it looks just how id like it. to bad you cant share matey :(
 

Crome969

Well-Known Member
Jan 9, 2014
195
20
32
Germany
www.RebirthUO.com
Shard Name
RebirthUO
Donate
Donate money to this user
The interface (Gump) is not the problem just the amount of Spots to customize. So i can understand that the Author dont want to publish all files or documentate.
I guess a final solution would be a simple framework, allowing to add new Entries to a generic UI and then let the user do the counting etc. That alone would help a few users i think.
 

dmurphy

Admin
ServUO Developer
Feb 10, 2014
1,017
233
30
That is the plan. It is actually almost finished. It is a fully modular system where you can drop in new achievements and it updates the whole system automatically. It also requires no distro edits!

I have finals in a few weeks so when they are finished then I will get this finished
 
  • Like
Reactions: Hank

Tresdni

Well-Known Member
Mar 10, 2013
93
37
36
I could just release the original that I had mentioned before everyone started making these new ones lol. Didn't realize the idea would blow up so big :)
 

dmurphy

Admin
ServUO Developer
Feb 10, 2014
1,017
233
30
Go ahead! I am sure people would love to use it :)

Mine was more of an experiment on my part that turned into a pretty big system in the end. Would love to compare with a completed system.

Edit: Didn't mean to thumbs down your post :O misclick!
 

Exale

Well-Known Member
Mar 2, 2014
230
21
38
Wisconsin
Shard Name
Mystical Nights
I have been wanting something like this for a while but it is very much outside my abilities. Don't just tease us lol. Any chance of a release of it soon since none other exist in the wild? This is directed at bother dmuprhy and Tresdni. :)
 

Unleashed

Active Member
May 17, 2015
27
9
I say this almost a joke. every shard is getting one and no one shares the code. Exale I wouldn't expect to see this anytime soon.
 
  • Like
Reactions: Exale

The_Real_Jeff

Well-Known Member
May 9, 2015
108
30
38
California
The hard part about sharing an achievement system would be making it easy to install. Achievements can happen all through-out the scripts, so making a system that doesn't require editing of core/script scripts, is pretty much near impossible. This makes supporting a shared Achievement system really difficult. I'll give you an example.

Lets say you wanted to give someone an achievement based on killing a specific mob. Theres really no good way to get notification of this unless you either override OnDeath on that specific Mob, or goto the Mobile.cs script in the Core, and edit OnDeath to notify your Achievement system (which would require your achievement system to reside in the core) or create a new event inside EventSink to allow notification of such events (In either case, a core edit... not advised).

The system itself would be extremely easy to make. Probably a simple script that tracked player achievements by id, could get simple notification with something like:
Code:
Achievements.Push("My Achievement Id", player);
This would either Add the achievement to the player, or up the count for the achievement if its a count based one.

Ideally you want someone to make a simple system that has no scripted achievements, containing Simple Gump setup and a single easy to make call to push and achievement to the player, then you can add the achievements manually as you see fit.
 

Crome969

Well-Known Member
Jan 9, 2014
195
20
32
Germany
www.RebirthUO.com
Shard Name
RebirthUO
Donate
Donate money to this user
I also think the most required thing would be a framework, so you can Push you own content to it. The details like What achievements you have are not necessary, but the framework easy add it.
 
  • Like
Reactions: Exale

dmurphy

Admin
ServUO Developer
Feb 10, 2014
1,017
233
30
The hard part about sharing an achievement system would be making it easy to install. Achievements can happen all through-out the scripts, so making a system that doesn't require editing of core/script scripts, is pretty much near impossible. This makes supporting a shared Achievement system really difficult. I'll give you an example.

Lets say you wanted to give someone an achievement based on killing a specific mob. Theres really no good way to get notification of this unless you either override OnDeath on that specific Mob, or goto the Mobile.cs script in the Core, and edit OnDeath to notify your Achievement system (which would require your achievement system to reside in the core) or create a new event inside EventSink to allow notification of such events (In either case, a core edit... not advised).

The system itself would be extremely easy to make. Probably a simple script that tracked player achievements by id, could get simple notification with something like:
Code:
Achievements.Push("My Achievement Id", player);
This would either Add the achievement to the player, or up the count for the achievement if its a count based one.

Ideally you want someone to make a simple system that has no scripted achievements, containing Simple Gump setup and a single easy to make call to push and achievement to the player, then you can add the achievements manually as you see fit.
Actually, a ton of achievements can be made without having to edit the distro by using the eventsink.

Check out this achievement from my system that requires you to kill x amount of ratmen. The system is not finished or I would share it but I am sure someone can see from this how it is done and work it out them self. If I had time I would and release it.

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using Server.Engines.XmlSpawner2;
using Server.Mobiles;

namespace Server.Achievements.MonsterHunt
{
    class ratmen
    {
        public static int ID = 0;// MUST BE UNIQUE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

        public static string category = "Monster Hunter";

        private static int[] levelAmounts = {100, 500, 1000, 5000, 10000};

        private static string[,] rewards =
        {
            {"Gold", "500"},
            {"Gold", "10000"},
            {"Gold", "20000"},
            {"Gold", "30000"},
            {"Gold", "60000"}
        };

      

        private static readonly AchievementInfo m_Info = new AchievementInfo(
            "Ratmen",
            "Prove yourself as a true RatMan slayer and slay the required amount of ratmen warriors, mages and archers!",
            levelAmounts.Length,
            levelAmounts, rewards, ID, category);


        public static void Initialize()
        {
            EventSink.OnKilledBy += EventSinkOnOnKilledBy;
            AchievementInfo.aList.Add(m_Info);
            if (!AchievementInfo.categories.Exists(e => e == category))
                AchievementInfo.categories.Add(category);

        }

        private static void EventSinkOnOnKilledBy(OnKilledByEventArgs e)
        {
            Mobile pm = e.KilledBy;
            Mobile m = e.Killed;


            var a = (AchievementAttachment)XmlAttach.FindAttachment(pm, typeof(AchievementAttachment));
            List<int> dvalue = a.data[ID];
            if (((BaseCreature)m).ControlMaster != null || ((BaseCreature)m).Summoned) return;
            if ((!(m is Ratman) && !(m is RatmanArcher) && !(m is RatmanMage)) || dvalue[0] > 10000) return;
            dvalue[0]++;

            foreach (int t in levelAmounts.Where(t => dvalue[0] == t))
            {

                dvalue[1]++;
                pm.SendMessage(50, "Achievement Unlocked!");
            }
        }
    }


}
I have made other achievement types too such as enter a certain location and all without having to edit the distro.

EDIT. It needs some work even in that script, initially I was using an array to hold all the achievement information but because there was so many achievments the array got quite large and as it was an object added to each playermobile object it would end up using a lot of resources on some shards, I was working on that problem the last time I was working on it, i had it almost cracked. I might get back to it soon and release what I have.
 
Last edited:

The_Real_Jeff

Well-Known Member
May 9, 2015
108
30
38
California
Actually, a ton of achievements can be made without having to edit the distro by using the eventsink.

Check out this achievement from my system that requires you to kill x amount of ratmen. The system is not finished or I would share it but I am sure someone can see from this how it is done and work it out them self. If I had time I would and release it.

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using Server.Engines.XmlSpawner2;
using Server.Mobiles;

namespace Server.Achievements.MonsterHunt
{
    class ratmen
    {
        public static int ID = 0;// MUST BE UNIQUE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

        public static string category = "Monster Hunter";

        private static int[] levelAmounts = {100, 500, 1000, 5000, 10000};

        private static string[,] rewards =
        {
            {"Gold", "500"},
            {"Gold", "10000"},
            {"Gold", "20000"},
            {"Gold", "30000"},
            {"Gold", "60000"}
        };

     

        private static readonly AchievementInfo m_Info = new AchievementInfo(
            "Ratmen",
            "Prove yourself as a true RatMan slayer and slay the required amount of ratmen warriors, mages and archers!",
            levelAmounts.Length,
            levelAmounts, rewards, ID, category);


        public static void Initialize()
        {
            EventSink.OnKilledBy += EventSinkOnOnKilledBy;
            AchievementInfo.aList.Add(m_Info);
            if (!AchievementInfo.categories.Exists(e => e == category))
                AchievementInfo.categories.Add(category);

        }

        private static void EventSinkOnOnKilledBy(OnKilledByEventArgs e)
        {
            Mobile pm = e.KilledBy;
            Mobile m = e.Killed;


            var a = (AchievementAttachment)XmlAttach.FindAttachment(pm, typeof(AchievementAttachment));
            List<int> dvalue = a.data[ID];
            if (((BaseCreature)m).ControlMaster != null || ((BaseCreature)m).Summoned) return;
            if ((!(m is Ratman) && !(m is RatmanArcher) && !(m is RatmanMage)) || dvalue[0] > 10000) return;
            dvalue[0]++;

            foreach (int t in levelAmounts.Where(t => dvalue[0] == t))
            {

                dvalue[1]++;
                pm.SendMessage(50, "Achievement Unlocked!");
            }
        }
    }


}
I have made other achievement types too such as enter a certain location and all without having to edit the distro.

EDIT. It needs some work even in that script, initially I was using an array to hold all the achievement information but because there was so many achievments the array got quite large and as it was an object added to each playermobile object it would end up using a lot of resources on some shards, I was working on that problem the last time I was working on it, i had it almost cracked. I might get back to it soon and release what I have.
Wasn't saying its not possible without distro edits. But there are some big obvious achievements where distro/core edits are needed. OnKilledBy on eventsink, thats not stock RunUO and I wasnt aware ServUO had it. I suppose ServUO might have a lot of core edits that make this possible which is nice. :)