using RPGCore.Core.Objects; using RPGCore.ObjectModules.EventObjectModule; using RPGCore.Stats.ObjectModules.StatsObjectModule.Events; using RPGCoreCommon.DynamicValues; using UnityEngine; namespace RPGCore.Stats.ObjectModules.StatsObjectModule { /// /// You should never instantiate this by yourself! /// Instantiated automatically by for every available . /// public sealed class StatValue { public readonly StatDefinitionSO definition; private readonly BaseObject _parent; public readonly DynamicValueSourceContext sourceContext = new(); /// /// Base value defined in attached to . /// Formula result will be added to this base value. /// Default base value is ZERO. /// public int baseValue { get; private set; } /// /// This value is calculated by in and can have two meanings:
/// 1. If - just simple value stat
/// 2. If - this is maximum value for that resource ///
public int value { get; private set; } /// /// Usable only when . is .
/// This value represent current resource of this stat. Always between and ///
public int resource { get; private set; } internal StatValue(StatDefinitionSO definition, int baseValue, BaseObject parent) { this.definition = definition; _parent = parent; this.baseValue = baseValue; } /// /// Refreshes , by calculating formula again. /// internal void Refresh() { var previous = value; value = baseValue + definition.dynamicValue.GetValue(sourceContext); _parent.events.Invoke(new StatValueChangeEvent { after = value, before = previous, statDefinition = definition, target = _parent }); } /// /// Sets new and then do to recalculate whole /// /// New base value public void SetBase(int amount) { baseValue = amount; Refresh(); } /// /// Changes (or simpler - uses) of this stat value by given amount. /// It just calls with: + /// /// Amount that will be added or subtracted from public void ChangeResource(int amount) { SetResource(resource + amount); } /// /// Sets to given amount. Amount will be clamped between ZERO and . /// /// New amount public void SetResource(int amount) { var old = resource; resource = Mathf.Clamp(amount, 0, value); _parent.events.Invoke(new StatResourceChangeEvent { delta = resource - old, after = resource, before = old, statDefinition = definition, target = _parent }); } /// /// Sets to given percentage. Percentage will be clamped between ZERO and ONE. /// /// New percentage public void SetResource(float percentage) { SetResource(Mathf.CeilToInt(Mathf.Clamp01(percentage) * value)); } } }