Advertisement
Thd3fp

ParagonCalculator

Mar 18th, 2021
255
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 14.69 KB | None | 0 0
  1. using Turbo.Plugins.Default;
  2. using System.Linq;
  3. using System.Collections.Generic;
  4.  
  5. namespace Turbo.Plugins.Thd3fp
  6. {
  7.     public class ParagonCalculator : BasePlugin, IInGameTopPainter, IAfterCollectHandler
  8.     {
  9.         public IFont TextFont { get; set; }
  10.         public IFont ParaFont { get; set; }
  11.         public string LabelTextPart1 { get; set; } = "Paragons";
  12.         public string LabelTextPart2 { get; set; } = "after Season:";
  13.         private List<Player> ListPlayers;
  14.         private float[] LabelLPointParaSoft = new float[] { 0, 0 };
  15.         private float[] LabelLPointParaHard = new float[] { 0, 0 };
  16.         private float LabelRightXsoft = 0;
  17.         private float LabelRightXhard = 0;
  18.         private long RefreshTimer = 0;
  19.         private const uint RefreshTimeMs = 200;
  20.  
  21.         public static double ParagonToExperience(int paragon)
  22.         {
  23.             return CalcParaAndXp(paragon);
  24.         }
  25.  
  26.         public static int ExperienceToParagon(double experience)
  27.         {
  28.             const int rangePara = 40000;
  29.             return (int)CalcParaAndXp(rangePara, experience);
  30.         }
  31.  
  32.         public ParagonCalculator()
  33.         {
  34.             Enabled = true;
  35.         }
  36.  
  37.         public override void Load(IController hud)
  38.         {
  39.             base.Load(hud);
  40.             TextFont = Hud.Render.CreateFont("tahoma", 8, 255, 181, 139, 72, false, false, false);
  41.             ParaFont = Hud.Render.CreateFont("tahoma", 8, 255, 225, 225, 225, false, false, false);
  42.             ListPlayers = new List<Player>();
  43.             RefreshTimer = Hud.Game.CurrentRealTimeMilliseconds;
  44.         }
  45.  
  46.         public void PaintTopInGame(ClipState clipState)
  47.         {
  48.             if (!Hud.Game.Me.IsInGame && clipState != ClipState.AfterClip)
  49.                 return;
  50.             if ((!UiNonSeasonSummary() && !UiSeasonSummary()) || !IsPlayedInCurrentSeason())  // show/draw in profile NonSeason/Season Summary only if login in game with season hero
  51.                 return;
  52.  
  53.             var offsetY = Hud.Window.Size.Height * 0.02f;
  54.             float x, y;
  55.             var player = ListPlayers.FirstOrDefault(p => p.Name == UiProfileName());
  56.             if (player?.SeasonSoftCoreParagon > 0)
  57.             {
  58.                 x = LabelLPointParaSoft[0];
  59.                 y = LabelLPointParaSoft[1] - offsetY;
  60.                 var curInRect = Hud.Window.CursorInsideRect(x, y, LabelRightXsoft - x, offsetY);
  61.                 var paraTextSum = " (" + player.NonSeasonSoftCoreParagon + "+" + player.SeasonSoftCoreParagon + ")";
  62.                 TextFont.DrawText(LabelTextPart1 + (curInRect ? paraTextSum : "") + " " + LabelTextPart2, x, y);
  63.                 var layout = ParaFont.GetTextLayout(player.AfterSeasonSoftCoreParagon.ToString());
  64.                 x = LabelRightXsoft - layout.Metrics.Width;
  65.                 ParaFont.DrawText(layout, x, y);
  66.             }
  67.             if (player?.SeasonHardCoreParagon > 0)
  68.             {
  69.                 x = LabelLPointParaHard[0];
  70.                 y = LabelLPointParaHard[1] - offsetY;
  71.                 var curInRect = Hud.Window.CursorInsideRect(x, y, LabelRightXhard - x, offsetY);
  72.                 var paraTextSum = " (" + player.NonSeasonHardCoreParagon + "+" + player.SeasonHardCoreParagon + ")";
  73.                 TextFont.DrawText(LabelTextPart1 + (curInRect ? paraTextSum : "") + " " + LabelTextPart2, x, y);
  74.                 var layout = ParaFont.GetTextLayout(player.AfterSeasonHardCoreParagon.ToString());
  75.                 x = LabelRightXhard - layout.Metrics.Width;
  76.                 var friendList = Hud.Render.GetUiElement("Root.NormalLayer.BattleNetFriendsList_main.LayoutRoot.OverlayContainer.FriendsListContent");
  77.                 var communities = Hud.Render.GetUiElement("Root.NormalLayer.GroupList_main.LayoutRoot.OverlayContainer.GroupsListContent");
  78.                 if (friendList?.Visible != true && communities?.Visible != true)
  79.                     ParaFont.DrawText(layout, x, y);
  80.             }
  81.         }
  82.  
  83.         private bool IsPlayedInCurrentSeason()
  84.         {
  85.             if (Hud.Game.Me.Hero == null)
  86.                 return false;
  87.  
  88.             int lastPlayedSeasonNumber = 0;
  89.             var path = "Root.NormalLayer.BattleNetProfile_main.LayoutRoot.OverlayContainer.CategoryList._content._stackpanel._item3.NavigationMenuListItemContainer.MenuListItem.MenuSubItem.MenuSubList._content._stackpanel._item0.SubListItemDown.SubListItemDownValue";
  90.             var uiLastPlayedSeason = Hud.Render.GetUiElement(path);
  91.             if (uiLastPlayedSeason == null)
  92.                 uiLastPlayedSeason = Hud.Render.RegisterUiElement(path, uiLastPlayedSeason, null);
  93.  
  94.             if (uiLastPlayedSeason != null)
  95.             {
  96.                 var lastPlayedSeasonText = uiLastPlayedSeason.ReadText(System.Text.Encoding.Default, removeColors: true);
  97.                 var lastPlayedSeasonTexttNumber = lastPlayedSeasonText != null ? new string(lastPlayedSeasonText.Where(char.IsDigit).ToArray()) : null; // remove non Digit symbols form string
  98.                 if (int.TryParse(lastPlayedSeasonTexttNumber, out int _seasonNumber))
  99.                     lastPlayedSeasonNumber = _seasonNumber;
  100.  
  101.                 var currentSeasonNumber = Hud.Game.Me.Hero.Season;
  102.                 return Hud.Game.Me.Hero.Seasonal && (lastPlayedSeasonNumber == currentSeasonNumber);
  103.             }
  104.             return false;
  105.         }
  106.  
  107.         private bool UiNonSeasonSummary()
  108.         {
  109.             var path = "Root.NormalLayer.BattleNetProfile_main.LayoutRoot.OverlayContainer.CategoryList._content._stackpanel._item0.NavigationMenuListItemContainer.MenuListItem.MenuSubItem.MenuSubList._content._stackpanel._item0.SubListItemDown.SubListItemDownValue";
  110.             var uiNonSeasonSummary = Hud.Render.GetUiElement(path);
  111.             if (uiNonSeasonSummary == null)
  112.                 uiNonSeasonSummary = Hud.Render.RegisterUiElement(path, uiNonSeasonSummary, null);
  113.  
  114.             return uiNonSeasonSummary.Visible;
  115.         }
  116.  
  117.         private bool UiSeasonSummary()
  118.         {
  119.             var path = "Root.NormalLayer.BattleNetProfile_main.LayoutRoot.OverlayContainer.CategoryList._content._stackpanel._item3.NavigationMenuListItemContainer.MenuListItem.MenuSubItem.MenuSubList._content._stackpanel._item0.MenuTertiaryList._content._stackpanel._item0.TertiaryListItemDown.TertiaryListItemDownValue";
  120.             var uiNonSeasonSummary = Hud.Render.GetUiElement(path);
  121.             if (uiNonSeasonSummary == null)
  122.                 uiNonSeasonSummary = Hud.Render.RegisterUiElement(path, uiNonSeasonSummary, null);
  123.  
  124.             return uiNonSeasonSummary.Visible;
  125.         }
  126.  
  127.         private string UiProfileName()
  128.         {
  129.             string name = "";
  130.             var path = "Root.NormalLayer.BattleNetProfile_main.LayoutRoot.OverlayContainer.PageHeader.PageTitle";
  131.             var uiNonSeasonSummary = Hud.Render.GetUiElement(path);
  132.             if (uiNonSeasonSummary == null)
  133.                 uiNonSeasonSummary = Hud.Render.RegisterUiElement(path, uiNonSeasonSummary, null);
  134.  
  135.             if (uiNonSeasonSummary.Visible)
  136.                 return uiNonSeasonSummary.ReadText(System.Text.Encoding.Default, removeColors: true);
  137.             return name;
  138.         }
  139.  
  140.         // can convert paragon to experience and experience to paragon
  141.         // when parameter experience == -1 // returns(convert) paragon to experience
  142.         // when parameter experience > 0  // returns(convert) experience to paragon, parameter paragon in this case must be a large number e.g. 20000 or 30000
  143.         private static double CalcParaAndXp(int paragon, double experience = -1)
  144.         {
  145.             if (paragon == 0 || experience == 0)
  146.                 return 0;
  147.             double paragonTotalExp = 0, xpToNextLvl = 0, diffNextLvl = 0, xpToParagon = 0;
  148.             for (int i = 1; i <= paragon; i++)
  149.             {
  150.                 if (i == 1)
  151.                     paragonTotalExp = xpToNextLvl += 7200000;
  152.                 else if (i > 1 && i <= 60)
  153.                     paragonTotalExp += xpToNextLvl += 1440000;
  154.                 else if (i > 60 && i <= 70)
  155.                     paragonTotalExp += xpToNextLvl += 2880000;
  156.                 else if (i > 70 && i <= 73)
  157.                     paragonTotalExp += xpToNextLvl += 5040000;
  158.                 else if (i == 74)
  159.                     paragonTotalExp += xpToNextLvl += 3660000;
  160.                 else if (i > 74 && i <= 149)
  161.                     paragonTotalExp += xpToNextLvl += 1020000;
  162.                 else if (i > 149 && i <= 250)
  163.                     paragonTotalExp += xpToNextLvl += 2040000;
  164.                 else if (i > 250 && i <= 350)
  165.                     paragonTotalExp += xpToNextLvl += 4080000;
  166.                 else if (i > 350 && i <= 449)
  167.                     paragonTotalExp += xpToNextLvl += 6120000;
  168.                 else if (i > 449 && i <= 500)
  169.                     paragonTotalExp += xpToNextLvl += 8160000;
  170.                 else if (i > 500 && i <= 550)
  171.                     paragonTotalExp += xpToNextLvl += 20400000;
  172.                 else if (i > 550 && i <= 600)
  173.                     paragonTotalExp += xpToNextLvl += 40800000;
  174.                 else if (i > 600 && i <= 650)
  175.                     paragonTotalExp += xpToNextLvl += 61200000;
  176.                 else if (i > 650 && i <= 700)
  177.                     paragonTotalExp += xpToNextLvl += 81600000;
  178.                 else if (i > 700 && i <= 750)
  179.                     paragonTotalExp += xpToNextLvl += 102000000;
  180.                 else if (i > 750 && i <= 2250)
  181.                     paragonTotalExp += xpToNextLvl += 122400000;
  182.                 else if (i == 2251)
  183.                     paragonTotalExp += xpToNextLvl += diffNextLvl = 229602000;
  184.                 else if (i > 2251)
  185.                 {
  186.                     diffNextLvl *= (i + 1f) / i;
  187.                     diffNextLvl = diffNextLvl % 1000 >= 500 ? diffNextLvl + 1000 - diffNextLvl % 1000 : diffNextLvl - diffNextLvl % 1000; // rounds to 1000
  188.                     xpToNextLvl += diffNextLvl;
  189.                     paragonTotalExp += xpToNextLvl;
  190.                 }
  191.  
  192.                 if (experience >= 0)
  193.                 {
  194.                     if (paragonTotalExp <= experience)
  195.                         xpToParagon = i;
  196.                     else
  197.                         return xpToParagon; // xp to paragons
  198.                 }
  199.             }
  200.             return paragonTotalExp; // paragons to xp
  201.         }
  202.  
  203.         // returns Paragons from profile softcor/hardcore
  204.         // index [0] = paragon
  205.         // index [1] = right point X on pragon label number
  206.         // path - UiElement string path for soft/hardcore paragon label
  207.         int[] GetParagon(string path)
  208.         {
  209.             var uiPragon = Hud.Render.GetUiElement(path);
  210.             if (uiPragon == null)
  211.                 uiPragon = Hud.Render.RegisterUiElement(path, uiPragon, null);
  212.  
  213.             if (uiPragon != null)
  214.             {
  215.                 var paraText = uiPragon.ReadText(System.Text.Encoding.Default, removeColors: true);
  216.                 paraText = paraText != null ? new string(paraText.Where(char.IsDigit).ToArray()) : null; // remove non Digit symbols form string, like '.' or ','
  217.                 if (int.TryParse(paraText, out int paraNumber))
  218.                     return new int[] { paraNumber, (int)uiPragon.Rectangle.Right };
  219.             }
  220.             return new int[] { 0, 0 };
  221.         }
  222.  
  223.         // returns upper-left corner on label in profile "Paragon Level:"
  224.         float[] GetLeftPointLabelParagonLevel(string path)
  225.         {
  226.             var uiPragon = Hud.Render.GetUiElement(path);
  227.             if (uiPragon == null)
  228.                 uiPragon = Hud.Render.RegisterUiElement(path, uiPragon, null);
  229.  
  230.             if (uiPragon?.Visible == true)
  231.                 return new float[] { uiPragon.Rectangle.X, uiPragon.Rectangle.Y };
  232.  
  233.             return new float[] { 0, 0 };
  234.         }
  235.  
  236.         public void AfterCollect()
  237.         {
  238.             if (!Hud.Game.Me.IsInGame || !IsPlayedInCurrentSeason()) // only if login in game with season hero
  239.                 return;
  240.             var isUiNonSeasonSummary = UiNonSeasonSummary();
  241.             var isUiSeasonSummary = UiSeasonSummary();
  242.             if (!isUiNonSeasonSummary && !isUiSeasonSummary)
  243.                 return;
  244.             if (Hud.Game.CurrentRealTimeMilliseconds - RefreshTimer < RefreshTimeMs)
  245.                 return;
  246.             RefreshTimer = Hud.Game.CurrentRealTimeMilliseconds;
  247.  
  248.             var uiProfileName = UiProfileName();
  249.             var paraSoftCore = GetParagon("Root.NormalLayer.BattleNetProfile_main.LayoutRoot.OverlayContainer.CareerTabContent.CharacterStats.NormalParagonValue");
  250.             var paraHardCore = GetParagon("Root.NormalLayer.BattleNetProfile_main.LayoutRoot.OverlayContainer.CareerTabContent.CharacterStats.HighestHardcoreParagonValue");
  251.             LabelLPointParaSoft = GetLeftPointLabelParagonLevel("Root.NormalLayer.BattleNetProfile_main.LayoutRoot.OverlayContainer.CareerTabContent.CharacterStats.unnamed16");
  252.             LabelLPointParaHard = GetLeftPointLabelParagonLevel("Root.NormalLayer.BattleNetProfile_main.LayoutRoot.OverlayContainer.CareerTabContent.CharacterStats.unnamed18");
  253.  
  254.             LabelRightXsoft = paraSoftCore[1];
  255.             LabelRightXhard = paraHardCore[1];
  256.             if (!ListPlayers.Any(p => p.Name == uiProfileName))
  257.                 ListPlayers.Add(new Player() { Name = uiProfileName });
  258.  
  259.             var player = ListPlayers.FirstOrDefault(p => p.Name == uiProfileName);
  260.             if (player == null)
  261.                 return;
  262.             if (isUiNonSeasonSummary)
  263.             {
  264.                 player.NonSeasonSoftCoreParagon = paraSoftCore[0];
  265.                 player.NonSeasonHardCoreParagon = paraHardCore[0];
  266.             }
  267.             else if (isUiSeasonSummary)
  268.             {
  269.                 player.SeasonSoftCoreParagon = paraSoftCore[0];
  270.                 player.SeasonHardCoreParagon = paraHardCore[0];
  271.             }
  272.         }
  273.  
  274.         private class Player
  275.         {
  276.             public string Name { get; set; }
  277.             public int NonSeasonSoftCoreParagon { get; set; }
  278.             public int SeasonSoftCoreParagon { get; set; }
  279.             public int AfterSeasonSoftCoreParagon
  280.             {
  281.                 get { return ParagonCalculator.ExperienceToParagon(ParagonCalculator.ParagonToExperience(NonSeasonSoftCoreParagon) + ParagonCalculator.ParagonToExperience(SeasonSoftCoreParagon)); }
  282.             }
  283.             public int NonSeasonHardCoreParagon { get; set; }
  284.             public int SeasonHardCoreParagon { get; set; }
  285.             public int AfterSeasonHardCoreParagon
  286.             {
  287.                 get { return ParagonCalculator.ExperienceToParagon(ParagonCalculator.ParagonToExperience(NonSeasonHardCoreParagon) + ParagonCalculator.ParagonToExperience(SeasonHardCoreParagon)); }
  288.             }
  289.         }
  290.     }
  291. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement