using System; using System.Collections.Generic; using UnityEngine; namespace CleverCrow.Fluid.StatsSystem { public class StatModifierCollection { private OperatorType _type; private Dictionary _dicValues = new Dictionary(); private List _listValues = new List(); /// /// Round all set numbers automatically /// public bool forceRound; public delegate void Action (); public event Action onDirty; /// /// List of all available values. WARNING editing this list directly will cause the StatModifierGroup to crash. /// public List ListValues => _listValues; public StatModifierCollection (OperatorType type) { _type = type; } /// /// Retrieve the modifier by id /// /// Identifier. public StatModifier Get (string id) { if (string.IsNullOrEmpty(id) || !_dicValues.TryGetValue(id, out var output)) { return null; } return output; } /// /// Set or change a modifier /// /// Identifier. /// Value. public void Set (string id, float value) { if (string.IsNullOrEmpty(id)) { return; } if (forceRound) { value = Mathf.Round(value); } if (_dicValues.TryGetValue(id, out var mod)) { mod.value = value; } else { // No value was found to modify, create a new one mod = new StatModifier(id, value); _dicValues[id] = mod; _listValues.Add(mod); } if (onDirty != null) onDirty.Invoke(); } /// /// Wipes a modifier from memory /// /// Identifier. public bool Remove (string id) { var target = Get(id); if (target == null) { return false; } _dicValues.Remove(id); _listValues.Remove(target); if (onDirty != null) onDirty.Invoke(); return true; } /// /// Modify a value based upon the modifiers /// /// /// /// public float ModifyValue (float original) { if (_type == OperatorType.Multiply) { var multiplier = 0f; foreach (var statModifier in _listValues) { multiplier += statModifier.value; } return Mathf.Max(0, original + original * multiplier); } var newVal = original; foreach (var statModifier in _listValues) { switch (_type) { case OperatorType.Add: newVal += statModifier.value; break; case OperatorType.Subtract: newVal -= statModifier.value; break; case OperatorType.Divide: newVal /= statModifier.value; break; default: throw new ArgumentOutOfRangeException(); } } return newVal; } } }