>> World of Warcraft Level System Utility/SDK Implementation Guide >> Pastebin - View this script with highlighting. 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. */ Code: using System; using Server; using Server.Items; using Server.Mobiles; using Server.Network; namespace Server.WoW { /// /// 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 /// public enum LevelColor { Grey = 946, Green = 243, Yellow = 53, Orange = 58, Red = 34, Skull = 144 } /// /// Experience bases for NPCs' of levels that would be found in these zones /// Azeroth (1->58->63~), /// Outland (57->68->73~), /// Northrend (67->83) /// public enum ZoneXPBase { Azeroth = 45, Outland = 235, Northrend = 580 } public class LevelUtility { /// /// Factors provided for experience gain calculation /// EliteXPFactor default: 2 (effectively doubles base XP) /// RestedXPFactor default: 2 (effectively doubles base XP) /// public const double EliteXPFactor = 2, RestedXPFactor = 2; /// /// Computes the amount of Experience required to reach the next level /// /// (int) The current level of the player /// (ZoneXPBase) The zone XP base to use during calculation /// (int) The total amount of experience required to reach the next level public static int ComputeExperienceReq(int playerLevel, ZoneXPBase xpZone) { return (int)Round((double)(((8 * playerLevel) + XPDiffReduction(playerLevel)) * XPFromNPC(playerLevel, playerLevel, xpZone) * XPReductionFactor(playerLevel)), -2); } /// /// 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 /// /// (int) The level from which to compute from /// (int) The level from which to compute to /// (ZoneXPBase) The zone XP base to use during calculation /// (int) The total amount of experience required to reach endLevel from startLevel 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; } /// /// Computes the experience gain potential /// Example: Killing an NPC /// /// (int) The current level of the player that is gaining the experience /// (int) The current level of the NPC that is providing the experience /// (bool) If the player is 'rested', the experience will be factored according to (double)WowLevelUtility.RestedXPFactor /// (bool) If the NPC is 'elite', the experience will be factored according to (double)WoWLevelUtility.EliteXPFactor /// (ZoneXPBase) The zone XP base to use during calculation /// (double) The total amount of experience that can potentially be gained from an NPC accroding to player & NPC level matching. 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; } /// /// Gets the level 'color' associated with World of Warcrafts' "Grey to Skull" scale. /// Obligatory He-man citation needed. /// /// (int) The current level of the player 'targeting' the NPC. /// (int) The current level of the NPC that is being 'targeted' by the player. /// (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. 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; } } } } } } /// /// Computes the amount of experience that an NPC may supply /// /// (int) The current level of the player /// (int) The current level of the NPC /// (ZoneXPBase) The zone XP base to use during calculation /// (double) The amount of experience that an NPC may supply 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; } /// /// Calculates the level difference threshold for gaining zero XP /// /// (int) The current level of the player /// (int) The level difference threshold for gaining zero XP 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; } /// /// Calculates the 'Grey Level' /// The 'Grey Level' is the highest level at which an NPC may not grant experience /// /// (int) The current level of the player /// (int) The highest level at which experience will not be granted 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; } /// /// Calculates the factor of XP reduction to implement difficulty scaling /// Effective from level 28 to 59 /// /// (int) The current level of the player /// (double) The factor of XP reduction to implement difficulty scaling (Effective for level 28 to 59 only) 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; } /// /// Calculates the factor of XP reduction to implement advanced difficulty scaling /// Effective for all levels /// /// (int) The current level of the player /// (double) The factor of XP reduction to implement advanced difficulty scaling (Effective for all levels) 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; } /// /// 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 /// /// (double) The value to round /// (int) Digits must be between -15 and 15 /// (double) The rounded value 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; } } } Attached Files: