using MalbersAnimations.Events;
using MalbersAnimations.Scriptables;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace MalbersAnimations
{
/// Component managing Stat Logic
[AddComponentMenu("Malbers/Stats/Stats Manager")]
public class Stats : MonoBehaviour, IAnimatorListener
{
//[Tooltip("Track these Stats in a Runtime Set")]
//[CreateScriptableAsset] public RuntimeStats Set;
/// List of Stats
public List stats = new List();
/// List of Stats Converted to Dictionary
public Dictionary stats_D;
/// Stored Stat to use the 'Pin' Methods
public Stat PinnedStat;
public virtual bool OnAnimatorBehaviourMessage(string message, object value) => this.InvokeWithParams(message, value);
public void Initialize()
{
StopAllCoroutines();
stats_D = new Dictionary();
foreach (var stat in stats)
{
if (stat.ID == null)
{
Debug.LogError("One of the Stats has an Empty ID", gameObject);
break;
}
stat.InitializeStat(this);
if (!stats_D.ContainsKey(stat.ID)) //Added by SkillManiacs 2020/10
{
stats_D.Add(stat.ID, stat); //Convert them to Dictionary
}
else
{
stats_D[stat.ID] = stat; //Replace it
}
}
}
private void Awake()
{
Initialize();
}
private void OnEnable()
{
foreach (var stat in stats_D)
{
if (stat.Value.ID == null)
{
Debug.LogError("One of the Stats has an Empty ID", gameObject);
break;
}
stat.Value.InitializeStat(this);
}
}
private void OnDisable() => StopAllCoroutines();
/// Updates all Stats
public virtual void Stats_Update()
{
foreach (var s in stats) s.UpdateStat();
}
/// Updates a stat logic by its Stat ID
public virtual void Stats_Update(StatID iD) => Stats_Update(iD.ID);
public virtual void Stats_Update(int iD) => Stat_Get(iD)?.UpdateStat();
/// Reset a Stat to the Default Max Value
public virtual void Stat_Reset_to_Max(StatID iD) => Stat_Get(iD)?.Reset_to_Max();
/// Reset a Stat to the Default Min Value
public virtual void Stat_Reset_to_Min(StatID iD) => Stat_Get(iD)?.Reset_to_Min();
/// Disable a stat
public virtual void Stat_Disable(StatID iD) => Stat_Get(iD)?.SetActive(false);
/// Disable a stat Degeneration logic
public virtual void Stat_Degenerate_Off(StatID ID) => Stat_Get(ID)?.SetDegeneration(false);
/// Enable a stat Degeneration logic
public virtual void Stat_Degenerate_On(StatID ID) => Stat_Get(ID)?.SetDegeneration(true);
/// Disable a stat Regeneration logic
public virtual void Stat_Regenerate_Off(StatID ID) => Stat_Get(ID)?.SetRegeneration(false);
/// Enable a stat Regeneration logic
public virtual void Stat_Regenerate_On(StatID ID) => Stat_Get(ID)?.SetRegeneration(true);
#region Callbacks with StatID parameters
/// Enable a stat
public virtual void Stat_Enable(StatID iD) => Stat_Get(iD)?.SetActive(true);
/// Set PinnedStat searching for a StatID
public virtual void Stat_Pin(StatID ID) => Stat_Get(ID.ID);
/// Find a Stat Using a StatID and Return if the Stat is on the List. Also Saves it to the PinnedStat
public virtual Stat Stat_Get(StatID ID) => Stat_Get(ID.ID);
// Set the Inmune Value of a Stat to true
public virtual void Stat_Inmune_Activate(StatID ID) => Stat_Get(ID)?.SetInmune(true);
/// Set the Inmune Value of a Stat to false
public virtual void Stat_Inmune_Deactivate(StatID ID) => Stat_Get(ID)?.SetInmune(false);
#endregion
/// Set PinnedStat searching for a Stat Name
public virtual void Stat_Pin(string name) => Stat_Get(name);
/// Set PinnedStat searching for a int ID value
public virtual void Stat_Pin(int ID) => Stat_Get(ID);
/// Find a Stat Using its name for the ID and Return if the Stat is on the List. Also Saves it to the PinnedStat
public virtual Stat Stat_Get(string name) => PinnedStat = stats.Find(item => item.Name == name);
/// Find a Stat Using a int Value for the ID and Return if the Stat is on the List. Also Saves it to the PinnedStat
public virtual Stat Stat_Get(int ID)
{
if (stats_D != null && stats_D.TryGetValue(ID, out PinnedStat))
return PinnedStat;
return null;
}
/// Find a Stat Using an IntVar and Return if the Stat is on the List. Also Saves it to the PinnedStat
public virtual Stat Stat_Get(IntVar ID) => Stat_Get(ID.Value);
public virtual void Stat_ModifyValue(StatID ID, float modifyvalue) => Stat_Get(ID)?.Modify(modifyvalue);
public virtual void Stat_ModifyValue(int ID, float modifyvalue) => Stat_Get(ID)?.Modify(modifyvalue);
public virtual void Stat_ModifyValue(string name, float modifyvalue) => Stat_Get(name)?.Modify(modifyvalue);
public virtual void Stat_ModifyValue(StatID ID, float modifyvalue, StatOption modifyType) => Stat_Get(ID)?.Modify(modifyvalue, modifyType);
public virtual void Stat_ModifyValue(string name, float modifyvalue, StatOption modifyType) => Stat_Get(name)?.Modify(modifyvalue, modifyType);
/// Modify Stat Value instantly (Add/Remove to the Value)
public virtual void Stat_Pin_ModifyValue(float value) => PinnedStat?.Modify(value);
/// Modify Stat Value instantly (Add/Remove to the Value)
public virtual void Stat_Pin_ModifyValue(FloatVar value) => PinnedStat?.Modify(value.Value);
/// Modify Stat Value instantly (Add/Remove to the Value)
public virtual void Stat_Pin_SetMult(float value) => PinnedStat?.SetMultiplier(value);
/// Modify Stat Value instantly (Add/Remove to the Value)
public virtual void Stat_Pin_SetMult(FloatVar value) => PinnedStat?.SetMultiplier(value.Value);
/// Modify Stat Value in a X time period(Add/Remove to the Value)
public virtual void Stat_Pin_ModifyValue(float value, float time) => PinnedStat?.Modify(value, time);
/// Modify Stat Value in 1 second period(Add/Remove to the Value)
public virtual void Stat_Pin_ModifyValue_1Sec(float value) => PinnedStat?.Modify(value, 1);
/// Set Stat Value to a fixed Value
public virtual void Stat_Pin_SetValue(float value) => PinnedStat.SetValue(value);
/// Modify the Pinned Stat MAX Value (Add or remove to the Max Value)
public virtual void Stat_Pin_ModifyMaxValue(float value) => PinnedStat?.ModifyMAX(value);
/// Set the Pinned Stat MAX Value
public virtual void Stat_Pin_SetMaxValue(float value) => PinnedStat?.SetMAX(value);
/// Enable/Disable the Pinned Stat Regeneration Rate
public virtual void Stat_Pin_Modify_RegenRate(float value) => PinnedStat?.ModifyRegenRate(value);
/// Enable/Disable the Pinned Stat Degeneration
public virtual void Stat_Pin_Degenerate(bool value) => PinnedStat?.SetDegeneration(value);
/// Enable/Disable the Pinned Stat Degeneration
public virtual void Stat_Pin_SetInmune(bool value) => PinnedStat?.SetInmune(value);
/// Enable/Disable the Pinned Stat Regeneration
public virtual void Stat_Pin_Regenerate(bool value) => PinnedStat?.SetRegeneration(value);
// public virtual void _PinStatRegenerate(bool value) { Stat_Pin_Regenerate(value); }
/// Enable/Disable the Pinned Stat
public virtual void Stat_Pin_Enable(bool value) => PinnedStat?.SetActive(value);
/// Modify the Pinned Stat value with a 'new Value', 'ticks' times , every 'timeBetweenTicks' seconds
public virtual void Stat_Pin_ModifyValue(float newValue, int ticks, float timeBetweenTicks) => PinnedStat?.Modify(newValue, ticks, timeBetweenTicks);
/// Clean the Pinned Stat from All Regeneration/Degeneration and Modify Tick Values
public virtual void Stat_Pin_CleanCoroutines() => PinnedStat?.CleanRoutines();
[Obsolete("Use Stat_Degenerate_Off instead")]
/// Disable a stat Degeneration logic
public virtual void DegenerateOff(StatID ID) => Stat_Degenerate_Off(ID);
[Obsolete("Use Stat_Degenerate_On instead")]
/// Enable a stat Degeneration logic
public virtual void DegenerateOn(StatID ID) => Stat_Degenerate_On(ID);
#if UNITY_EDITOR
[ContextMenu("Create/Stamina")]
private void ConnectStamina()
{
if (stats == null) stats = new List();
var staminaID = MTools.GetInstance("Stamina");
if (staminaID != null)
{
var staminaStat = Stat_Get(staminaID);
if (staminaStat == null)
{
staminaStat = new Stat()
{
ID = staminaID,
value = new FloatReference(100),
InmuneTime = new FloatReference(0.5f),
regenerate = new BoolReference(true),
RegenRate = new FloatReference(40),
DegenRate = new FloatReference(20),
RegenWaitTime = new FloatReference(2),
Above = 15f, Below = 10f,
};
stats.Add(staminaStat);
}
//Connect to the Animal Controller in case it exist
var method = this.GetUnityAction("MAnimal", "UseSprint");
if (method != null)
{
Debug.Log("medho" + method.ToString());
UnityEditor.Events.UnityEventTools.AddBoolPersistentListener(staminaStat.OnStatBelow, method, false);
UnityEditor.Events.UnityEventTools.AddBoolPersistentListener(staminaStat.OnStatAbove, method, true);
}
MEvent UIStamina = MTools.GetInstance("UI Stamina Stat");
if (UIStamina)
{
UnityEditor.Events.UnityEventTools.AddPersistentListener(staminaStat.OnValueChangeNormalized,UIStamina.Invoke);
UnityEditor.Events.UnityEventTools.AddPersistentListener(staminaStat.OnStatFull,UIStamina.Invoke);
}
var onSprintEnable = this.GetFieldClass("MAnimal", "OnSprintEnabled");
if (onSprintEnable != null)
{
UnityEditor.Events.UnityEventTools.AddObjectPersistentListener(onSprintEnable, Stat_Pin, staminaID);
UnityEditor.Events.UnityEventTools.AddPersistentListener(onSprintEnable, Stat_Pin_Degenerate);
}
MTools.SetDirty(this);
}
}
[ContextMenu("Create/Health")]
void CreateHealth()
{
var health = MTools.GetInstance("Health");
if (health != null)
{
var HealthStat = new Stat()
{
ID = health,
value = new FloatReference(100),
DisableOnEmpty = new BoolReference(true),
InmuneTime = new FloatReference(0.1f)
};
stats.Add(HealthStat);
var deathID = MTools.GetInstance("Death");
var method = this.GetUnityAction("MAnimal", "State_Activate");
if (method != null) UnityEditor.Events.UnityEventTools.AddObjectPersistentListener(HealthStat.OnStatEmpty, method, deathID);
MEvent UIHealth = MTools.GetInstance("UI Health Stat");
if (UIHealth)
{
UnityEditor.Events.UnityEventTools.AddPersistentListener(HealthStat.OnValueChangeNormalized, UIHealth.Invoke);
UnityEditor.Events.UnityEventTools.AddPersistentListener(HealthStat.OnStatFull, UIHealth.Invoke);
}
MTools.SetDirty(this);
}
}
[ContextMenu("Create/Mana")]
void CreateMana()
{
var Mana = MTools.GetInstance("Mana");
if (Mana != null)
{
var HealthStat = new Stat()
{
ID = Mana,
value = new FloatReference(100),
DisableOnEmpty = new BoolReference(true),
InmuneTime = new FloatReference(0),
regenerate = new BoolReference(true),
RegenWaitTime = new FloatReference(2),
RegenRate = new FloatReference(10),
DegenRate = new FloatReference(10)
};
stats.Add(HealthStat);
MEvent UIHealth = MTools.GetInstance("UI Mana Stat");
if (UIHealth)
{
UnityEditor.Events.UnityEventTools.AddPersistentListener(HealthStat.OnValueChangeNormalized, UIHealth.Invoke);
UnityEditor.Events.UnityEventTools.AddPersistentListener(HealthStat.OnStatFull, UIHealth.Invoke);
}
MTools.SetDirty(this);
}
}
private void Reset()
{
if (stats == null) stats = new List();
CreateHealth();
}
#endif
}
///──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
///──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
///STAT CLASS
///──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
///──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
[Serializable]
public class Stat
{
#region Variables
[Tooltip("Enable/Disable the Stat. Disable Stats cannot be modified")]
public bool active = true;
[Tooltip("Key Idendifier for the Stat")]
public StatID ID;
[Tooltip("Current Value of the Stat")]
public FloatReference value = new FloatReference(0);
[Tooltip("Maximun Value of the Stat")]
public FloatReference maxValue = new FloatReference(100);
[Tooltip("Minimum Value of the Stat")]
public FloatReference minValue = new FloatReference();
[Tooltip("If the Stat is Empty it will be disabled to avoid future changes")]
public BoolReference DisableOnEmpty = new BoolReference();
/// Multiplier to modify the Stat value
[SerializeField] internal FloatReference multiplier = new FloatReference(1);
/// Can the Stat regenerate overtime
[SerializeField] internal BoolReference regenerate = new BoolReference( false);
/// Regeneration Rate. Change the Speed of the Regeneration
public FloatReference RegenRate;
/// Regeneration Rate. When the value is modified this will increase or decrease it over time.
public FloatReference RegenWaitTime = new FloatReference(0);
/// Regeneration Rate. When the value is modified this will increase or decrease it over time.
public FloatReference DegenWaitTime = new FloatReference(0);
/// Can the Stat degenerate overtime
[SerializeField] internal BoolReference degenerate = new BoolReference(false);
/// Degeneration Rate. Change the Speed of the Degeneration
public FloatReference DegenRate;
/// If greater than zero, the Stat cannot be modify until the inmune time have passed
public FloatReference InmuneTime;
/// If the ResetStat funtion is called it will reset to Max or Low Value
public ResetTo resetTo = ResetTo.MaxValue;
/// Save the Last State of the Regeneration bool
private bool regenerate_LastValue;
/// Save the Last State of the Regeneration bool
private bool degenerate_LastValue;
/// Is the Stat Below the Below Value
private bool isBelow = false;
/// Is the Stat Above the Above Value
private bool isAbove = false;
#endregion
#region Events
public UnityEvent OnStatFull = new UnityEvent();
public UnityEvent OnStatEmpty = new UnityEvent();
public UnityEvent OnStat = new UnityEvent();
public float Below;
public float Above;
public UnityEvent OnStatBelow = new UnityEvent();
public UnityEvent OnStatAbove = new UnityEvent();
public FloatEvent OnValueChangeNormalized = new FloatEvent();
public FloatEvent OnValueChange = new FloatEvent();
public BoolEvent OnDegenerate = new BoolEvent();
public BoolEvent OnRegenerate = new BoolEvent();
public BoolEvent OnActive = new BoolEvent();
#endregion
#region Properties
/// Is the Stat Enabled? when Disable no modification can be done. All current modification can't be stopped
public bool Active
{
get => active;
set
{
active = value;
OnActive.Invoke(value);
if (value)
StartRegeneration(); //If the Stat was activated start the regeneration
else
StopRegeneration();
}
}
public string Name
{
get
{
if (ID != null)
{
return ID.name;
}
return string.Empty;
}
}
/// Current value of the Stat
public float Value
{
get => value;
set => SetValue(value);
}
public bool IsFull => Value == MaxValue;
public bool IsEmpty => Value == MinValue;
/// Current Multiplier of the Stat
public float Multiplier { get => multiplier.Value; set => multiplier.Value = value; }
/// Returns the Normalized value of the Stat
public float NormalizedValue => Value / MaxValue;
/// If True: The Stat cannot be modify
public bool IsInmune { get; set; }
/// Maximum Value of the Stat
public float MaxValue { get => maxValue.Value; set => maxValue.Value = value; }
/// Minimun Value of the Stat
public float MinValue { get => minValue.Value; set => minValue.Value = value; }
/// Is the Stat Regenerating?
public bool IsRegenerating { get; private set; }
/// Is the Stat Degenerating?
public bool IsDegenerating { get; private set; }
[SerializeField] internal int EditorTabs = 0;
/// Can the Stat Regenerate over time
public bool Regenerate
{
get => regenerate.Value;
set
{
regenerate.Value = value;
regenerate_LastValue = regenerate; //In case Regenerate is changed
OnRegenerate.Invoke(value);
if (regenerate)
{
degenerate.Value = false; //Do not Degenerate if we are Regenerating
StopDegeneration();
StartRegeneration();
}
else
{
degenerate.Value = degenerate_LastValue; //If we are no longer Regenerating Start Degenerating again in case the Degenerate was true
StopRegeneration();
StartDegeneration();
}
}
}
/// Can the Stat Degenerate over time
public bool Degenerate
{
get => degenerate.Value;
set
{
degenerate.Value = value;
degenerate_LastValue = degenerate; //In case Regenerate is changed
OnDegenerate.Invoke(value);
if (degenerate)
{
regenerate.Value = false; //Do not Regenerate if we are Degenerating
StartDegeneration();
StopRegeneration();
}
else
{
regenerate.Value = regenerate_LastValue; //If we are no longer Degenerating Start Regenerating again in case the Regenerate was true
StopDegeneration();
StartRegeneration();
}
}
}
#endregion
[NonSerialized] private WaitForSeconds InmuneWait;
internal void InitializeStat(Stats holder)
{
isAbove = isBelow = false;
Owner = holder; //Save the Monobehaviour to save coroutines
if (value.Value >= Above) isAbove = true; //This means that The Stat Value is over the Above value
else if (value.Value <= Below) isBelow = true; //This means that The Stat Value is under the Below value
regenerate_LastValue = Regenerate;
if (MaxValue < Value) MaxValue = Value;
I_Regeneration = null;
I_Degeneration = null;
I_ModifyPerTicks = null;
InmuneWait = new WaitForSeconds(InmuneTime);
if (Active)
{
StartRegeneration();
StartDegeneration();
}
holder.Delay_Action(3,() => ValueEvents());
}
internal void SetMultiplier(float value) => multiplier.Value = value;
internal void ValueEvents()
{
OnValueChangeNormalized.Invoke(NormalizedValue);
OnValueChange.Invoke(value);
if (this.value == minValue.Value)
{
this.value.Value = minValue.Value;
OnStatEmpty.Invoke(); //if the Value is 0 invoke Empty Stat
if (DisableOnEmpty.Value)
{
SetActive(false);
return;
}
}
else if (this.value == maxValue.Value)
{
this.value.Value = maxValue.Value;
OnStatFull.Invoke(); //if the Value is 0 invoke Empty Stat
}
if (this.value >= Above && !isAbove)
{
OnStatAbove.Invoke();
isAbove = true;
isBelow = false;
}
else if (this.value <= Below && !isBelow)
{
OnStatBelow.Invoke();
isBelow = true;
isAbove = false;
}
}
internal void SetValue(float value)
{
var RealValue = Mathf.Clamp(value * Multiplier, MinValue, maxValue);
if ((!Active) || //If the Stat is not Active do nothing
(this.value.Value == RealValue)) return; //If the values are equal do nothing. Avoid Stack Overflow
this.value.Value = RealValue;
ValueEvents();
}
/// Enable or Disable a Stat
public void SetActive(bool value) => Active = value;
public void SetRegeneration(bool value) => Regenerate = value;
public void SetDegeneration(bool value) => Degenerate = value;
public void SetInmune(bool value) => IsInmune = value;
/// Adds or remove to the Stat Value
public virtual void Modify(float newValue)
{
if (!IsInmune && Active)
{
Value += newValue;
StartRegeneration();
if (!Regenerate)
StartDegeneration();
SetInmune();
}
}
public virtual void UpdateStat()
{
SetValue(value);
StartRegeneration();
if (!Regenerate)
StartDegeneration();
}
/// Adds or remove to the Stat Value
public virtual void Modify(float newValue, float time)
{
if (!IsInmune && Active)
{
StopSlowModification();
Owner.StartCoroutine(out I_ModifySlow, C_SmoothChangeValue(newValue, time));
SetInmune();
}
}
/// Modify the Stat value with a 'new Value', 'ticks' times , every 'timeBetweenTicks' seconds
public virtual void Modify(float newValue, int ticks, float timeBetweenTicks)
{
if (!Active) return; //Ignore if the Stat is Disable
StopCoroutine(I_ModifyPerTicks);
Owner.StartCoroutine(out I_ModifyPerTicks, C_ModifyTicksValue(newValue, ticks, timeBetweenTicks));
}
/// Add or Remove Value the 'MaxValue' of the Stat
public virtual void ModifyMAX(float newValue)
{
if (!Active) return; //Ignore if the Stat is Disable
MaxValue += newValue;
StartRegeneration();
}
/// Sets the 'MaxValue' of the Stat
public virtual void SetMAX(float newValue)
{
if (!Active) return;
MaxValue = newValue;
StartRegeneration();
}
/// Add or Remove Rate to the Regeneration Rate
public virtual void ModifyRegenRate(float newValue)
{
if (!Active) return; //Ignore if the Stat is Disable
RegenRate.Value += newValue;
StartRegeneration();
}
public virtual void SetRegenerationWait(float newValue)
{
if (!Active) return; //Ignore if the Stat is Disable
RegenWaitTime.Value = newValue;
if (RegenWaitTime < 0) RegenWaitTime.Value = 0;
}
/// Set a new Regeneration Rate
public virtual void SetRegenerationRate(float newValue)
{
if (!Active) return; //Ignore if the Stat is Disable
RegenRate.Value = newValue;
}
/// Reset the Stat to the Default Max Value
public virtual void Reset() => Value = (resetTo == ResetTo.MaxValue) ? MaxValue : MinValue;
/// Reset the Stat to the Default Min or Max Value
public virtual void Reset_to_Max() => Value = MaxValue;
/// Reset the Stat to the Default Min Value
public virtual void Reset_to_Min() => Value = MinValue;
/// Clean all Coroutines
internal void CleanRoutines()
{
StopDegeneration();
StopRegeneration();
StopTickDamage();
StopSlowModification();
}
public virtual void RegenerateOverTime(float time)
{
if (time <= 0)
{
StartRegeneration();
}
else
{
Owner.StartCoroutine(C_RegenerateOverTime(time));
}
}
protected virtual void SetInmune()
{
if (InmuneTime > 0)
{
StopCoroutine(I_IsInmune);
Owner.StartCoroutine(out I_IsInmune, C_InmuneTime());
}
}
private void StopCoroutine(IEnumerator Cor)
{
if (Cor != null) Owner.StopCoroutine(Cor);
}
protected virtual void StartRegeneration()
{
StopRegeneration();
if (RegenRate == 0 || !Regenerate) return; //Means if there's no Regeneration
Owner.StartCoroutine(out I_Regeneration, C_Regenerate());
}
protected virtual void StartDegeneration()
{
StopDegeneration();
if (DegenRate == 0 || !Degenerate) return; //Means there's no Degeneration
Owner.StartCoroutine(out I_Degeneration, C_Degenerate());
}
protected virtual void StopRegeneration()
{
StopCoroutine(I_Regeneration); //If there was a regenation active .... interrupt it
I_Regeneration = null;
IsRegenerating = false;
}
protected virtual void StopDegeneration()
{
StopCoroutine(I_Degeneration); //if it was ALREADY Degenerating.. stop
I_Degeneration = null;
IsDegenerating = false;
}
protected virtual void StopTickDamage()
{
StopCoroutine(I_ModifyPerTicks); //if it was ALREADY Degenerating.. stop...
I_ModifyPerTicks = null;
}
protected virtual void StopSlowModification()
{
StopCoroutine(I_ModifySlow); //If there was a regenation active .... interrupt it
I_ModifySlow = null;
}
/// Modify the Stats on an animal
public void Modify(float Value, StatOption modify)
{
switch (modify)
{
case StatOption.AddValue:
Modify(Value);
break;
case StatOption.SetValue:
this.Value = Value;
break;
case StatOption.SubstractValue:
Modify(-Value);
break;
case StatOption.ModifyMaxValue:
ModifyMAX(Value);
break;
case StatOption.SetMaxValue:
MaxValue = Value;
break;
case StatOption.Degenerate:
DegenRate = Value;
Degenerate = true;
break;
case StatOption.StopDegenerate:
DegenRate = Value;
Degenerate = false;
break;
case StatOption.Regenerate:
Regenerate = true;
RegenRate = Value;
break;
case StatOption.StopRegenerate:
Regenerate = false;
RegenRate = Value;
break;
case StatOption.Reset:
Reset();
break;
case StatOption.ReduceByPercent:
Modify(-(MaxValue * Value / 100));
break;
case StatOption.IncreaseByPercent:
Modify(MaxValue * Value / 100);
break;
case StatOption.Multiplier:
Multiplier = Value;
break;
case StatOption.ResetToMax:
Reset_to_Max();
break;
case StatOption.ResetToMin:
Reset_to_Min();
break;
case StatOption.None:
break;
default:
break;
}
}
#region Coroutines
///
/// I need this to use coroutines in this class because it does not inherit from Monobehaviour, Also to Identify where is this Stat coming from
///
public Stats Owner { get; private set; }
private IEnumerator I_Regeneration;
private IEnumerator I_Degeneration;
private IEnumerator I_ModifyPerTicks;
private IEnumerator I_ModifySlow;
private IEnumerator I_IsInmune;
protected IEnumerator C_RegenerateOverTime(float time)
{
float ReachValue = RegenRate > 0 ? MaxValue : MinValue; //Set to the default or 0
bool Positive = RegenRate > 0; //Is the Regeneration Positive?
float currentTime = Time.time;
while (Value != ReachValue || currentTime > time )
{
Value += (RegenRate * Time.deltaTime);
if (Positive && Value > MaxValue)
{
Value = MaxValue;
}
else if (!Positive && Value < 0)
{
Value = MinValue;
}
currentTime += Time.deltaTime;
yield return null;
}
yield return null;
}
protected IEnumerator C_InmuneTime()
{
IsInmune = true;
yield return InmuneWait;
IsInmune = false;
}
protected IEnumerator C_Regenerate()
{
yield return null;
if (RegenWaitTime > 0)
yield return new WaitForSeconds(RegenWaitTime); //Wait a time to regenerate
IsRegenerating = true;
while (Regenerate && Value < MaxValue)
{
Value += (RegenRate * Time.deltaTime);
yield return null;
}
IsRegenerating = false;
yield return null;
}
protected IEnumerator C_Degenerate()
{
yield return null;
if (DegenWaitTime > 0)
yield return new WaitForSeconds(DegenWaitTime); //Wait a time to regenerate
IsDegenerating = true;
while (Degenerate && Value > MinValue)
{
Value -= (DegenRate * Time.deltaTime);
yield return null;
}
IsDegenerating = false;
yield return null;
}
protected IEnumerator C_ModifyTicksValue(float value, int Ticks, float time)
{
var WaitForTicks = new WaitForSeconds(time);
for (int i = 0; i < Ticks; i++)
{
Value += value;
if (Value <= MinValue)
{
Value = MinValue;
break;
}
yield return WaitForTicks;
}
yield return null;
StartRegeneration();
}
protected IEnumerator C_SmoothChangeValue(float newvalue, float time)
{
StopRegeneration();
float currentTime = 0;
float currentValue = Value;
newvalue = Value + newvalue;
yield return null;
while (currentTime <= time)
{
Value = Mathf.Lerp(currentValue, newvalue, currentTime / time);
currentTime += Time.deltaTime;
yield return null;
}
Value = newvalue;
yield return null;
StartRegeneration();
}
#endregion
public enum ResetTo
{
MinValue,
MaxValue
}
}
}