// ReSharper disable MemberCanBePrivate.Global using System; using System.Collections.Generic; using System.Linq; using CUE.NET.Exceptions; namespace CUE.NET.Effects { /// /// Represents an generic effect-target. /// /// public abstract class AbstractEffectTarget : IEffectTarget where T : IEffectTarget { #region Properties & Fields /// /// Gets a list of storing the attached effects. /// protected IList EffectTimes { get; } = new List(); /// /// Gets all attached to this target. /// public IList> Effects => EffectTimes.Select(x => x.Effect).Cast>().ToList(); /// /// Gets the strongly-typed target used for the effect. /// protected abstract T EffectTarget { get; } #endregion #region Methods /// /// Updates all effects added to this target. /// public virtual void UpdateEffects() { lock (Effects) { for (int i = EffectTimes.Count - 1; i >= 0; i--) { EffectTimeContainer effectTime = EffectTimes[i]; long currentTicks = DateTime.Now.Ticks; float deltaTime; if (effectTime.TicksAtLastUpdate < 0) { effectTime.TicksAtLastUpdate = currentTicks; deltaTime = 0f; } else deltaTime = (currentTicks - effectTime.TicksAtLastUpdate) / 10000000f; effectTime.TicksAtLastUpdate = currentTicks; effectTime.Effect.Update(deltaTime); if (effectTime.Effect.IsDone) EffectTimes.RemoveAt(i); } } } /// /// Adds an affect. /// /// The effect to add. public virtual void AddEffect(IEffect effect) { if (EffectTimes.Any(x => x.Effect == effect)) return; if (!effect.CanBeAppliedTo(EffectTarget)) throw new WrapperException($"Failed to add effect.\r\nThe effect of type '{effect.GetType()}' can't be applied to the target of type '{EffectTarget.GetType()}'."); effect.OnAttach(EffectTarget); EffectTimes.Add(new EffectTimeContainer(effect, -1)); } /// /// Removes an effect /// /// The effect to remove. public virtual void RemoveEffect(IEffect effect) { EffectTimeContainer effectTimeToRemove = EffectTimes.FirstOrDefault(x => x.Effect == effect); if (effectTimeToRemove == null) return; effect.OnDetach(EffectTarget); EffectTimes.Remove(effectTimeToRemove); } #endregion } }