Humzie

Citizen
I would like to get this running on my project and we are using RunUO 2.7 - anyone come across these errors below(attachment)?
 

Attachments

  • unknown.png
    unknown.png
    46.3 KB · Views: 17

tass23

Knight
I was able to get this system working on my old core, which is not running the latest DotNet framework, which is also half the problem people with older cores are having. Some coding changes in versions make merging the EventSinks problematic. The two that cause issue here are
=> and { get; }.
DotNet version code changes:
=> also equals { get { return X; } } -> for example { get { return m_From; } }
{ get; } also equals { get; private set; } -> for example public Mobile Harvester { get; private set; }

The other half is related to EventSinks added in the ServUO repos that are not in the older 'shard Server->EventSink.cs file. These can be merged into an older EventSink.cs, but the calls to the EventSinks must still be added into the Scripts. Whereas ServUO repos have the code already in place for the new EventSinks.

An EventSink is when something specific occurs in-game, like successfully crafting an item, or logging it and out. Newer versions of ServUO repos have more EventSinks added, which means not only merging in the data from EventSink.cs, but also looking in the Scripts folder to merge the Distro calls for the new EventSinks.

Guide to installing Mythik Achievement System to a 'shard core running DotNet < 4.8, using ServUO Pub 57 repo as a foundation:
1. The Server folder contains the EventSink.cs file. Open both EventSink.cs files "side-by-side", using a program such as WinMerge. Sometimes the merges are nice and clean, but if the EventSink is much older, the merge might be a lot more complex, so in the event of a messy merge, use Notepad++ to open both files and then copy/paste entire sections of code from ServUO's repo into the older core. Note the version code changes mentioned above!

2. If you do not have the Playermobile edits, you will have to use the define STOREITEM <--- This is what creates the AchievementSystemMemoryStone in the next step.
Drag/Drop Mythik Achievement System into Scripts->Customs and then open AchievementSystem.cs and remove the // at the very top from define STOREITEM and make the following changes to "force" the system to use the stone.
Scroll down a few lines and add // to the lines that say:
```
//#if STOREONITEM
//#else
//using Scripts.Mythik.Mobiles;
//#endif

#if STOREONITEM
if (!AchievementSystemMemoryStone.GetInstance().Achievements.ContainsKey(player.Serial))
AchievementSystemMemoryStone.GetInstance().Achievements.Add(player.Serial, new Dictionary<int, AchieveData>());
var achieves = AchievementSystemMemoryStone.GetInstance().Achievements[player.Serial];
var total = AchievementSystemMemoryStone.GetInstance().GetPlayerPointsTotal(player);
//#else
//var achieves = (player as MythikPlayerMobile).Achievements;
//var total = (player as MythikPlayerMobile).AchievementPointsTotal;
#endif

#if STOREONITEM
if (!AchievementSystemMemoryStone.GetInstance().Achievements.ContainsKey(player.Serial))
AchievementSystemMemoryStone.GetInstance().Achievements.Add(player.Serial, new Dictionary<int, AchieveData>());
var achieves = AchievementSystemMemoryStone.GetInstance().Achievements[player.Serial];
//#else
//var achieves = (player as MythikPlayerMobile).Achievements;
#endif
```

3. Next open AchievementSystemMemoryStone.cs and at the top where it says:
```
public static AchievementSystemMemoryStone GetInstance()
{
if (m_instance == null)
m_instance = new AchievementSystemMemoryStone();
m_instance.MoveToWorld(new Point3D(0, 0, 0), Map.Felucca); //<----- CHANGE THESE LOCATION COORDS
return m_instance;
}
```
If you do not change these coords, every time a player uses the command Feats, the stone will move to those coordinates. If you move the stone to another location, it will move back. You do not have to change the coords, but the stone will be at 0,0,0 in Felucca, which is the top corner of the ocean on the map.

The system is dependent upon EventSinks, so those need to be added in the proper locations.
4a. For the HarvestSystem.cs file and InvokeResourceHarvestSuccess, those changes are in BonusHarvestResource (bonusItem does not exist outside this method):
```
BonusHarvestResource bonus = def.GetBonusResource();
if ( bonus != null && bonus.Type != null && skillBase >= bonus.ReqSkill )
{
Item bonusItem = Construct( bonus.Type, from );

if ( Give( from, bonusItem, true ) ) //Bonuses always allow placing at feet, even if pack is full irregrdless of def
{
bonus.SendSuccessTo( from );
}
else
{
item.Delete();
}
#region ServUO Pub 57 for Mythik Achievement System
EventSink.InvokeResourceHarvestSuccess(new ResourceHarvestSuccessEventArgs(from, tool, item, bonusItem, this)); //<--- This means every time players harvest a *bonus* resource while mining, it will increase the ore count for the Achievement for that attempt only.
#endregion
}
```
4b. For BaseCreature.cs and InvokeOnKilledBy, those changes are in OnKilledBy:
```
public virtual void OnKilledBy(Mobile mob)
{
#region Mondain's Legacy
if (GivesMinorArtifact && Paragon.CheckArtifactChance(mob, this))
GiveMinorArtifact(mob);
#endregion
#region SA
if (GivesSAArtifact && Paragon.CheckArtifactChance(mob, this))
GiveSAArtifact(mob);
#endregion
#region ServUO Pub 57 Mythik Achievement System
EventSink.InvokeOnKilledBy(new OnKilledByEventArgs(this, mob));
#endregion
}
```
4c. For Server->Region.cs and Invoke OnEnterRegion, those changes are in OnRegionChange:
```
//Region oldR = oldRegion;
//Region newR = newRegion;
#region ServUO Pub 57 Mythik Achievement System
var oldR = oldRegion;
var newR = newRegion;
while (oldR != newR)
{
var oldRChild = oldR != null ? oldR.ChildLevel : -1;
var newRChild = newR != null ? newR.ChildLevel : -1;

if (oldRChild >= newRChild && oldR != null)
{
oldR.OnExit(m);
oldR = oldR.Parent;
}
if (newRChild >= oldRChild && newR != null)
{
newR.OnEnter(m);
EventSink.InvokeOnEnterRegion(new OnEnterRegionEventArgs(m, oldRegion, newR));
newR = newR.Parent;
}
}
#endregion
/*
while ( oldR != newR )
{
int oldRChild = ( oldR != null ? oldR.ChildLevel : -1 );
int newRChild = ( newR != null ? newR.ChildLevel : -1 );

if ( oldRChild >= newRChild )
{
oldR.OnExit( m );
oldR = oldR.Parent;
}

if ( newRChild >= oldRChild )
{
newR.OnEnter( m );
newR = newR.Parent;
}
}
*/
```
4d. For Crafting and Scripts->Services->Craft->CraftItem.cs, those changes are inside CheckSkills->item !=null, which is part of CompleteCraft:
```
if (item != null)...

from.AddToBackpack(item);

#region ServUO Pub 57 Mythik Achievement System
EventSink.InvokeCraftSuccess(new CraftSuccessEventArgs(from, item, tool is Item ? (Item)tool : null));
#endregion

from.PlaySound( 0x57 );
```

5. Editing the AchievementGump:
A good example of the menu structure is more easily noticeable if the code is staggered.
```
Categories.Add(new AchievementCategory(1, 0, "Exploration"));
Categories.Add(new AchievementCategory(2, 1, "Towns"));
Categories.Add(new AchievementCategory(3, 1, "Dungeons"));
Achievements.Add(new DiscoveryAchievement(0, 2, 0x14EB, false, null, "Minoc", "Discover Minoc Township", 5, "Minoc"));
```
The hierarchy is Exploration -> Towns | Dungeons ->Minoc. Notice the integers in the code: 1, 0, Exploration, 2, 1, Towns, 3, 1, Dungeons, 0, 2, Minoc. This is how the menus are connected together. Each Child adopts the Parent's number, so Exploration is the Parent (1), Towns | Dungeons are each a Child and a Parent and inherit from Parent (1) and provide for Child (2) and (3), and Minoc is a Child of Towns (2). If a dungeon is added, it would be a Child of Dungeons (3).

There is limited space vertically on the whole interface, so use that space as wisely as possible by nesting Achievements, but also note that you can only nest so far as well.

Each Achievement is structured in a similar fashion, for example DiscoveryAchievement:
var achieve = new HarvestAchievement(100, 7, 0, false, null, 100, "100 Iron Ore", "Mine up a bonus resource and increase the Iron Ore total to reach the goal.", 5, typeof(IronOre), typeof(Lettuce));
AchievementType(AchieveMentNumber, MenuParent, MenuPosition, itemIcon, HiddenUntilComplete (true/false), Pre-requisite or null, "MenuEntry", "Achievement Title", 5 <- Points earned when completed, typeof(IronOre)<-required object to complete, typeof(Lettuce)<-item awarded when complete.

If linking achievements together, create an entry for each var, increasing the value by +1,var1, var2, var3...then call that var in the next linked achievement, for example:
var achieve = new HarvestAchievement(100, 7, 0, false, null, 100, "100 Iron Ore", "Mine up a bonus resource and increase the Iron Ore total to reach the goal.", 5, typeof(IronOre), typeof(Lettuce));
Achievements.Add(achieve); //<--Entry added for var achieve above
Achievements.Add(new HarvestAchievement(101, 7, 1, false, achieve, 500, "500 Iron Ore", "Mine 500 Iron Ore for each bonus received.", 5, typeof(IronOre), typeof(Peach))); //VAR ^

Hopefully a lot more folks can get this system installed, because DL (darklotus) knocked this out of the park! It is an incredible benefit to any 'shard!
 
Last edited:

Carlos_ar

Gold Sponsor
I really like this system. I'm working on adding it to my little home away from home.

There are two things that always stick me... and for some reason I can never puzzle them out quickly as it seems they are different depending on the script.

The line is
UnmoddedLine:
Achievements.Add(new HunterAchievement(1001, 3000, 0x25D1, false, null, 100, "Dragon Slayer", "Slay 100 Dragon", 5, typeof(Dragon)));

I want to give gold as well as an item so with the item it's
StatueModed:
Achievements.Add(new HunterAchievement(1001, 3000, 0x25D1, false, null, 100, "Dragon Slayer", "Slay 100 Dragon", 5, typeof(Dragon), typeof(DragonStatue)));

To add the gold with an amount?
GoldModded:
Achievements.Add(new HunterAchievement(1001, 3000, 0x25D1, false, null, 100, "Dragon Slayer", "Slay 100 Dragon", 5, typeof(Dragon), typeof(DragonStatue), typeof(Gold, 1000)));

I tried that and a few other things, but that's the type of stuff that I get stuck on... that and bypassing the label numbers on things to add my own titles or text.
 

Shazzy

Citizen
This is something that is in the pay releases here so we will have to figure this out as a team !
change "points" to an item across the board
so if your 'points' are gold or a sovereign, whatever, then it just happens with no additional scripting.
have someone work on areas
skills
etc
if we separate the sections our productivity increases!
I'm in, who is with me?!

Shazzy :)
 

Carlos_ar

Gold Sponsor
This is something that is in the pay releases here so we will have to figure this out as a team !
change "points" to an item across the board
so if your 'points' are gold or a sovereign, whatever, then it just happens with no additional scripting.
have someone work on areas
skills
etc
if we separate the sections our productivity increases!
I'm in, who is with me?!

Shazzy :)
I'm not sure what you mean, but I am certainly down for anything :)
 

Visam

Squire
This is something that is in the pay releases here so we will have to figure this out as a team !
This isn't the pay release achievement system. Your thinking of:
 

Carlos_ar

Gold Sponsor
Still plugging away at this. For whatever reason it seems like these things should be so simple and I'm missing some key in my limited knowledge that isn't letting me see the solution.

Apparently simply calling typeof(DragonStatue) isnt going to work either... Still can't get the Sovereigns to show.

Completely stuck

Heh I've resorted to the only thing I know how to do, and that's to get books on C# and go learn. :) Wish me luck.
 

Carlos_ar

Gold Sponsor
Just discovered that this doesn't work. You never get more than the first typeof() item

Achievement Code:
Achievements.Add(new HunterAchievement(1001, 3000, 0x25D1, false, null, 1, "Dragon Slayer", "Slay 100 Dragon", 5, typeof(Dragon), typeof(MonsterStatuette), typeof(HeritageSovereign)));

Trying to grant a dragon statue and 10 sovereigns... cant figure how to do more than 1 sovereign and no matter how I changed the code I couldn't get it to do the dragon statue... this will drop the fiorst statue on the list (the aligator) but no sovereign. If I get rid of the typeof(MonsterStatuette) it will drop the sovereign.
 

jayates

Citizen
This looks like a nice system! I want to set the awards as Achievement Tokens though. I scripted the token... np. But, how would I set this system to awarding more than one token as in the example below, anyone? Here's that part of AchievementSystem.cs:
Achievements.Add(new HunterAchievement(1000, 3000, 0x25D1, false, null, 5, "Dog Slayer", "Slay 5 Dogs", 5, typeof(Dog), typeof(AchievementToken))); //awarding 5?
Achievements.Add(new HunterAchievement(1001, 3000, 0x25D1, false, null, 5, "Dragon Slayer", "Slay 5 Dragons", 5, typeof(Dragon), typeof(AchievementToken))); //awarding 10?
 
Last edited:

jayates

Citizen
This is something that is in the pay releases here so we will have to figure this out as a team !
change "points" to an item across the board
so if your 'points' are gold or a sovereign, whatever, then it just happens with no additional scripting.
have someone work on areas
skills
etc
if we separate the sections our productivity increases!
I'm in, who is with me?!

Shazzy :)
No posts since Jan so, I tried a stab at this.
I tried to change the "points" to an actual item... failed! So, here's my work around.
I commented out the area where it shows "Total Points and added my server name (since i'm not using the original points) in the AcievementGump.cs:
this.AddLabel(360, 11, 82," UOEV"); //total + @" Points");
Then created an AchievementTokenDeed and set it to be the reward for an Achievement in AchievementSystem.cs:
Achievements.Add(new HarvestAchievement(502, 2000, 0x0E85, false, achieve, 50, "50 Iron Ore", "Mine 50 Iron Ore", 1, typeof(IronOre), typeof(AchieveTokenDeed1))); //typeof(AncientSmithyHammer),typeof(TinkerTools),typeof(HatOfTheMagi)));
Deeds can be created for all rewards. Achievement Tokens can be used on a vendor stone.
Maybe this'll be useful?::rolleyes:
 

Attachments

  • AchieveTokenDeed1.cs
    1.6 KB · Views: 2
  • AchievementToken.cs
    868 bytes · Views: 2

Carlos_ar

Gold Sponsor
No posts since Jan so, I tried a stab at this.
I tried to change the "points" to an actual item... failed! So, here's my work around.
I commented out the area where it shows "Total Points and added my server name (since i'm not using the original points) in the AcievementGump.cs:
this.AddLabel(360, 11, 82," UOEV"); //total + @" Points");
Then created an AchievementTokenDeed and set it to be the reward for an Achievement in AchievementSystem.cs:
Achievements.Add(new HarvestAchievement(502, 2000, 0x0E85, false, achieve, 50, "50 Iron Ore", "Mine 50 Iron Ore", 1, typeof(IronOre), typeof(AchieveTokenDeed1))); //typeof(AncientSmithyHammer),typeof(TinkerTools),typeof(HatOfTheMagi)));
Deeds can be created for all rewards. Achievement Tokens can be used on a vendor stone.
Maybe this'll be useful?::rolleyes:
Are you working with the free version or the paid version?

I have both, and the paid version is incredibly robust and stable. The free version, I found didn't drop the items that it is coded to do. I'm not sure why. It compiles but doesn't actually work beyond triggering the fact that you completed the achievement.
 

jayates

Citizen
Working with the free version at the moment. I also have the paid version but, it won't work with my version on ServUO (Land Of Archon) which is apparently close to RunUO. Maybe I should just plug through it and try to figure it out. The author said he didn't have a version of it for RunUO.