Advertisement
Krythic

GamePrice

Nov 14th, 2020
1,099
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 13.42 KB | None | 0 0
  1. using System;
  2. using VoidwalkerEngine.Framework.Maths;
  3.  
  4. namespace VoidwalkerEngine.Framework.DataTypes
  5. {
  6.  
  7.     public enum CoinType
  8.     {
  9.         /// <summary>
  10.         /// Copper
  11.         /// </summary>
  12.         Copper = 1,
  13.         /// <summary>
  14.         /// Silver
  15.         /// </summary>
  16.         Silver = 100,
  17.         /// <summary>
  18.         /// Gold
  19.         /// </summary>
  20.         Gold = 10000
  21.     }
  22.  
  23.     [Serializable]
  24.     public struct GamePrice : IEquatable<GamePrice>
  25.     {
  26.         public const string CopperName = "Copper";
  27.         public const string SilverName = "Silver";
  28.         public const string GoldName = "Gold";
  29.         public const char CopperAbbreviation = 'c';
  30.         public const char SilverAbbreviation = 's';
  31.         public const char GoldAbbreviation = 'g';
  32.         public const int MaximumBaseDenomination = 99999999;
  33.         public const int MaximumCopper = MaximumBaseDenomination;
  34.         public const int MaximumSilver = ((MaximumBaseDenomination / (int)CoinType.Silver) + 1);
  35.         public const int MaximumGold = ((MaximumBaseDenomination / (int)CoinType.Gold) + 1);
  36.         /// <summary>
  37.         /// The internal value used to generate
  38.         /// other denominations.
  39.         /// </summary>
  40.         public int BaseDenomination { get; }
  41.         /// <summary>
  42.         /// The displayable amount of Copper.
  43.         /// </summary>
  44.         public int Copper
  45.         {
  46.             get
  47.             {
  48.                 return TotalCopper % 100;
  49.             }
  50.         }
  51.  
  52.         /// <summary>
  53.         /// The displayable amount of Silver.
  54.         /// </summary>
  55.         public int Silver
  56.         {
  57.             get
  58.             {
  59.                 return TotalSilver % 100;
  60.             }
  61.         }
  62.  
  63.         /// <summary>
  64.         /// The displayable amount of Gold.
  65.         /// </summary>
  66.         public int Gold
  67.         {
  68.             get
  69.             {
  70.                 return TotalGold;
  71.             }
  72.         }
  73.  
  74.         /// <summary>
  75.         /// The total amount of Copper.
  76.         /// </summary>
  77.         public int TotalCopper
  78.         {
  79.             get
  80.             {
  81.                 return BaseDenomination / (int)CoinType.Copper;
  82.             }
  83.         }
  84.  
  85.         /// <summary>
  86.         /// The total amount of Silver.
  87.         /// </summary>
  88.         public int TotalSilver
  89.         {
  90.             get
  91.             {
  92.                 return BaseDenomination / (int)CoinType.Silver;
  93.             }
  94.         }
  95.  
  96.         /// <summary>
  97.         /// The total amount of Gold.
  98.         /// </summary>
  99.         public int TotalGold
  100.         {
  101.             get
  102.             {
  103.                 return BaseDenomination / (int)CoinType.Gold;
  104.             }
  105.         }
  106.  
  107.         public static GamePrice Empty
  108.         {
  109.             get
  110.             {
  111.                 return new GamePrice();
  112.             }
  113.         }
  114.  
  115.         public static GamePrice Full
  116.         {
  117.             get
  118.             {
  119.                 return new GamePrice(MaximumBaseDenomination);
  120.             }
  121.         }
  122.  
  123.         public bool IsFull
  124.         {
  125.             get
  126.             {
  127.                 return BaseDenomination == MaximumBaseDenomination;
  128.             }
  129.         }
  130.  
  131.         public bool IsEmpty
  132.         {
  133.             get
  134.             {
  135.                 return BaseDenomination == 0;
  136.             }
  137.         }
  138.  
  139.         public GamePrice(int baseDenomination)
  140.         {
  141.             this.BaseDenomination = baseDenomination;
  142.         }
  143.  
  144.         public GamePrice(int gold, int silver, int copper)
  145.             : this()
  146.         {
  147.             this.BaseDenomination = ComputeBaseDenomination(gold, silver, copper);
  148.         }
  149.  
  150.         public GamePrice(string data)
  151.             : this()
  152.         {
  153.             this.BaseDenomination = Parse(data).BaseDenomination;
  154.         }
  155.  
  156.         public static int ComputeBaseDenomination(int gold = 0, int silver = 0, int copper = 0, bool clampMaximum = true)
  157.         {
  158.             // Negative Clamp
  159.             copper = VoidwalkerMath.ClampMinimum(copper, 0);
  160.             silver = VoidwalkerMath.ClampMinimum(silver, 0);
  161.             gold = VoidwalkerMath.ClampMinimum(gold, 0);
  162.             // Early limitation detection.
  163.             if (copper > MaximumCopper || silver > MaximumSilver || gold > MaximumGold)
  164.             {
  165.                 return MaximumBaseDenomination;
  166.             }
  167.             int computedDenomination = 0;
  168.             computedDenomination += copper;
  169.             computedDenomination += ((silver * (int)CoinType.Silver));
  170.             computedDenomination += ((gold * (int)CoinType.Gold));
  171.             if (clampMaximum)
  172.             {
  173.                 return computedDenomination > MaximumBaseDenomination
  174.                 ? MaximumBaseDenomination
  175.                 : computedDenomination;
  176.             }
  177.             return computedDenomination;
  178.         }
  179.  
  180.         public GamePrice Add(GamePrice other)
  181.         {
  182.             return new GamePrice(this.BaseDenomination + other.BaseDenomination);
  183.         }
  184.  
  185.         public GamePrice Add(int baseDenomination)
  186.         {
  187.             return Add(new GamePrice(baseDenomination));
  188.         }
  189.  
  190.         public GamePrice Subtract(GamePrice other)
  191.         {
  192.             return new GamePrice(this.BaseDenomination - other.BaseDenomination);
  193.         }
  194.  
  195.         public GamePrice Subtract(int baseDenomination)
  196.         {
  197.             return Subtract(new GamePrice(baseDenomination));
  198.         }
  199.  
  200.         /// <summary>
  201.         /// Splits this Moneybag into two equal bags.
  202.         /// </summary>
  203.         /// <returns></returns>
  204.         public void Split(out GamePrice bag1, out GamePrice bag2)
  205.         {
  206.             if (this.BaseDenomination <= 1)
  207.             {
  208.                 // A split is impossible
  209.                 bag1 = this; // Will equal 1
  210.                 bag2 = Empty;
  211.                 return;
  212.             }
  213.             int splitResult = (this.BaseDenomination / 2);
  214.             if (VoidwalkerMath.IsEven(BaseDenomination))
  215.             {
  216.                 bag1 = new GamePrice(splitResult);
  217.                 bag2 = new GamePrice(splitResult);
  218.                 return;
  219.             }
  220.             bag1 = new GamePrice(splitResult);
  221.             bag2 = new GamePrice(splitResult + 1);
  222.         }
  223.  
  224.         /// <summary>
  225.         ///
  226.         /// </summary>
  227.         /// <param name="type"></param>
  228.         /// <returns></returns>
  229.         public bool Has(CoinType type)
  230.         {
  231.             switch (type)
  232.             {
  233.                 case CoinType.Copper:
  234.                     return TotalCopper > 0;
  235.                 case CoinType.Silver:
  236.                     return TotalSilver > 0;
  237.                 case CoinType.Gold:
  238.                     return TotalGold > 0;
  239.                 default:
  240.                     throw new ArgumentOutOfRangeException(nameof(type), type, null);
  241.             }
  242.         }
  243.  
  244.         public bool Has(GamePrice amount)
  245.         {
  246.             return this.BaseDenomination >= amount.BaseDenomination;
  247.         }
  248.  
  249.         public bool CanHold(GamePrice amount)
  250.         {
  251.             if (this.IsFull)
  252.             {
  253.                 return false;
  254.             }
  255.             return this.BaseDenomination + amount.BaseDenomination <= MaximumBaseDenomination;
  256.         }
  257.  
  258.         /// <summary>
  259.         /// Acceptable Format: '0g,0s,0c'
  260.         /// </summary>
  261.         /// <param name="data"></param>
  262.         /// <returns></returns>
  263.         public static GamePrice Parse(string data)
  264.         {
  265.             TryParse(data, out GamePrice? result);
  266.             if (result != null)
  267.             {
  268.                 return result.Value;
  269.             }
  270.             else
  271.             {
  272.                 throw new Exception("GamePrice was not in a valid format!");
  273.             }
  274.         }
  275.  
  276.         /// <summary>
  277.         ///
  278.         /// </summary>
  279.         /// <param name="data"></param>
  280.         /// <param name="result"></param>
  281.         public static void TryParse(string data, out GamePrice? result)
  282.         {
  283.             if (data != null || data.Length > 0)
  284.             {
  285.                 string[] splitData = data.Split(',');
  286.                 if (splitData.Length == 3)
  287.                 {
  288.                     if (splitData[0].Length >= 2 &&
  289.                         splitData[1].Length >= 2 &&
  290.                         splitData[2].Length >= 2)
  291.                     {
  292.                         if (splitData[0][splitData[0].Length - 1] == GoldAbbreviation &&
  293.                             splitData[1][splitData[1].Length - 1] == SilverAbbreviation &&
  294.                             splitData[2][splitData[2].Length - 1] == CopperAbbreviation)
  295.                         {
  296.                             if (Int32.TryParse(splitData[0].Substring(0, splitData[0].Length - 1), out int goldResult) &&
  297.                                 Int32.TryParse(splitData[1].Substring(0, splitData[1].Length - 1), out int silverResult) &&
  298.                                 Int32.TryParse(splitData[2].Substring(0, splitData[2].Length - 1), out int copperResult))
  299.                             {
  300.                                 if (copperResult <= MaximumCopper && silverResult <= MaximumSilver && goldResult <= MaximumGold)
  301.                                 {
  302.                                     int baseDenomination = ComputeBaseDenomination(goldResult, silverResult, copperResult, false);
  303.                                     if (baseDenomination <= MaximumBaseDenomination)
  304.                                     {
  305.                                         result = new GamePrice(goldResult, silverResult, copperResult);
  306.                                         return;
  307.                                     }
  308.                                 }
  309.                             }
  310.                         }
  311.                     }
  312.                 }
  313.             }
  314.             result = null;
  315.         }
  316.  
  317.         /// <summary>
  318.         /// Acceptable Format: '0g,0s,0c'
  319.         /// </summary>
  320.         /// <param name="data"></param>
  321.         /// <returns></returns>
  322.         public static bool TryParse(string data)
  323.         {
  324.             TryParse(data, out GamePrice? result);
  325.             return result != null;
  326.         }
  327.  
  328.         /// <summary>
  329.         ///
  330.         /// </summary>
  331.         /// <param name="culture"></param>
  332.         /// <returns></returns>
  333.         public override string ToString()
  334.         {
  335.             return $"{Gold}" + $"{GoldAbbreviation}," + $"{Silver}" + $"{SilverAbbreviation}," + $"{Copper}" + $"{CopperAbbreviation}";
  336.         }
  337.  
  338.         static public explicit operator int(GamePrice price)
  339.         {
  340.             return price.BaseDenomination;
  341.         }
  342.  
  343.         /// <summary>
  344.         ///
  345.         /// </summary>
  346.         /// <returns></returns>
  347.         public int ToInt32()
  348.         {
  349.             return this.BaseDenomination;
  350.         }
  351.  
  352.         /// <summary>
  353.         /// Returns format: Gold, Silver, Copper
  354.         /// </summary>
  355.         public int[] ToArray()
  356.         {
  357.             return new[]
  358.             {
  359.                 Gold,
  360.                 Silver,
  361.                 Copper
  362.             };
  363.         }
  364.  
  365.         public static GamePrice FromArray(int[] array)
  366.         {
  367.             if (array.Length != 3)
  368.             {
  369.                 throw new Exception("GamePrice Array Source must be 3 indices long!");
  370.             }
  371.             return new GamePrice(array[0], array[1], array[3]);
  372.         }
  373.  
  374.         public bool Equals(GamePrice other)
  375.         {
  376.             return BaseDenomination == other.BaseDenomination;
  377.         }
  378.  
  379.         public override bool Equals(object obj)
  380.         {
  381.             return (obj is GamePrice bag) && Equals(bag);
  382.         }
  383.  
  384.         public override int GetHashCode()
  385.         {
  386.             return BaseDenomination.GetHashCode();
  387.         }
  388.  
  389.         public static bool operator ==(GamePrice a, GamePrice b)
  390.         {
  391.             return a.BaseDenomination == b.BaseDenomination;
  392.         }
  393.  
  394.         public static bool operator !=(GamePrice a, GamePrice b)
  395.         {
  396.             return a.BaseDenomination != b.BaseDenomination;
  397.         }
  398.  
  399.         public static bool operator <(GamePrice a, GamePrice b)
  400.         {
  401.             return a.BaseDenomination < b.BaseDenomination;
  402.         }
  403.  
  404.         public static bool operator >(GamePrice a, GamePrice b)
  405.         {
  406.             return a.BaseDenomination > b.BaseDenomination;
  407.         }
  408.  
  409.         public static GamePrice operator +(GamePrice left, GamePrice right)
  410.         {
  411.             return left.Add(right);
  412.         }
  413.  
  414.         public static GamePrice operator -(GamePrice left, GamePrice right)
  415.         {
  416.             return left.Subtract(right);
  417.         }
  418.  
  419.         public static GamePrice operator +(GamePrice left, int right)
  420.         {
  421.             return left.Add(new GamePrice(right));
  422.         }
  423.  
  424.         public static GamePrice operator -(GamePrice left, int right)
  425.         {
  426.             return left.Subtract(new GamePrice(right));
  427.         }
  428.  
  429.         public static GamePrice operator *(GamePrice left, double right)
  430.         {
  431.             return new GamePrice((int)(left.BaseDenomination * right));
  432.         }
  433.  
  434.         public static implicit operator GamePrice(int baseDenomination)
  435.         {
  436.             return new GamePrice(baseDenomination);
  437.         }
  438.  
  439.         public static implicit operator GamePrice(string data)
  440.         {
  441.             return new GamePrice(data);
  442.         }
  443.  
  444.         public string ToUSD()
  445.         {
  446.             int dollars = TotalSilver;
  447.             int cents = Copper;
  448.             return "$" + dollars + "." + cents;
  449.         }
  450.     }
  451. }
  452.  
  453.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement