Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using VoidwalkerEngine.Framework.Maths;
- namespace VoidwalkerEngine.Framework.DataTypes
- {
- public enum CoinType
- {
- /// <summary>
- /// Copper
- /// </summary>
- Copper = 1,
- /// <summary>
- /// Silver
- /// </summary>
- Silver = 100,
- /// <summary>
- /// Gold
- /// </summary>
- Gold = 10000
- }
- [Serializable]
- public struct GamePrice : IEquatable<GamePrice>
- {
- public const string CopperName = "Copper";
- public const string SilverName = "Silver";
- public const string GoldName = "Gold";
- public const char CopperAbbreviation = 'c';
- public const char SilverAbbreviation = 's';
- public const char GoldAbbreviation = 'g';
- public const int MaximumBaseDenomination = 99999999;
- public const int MaximumCopper = MaximumBaseDenomination;
- public const int MaximumSilver = ((MaximumBaseDenomination / (int)CoinType.Silver) + 1);
- public const int MaximumGold = ((MaximumBaseDenomination / (int)CoinType.Gold) + 1);
- /// <summary>
- /// The internal value used to generate
- /// other denominations.
- /// </summary>
- public int BaseDenomination { get; }
- /// <summary>
- /// The displayable amount of Copper.
- /// </summary>
- public int Copper
- {
- get
- {
- return TotalCopper % 100;
- }
- }
- /// <summary>
- /// The displayable amount of Silver.
- /// </summary>
- public int Silver
- {
- get
- {
- return TotalSilver % 100;
- }
- }
- /// <summary>
- /// The displayable amount of Gold.
- /// </summary>
- public int Gold
- {
- get
- {
- return TotalGold;
- }
- }
- /// <summary>
- /// The total amount of Copper.
- /// </summary>
- public int TotalCopper
- {
- get
- {
- return BaseDenomination / (int)CoinType.Copper;
- }
- }
- /// <summary>
- /// The total amount of Silver.
- /// </summary>
- public int TotalSilver
- {
- get
- {
- return BaseDenomination / (int)CoinType.Silver;
- }
- }
- /// <summary>
- /// The total amount of Gold.
- /// </summary>
- public int TotalGold
- {
- get
- {
- return BaseDenomination / (int)CoinType.Gold;
- }
- }
- public static GamePrice Empty
- {
- get
- {
- return new GamePrice();
- }
- }
- public static GamePrice Full
- {
- get
- {
- return new GamePrice(MaximumBaseDenomination);
- }
- }
- public bool IsFull
- {
- get
- {
- return BaseDenomination == MaximumBaseDenomination;
- }
- }
- public bool IsEmpty
- {
- get
- {
- return BaseDenomination == 0;
- }
- }
- public GamePrice(int baseDenomination)
- {
- this.BaseDenomination = baseDenomination;
- }
- public GamePrice(int gold, int silver, int copper)
- : this()
- {
- this.BaseDenomination = ComputeBaseDenomination(gold, silver, copper);
- }
- public GamePrice(string data)
- : this()
- {
- this.BaseDenomination = Parse(data).BaseDenomination;
- }
- public static int ComputeBaseDenomination(int gold = 0, int silver = 0, int copper = 0, bool clampMaximum = true)
- {
- // Negative Clamp
- copper = VoidwalkerMath.ClampMinimum(copper, 0);
- silver = VoidwalkerMath.ClampMinimum(silver, 0);
- gold = VoidwalkerMath.ClampMinimum(gold, 0);
- // Early limitation detection.
- if (copper > MaximumCopper || silver > MaximumSilver || gold > MaximumGold)
- {
- return MaximumBaseDenomination;
- }
- int computedDenomination = 0;
- computedDenomination += copper;
- computedDenomination += ((silver * (int)CoinType.Silver));
- computedDenomination += ((gold * (int)CoinType.Gold));
- if (clampMaximum)
- {
- return computedDenomination > MaximumBaseDenomination
- ? MaximumBaseDenomination
- : computedDenomination;
- }
- return computedDenomination;
- }
- public GamePrice Add(GamePrice other)
- {
- return new GamePrice(this.BaseDenomination + other.BaseDenomination);
- }
- public GamePrice Add(int baseDenomination)
- {
- return Add(new GamePrice(baseDenomination));
- }
- public GamePrice Subtract(GamePrice other)
- {
- return new GamePrice(this.BaseDenomination - other.BaseDenomination);
- }
- public GamePrice Subtract(int baseDenomination)
- {
- return Subtract(new GamePrice(baseDenomination));
- }
- /// <summary>
- /// Splits this Moneybag into two equal bags.
- /// </summary>
- /// <returns></returns>
- public void Split(out GamePrice bag1, out GamePrice bag2)
- {
- if (this.BaseDenomination <= 1)
- {
- // A split is impossible
- bag1 = this; // Will equal 1
- bag2 = Empty;
- return;
- }
- int splitResult = (this.BaseDenomination / 2);
- if (VoidwalkerMath.IsEven(BaseDenomination))
- {
- bag1 = new GamePrice(splitResult);
- bag2 = new GamePrice(splitResult);
- return;
- }
- bag1 = new GamePrice(splitResult);
- bag2 = new GamePrice(splitResult + 1);
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="type"></param>
- /// <returns></returns>
- public bool Has(CoinType type)
- {
- switch (type)
- {
- case CoinType.Copper:
- return TotalCopper > 0;
- case CoinType.Silver:
- return TotalSilver > 0;
- case CoinType.Gold:
- return TotalGold > 0;
- default:
- throw new ArgumentOutOfRangeException(nameof(type), type, null);
- }
- }
- public bool Has(GamePrice amount)
- {
- return this.BaseDenomination >= amount.BaseDenomination;
- }
- public bool CanHold(GamePrice amount)
- {
- if (this.IsFull)
- {
- return false;
- }
- return this.BaseDenomination + amount.BaseDenomination <= MaximumBaseDenomination;
- }
- /// <summary>
- /// Acceptable Format: '0g,0s,0c'
- /// </summary>
- /// <param name="data"></param>
- /// <returns></returns>
- public static GamePrice Parse(string data)
- {
- TryParse(data, out GamePrice? result);
- if (result != null)
- {
- return result.Value;
- }
- else
- {
- throw new Exception("GamePrice was not in a valid format!");
- }
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="data"></param>
- /// <param name="result"></param>
- public static void TryParse(string data, out GamePrice? result)
- {
- if (data != null || data.Length > 0)
- {
- string[] splitData = data.Split(',');
- if (splitData.Length == 3)
- {
- if (splitData[0].Length >= 2 &&
- splitData[1].Length >= 2 &&
- splitData[2].Length >= 2)
- {
- if (splitData[0][splitData[0].Length - 1] == GoldAbbreviation &&
- splitData[1][splitData[1].Length - 1] == SilverAbbreviation &&
- splitData[2][splitData[2].Length - 1] == CopperAbbreviation)
- {
- if (Int32.TryParse(splitData[0].Substring(0, splitData[0].Length - 1), out int goldResult) &&
- Int32.TryParse(splitData[1].Substring(0, splitData[1].Length - 1), out int silverResult) &&
- Int32.TryParse(splitData[2].Substring(0, splitData[2].Length - 1), out int copperResult))
- {
- if (copperResult <= MaximumCopper && silverResult <= MaximumSilver && goldResult <= MaximumGold)
- {
- int baseDenomination = ComputeBaseDenomination(goldResult, silverResult, copperResult, false);
- if (baseDenomination <= MaximumBaseDenomination)
- {
- result = new GamePrice(goldResult, silverResult, copperResult);
- return;
- }
- }
- }
- }
- }
- }
- }
- result = null;
- }
- /// <summary>
- /// Acceptable Format: '0g,0s,0c'
- /// </summary>
- /// <param name="data"></param>
- /// <returns></returns>
- public static bool TryParse(string data)
- {
- TryParse(data, out GamePrice? result);
- return result != null;
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="culture"></param>
- /// <returns></returns>
- public override string ToString()
- {
- return $"{Gold}" + $"{GoldAbbreviation}," + $"{Silver}" + $"{SilverAbbreviation}," + $"{Copper}" + $"{CopperAbbreviation}";
- }
- static public explicit operator int(GamePrice price)
- {
- return price.BaseDenomination;
- }
- /// <summary>
- ///
- /// </summary>
- /// <returns></returns>
- public int ToInt32()
- {
- return this.BaseDenomination;
- }
- /// <summary>
- /// Returns format: Gold, Silver, Copper
- /// </summary>
- public int[] ToArray()
- {
- return new[]
- {
- Gold,
- Silver,
- Copper
- };
- }
- public static GamePrice FromArray(int[] array)
- {
- if (array.Length != 3)
- {
- throw new Exception("GamePrice Array Source must be 3 indices long!");
- }
- return new GamePrice(array[0], array[1], array[3]);
- }
- public bool Equals(GamePrice other)
- {
- return BaseDenomination == other.BaseDenomination;
- }
- public override bool Equals(object obj)
- {
- return (obj is GamePrice bag) && Equals(bag);
- }
- public override int GetHashCode()
- {
- return BaseDenomination.GetHashCode();
- }
- public static bool operator ==(GamePrice a, GamePrice b)
- {
- return a.BaseDenomination == b.BaseDenomination;
- }
- public static bool operator !=(GamePrice a, GamePrice b)
- {
- return a.BaseDenomination != b.BaseDenomination;
- }
- public static bool operator <(GamePrice a, GamePrice b)
- {
- return a.BaseDenomination < b.BaseDenomination;
- }
- public static bool operator >(GamePrice a, GamePrice b)
- {
- return a.BaseDenomination > b.BaseDenomination;
- }
- public static GamePrice operator +(GamePrice left, GamePrice right)
- {
- return left.Add(right);
- }
- public static GamePrice operator -(GamePrice left, GamePrice right)
- {
- return left.Subtract(right);
- }
- public static GamePrice operator +(GamePrice left, int right)
- {
- return left.Add(new GamePrice(right));
- }
- public static GamePrice operator -(GamePrice left, int right)
- {
- return left.Subtract(new GamePrice(right));
- }
- public static GamePrice operator *(GamePrice left, double right)
- {
- return new GamePrice((int)(left.BaseDenomination * right));
- }
- public static implicit operator GamePrice(int baseDenomination)
- {
- return new GamePrice(baseDenomination);
- }
- public static implicit operator GamePrice(string data)
- {
- return new GamePrice(data);
- }
- public string ToUSD()
- {
- int dollars = TotalSilver;
- int cents = Copper;
- return "$" + dollars + "." + cents;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement