using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using Sirenix.OdinInspector; using NCalc; namespace KairoEngine.Stats { [System.Serializable] public class Stat { [HideInInspector] public string title; private string description; [LabelText("@title"), PropertyOrder(1)] [ProgressBar("@_minValue + modifiers.minValue", "@_maxValue + modifiers.maxValue", ColorGetter="GetDisplayColor", Height=18)] [PropertyTooltip("@description"), ShowInInspector, InlineButton("ShowModifiers", "@modifiers.pretyCount()")] public int value { get { if(template.currentValueType == StatValueType.Equation) this._value = SolveEquation(template.currentValueEquation); int finalValue = this._value; finalValue += modifiers.value; if(finalValue > maxValue) finalValue = maxValue; if(finalValue < minValue) finalValue = minValue; return finalValue; } set { if(template.currentValueType == StatValueType.Value) this._value = value; else _value = SolveEquation(template.currentValueEquation); if(this._value > maxValue) this._value = maxValue; if(this._value < minValue) this._value = minValue; if(this._value != value) Changed(); } } [SerializeField, HideInInspector] private int _value; public int GetValueRaw() => _value; public int minValue { get { if(template.minValueType == StatValueType.Equation) this._minValue = SolveEquation(template.minValueEquation); int finalValue = this._minValue; finalValue += modifiers.minValue; return finalValue; } set { if(template.minValueType == StatValueType.Value) this._minValue = value; else this._minValue = SolveEquation(template.minValueEquation); } } [SerializeField, HideInInspector] private int _minValue = 0; public int GetMinValueRaw() => _minValue; public int maxValue { get { if(template.maxValueType == StatValueType.Equation) this._maxValue = SolveEquation(template.maxValueEquation); int finalValue = this._maxValue; finalValue += modifiers.maxValue; return finalValue; } set { if(template.maxValueType == StatValueType.Value) this._maxValue = value; else this._maxValue = SolveEquation(template.maxValueEquation); } } [SerializeField, HideInInspector] private int _maxValue = 1; public int GetMaxValueRaw() => _maxValue; private bool showModifiersEditor = false; [PropertyOrder(2), InlineProperty, HideLabel, ShowIf("@showModifiersEditor"), Space] public StatModifiersController modifiers; [SerializeField, HideInInspector] public StatTemplate template; [HideInInspector, System.NonSerialized] public StatsController controller; public Stat(StatTemplate template, StatsController controller, SerializedStat data = null) { this.title = template.title; this.template = template; this.controller = controller; this.description = template.description; this.modifiers = new StatModifiersController(this); if(data != null) { _value = data.value; _minValue = data.minValue; _maxValue = data.maxValue; for (int i = 0; i < data.modifiers.Count; i++) modifiers.list.Add(data.modifiers[i]); } this.modifiers.Calculate(); } public void Initialize() { if(template.currentValueType == StatValueType.Value) { if(template.initialValueType == StatValueType.Value) this.value = template.initialValue; else this.value = SolveEquation(template.initialValueEquation); } else this._value = value; this.minValue = template.minValue; this.maxValue = template.maxValue; modifiers.stat = this; } public void Update() { title = template.title; description = template.description; value = _value; minValue = _minValue; maxValue =_maxValue; //Debug.Log($"Updating {StatLog()}"); } public void Changed() => controller.UpdateStats(); public int SolveEquation(string equation) { int result = 0; if(equation == "") { Debug.LogError(StatLog()); return result; } if(controller == null) return result; var expr = new Expression(equation); Func f = expr.ToLambda(); var context = new StatEquationContext { value = _value, minValue = _minValue, maxValue = _maxValue, controller = controller}; result = f(context); //Debug.Log($"{title}: {equation} = {result}"); return result; } public string StatLog() { string s = $" {title}: "; s += $" value={this._value} minValue={this._minValue} maxValue={this._maxValue} "; if(template.currentValueType == StatValueType.Equation) s += $"currentEquation='{template.currentValueEquation}' "; if(template.initialValueType == StatValueType.Equation) s += $"initialEquation='{template.initialValueEquation}' "; if(template.minValueType == StatValueType.Equation) s += $"minEquation='{template.minValueEquation}' "; if(template.maxValueType == StatValueType.Equation) s += $"maxEquation='{template.maxValueEquation}' "; return s; } private Color GetDisplayColor() { if(template.currentValueType == StatValueType.Equation) return Color.gray; else { Color color; if ( !ColorUtility.TryParseHtmlString("#3e649e", out color)) color = Color.cyan; return color; } } public SerializedStat Serialize() => new SerializedStat(title, _value, _minValue, _maxValue, modifiers.list); public static Stat Deserialize(SerializedStat data, StatsController controller) { Stat stat = new Stat(controller.GetStatTemplate(data.title), controller, data); return stat; } public void ShowModifiers() { if(showModifiersEditor) showModifiersEditor = false; else showModifiersEditor = true; modifiers.Calculate(); } } public class StatEquationContext { public int value { get; set; } public int minValue { get; set; } public int maxValue { get; set; } public StatsController controller { get; set; } public int s(string title) => controller.GetStatValue(title); } [System.Serializable] public class SerializedStat { public string title; public int value; public int minValue; public int maxValue; public List modifiers = new List(); public SerializedStat(string title, int value, int minValue, int maxValue, List modifiers) { this.title = title; this.value = value; this.minValue = minValue; this.maxValue = maxValue; for (int i = 0; i < modifiers.Count; i++) { this.modifiers.Add(modifiers[i]); } } } }