RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

[RUO X] World of Warcraft Level System Utility/SDK

Vorspire

Knight
>> World of Warcraft Level System Utility/SDK Implementation Guide

>> Pastebin - View this script with highlighting.

Rich (BB code):
/*
 * Name:		World of Warcraft Level System Utility (Pre-LK with LK estimations)
 * Version:		1.0.0.0
 * License:		GNU/GPL
 * Support:	RunUO x
 * Author:		Vorspire
 * Date:		02-05-09 (2nd May, 2009)
 * Server:		Rhovanion-PK: CORE
 * Website:	http://www.rpk-uo.com
 * Research:	Based on algorithms provided at http://www.wowwiki.com/Formulas:XP_To_Level
 * Summary:
 *
 * A simple library of simple utilities using algorithms designed to emulate aspects
 * of the level system used in World of Warcraft.
 *
 * This utility package (SDK) is *NOT* a level system. It was designed to provide a means
 * for developers to develop a WoW-based level system without having to decipher all
 * of the formulae and equations associated with WoW's level system.
 *
 * As of now, this SDK provides accuracy up to level 70, anything above level 70 is
 * found by educated estimation.
 *
 * Everything you need to know about each function has been decribed using documentation
 * nodes for easy-reading and to enhance your understanding by providing correct IDE
 * tooltips when using professional development software(s).
 *
 * Feel free to redistribute/update/edit as you like.
 * Some tweaks may be required for full LK support.
*/
Rich (BB code):
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Network;

namespace Server.WoW
{
	/// <summary>
	/// The 'Grey to Skull' Level Color scale as used in World of Warcraft
	/// Key values represent the UO hue relevant to the Key names
	/// 'Skull' is represented by a dark-red
	/// </summary>
	public enum LevelColor
	{
		Grey = 946,
		Green = 243,
		Yellow = 53,
		Orange = 58,
		Red = 34,
		Skull = 144
	}

	/// <summary>
	/// Experience bases for NPCs' of levels that would be found in these zones
	/// Azeroth (1->58->63~),
	/// Outland (57->68->73~),
	/// Northrend (67->83)
	/// </summary>
	public enum ZoneXPBase
	{
		Azeroth = 45,
		Outland = 235,
		Northrend = 580
	}

	public class LevelUtility
	{
		/// <summary>
		/// Factors provided for experience gain calculation
		/// EliteXPFactor default: 2 (effectively doubles base XP)
		/// RestedXPFactor default: 2 (effectively doubles base XP)
		/// </summary>
		public const double
			EliteXPFactor = 2,
			RestedXPFactor = 2;

		/// <summary>
		/// Computes the amount of Experience required to reach the next level
		/// </summary>
		/// <param name="playerLevel">(int) The current level of the player</param>
		/// <param name="xpZone">(ZoneXPBase) The zone XP base to use during calculation</param>
		/// <returns>(int) The total amount of experience required to reach the next level</returns>
		public static int ComputeExperienceReq(int playerLevel, ZoneXPBase xpZone)
		{
			return (int)Round((double)(((8 * playerLevel) + XPDiffReduction(playerLevel)) * XPFromNPC(playerLevel, playerLevel, xpZone) * XPReductionFactor(playerLevel)), -2);
		}

		/// <summary>
		/// Recursively computes the total amount of experience required to reach endLevel from startLevel
		/// endLevel can not be less than, or equal to startLevel, if this occurs, endLevel will be corrected to equal startLevel + 1
		/// </summary>
		/// <param name="startLevel">(int) The level from which to compute from</param>
		/// <param name="endLevel">(int) The level from which to compute to</param>
		/// <param name="xpZone">(ZoneXPBase) The zone XP base to use during calculation</param>
		/// <returns>(int) The total amount of experience required to reach endLevel from startLevel</returns>
		public static int ComputeExperienceReq(int startLevel, int endLevel, ZoneXPBase xpZone)
		{
			int xpReq = 0;

			if (startLevel < 1)
				startLevel = 1;

			if (endLevel <= startLevel)
				endLevel = startLevel + 1;

			for (int i = startLevel; i < endLevel; i++)
			{
				xpReq += ComputeExperienceReq(i, xpZone);
			}

			return xpReq;
		}

		/// <summary>
		/// Computes the experience gain potential
		/// Example: Killing an NPC
		/// </summary>
		/// <param name="playerLevel">(int) The current level of the player that is gaining the experience</param>
		/// <param name="npcLevel">(int) The current level of the NPC that is providing the experience</param>
		/// <param name="rested">(bool) If the player is 'rested', the experience will be factored according to (double)WowLevelUtility.RestedXPFactor</param>
		/// <param name="elite">(bool) If the NPC is 'elite', the experience will be factored according to (double)WoWLevelUtility.EliteXPFactor</param>
		/// <param name="xpZone">(ZoneXPBase) The zone XP base to use during calculation</param>
		/// <returns>(double) The total amount of experience that can potentially be gained from an NPC accroding to player & NPC level matching.</returns>
		public static double ComputeExperienceGain(int playerLevel, int npcLevel, bool rested, bool elite, ZoneXPBase xpZone)
		{
			double baseXP = XPFromNPC(playerLevel, npcLevel, xpZone);

			if (elite)
				baseXP *= EliteXPFactor;

			if (rested)
				baseXP *= RestedXPFactor;

			return baseXP;
		}

		/// <summary>
		/// Gets the level 'color' associated with World of Warcrafts' "Grey to Skull" scale.
		/// Obligatory He-man citation needed.
		/// </summary>
		/// <param name="playerLevel">(int) The current level of the player 'targeting' the NPC.</param>
		/// <param name="npcLevel">(int) The current level of the NPC that is being 'targeted' by the player.</param>
		/// <returns>(WowLevelColor) The level 'color' associated with World of Warcrafts' 'Grey to Skull' scale.
		/// Incidentally, the value name returned also translates into the correct hue id number for use with text.</returns>
		public static LevelColor GetLevelColor(int playerLevel, int npcLevel)
		{
			if (playerLevel + 5 <= npcLevel)
			{
				if (playerLevel + 10 <= npcLevel)
				{
					return LevelColor.Skull;
				}
				else
				{
					return LevelColor.Red;
				}
			}
			else
			{
				switch (npcLevel - playerLevel)
				{
					case 4: { return LevelColor.Orange; }
					case 3: { return LevelColor.Orange; }
					case 2: { return LevelColor.Yellow; }
					case 1: { return LevelColor.Yellow; }
					case 0: { return LevelColor.Yellow; }
					case -1: { return LevelColor.Yellow; }
					case -2: { return LevelColor.Yellow; }
					default:
						if (playerLevel <= 5)
						{
							return LevelColor.Green;
						}
						else
						{
							if (playerLevel <= 39)
							{
								if (npcLevel <= (playerLevel - 5 - Math.Floor((double)(playerLevel / 10))))
								{
									return LevelColor.Grey;
								}
								else
								{
									return LevelColor.Green;
								}
							}
							else
							{
								if (npcLevel <= (playerLevel - 1 - Math.Floor((double)(playerLevel / 5))))
								{
									return LevelColor.Grey;
								}
								else
								{
									return LevelColor.Green;
								}
							}
						}
				}
			}
		}

		/// <summary>
		/// Computes the amount of experience that an NPC may supply
		/// </summary>
		/// <param name="playerLevel">(int) The current level of the player</param>
		/// <param name="npcLevel">(int) The current level of the NPC</param>
		/// <param name="xpZone">(ZoneXPBase) The zone XP base to use during calculation</param>
		/// <returns>(double) The amount of experience that an NPC may supply</returns>
		public static double XPFromNPC(int playerLevel, int npcLevel, ZoneXPBase xpZone)
		{
			double baseXP = 0.0;

			if (GetLevelColor(playerLevel, npcLevel) == LevelColor.Grey)
				return baseXP;

			baseXP = (int)xpZone + (5 * playerLevel);

			if (npcLevel < playerLevel && npcLevel > ZeroXPLevel(playerLevel))
			{
				return baseXP * (1 - (playerLevel - npcLevel) / XPZeroDiff(playerLevel));
			}
			else if (npcLevel > playerLevel)
			{
				return baseXP * (1 + 0.05 * (npcLevel - playerLevel));
			}

			return baseXP;
		}

		/// <summary>
		/// Calculates the level difference threshold for gaining zero XP
		/// </summary>
		/// <param name="playerLevel">(int) The current level of the player</param>
		/// <returns>(int) The level difference threshold for gaining zero XP</returns>
		public static int XPZeroDiff(int playerLevel)
		{
			if (playerLevel <= 7)
			{
				return 5;
			}
			else if (playerLevel >= 8 && playerLevel <= 9)
			{
				return 6;
			}
			else if (playerLevel >= 10 && playerLevel <= 11)
			{
				return 7;
			}
			else if (playerLevel >= 12 && playerLevel <= 15)
			{
				return 8;
			}
			else if (playerLevel >= 16 && playerLevel <= 19)
			{
				return 9;
			}
			else if (playerLevel >= 20 && playerLevel <= 29)
			{
				return 11;
			}
			else if (playerLevel >= 30 && playerLevel <= 39)
			{
				return 12;
			}
			else if (playerLevel >= 40 && playerLevel <= 44)
			{
				return 13;
			}
			else if (playerLevel >= 45 && playerLevel <= 49)
			{
				return 14;
			}
			else if (playerLevel >= 50 && playerLevel <= 54)
			{
				return 15;
			}
			else if (playerLevel >= 55 && playerLevel <= 59)
			{
				return 16;
			}
			else if (playerLevel >= 60 && playerLevel <= 79)
			{
				return 17;
			}
			else if (playerLevel >= 80)
			{
				return 18;
			}

			return 0;
		}

		/// <summary>
		/// Calculates the 'Grey Level'
		/// The 'Grey Level' is the highest level at which an NPC may not grant experience
		/// </summary>
		/// <param name="playerLevel">(int) The current level of the player</param>
		/// <returns>(int) The highest level at which experience will not be granted</returns>
		public static int ZeroXPLevel(int playerLevel)
		{
			if (playerLevel <= 5)
			{
				return 0;
			}
			else if (playerLevel >= 6 && playerLevel <= 39)
			{
				return (int)(playerLevel - Math.Floor((double)(playerLevel / 10)) - 5);
			}
			else if (playerLevel >= 40 && playerLevel <= 59)
			{
				return (int)(playerLevel - Math.Floor((double)(playerLevel / 5)) - 1);
			}
			else if (playerLevel >= 60)
			{
				return (int)(playerLevel - 9);
			}

			return 0;
		}

		/// <summary>
		/// Calculates the factor of XP reduction to implement difficulty scaling
		/// Effective from level 28 to 59
		/// </summary>
		/// <param name="playerLevel">(int) The current level of the player</param>
		/// <returns>(double) The factor of XP reduction to implement difficulty scaling (Effective for level 28 to 59 only)</returns>
		public static double XPDiffReduction(int playerLevel)
		{
			if (playerLevel <= 28)
			{
				return 0;
			}
			else if (playerLevel == 29)
			{
				return 1;
			}
			else if (playerLevel == 30)
			{
				return 3;
			}
			else if (playerLevel == 31)
			{
				return 6;
			}
			else if (playerLevel >= 32 && playerLevel <= 59)
			{
				return 5 * (playerLevel - 30);
			}

			return 0;
		}

		/// <summary>
		/// Calculates the factor of XP reduction to implement advanced difficulty scaling
		/// Effective for all levels
		/// </summary>
		/// <param name="playerLevel">(int) The current level of the player</param>
		/// <returns>(double) The factor of XP reduction to implement advanced difficulty scaling (Effective for all levels)</returns>
		public static double XPReductionFactor(int playerLevel)
		{
			if (playerLevel <= 10)
			{
				return 1;
			}
			else if (playerLevel >= 11 && playerLevel <= 27)
			{
				return (1 - (playerLevel - 10) / 100);
			}
			else if (playerLevel >= 28 && playerLevel <= 59)
			{
				return 0.82;
			}
			else if (playerLevel >= 60)
			{
				return 1;
			}

			return 1;
		}

		/// <summary>
		/// Provides a means to round (double) values to X amount of digits
		/// All experience requirements are scaled to the nearest 100
		/// Example: Round( 1584.82, -2 ); would return (double) 1600.00
		/// </summary>
		/// <param name="value">(double) The value to round</param>
		/// <param name="digits">(int) Digits must be between -15 and 15</param>
		/// <returns>(double) The rounded value</returns>
		public static double Round(double value, int digits)
		{
			if ((digits < -15) || (digits > 15))
				return value;

			if (digits >= 0)
				return Math.Round(value, digits);

			double n = Math.Pow(10, -digits);

			return Math.Round(value / n, 0) * n;
		}
	}
}
 

Attachments

  • WoWLevelUtility.cs
    12.1 KB · Views: 190

Vorspire

Knight
wlrdwawoolard;799145 said:
soooo how you use it. i have added it and cant find no commands or objects can you explain more please:confused:

No commands? - There isn't supposed to be any!
Did you even take the time to read the description before you downloaded the script?
Did you not notice that EVERY method has annotation and explains exactly how to use it and what it is for?
Did you notice that this system is NOT a level system?
Did you notice the comment that states this was "designed for developers"?

Answer yes to all of these and win a slice of cake!

You use this to develop your own WoW-style level system :)

Simples.
 

jacquesc1

Sorceror
Vorspire;799157 said:
No commands? - There isn't supposed to be any!
Did you even take the time to read the description before you downloaded the script?
Did you not notice that EVERY method has annotation and explains exactly how to use it and what it is for?
Did you notice that this system is NOT a level system?
Did you notice the comment that states this was "designed for developers"?

Answer yes to all of these and win a slice of cake!

You use this to develop your own WoW-style level system :)

Simples.

im no developer can you mabey make it so it works for the peeps that cant do coding to work aswell :)
 

wlrdwawoolard

Sorceror
well okay and yes i read it didnt say anything about make your own :/ need to be more clearer with scripts so people know what and how you use it for
and dont think i didnt notice u edited wat the script says ;)
 

old_school

Wanderer
Little Harsh comments.

Well im kinda Dev I guess at this point lol Im still puzzled my self a little on the system. An yes I read your post. Its a level system. Well do we edit anything? Is it drag an drop? Does it take effect instantly? Whats included just one script or is it a package? Etc.

Think about it this way. You may know what it does and understand. But were all cluess. Yes I know the pot calling the kettle black cause Im not the most descriptive in my post. But damn I dont jump people for asking lol. You have to understand if we put this on a server we need a Full description of what it does and how its used.

I mean it looks like a great concept. An I personaly been looking for something simple for pets leveling wise. So it could be useful. But we all dont know what the hell it is lol. I see its a level system. Great. How high you go? Whats the exp levels? etc. lol We need to know.
 

Vorspire

Knight
OK, I guess I should dumb the descriptive comments down a little next time, but this script isn't for beginners, so really, I don't have to describe anything more than what is already said in the first post.

If you can't understand what the comments mean, you should really learn about key words in C# before attempting to work with any script.

Here's a little help for newer developers: C# Keywords (C#)

OK, now for a small implimentation guide for this system...

http://www.runuo.com/forums/custom-...-system-utility-sdk-implimentation-guide.html
 

jacquesc1

Sorceror
thx Vorspire this is most helpfull to the newbs out there (talking abouth my self aswell) :)
and thx for all the great scrips you make for runuo your the best
 

Vorspire

Knight
I'm glad to help out :)

As for the comments I made earlier, if anyone was offended by them, I apologise for that, but I did provide a lot of information with the original post, minus the guide ;)
 

jacquesc1

Sorceror
Vorspire;799383 said:
I'm glad to help out :)

As for the comments I made earlier, if anyone was offended by them, I apologise for that, but I did provide a lot of information with the original post, minus the guide ;)

:)we love your scrips and your responses to them aswell:)
 
Top