using System; using System.Collections.Generic; using System.Linq; using SLSUtilities.General; using UnityEngine; namespace Cielonos.MainGame.Buffs { /// /// Buff 生命周期调用期间使用的临时上下文,不参与 Unity/Odin 序列化。 /// public class BuffContext { internal static readonly BuffContext Empty = new BuffContext(); [NonSerialized] public readonly Dictionary values = new Dictionary(); public void Set(string key, T value) { values[key] = value; } public bool TryGet(string key, out T value) { if (values.TryGetValue(key, out object rawValue) && rawValue is T typedValue) { value = typedValue; return true; } value = default; return false; } public T Get(string key, T defaultValue = default) { return TryGet(key, out T value) ? value : defaultValue; } } public enum BuffDispelLevel { Basic = 0, //弱驱散 Strong = 10, //强驱散 DeathOnly = 20, //不可驱散(死亡除外) Undispellable = 100 //不可驱散(包括死亡) } public enum BuffType { Positive, Negative, Neutral } public abstract partial class BuffBase : IPrioritized { public string identification; public BuffType buffType; public BuffDispelLevel dispelThreshold; public ContentSubmodule contentSubmodule; public int Priority { get; private set; } public BuffContext CurrentContext { get; private set; } = BuffContext.Empty; /// /// 该 Buff 当前是否正在生效/发挥作用。默认为 true,可在子类中重写(例如在特定条件下才生效)。 /// public virtual bool IsTakingEffect => true; protected void Initialize(BuffType buffType, BuffDispelLevel dispelThreshold, int priority = 0) { this.buffType = buffType; this.dispelThreshold = dispelThreshold; this.Priority = priority; } protected void SetIdentification(string id) { this.identification = id; } } public partial class BuffBase { protected bool FindExistingSameBuff(out T2 existingBuff, List buffList) where T1 : BuffBase where T2 : BuffBase { existingBuff = null; foreach (T1 buff in buffList) { if (buff.GetType() == this.GetType()) { existingBuff = buff as T2; return true; } else { //Debug.LogAssertion("Buff types do not match."); } } return false; } public void Apply(T attached) { Apply(attached, null); } public abstract void Apply(T attached, BuffContext context); public virtual void Update(BuffContext context) { SetCurrentContext(context); OnBuffUpdate(); } public void Update() { Update(null); } public void Remove() { Remove(null); } public abstract void Remove(BuffContext context); public void UntriggerRemove() { UntriggerRemove(null); } public abstract void UntriggerRemove(BuffContext context); public virtual void Dispel(BuffDispelLevel dispelLevel) { Dispel(dispelLevel, null); } public virtual void Dispel(BuffDispelLevel dispelLevel, BuffContext context) { SetCurrentContext(context); if (CanBeDispelled(dispelLevel)) { OnBuffDispel(); Remove(context); } } protected void SetCurrentContext(BuffContext context) { CurrentContext = context ?? BuffContext.Empty; } } public partial class BuffBase { //Buff生命周期函数 /// /// Buff被尝试添加到角色时调用。 /// public virtual bool OnBuffApply(out BuffBase existingBuff) { throw new System.NotImplementedException(); //需要在子类中实现 } /// /// Buff首次成功添加到角色后调用。在OnBuffApply完成,且返回true之后调用。 /// 如果Buff在被添加时,发现已有同类Buff存在,则不会调用此函数。 /// public virtual void OnAfterFirstApply() { } public virtual void OnBuffUpdate() { } /// /// Buff被驱散(移除)时调用,在OnBuffRemove之前调用。 /// public virtual void OnBuffDispel() { } /// /// Buff被正常移除(包括驱散)时调用。在Buff生命周期结束时调用。 /// UntriggerRemove不会调用此函数。但是UntriggerRemove通常情况下绝不会被调用。 /// public virtual void OnBuffRemove() { } } public partial class BuffBase { /// /// 判断该Buff能否被指定驱散等级的驱散效果驱散。 /// protected bool CanBeDispelled(BuffDispelLevel dispelLevel) { return dispelLevel >= dispelThreshold; } } }