using System; using System.Collections.Generic; using System.Linq; using Continentis.MainGame.UI; using SoulliesFramework.General; using UnityEngine; using UnityEngine.Events; namespace Continentis.MainGame { public partial class BuffBase { public abstract class BuffSubmodule : SubmoduleBase> { public BuffBase buff; protected BuffSubmodule(BuffBase buff) : base(buff) { this.buff = buff; } } public class UISubmodule : BuffSubmodule { public bool hasIcon; public string iconPath; public Sprite icon; public List> setTextFunctions; public HUD_CharacterBuffIcon buffIcon; public UISubmodule(BuffBase buff, string iconPath = "", params Func[] setTextFunctions) : base(buff) { this.hasIcon = !string.IsNullOrEmpty(iconPath); this.iconPath = iconPath; if (hasIcon) { this.icon = AssetLoader.LoadAsset(iconPath); } this.setTextFunctions = setTextFunctions.ToList(); } } public class CountSubmodule : BuffSubmodule { public int maximumCount; public int remainingCount; public bool isInfinite => maximumCount < 0; public float remainingPercentage => (float)remainingCount / maximumCount; /// /// duration为负数表示无限持续时间。 /// public CountSubmodule(BuffBase buff, int maximumCount) : base(buff) { this.maximumCount = maximumCount; this.remainingCount = maximumCount; } public void UpdateModule() { if (isInfinite) { return; } remainingCount--; if (remainingCount <= 0) { buff.Remove(); } } /// /// 刷新剩余时间至初始值。 /// public void RefreshDuration() { if (isInfinite) { return; } remainingCount = maximumCount; } /// /// 覆盖(可选保留更大的duration)并刷新剩余时间。 /// public void RefreshDuration(int overrideDuration, bool keepMaximal = true) { if (isInfinite) { return; } maximumCount = keepMaximal ? Mathf.Max(maximumCount, overrideDuration) : overrideDuration; remainingCount = maximumCount; } /// /// 增加持续时间和剩余时间。 /// public void AddDuration(int additionalDuration) { if (isInfinite) { return; } maximumCount += additionalDuration; remainingCount += additionalDuration; } /// /// 仅增加剩余时间,不改变总持续时间。 /// 如果增加后剩余时间超过总持续时间,则剩余时间等于总持续时间。 /// public void AddTime(int additionalTime) { if (isInfinite) { return; } remainingCount += additionalTime; remainingCount = Mathf.Min(remainingCount, maximumCount); } } /// /// Buff叠加模块,叠加层数统一。 /// public class UnitedStackSubmodule : BuffSubmodule { public bool willRemoveOnZero; //是否在层数为0时移除Buff public int stackAmount; //当前层数 public int stackUpperLimit; //层数上限,-1表示无限制 public UnitedStackSubmodule(BuffBase buff, bool willRemoveOnZero, int stackUpperLimit = -1, int initialStackAmount = 1) : base(buff) { this.willRemoveOnZero = willRemoveOnZero; this.stackAmount = initialStackAmount; this.stackUpperLimit = stackUpperLimit; } public void RefreshStackUpperLimit(int upperLimit, bool keepMaximal = true) { stackUpperLimit = keepMaximal ? Mathf.Max(stackUpperLimit, upperLimit) : upperLimit; } public void AddStack(int amount) { stackAmount += amount; if (stackUpperLimit > 0) { stackAmount = Mathf.Min(stackAmount, stackUpperLimit); } } public void ReduceStack(int amount) { stackAmount -= amount; if (willRemoveOnZero && stackAmount <= 0) { buff.Remove(); } } } /// /// Buff独立叠加模块,每一层的持续时间和层数可以不同。 /// public class IndependentStackSubmodule : BuffSubmodule { public bool willRemoveOnZero; public List independentStacks; public int totalStackAmount; public IndependentStackSubmodule(BuffBase buff, bool willRemoveOnZero) : base(buff) { this.willRemoveOnZero = willRemoveOnZero; independentStacks = new List(); totalStackAmount = 0; } public void UpdateModule() { independentStacks.ForEach(x => x.remainingTime--); independentStacks.RemoveAll(x => !x.IsInfinite && x.remainingTime <= 0); totalStackAmount = independentStacks.Sum(x => x.stackAmount); if (willRemoveOnZero && totalStackAmount <= 0) { buff.Remove(); } } public IndependentStackUnit AddStack(int stackAmount, int duration) { IndependentStackUnit addition = new IndependentStackUnit(stackAmount, duration); independentStacks.Add(addition); independentStacks.Sort(); return addition; } public void ReduceStack(int stackAmount) { for (int i = 0; i < independentStacks.Count; i++) { if (stackAmount <= independentStacks[i].stackAmount) { independentStacks[i].stackAmount -= stackAmount; if (independentStacks[i].stackAmount <= 0) { independentStacks.RemoveAt(i); } return; } stackAmount -= independentStacks[i].stackAmount; independentStacks.RemoveAt(i); i--; } totalStackAmount = independentStacks.Sum(x => x.stackAmount); if (willRemoveOnZero && totalStackAmount <= 0) { buff.Remove(); } } public class IndependentStackUnit : IComparable { public int stackAmount; public int duration; public int remainingTime; public Dictionary parameters; public bool IsInfinite => duration < 0; public IndependentStackUnit(int stackAmount, int duration) { this.stackAmount = stackAmount; this.duration = duration; this.remainingTime = duration; this.parameters = new Dictionary(); } public int CompareTo(IndependentStackUnit other) { return remainingTime.CompareTo(other.remainingTime); } } } } }