using SUISS.Storage; using System; using System.Collections.Generic; using System.Text; using UnityEngine; namespace SUISSEngine { [Serializable] public class Currencies : IStorable { public enum RoundingMethod { Nearest, Floor, Ceiling } private static Currencies zero = new Currencies(); [SerializeField] private List values = new List(); private int hash; public static Currencies Zero => zero; public int KeyCount => values.Count; public Currencies() { } public Currencies(Currencies copyFrom) { foreach (CurrencyValue value in copyFrom.values) { SetValue(value.Currency, value.Value); } } public Currencies(string currency, decimal value) { if (currency == null) { throw new ArgumentException("Currency can't be null.", "currency"); } SetValue(currency, value); } public Currencies(params object[] currencyValues) { if (currencyValues == null) { return; } if (currencyValues.Length % 2 != 0) { throw new ArgumentException("Expected an even number of arguments.", "currencyValues"); } int num = 0; while (true) { if (num < currencyValues.Length / 2) { if (!(currencyValues[num * 2] is string)) { throw new ArgumentException("Expected argument " + (num * 2 + 1) + " to be a string.", "currencyValues"); } if (!(currencyValues[num * 2 + 1] is decimal)) { break; } SetValue((string)currencyValues[num * 2], (decimal)currencyValues[num * 2 + 1]); num++; continue; } return; } throw new ArgumentException("Expected argument " + (num * 2 + 2) + " to be a decimal.", "currencyValues"); } private Currencies(List values) { if (values != null) { this.values = values; } } public static Currencies NonNull(Currencies c) { if (object.ReferenceEquals(c, null)) { return zero; } return c; } public static Currencies NonNegative(Currencies c) { for (int i = 0; i < c.values.Count; i++) { c.SetValue(c.values[i].Currency, (decimal)Mathf.Max((float)c.values[i].Value, 0f)); } return c; } public CurrencyValue GetCurrency(int index) { if (index >= 0 && index < values.Count) { return values[index]; } return null; } public decimal GetValue(string currency) { int num = IndexOfCurrency(currency); if (num < 0) { return 0.0m; } return values[num].Value; } public bool IsEmpty() { foreach (CurrencyValue value in values) { if (value.Value != 0.0m) { return false; } } return true; } public bool Contains(string currency) { return IndexOfCurrency(currency) >= 0; } public bool ContainsPositive(string currency) { int num = IndexOfCurrency(currency); if (num < 0) { return false; } return values[num].Value > 0m; } public bool ContainsApproximate(string currency) { int num = IndexOfCurrency(currency); if (num < 0) { return false; } return !Mathf.Approximately((float)GetValue(currency), 0f); } public Currencies MissingCurrencies(Currencies c) { List list = new List(); foreach (CurrencyValue value in c.values) { decimal num = GetValue(value.Currency) - value.Value; if (num < 0.0m) { CurrencyValue item = new CurrencyValue(value.Currency, -num); list.Add(item); } } return new Currencies(list); } public Currencies Round() { return Round(RoundingMethod.Nearest, 0); } public Currencies Round(RoundingMethod method) { return Round(method, 0); } public Currencies Round(int precision) { return Round(RoundingMethod.Nearest, precision); } public Currencies Round(RoundingMethod method, int precision) { List list = new List(); foreach (CurrencyValue value in values) { list.Add(value.Round(method, precision)); } return new Currencies(list); } public Currencies Cap(Currencies input, bool capUnknownWithZero) { Currencies currencies = new Currencies(); foreach (CurrencyValue value in input.values) { string currency = value.Currency; decimal num = value.Value; if (ContainsPositive(currency)) { num = Math.Min(num, GetValue(currency)); } else if (capUnknownWithZero) { num = 0m; } currencies.values.Add(new CurrencyValue(currency, num)); } return currencies; } public static bool TryParse(string currenciesformat, out Currencies result) { int num = currenciesformat.IndexOf("{"); int num2 = currenciesformat.IndexOf("}"); if (num < 0 || num2 < 0 || num2 <= num) { UnityEngine.Debug.LogError("Invalid Currencies format: " + currenciesformat); result = Zero; return false; } string text = currenciesformat.Substring(num + 1, num2 - num - 1).Trim(); if (text.Length == 0) { result = Zero; return true; } string[] array = text.Split(','); List list = new List(array.Length); string[] array2 = array; foreach (string text2 in array2) { string[] array3 = text2.Trim().Split(':'); decimal result2; if (array3.Length != 2) { UnityEngine.Debug.LogError("Invalid CurrencyValue format: " + text2); } else if (decimal.TryParse(array3[1], out result2)) { list.Add(new CurrencyValue(array3[0], result2)); } else { UnityEngine.Debug.LogError("Invalid CurrencyValue format: " + text2 + " (Cannot parse decimal: " + array3[1] + ")"); } } result = new Currencies(list); return true; } private int IndexOfCurrency(string currency) { if (currency == null) { return -1; } for (int i = 0; i < values.Count; i++) { if (currency.Equals(values[i].Currency)) { return i; } } return -1; } private void SetValue(string currency, decimal value) { int num = IndexOfCurrency(currency); if (num < 0) { if (currency != null) { for (num = 0; num < values.Count && string.Compare(currency, values[num].Currency) >= 0; num++) { } values.Insert(num, new CurrencyValue(currency, value)); } } else { values[num] = new CurrencyValue(currency, value); } hash = 0; } void IStorable.FromStorage(IDictionary dict) { values.Clear(); foreach (KeyValuePair item in dict) { values.Add(new CurrencyValue(item.Key, (decimal)item.Value)); } } IDictionary IStorable.ToStorage() { Dictionary dictionary = new Dictionary(values.Count); foreach (CurrencyValue value in values) { dictionary[value.Currency] = value.Value; } return dictionary; } public override int GetHashCode() { if (hash == 0) { hash = ToString().GetHashCode(); } return hash; } public override string ToString() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("{"); int num = 0; foreach (CurrencyValue value in values) { if (num > 0) { stringBuilder.Append(","); } stringBuilder.Append(value.ToString()); num++; } stringBuilder.Append("}"); return stringBuilder.ToString(); } public override bool Equals(object obj) { if (!(obj is Currencies)) { return false; } List list = (values != null) ? values : new List(); List list2 = (((Currencies)obj).values != null) ? ((Currencies)obj).values : new List(); int num = 0; while (num < list.Count) { if (list[num].Value == 0.0m) { list.RemoveAt(num); } else { num++; } } int num2 = 0; while (num2 < list2.Count) { if (list2[num2].Value == 0.0m) { list2.RemoveAt(num2); } else { num2++; } } if (list.Count != list2.Count) { return false; } for (int i = 0; i < list.Count; i++) { if (!object.Equals(list[i].Currency, list2[i].Currency) || list[i].Value != list2[i].Value) { return false; } } return true; } public static bool operator ==(Currencies c1, Currencies c2) { if (object.ReferenceEquals(c1, c2)) { return true; } if (object.ReferenceEquals(c1, null)) { return c2.IsEmpty(); } if (object.ReferenceEquals(c2, null)) { return c1.IsEmpty(); } return object.Equals(c1, c2); } public static bool operator !=(Currencies c1, Currencies c2) { if (object.ReferenceEquals(c1, c2)) { return false; } if (object.ReferenceEquals(c1, null)) { return !c2.IsEmpty(); } if (object.ReferenceEquals(c2, null)) { return !c1.IsEmpty(); } return !object.Equals(c1, c2); } public static Currencies operator -(Currencies c) { if (object.ReferenceEquals(c, null)) { return null; } List list = new List(); foreach (CurrencyValue value in c.values) { CurrencyValue item = new CurrencyValue(value.Currency, -value.Value); list.Add(item); } return new Currencies(list); } public static Currencies operator +(Currencies c1, Currencies c2) { if (object.ReferenceEquals(c1, null)) { if (object.ReferenceEquals(c2, null)) { return null; } return c2; } if (object.ReferenceEquals(c2, null)) { return c1; } List list = new List(c1.values); Currencies currencies = new Currencies(list); foreach (CurrencyValue value in c2.values) { currencies.SetValue(value.Currency, currencies.GetValue(value.Currency) + value.Value); } return new Currencies(list); } public static Currencies operator -(Currencies c1, Currencies c2) { if (object.ReferenceEquals(c1, null)) { if (object.ReferenceEquals(c2, null)) { return null; } return -c2; } if (object.ReferenceEquals(c2, null)) { return c1; } List list = new List(c1.values); Currencies currencies = new Currencies(list); foreach (CurrencyValue value in c2.values) { currencies.SetValue(value.Currency, currencies.GetValue(value.Currency) - value.Value); } return new Currencies(list); } public static Currencies operator *(Currencies c, decimal m) { if (object.ReferenceEquals(c, null)) { return null; } List list = new List(); foreach (CurrencyValue value in c.values) { CurrencyValue item = new CurrencyValue(value.Currency, value.Value * m); list.Add(item); } return new Currencies(list); } public static Currencies operator *(decimal m, Currencies c) { return c * m; } public static Currencies operator /(Currencies c, decimal d) { if (object.ReferenceEquals(c, null)) { return null; } List list = new List(); foreach (CurrencyValue value in c.values) { CurrencyValue item = new CurrencyValue(value.Currency, value.Value / d); list.Add(item); } return new Currencies(list); } } }