You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

524 lines
16 KiB

  1. using SUISS.Storage;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Text;
  5. using UnityEngine;
  6. namespace SUISSEngine
  7. {
  8. [Serializable]
  9. public class Currencies : IStorable
  10. {
  11. public enum RoundingMethod
  12. {
  13. Nearest,
  14. Floor,
  15. Ceiling
  16. }
  17. private static Currencies zero = new Currencies();
  18. [SerializeField]
  19. private List<CurrencyValue> values = new List<CurrencyValue>();
  20. private int hash;
  21. public static Currencies Zero => zero;
  22. public int KeyCount => values.Count;
  23. public Currencies()
  24. {
  25. }
  26. public Currencies(Currencies copyFrom)
  27. {
  28. foreach (CurrencyValue value in copyFrom.values)
  29. {
  30. SetValue(value.Currency, value.Value);
  31. }
  32. }
  33. public Currencies(string currency, decimal value)
  34. {
  35. if (currency == null)
  36. {
  37. throw new ArgumentException("Currency can't be null.", "currency");
  38. }
  39. SetValue(currency, value);
  40. }
  41. public Currencies(params object[] currencyValues)
  42. {
  43. if (currencyValues == null)
  44. {
  45. return;
  46. }
  47. if (currencyValues.Length % 2 != 0)
  48. {
  49. throw new ArgumentException("Expected an even number of arguments.", "currencyValues");
  50. }
  51. int num = 0;
  52. while (true)
  53. {
  54. if (num < currencyValues.Length / 2)
  55. {
  56. if (!(currencyValues[num * 2] is string))
  57. {
  58. throw new ArgumentException("Expected argument " + (num * 2 + 1) + " to be a string.", "currencyValues");
  59. }
  60. if (!(currencyValues[num * 2 + 1] is decimal))
  61. {
  62. break;
  63. }
  64. SetValue((string)currencyValues[num * 2], (decimal)currencyValues[num * 2 + 1]);
  65. num++;
  66. continue;
  67. }
  68. return;
  69. }
  70. throw new ArgumentException("Expected argument " + (num * 2 + 2) + " to be a decimal.", "currencyValues");
  71. }
  72. private Currencies(List<CurrencyValue> values)
  73. {
  74. if (values != null)
  75. {
  76. this.values = values;
  77. }
  78. }
  79. public static Currencies NonNull(Currencies c)
  80. {
  81. if (object.ReferenceEquals(c, null))
  82. {
  83. return zero;
  84. }
  85. return c;
  86. }
  87. public static Currencies NonNegative(Currencies c)
  88. {
  89. for (int i = 0; i < c.values.Count; i++)
  90. {
  91. c.SetValue(c.values[i].Currency, (decimal)Mathf.Max((float)c.values[i].Value, 0f));
  92. }
  93. return c;
  94. }
  95. public CurrencyValue GetCurrency(int index)
  96. {
  97. if (index >= 0 && index < values.Count)
  98. {
  99. return values[index];
  100. }
  101. return null;
  102. }
  103. public decimal GetValue(string currency)
  104. {
  105. int num = IndexOfCurrency(currency);
  106. if (num < 0)
  107. {
  108. return 0.0m;
  109. }
  110. return values[num].Value;
  111. }
  112. public bool IsEmpty()
  113. {
  114. foreach (CurrencyValue value in values)
  115. {
  116. if (value.Value != 0.0m)
  117. {
  118. return false;
  119. }
  120. }
  121. return true;
  122. }
  123. public bool Contains(string currency)
  124. {
  125. return IndexOfCurrency(currency) >= 0;
  126. }
  127. public bool ContainsPositive(string currency)
  128. {
  129. int num = IndexOfCurrency(currency);
  130. if (num < 0)
  131. {
  132. return false;
  133. }
  134. return values[num].Value > 0m;
  135. }
  136. public bool ContainsApproximate(string currency)
  137. {
  138. int num = IndexOfCurrency(currency);
  139. if (num < 0)
  140. {
  141. return false;
  142. }
  143. return !Mathf.Approximately((float)GetValue(currency), 0f);
  144. }
  145. public Currencies MissingCurrencies(Currencies c)
  146. {
  147. List<CurrencyValue> list = new List<CurrencyValue>();
  148. foreach (CurrencyValue value in c.values)
  149. {
  150. decimal num = GetValue(value.Currency) - value.Value;
  151. if (num < 0.0m)
  152. {
  153. CurrencyValue item = new CurrencyValue(value.Currency, -num);
  154. list.Add(item);
  155. }
  156. }
  157. return new Currencies(list);
  158. }
  159. public Currencies Round()
  160. {
  161. return Round(RoundingMethod.Nearest, 0);
  162. }
  163. public Currencies Round(RoundingMethod method)
  164. {
  165. return Round(method, 0);
  166. }
  167. public Currencies Round(int precision)
  168. {
  169. return Round(RoundingMethod.Nearest, precision);
  170. }
  171. public Currencies Round(RoundingMethod method, int precision)
  172. {
  173. List<CurrencyValue> list = new List<CurrencyValue>();
  174. foreach (CurrencyValue value in values)
  175. {
  176. list.Add(value.Round(method, precision));
  177. }
  178. return new Currencies(list);
  179. }
  180. public Currencies Cap(Currencies input, bool capUnknownWithZero)
  181. {
  182. Currencies currencies = new Currencies();
  183. foreach (CurrencyValue value in input.values)
  184. {
  185. string currency = value.Currency;
  186. decimal num = value.Value;
  187. if (ContainsPositive(currency))
  188. {
  189. num = Math.Min(num, GetValue(currency));
  190. }
  191. else if (capUnknownWithZero)
  192. {
  193. num = 0m;
  194. }
  195. currencies.values.Add(new CurrencyValue(currency, num));
  196. }
  197. return currencies;
  198. }
  199. public static bool TryParse(string currenciesformat, out Currencies result)
  200. {
  201. int num = currenciesformat.IndexOf("{");
  202. int num2 = currenciesformat.IndexOf("}");
  203. if (num < 0 || num2 < 0 || num2 <= num)
  204. {
  205. UnityEngine.Debug.LogError("Invalid Currencies format: " + currenciesformat);
  206. result = Zero;
  207. return false;
  208. }
  209. string text = currenciesformat.Substring(num + 1, num2 - num - 1).Trim();
  210. if (text.Length == 0)
  211. {
  212. result = Zero;
  213. return true;
  214. }
  215. string[] array = text.Split(',');
  216. List<CurrencyValue> list = new List<CurrencyValue>(array.Length);
  217. string[] array2 = array;
  218. foreach (string text2 in array2)
  219. {
  220. string[] array3 = text2.Trim().Split(':');
  221. decimal result2;
  222. if (array3.Length != 2)
  223. {
  224. UnityEngine.Debug.LogError("Invalid CurrencyValue format: " + text2);
  225. }
  226. else if (decimal.TryParse(array3[1], out result2))
  227. {
  228. list.Add(new CurrencyValue(array3[0], result2));
  229. }
  230. else
  231. {
  232. UnityEngine.Debug.LogError("Invalid CurrencyValue format: " + text2 + " (Cannot parse decimal: " + array3[1] + ")");
  233. }
  234. }
  235. result = new Currencies(list);
  236. return true;
  237. }
  238. private int IndexOfCurrency(string currency)
  239. {
  240. if (currency == null)
  241. {
  242. return -1;
  243. }
  244. for (int i = 0; i < values.Count; i++)
  245. {
  246. if (currency.Equals(values[i].Currency))
  247. {
  248. return i;
  249. }
  250. }
  251. return -1;
  252. }
  253. private void SetValue(string currency, decimal value)
  254. {
  255. int num = IndexOfCurrency(currency);
  256. if (num < 0)
  257. {
  258. if (currency != null)
  259. {
  260. for (num = 0; num < values.Count && string.Compare(currency, values[num].Currency) >= 0; num++)
  261. {
  262. }
  263. values.Insert(num, new CurrencyValue(currency, value));
  264. }
  265. }
  266. else
  267. {
  268. values[num] = new CurrencyValue(currency, value);
  269. }
  270. hash = 0;
  271. }
  272. void IStorable.FromStorage(IDictionary<string, object> dict)
  273. {
  274. values.Clear();
  275. foreach (KeyValuePair<string, object> item in dict)
  276. {
  277. values.Add(new CurrencyValue(item.Key, (decimal)item.Value));
  278. }
  279. }
  280. IDictionary<string, object> IStorable.ToStorage()
  281. {
  282. Dictionary<string, object> dictionary = new Dictionary<string, object>(values.Count);
  283. foreach (CurrencyValue value in values)
  284. {
  285. dictionary[value.Currency] = value.Value;
  286. }
  287. return dictionary;
  288. }
  289. public override int GetHashCode()
  290. {
  291. if (hash == 0)
  292. {
  293. hash = ToString().GetHashCode();
  294. }
  295. return hash;
  296. }
  297. public override string ToString()
  298. {
  299. StringBuilder stringBuilder = new StringBuilder();
  300. stringBuilder.Append("{");
  301. int num = 0;
  302. foreach (CurrencyValue value in values)
  303. {
  304. if (num > 0)
  305. {
  306. stringBuilder.Append(",");
  307. }
  308. stringBuilder.Append(value.ToString());
  309. num++;
  310. }
  311. stringBuilder.Append("}");
  312. return stringBuilder.ToString();
  313. }
  314. public override bool Equals(object obj)
  315. {
  316. if (!(obj is Currencies))
  317. {
  318. return false;
  319. }
  320. List<CurrencyValue> list = (values != null) ? values : new List<CurrencyValue>();
  321. List<CurrencyValue> list2 = (((Currencies)obj).values != null) ? ((Currencies)obj).values : new List<CurrencyValue>();
  322. int num = 0;
  323. while (num < list.Count)
  324. {
  325. if (list[num].Value == 0.0m)
  326. {
  327. list.RemoveAt(num);
  328. }
  329. else
  330. {
  331. num++;
  332. }
  333. }
  334. int num2 = 0;
  335. while (num2 < list2.Count)
  336. {
  337. if (list2[num2].Value == 0.0m)
  338. {
  339. list2.RemoveAt(num2);
  340. }
  341. else
  342. {
  343. num2++;
  344. }
  345. }
  346. if (list.Count != list2.Count)
  347. {
  348. return false;
  349. }
  350. for (int i = 0; i < list.Count; i++)
  351. {
  352. if (!object.Equals(list[i].Currency, list2[i].Currency) || list[i].Value != list2[i].Value)
  353. {
  354. return false;
  355. }
  356. }
  357. return true;
  358. }
  359. public static bool operator ==(Currencies c1, Currencies c2)
  360. {
  361. if (object.ReferenceEquals(c1, c2))
  362. {
  363. return true;
  364. }
  365. if (object.ReferenceEquals(c1, null))
  366. {
  367. return c2.IsEmpty();
  368. }
  369. if (object.ReferenceEquals(c2, null))
  370. {
  371. return c1.IsEmpty();
  372. }
  373. return object.Equals(c1, c2);
  374. }
  375. public static bool operator !=(Currencies c1, Currencies c2)
  376. {
  377. if (object.ReferenceEquals(c1, c2))
  378. {
  379. return false;
  380. }
  381. if (object.ReferenceEquals(c1, null))
  382. {
  383. return !c2.IsEmpty();
  384. }
  385. if (object.ReferenceEquals(c2, null))
  386. {
  387. return !c1.IsEmpty();
  388. }
  389. return !object.Equals(c1, c2);
  390. }
  391. public static Currencies operator -(Currencies c)
  392. {
  393. if (object.ReferenceEquals(c, null))
  394. {
  395. return null;
  396. }
  397. List<CurrencyValue> list = new List<CurrencyValue>();
  398. foreach (CurrencyValue value in c.values)
  399. {
  400. CurrencyValue item = new CurrencyValue(value.Currency, -value.Value);
  401. list.Add(item);
  402. }
  403. return new Currencies(list);
  404. }
  405. public static Currencies operator +(Currencies c1, Currencies c2)
  406. {
  407. if (object.ReferenceEquals(c1, null))
  408. {
  409. if (object.ReferenceEquals(c2, null))
  410. {
  411. return null;
  412. }
  413. return c2;
  414. }
  415. if (object.ReferenceEquals(c2, null))
  416. {
  417. return c1;
  418. }
  419. List<CurrencyValue> list = new List<CurrencyValue>(c1.values);
  420. Currencies currencies = new Currencies(list);
  421. foreach (CurrencyValue value in c2.values)
  422. {
  423. currencies.SetValue(value.Currency, currencies.GetValue(value.Currency) + value.Value);
  424. }
  425. return new Currencies(list);
  426. }
  427. public static Currencies operator -(Currencies c1, Currencies c2)
  428. {
  429. if (object.ReferenceEquals(c1, null))
  430. {
  431. if (object.ReferenceEquals(c2, null))
  432. {
  433. return null;
  434. }
  435. return -c2;
  436. }
  437. if (object.ReferenceEquals(c2, null))
  438. {
  439. return c1;
  440. }
  441. List<CurrencyValue> list = new List<CurrencyValue>(c1.values);
  442. Currencies currencies = new Currencies(list);
  443. foreach (CurrencyValue value in c2.values)
  444. {
  445. currencies.SetValue(value.Currency, currencies.GetValue(value.Currency) - value.Value);
  446. }
  447. return new Currencies(list);
  448. }
  449. public static Currencies operator *(Currencies c, decimal m)
  450. {
  451. if (object.ReferenceEquals(c, null))
  452. {
  453. return null;
  454. }
  455. List<CurrencyValue> list = new List<CurrencyValue>();
  456. foreach (CurrencyValue value in c.values)
  457. {
  458. CurrencyValue item = new CurrencyValue(value.Currency, value.Value * m);
  459. list.Add(item);
  460. }
  461. return new Currencies(list);
  462. }
  463. public static Currencies operator *(decimal m, Currencies c)
  464. {
  465. return c * m;
  466. }
  467. public static Currencies operator /(Currencies c, decimal d)
  468. {
  469. if (object.ReferenceEquals(c, null))
  470. {
  471. return null;
  472. }
  473. List<CurrencyValue> list = new List<CurrencyValue>();
  474. foreach (CurrencyValue value in c.values)
  475. {
  476. CurrencyValue item = new CurrencyValue(value.Currency, value.Value / d);
  477. list.Add(item);
  478. }
  479. return new Currencies(list);
  480. }
  481. }
  482. }