1 
using System;
   2 
using System.Collections.Generic;
   3 
 
   4 
namespace Sapling.Character {
   5 
    public class AbilityTrait {
   6 
        const int GROWTH_DIVISOR = 128;
   7 
 
   8 
        public enum ModifierType : uint { Add, Mult }
   9 
 
  10 
        public struct Modifier
  11 
        {
  12 
            internal string id;
  13 
            internal ModifierType type;
  14 
            internal float value;
  15 
 
  16 
            public Modifier(string aId, int aAdd)
  17 
                : this(aId, ModifierType.Add, (float)aAdd) {}
  18 
 
  19 
            public Modifier(string aId, float aMult)
  20 
                : this(aId, ModifierType.Mult, aMult) {}
  21 
 
  22 
            public Modifier(string aId, ModifierType aType, float aValue)
  23 
            {
  24 
                id = aId;
  25 
                type = aType;
  26 
                value = aValue;
  27 
            }
  28 
        }
  29 
 
  30 
        public int baseValue { get { return _baseValue; } }
  31 
 
  32 
        public int currentValue { get { return _currentValue; } }
  33 
 
  34 
        public int effectiveValue { get { return _effectiveValue; } }
  35 
 
  36 
        public string id { get { return _id; } }
  37 
 
  38 
        private int _baseValue;
  39 
        private int _bonus = 0;
  40 
        private int _currentValue;
  41 
        private int _effectiveValue;
  42 
        private int _growthFactor;
  43 
        private string _id;
  44 
        private Dictionary<string, Modifier> _modifiers = new Dictionary<string, Modifier>();
  45 
 
  46 
       
  47 
        public AbilityTrait(string aId, int aBaseValue, int aGrowthFactor)
  48 
            : this(aId, aBaseValue, aGrowthFactor, 1) {}
  49 
 
  50 
        public AbilityTrait(string aId, int aBaseValue, int aGrowthFactor, int aLevel)
  51 
        {
  52 
            _id = aId;
  53 
            _baseValue = aBaseValue;
  54 
            _growthFactor = aGrowthFactor;
  55 
            SetLevel(aLevel);
  56 
        }
  57 
 
  58 
       
  59 
        public void AddModifier(string aId, int aAdd)
  60 
        {
  61 
            AddModifier(new Modifier(aId, aAdd));
  62 
        }
  63 
 
  64 
        public void AddModifier(string aId, float aMult)
  65 
        {
  66 
            AddModifier(new Modifier(aId, aMult));
  67 
        }
  68 
 
  69 
        public void AddModifier(Modifier aMod)
  70 
        {
  71 
            _modifiers[aMod.id] = aMod;
  72 
        }
  73 
 
  74 
        public void ClearModifiers()
  75 
        {
  76 
            _modifiers.Clear();
  77 
        }
  78 
 
  79 
        private void Recalculate()
  80 
        {
  81 
            _currentValue = _baseValue + _bonus;
  82 
 
  83 
            float accum = (float)_currentValue;
  84 
            float add = 0f;
  85 
            float mult = 1f;
  86 
            foreach (Modifier mod in _modifiers.Values)
  87 
            {
  88 
                if (mod.type == ModifierType.Add)
  89 
                {
  90 
                    add += mod.value;
  91 
                }
  92 
                else
  93 
                {
  94 
                    mult += mod.value;
  95 
                }
  96 
            }
  97 
            accum = (accum * mult) + add;
  98 
            _effectiveValue = (int)accum;
  99 
        }
 100 
 
 101 
        public void RemoveModifier(Modifier aMod)
 102 
        {
 103 
            RemoveModifier(aMod.id);
 104 
        }
 105 
 
 106 
        public void RemoveModifier(string aId)
 107 
        {
 108 
            _modifiers.Remove(aId);
 109 
        }
 110 
 
 111 
        public int SetLevel(int aLevel)
 112 
        {
 113 
            _bonus = (level * _growthFactor) / GROWTH_DIVISOR;
 114 
            Recalculate();
 115 
            return _currentValue;
 116 
        }
 117 
 
 118 
        public int SetLevel(int aLevel, out int oldValue)
 119 
        {
 120 
            oldValue = _currentValue;
 121 
            return SetLevel(aLevel);
 122 
        }
 123 
    }
 124 
}