Stat.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using Sirenix.OdinInspector;
  6. using NCalc;
  7. namespace KairoEngine.Stats
  8. {
  9. [System.Serializable]
  10. public class Stat
  11. {
  12. [HideInInspector] public string title;
  13. private string description;
  14. [LabelText("@title"), PropertyOrder(1)]
  15. [ProgressBar("@_minValue + modifiers.minValue", "@_maxValue + modifiers.maxValue", ColorGetter="GetDisplayColor", Height=18)]
  16. [PropertyTooltip("@description"), ShowInInspector, InlineButton("ShowModifiers", "@modifiers.pretyCount()")]
  17. public int value
  18. {
  19. get
  20. {
  21. if(template.currentValueType == StatValueType.Equation) this._value = SolveEquation(template.currentValueEquation);
  22. int finalValue = this._value;
  23. finalValue += modifiers.value;
  24. if(finalValue > maxValue) finalValue = maxValue;
  25. if(finalValue < minValue) finalValue = minValue;
  26. return finalValue;
  27. }
  28. set
  29. {
  30. if(template.currentValueType == StatValueType.Value) this._value = value;
  31. else _value = SolveEquation(template.currentValueEquation);
  32. if(this._value > maxValue) this._value = maxValue;
  33. if(this._value < minValue) this._value = minValue;
  34. if(this._value != value) Changed();
  35. }
  36. }
  37. [SerializeField, HideInInspector] private int _value;
  38. public int GetValueRaw() => _value;
  39. public int minValue
  40. {
  41. get
  42. {
  43. if(template.minValueType == StatValueType.Equation) this._minValue = SolveEquation(template.minValueEquation);
  44. int finalValue = this._minValue;
  45. finalValue += modifiers.minValue;
  46. return finalValue;
  47. }
  48. set
  49. {
  50. if(template.minValueType == StatValueType.Value) this._minValue = value;
  51. else this._minValue = SolveEquation(template.minValueEquation);
  52. }
  53. }
  54. [SerializeField, HideInInspector] private int _minValue = 0;
  55. public int GetMinValueRaw() => _minValue;
  56. public int maxValue
  57. {
  58. get
  59. {
  60. if(template.maxValueType == StatValueType.Equation) this._maxValue = SolveEquation(template.maxValueEquation);
  61. int finalValue = this._maxValue;
  62. finalValue += modifiers.maxValue;
  63. return finalValue;
  64. }
  65. set
  66. {
  67. if(template.maxValueType == StatValueType.Value) this._maxValue = value;
  68. else this._maxValue = SolveEquation(template.maxValueEquation);
  69. }
  70. }
  71. [SerializeField, HideInInspector] private int _maxValue = 1;
  72. public int GetMaxValueRaw() => _maxValue;
  73. private bool showModifiersEditor = false;
  74. [PropertyOrder(2), InlineProperty, HideLabel, ShowIf("@showModifiersEditor"), Space] public StatModifiersController modifiers;
  75. [SerializeField, HideInInspector] public StatTemplate template;
  76. [HideInInspector, System.NonSerialized] public StatsController controller;
  77. public Stat(StatTemplate template, StatsController controller, SerializedStat data = null)
  78. {
  79. this.title = template.title;
  80. this.template = template;
  81. this.controller = controller;
  82. this.description = template.description;
  83. this.modifiers = new StatModifiersController(this);
  84. if(data != null)
  85. {
  86. _value = data.value;
  87. _minValue = data.minValue;
  88. _maxValue = data.maxValue;
  89. for (int i = 0; i < data.modifiers.Count; i++) modifiers.list.Add(data.modifiers[i]);
  90. }
  91. this.modifiers.Calculate();
  92. }
  93. public void Initialize()
  94. {
  95. if(template.currentValueType == StatValueType.Value)
  96. {
  97. if(template.initialValueType == StatValueType.Value) this.value = template.initialValue;
  98. else this.value = SolveEquation(template.initialValueEquation);
  99. }
  100. else this._value = value;
  101. this.minValue = template.minValue;
  102. this.maxValue = template.maxValue;
  103. modifiers.stat = this;
  104. }
  105. public void Update()
  106. {
  107. title = template.title;
  108. description = template.description;
  109. value = _value;
  110. minValue = _minValue;
  111. maxValue =_maxValue;
  112. //Debug.Log($"Updating {StatLog()}");
  113. }
  114. public void Changed() => controller.UpdateStats();
  115. public int SolveEquation(string equation)
  116. {
  117. int result = 0;
  118. if(equation == "")
  119. {
  120. Debug.LogError(StatLog());
  121. return result;
  122. }
  123. if(controller == null) return result;
  124. var expr = new Expression(equation);
  125. Func<StatEquationContext, int> f = expr.ToLambda<StatEquationContext, int>();
  126. var context = new StatEquationContext { value = _value, minValue = _minValue, maxValue = _maxValue, controller = controller};
  127. result = f(context);
  128. //Debug.Log($"{title}: {equation} = {result}");
  129. return result;
  130. }
  131. public string StatLog()
  132. {
  133. string s = $" {title}: ";
  134. s += $" value={this._value} minValue={this._minValue} maxValue={this._maxValue} ";
  135. if(template.currentValueType == StatValueType.Equation) s += $"currentEquation='{template.currentValueEquation}' ";
  136. if(template.initialValueType == StatValueType.Equation) s += $"initialEquation='{template.initialValueEquation}' ";
  137. if(template.minValueType == StatValueType.Equation) s += $"minEquation='{template.minValueEquation}' ";
  138. if(template.maxValueType == StatValueType.Equation) s += $"maxEquation='{template.maxValueEquation}' ";
  139. return s;
  140. }
  141. private Color GetDisplayColor()
  142. {
  143. if(template.currentValueType == StatValueType.Equation) return Color.gray;
  144. else
  145. {
  146. Color color;
  147. if ( !ColorUtility.TryParseHtmlString("#3e649e", out color)) color = Color.cyan;
  148. return color;
  149. }
  150. }
  151. public SerializedStat Serialize() => new SerializedStat(title, _value, _minValue, _maxValue, modifiers.list);
  152. public static Stat Deserialize(SerializedStat data, StatsController controller)
  153. {
  154. Stat stat = new Stat(controller.GetStatTemplate(data.title), controller, data);
  155. return stat;
  156. }
  157. public void ShowModifiers()
  158. {
  159. if(showModifiersEditor) showModifiersEditor = false;
  160. else showModifiersEditor = true;
  161. modifiers.Calculate();
  162. }
  163. }
  164. public class StatEquationContext
  165. {
  166. public int value { get; set; }
  167. public int minValue { get; set; }
  168. public int maxValue { get; set; }
  169. public StatsController controller { get; set; }
  170. public int s(string title) => controller.GetStatValue(title);
  171. }
  172. [System.Serializable]
  173. public class SerializedStat
  174. {
  175. public string title;
  176. public int value;
  177. public int minValue;
  178. public int maxValue;
  179. public List<StatModifier> modifiers = new List<StatModifier>();
  180. public SerializedStat(string title, int value, int minValue, int maxValue, List<StatModifier> modifiers)
  181. {
  182. this.title = title;
  183. this.value = value;
  184. this.minValue = minValue;
  185. this.maxValue = maxValue;
  186. for (int i = 0; i < modifiers.Count; i++)
  187. {
  188. this.modifiers.Add(modifiers[i]);
  189. }
  190. }
  191. }
  192. }