Advertisement
Guest User

Vorspire

a guest
May 4th, 2009
203
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 12.02 KB | None | 0 0
  1. /*
  2.  * Name:        World of Warcraft Level System Utility (Pre-LK with LK estimations)
  3.  * Version:     1.0.0.0
  4.  * License:     GNU/GPL
  5.  * Support: RunUO x
  6.  * Author:      Vorspire
  7.  * Date:        02-05-09 (2nd May, 2009)
  8.  * Server:      Rhovanion-PK: CORE
  9.  * Website: http://www.rpk-uo.com
  10.  * Research:    Based on algorithms provided at http://www.wowwiki.com/Formulas:XP_To_Level
  11.  * Summary:
  12.  *
  13.  * A simple library of simple utilities using algorithms designed to emulate aspects
  14.  * of the level system used in World of Warcraft.
  15.  *
  16.  * This utility package (SDK) is *NOT* a level system. It was designed to provide a means
  17.  * for developers to develop a WoW-based level system without having to decipher all
  18.  * of the formulae and equations associated with WoW's level system.
  19.  *
  20.  * As of now, this SDK provides accuracy up to level 70, anything above level 70 is
  21.  * found by educated estimation.
  22.  *
  23.  * Everything you need to know about each function has been decribed using documentation
  24.  * nodes for easy-reading and to enhance your understanding by providing correct IDE
  25.  * tooltips when using professional development software(s).
  26.  *
  27.  * Feel free to redistribute/update/edit as you like.
  28.  * Some tweaks may be required for full LK support.
  29. */
  30.  
  31. using System;
  32.  
  33. namespace WoW
  34. {
  35.     /// <summary>
  36.     /// The 'Grey to Skull' Level Color scale as used in World of Warcraft
  37.     /// Key values represent the UO hue relevant to the Key names
  38.     /// 'Skull' is represented by a dark-red
  39.     /// </summary>
  40.     public enum LevelColor
  41.     {
  42.         Grey = 946,
  43.         Green = 243,
  44.         Yellow = 53,
  45.         Orange = 58,
  46.         Red = 34,
  47.         Skull = 144
  48.     }
  49.  
  50.     /// <summary>
  51.     /// Experience bases for NPCs' of levels that would be found in these zones
  52.     /// Azeroth (1->58->63~),
  53.     /// Outland (57->68->73~),
  54.     /// Northrend (67->83)
  55.     /// </summary>
  56.     public enum ZoneXPBase
  57.     {
  58.         Azeroth = 45,
  59.         Outland = 235,
  60.         Northrend = 580
  61.     }
  62.  
  63.     public class LevelUtility
  64.     {
  65.         /// <summary>
  66.         /// Factors provided for experience gain calculation
  67.         /// EliteXPFactor default: 2 (effectively doubles base XP)
  68.         /// RestedXPFactor default: 2 (effectively doubles base XP)
  69.         /// </summary>
  70.         public const double
  71.             EliteXPFactor = 2,
  72.             RestedXPFactor = 2;
  73.  
  74.         /// <summary>
  75.         /// Computes the amount of Experience required to reach the next level
  76.         /// </summary>
  77.         /// <param name="playerLevel">(int) The current level of the player</param>
  78.         /// <param name="xpZone">(ZoneXPBase) The zone XP base to use during calculation</param>
  79.         /// <returns>(int) The total amount of experience required to reach the next level</returns>
  80.         public static int ComputeExperienceReq(int playerLevel, ZoneXPBase xpZone)
  81.         {
  82.             return (int)Round((double)(((8 * playerLevel) + XPDiffReduction(playerLevel)) * XPFromNPC(playerLevel, playerLevel, xpZone) * XPReductionFactor(playerLevel)), -2);
  83.         }
  84.  
  85.         /// <summary>
  86.         /// Recursively computes the total amount of experience required to reach endLevel from startLevel
  87.         /// endLevel can not be less than, or equal to startLevel, if this occurs, endLevel will be corrected to equal startLevel + 1
  88.         /// </summary>
  89.         /// <param name="startLevel">(int) The level from which to compute from</param>
  90.         /// <param name="endLevel">(int) The level from which to compute to</param>
  91.         /// <param name="xpZone">(ZoneXPBase) The zone XP base to use during calculation</param>
  92.         /// <returns>(int) The total amount of experience required to reach endLevel from startLevel</returns>
  93.         public static int ComputeExperienceReq(int startLevel, int endLevel, ZoneXPBase xpZone)
  94.         {
  95.             int xpReq = 0;
  96.  
  97.             if (startLevel < 1)
  98.                 startLevel = 1;
  99.  
  100.             if (endLevel <= startLevel)
  101.                 endLevel = startLevel + 1;
  102.  
  103.             for (int i = startLevel; i < endLevel; i++)
  104.             {
  105.                 xpReq += ComputeExperienceReq(i, xpZone);
  106.             }
  107.  
  108.             return xpReq;
  109.         }
  110.  
  111.         /// <summary>
  112.         /// Computes the experience gain potential
  113.         /// Example: Killing an NPC
  114.         /// </summary>
  115.         /// <param name="playerLevel">(int) The current level of the player that is gaining the experience</param>
  116.         /// <param name="npcLevel">(int) The current level of the NPC that is providing the experience</param>
  117.         /// <param name="rested">(bool) If the player is 'rested', the experience will be factored according to (double)WowLevelUtility.RestedXPFactor</param>
  118.         /// <param name="elite">(bool) If the NPC is 'elite', the experience will be factored according to (double)WoWLevelUtility.EliteXPFactor</param>
  119.         /// <param name="xpZone">(ZoneXPBase) The zone XP base to use during calculation</param>
  120.         /// <returns>(double) The total amount of experience that can potentially be gained from an NPC accroding to player & NPC level matching.</returns>
  121.         public static double ComputeExperienceGain(int playerLevel, int npcLevel, bool rested, bool elite, ZoneXPBase xpZone)
  122.         {
  123.             double baseXP = XPFromNPC(playerLevel, npcLevel, xpZone);
  124.  
  125.             if (elite)
  126.                 baseXP *= EliteXPFactor;
  127.  
  128.             if (rested)
  129.                 baseXP *= RestedXPFactor;
  130.  
  131.             return baseXP;
  132.         }
  133.  
  134.         /// <summary>
  135.         /// Gets the level 'color' associated with World of Warcrafts' "Grey to Skull" scale.
  136.         /// Obligatory He-man citation needed.
  137.         /// </summary>
  138.         /// <param name="playerLevel">(int) The current level of the player 'targeting' the NPC.</param>
  139.         /// <param name="npcLevel">(int) The current level of the NPC that is being 'targeted' by the player.</param>
  140.         /// <returns>(WowLevelColor) The level 'color' associated with World of Warcrafts' 'Grey to Skull' scale.
  141.         /// Incidentally, the value name returned also translates into the correct hue id number for use with text.</returns>
  142.         public static LevelColor GetLevelColor(int playerLevel, int npcLevel)
  143.         {
  144.             if (playerLevel + 5 <= npcLevel)
  145.             {
  146.                 if (playerLevel + 10 <= npcLevel)
  147.                 {
  148.                     return LevelColor.Skull;
  149.                 }
  150.                 else
  151.                 {
  152.                     return LevelColor.Red;
  153.                 }
  154.             }
  155.             else
  156.             {
  157.                 switch (npcLevel - playerLevel)
  158.                 {
  159.                     case 4: { return LevelColor.Orange; }
  160.                     case 3: { return LevelColor.Orange; }
  161.                     case 2: { return LevelColor.Yellow; }
  162.                     case 1: { return LevelColor.Yellow; }
  163.                     case 0: { return LevelColor.Yellow; }
  164.                     case -1: { return LevelColor.Yellow; }
  165.                     case -2: { return LevelColor.Yellow; }
  166.                     default:
  167.                         if (playerLevel <= 5)
  168.                         {
  169.                             return LevelColor.Green;
  170.                         }
  171.                         else
  172.                         {
  173.                             if (playerLevel <= 39)
  174.                             {
  175.                                 if (npcLevel <= (playerLevel - 5 - Math.Floor((double)(playerLevel / 10))))
  176.                                 {
  177.                                     return LevelColor.Grey;
  178.                                 }
  179.                                 else
  180.                                 {
  181.                                     return LevelColor.Green;
  182.                                 }
  183.                             }
  184.                             else
  185.                             {
  186.                                 if (npcLevel <= (playerLevel - 1 - Math.Floor((double)(playerLevel / 5))))
  187.                                 {
  188.                                     return LevelColor.Grey;
  189.                                 }
  190.                                 else
  191.                                 {
  192.                                     return LevelColor.Green;
  193.                                 }
  194.                             }
  195.                         }
  196.                 }
  197.             }
  198.         }
  199.  
  200.         /// <summary>
  201.         /// Computes the amount of experience that an NPC may supply
  202.         /// </summary>
  203.         /// <param name="playerLevel">(int) The current level of the player</param>
  204.         /// <param name="npcLevel">(int) The current level of the NPC</param>
  205.         /// <param name="xpZone">(ZoneXPBase) The zone XP base to use during calculation</param>
  206.         /// <returns>(double) The amount of experience that an NPC may supply</returns>
  207.         public static double XPFromNPC(int playerLevel, int npcLevel, ZoneXPBase xpZone)
  208.         {
  209.             double baseXP = 0.0;
  210.  
  211.             if (GetLevelColor(playerLevel, npcLevel) == LevelColor.Grey)
  212.                 return baseXP;
  213.  
  214.             baseXP = (int)xpZone + (5 * playerLevel);
  215.  
  216.             if (npcLevel < playerLevel && npcLevel > ZeroXPLevel(playerLevel))
  217.             {
  218.                 return baseXP * (1 - (playerLevel - npcLevel) / XPZeroDiff(playerLevel));
  219.             }
  220.             else if (npcLevel > playerLevel)
  221.             {
  222.                 return baseXP * (1 + 0.05 * (npcLevel - playerLevel));
  223.             }
  224.  
  225.             return baseXP;
  226.         }
  227.  
  228.         /// <summary>
  229.         /// Calculates the level difference threshold for gaining zero XP
  230.         /// </summary>
  231.         /// <param name="playerLevel">(int) The current level of the player</param>
  232.         /// <returns>(int) The level difference threshold for gaining zero XP</returns>
  233.         public static int XPZeroDiff(int playerLevel)
  234.         {
  235.             if (playerLevel <= 7)
  236.             {
  237.                 return 5;
  238.             }
  239.             else if (playerLevel >= 8 && playerLevel <= 9)
  240.             {
  241.                 return 6;
  242.             }
  243.             else if (playerLevel >= 10 && playerLevel <= 11)
  244.             {
  245.                 return 7;
  246.             }
  247.             else if (playerLevel >= 12 && playerLevel <= 15)
  248.             {
  249.                 return 8;
  250.             }
  251.             else if (playerLevel >= 16 && playerLevel <= 19)
  252.             {
  253.                 return 9;
  254.             }
  255.             else if (playerLevel >= 20 && playerLevel <= 29)
  256.             {
  257.                 return 11;
  258.             }
  259.             else if (playerLevel >= 30 && playerLevel <= 39)
  260.             {
  261.                 return 12;
  262.             }
  263.             else if (playerLevel >= 40 && playerLevel <= 44)
  264.             {
  265.                 return 13;
  266.             }
  267.             else if (playerLevel >= 45 && playerLevel <= 49)
  268.             {
  269.                 return 14;
  270.             }
  271.             else if (playerLevel >= 50 && playerLevel <= 54)
  272.             {
  273.                 return 15;
  274.             }
  275.             else if (playerLevel >= 55 && playerLevel <= 59)
  276.             {
  277.                 return 16;
  278.             }
  279.             else if (playerLevel >= 60 && playerLevel <= 79)
  280.             {
  281.                 return 17;
  282.             }
  283.             else if (playerLevel >= 80)
  284.             {
  285.                 return 18;
  286.             }
  287.  
  288.             return 0;
  289.         }
  290.  
  291.         /// <summary>
  292.         /// Calculates the 'Grey Level'
  293.         /// The 'Grey Level' is the highest level at which an NPC may not grant experience
  294.         /// </summary>
  295.         /// <param name="playerLevel">(int) The current level of the player</param>
  296.         /// <returns>(int) The highest level at which experience will not be granted</returns>
  297.         public static int ZeroXPLevel(int playerLevel)
  298.         {
  299.             if (playerLevel <= 5)
  300.             {
  301.                 return 0;
  302.             }
  303.             else if (playerLevel >= 6 && playerLevel <= 39)
  304.             {
  305.                 return (int)(playerLevel - Math.Floor((double)(playerLevel / 10)) - 5);
  306.             }
  307.             else if (playerLevel >= 40 && playerLevel <= 59)
  308.             {
  309.                 return (int)(playerLevel - Math.Floor((double)(playerLevel / 5)) - 1);
  310.             }
  311.             else if (playerLevel >= 60)
  312.             {
  313.                 return (int)(playerLevel - 9);
  314.             }
  315.  
  316.             return 0;
  317.         }
  318.  
  319.         /// <summary>
  320.         /// Calculates the factor of XP reduction to implement difficulty scaling
  321.         /// Effective from level 28 to 59
  322.         /// </summary>
  323.         /// <param name="playerLevel">(int) The current level of the player</param>
  324.         /// <returns>(double) The factor of XP reduction to implement difficulty scaling (Effective for level 28 to 59 only)</returns>
  325.         public static double XPDiffReduction(int playerLevel)
  326.         {
  327.             if (playerLevel <= 28)
  328.             {
  329.                 return 0;
  330.             }
  331.             else if (playerLevel == 29)
  332.             {
  333.                 return 1;
  334.             }
  335.             else if (playerLevel == 30)
  336.             {
  337.                 return 3;
  338.             }
  339.             else if (playerLevel == 31)
  340.             {
  341.                 return 6;
  342.             }
  343.             else if (playerLevel >= 32 && playerLevel <= 59)
  344.             {
  345.                 return 5 * (playerLevel - 30);
  346.             }
  347.  
  348.             return 0;
  349.         }
  350.  
  351.         /// <summary>
  352.         /// Calculates the factor of XP reduction to implement advanced difficulty scaling
  353.         /// Effective for all levels
  354.         /// </summary>
  355.         /// <param name="playerLevel">(int) The current level of the player</param>
  356.         /// <returns>(double) The factor of XP reduction to implement advanced difficulty scaling (Effective for all levels)</returns>
  357.         public static double XPReductionFactor(int playerLevel)
  358.         {
  359.             if (playerLevel <= 10)
  360.             {
  361.                 return 1;
  362.             }
  363.             else if (playerLevel >= 11 && playerLevel <= 27)
  364.             {
  365.                 return (1 - (playerLevel - 10) / 100);
  366.             }
  367.             else if (playerLevel >= 28 && playerLevel <= 59)
  368.             {
  369.                 return 0.82;
  370.             }
  371.             else if (playerLevel >= 60)
  372.             {
  373.                 return 1;
  374.             }
  375.  
  376.             return 1;
  377.         }
  378.  
  379.         /// <summary>
  380.         /// Provides a means to round (double) values to X amount of digits
  381.         /// All experience requirements are scaled to the nearest 100
  382.         /// Example: Round( 1584.82, -2 ); would return (double) 1600.00
  383.         /// </summary>
  384.         /// <param name="value">(double) The value to round</param>
  385.         /// <param name="digits">(int) Digits must be between -15 and 15</param>
  386.         /// <returns>(double) The rounded value</returns>
  387.         public static double Round(double value, int digits)
  388.         {
  389.             if ((digits < -15) || (digits > 15))
  390.                 return value;
  391.  
  392.             if (digits >= 0)
  393.                 return Math.Round(value, digits);
  394.  
  395.             double n = Math.Pow(10, -digits);
  396.  
  397.             return Math.Round(value / n, 0) * n;
  398.         }
  399.     }
  400. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement