214 lines
5.8 KiB
C#
214 lines
5.8 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using SLSUtilities.General;
|
||
using UnityEngine;
|
||
|
||
namespace Cielonos.MainGame.Buffs
|
||
{
|
||
/// <summary>
|
||
/// Buff 生命周期调用期间使用的临时上下文,不参与 Unity/Odin 序列化。
|
||
/// </summary>
|
||
public class BuffContext
|
||
{
|
||
internal static readonly BuffContext Empty = new BuffContext();
|
||
|
||
[NonSerialized]
|
||
public readonly Dictionary<string, object> values = new Dictionary<string, object>();
|
||
|
||
public void Set<T>(string key, T value)
|
||
{
|
||
values[key] = value;
|
||
}
|
||
|
||
public bool TryGet<T>(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<T>(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<T> : 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;
|
||
|
||
/// <summary>
|
||
/// 该 Buff 当前是否正在生效/发挥作用。默认为 true,可在子类中重写(例如在特定条件下才生效)。
|
||
/// </summary>
|
||
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<T>
|
||
{
|
||
protected bool FindExistingSameBuff<T1, T2>(out T2 existingBuff, List<T1> buffList) where T1 : BuffBase<T> where T2 : BuffBase<T>
|
||
{
|
||
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<T>
|
||
{
|
||
//Buff生命周期函数
|
||
|
||
/// <summary>
|
||
/// Buff被尝试添加到角色时调用。
|
||
/// </summary>
|
||
public virtual bool OnBuffApply(out BuffBase<T> existingBuff)
|
||
{
|
||
throw new System.NotImplementedException(); //需要在子类中实现
|
||
}
|
||
|
||
/// <summary>
|
||
/// Buff首次成功添加到角色后调用。在OnBuffApply完成,且返回true之后调用。
|
||
/// 如果Buff在被添加时,发现已有同类Buff存在,则不会调用此函数。
|
||
/// </summary>
|
||
public virtual void OnAfterFirstApply()
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void OnBuffUpdate()
|
||
{
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// Buff被驱散(移除)时调用,在OnBuffRemove之前调用。
|
||
/// </summary>
|
||
public virtual void OnBuffDispel()
|
||
{
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// Buff被正常移除(包括驱散)时调用。在Buff生命周期结束时调用。
|
||
/// UntriggerRemove不会调用此函数。但是UntriggerRemove通常情况下绝不会被调用。
|
||
/// </summary>
|
||
public virtual void OnBuffRemove()
|
||
{
|
||
|
||
}
|
||
}
|
||
|
||
public partial class BuffBase<T>
|
||
{
|
||
/// <summary>
|
||
/// 判断该Buff能否被指定驱散等级的驱散效果驱散。
|
||
/// </summary>
|
||
protected bool CanBeDispelled(BuffDispelLevel dispelLevel)
|
||
{
|
||
return dispelLevel >= dispelThreshold;
|
||
}
|
||
}
|
||
|
||
}
|