267 lines
8.5 KiB
C#
267 lines
8.5 KiB
C#
|
|
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<T>
|
|||
|
|
{
|
|||
|
|
public abstract class BuffSubmodule : SubmoduleBase<BuffBase<T>>
|
|||
|
|
{
|
|||
|
|
public BuffBase<T> buff;
|
|||
|
|
|
|||
|
|
protected BuffSubmodule(BuffBase<T> buff) : base(buff)
|
|||
|
|
{
|
|||
|
|
this.buff = buff;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public class UISubmodule : BuffSubmodule
|
|||
|
|
{
|
|||
|
|
public bool hasIcon;
|
|||
|
|
public string iconPath;
|
|||
|
|
public Sprite icon;
|
|||
|
|
public List<Func<string>> setTextFunctions;
|
|||
|
|
|
|||
|
|
public HUD_CharacterBuffIcon buffIcon;
|
|||
|
|
|
|||
|
|
public UISubmodule(BuffBase<T> buff, string iconPath = "",
|
|||
|
|
params Func<string>[] setTextFunctions) : base(buff)
|
|||
|
|
{
|
|||
|
|
this.hasIcon = !string.IsNullOrEmpty(iconPath);
|
|||
|
|
this.iconPath = iconPath;
|
|||
|
|
|
|||
|
|
if (hasIcon)
|
|||
|
|
{
|
|||
|
|
this.icon = AssetLoader.LoadAsset<Sprite>(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;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// duration为负数表示无限持续时间。
|
|||
|
|
/// </summary>
|
|||
|
|
public CountSubmodule(BuffBase<T> buff, int maximumCount) : base(buff)
|
|||
|
|
{
|
|||
|
|
this.maximumCount = maximumCount;
|
|||
|
|
this.remainingCount = maximumCount;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void UpdateModule()
|
|||
|
|
{
|
|||
|
|
if (isInfinite)
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
remainingCount--;
|
|||
|
|
|
|||
|
|
if (remainingCount <= 0)
|
|||
|
|
{
|
|||
|
|
buff.Remove();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 刷新剩余时间至初始值。
|
|||
|
|
/// </summary>
|
|||
|
|
public void RefreshDuration()
|
|||
|
|
{
|
|||
|
|
if (isInfinite)
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
remainingCount = maximumCount;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 覆盖(可选保留更大的duration)并刷新剩余时间。
|
|||
|
|
/// </summary>
|
|||
|
|
public void RefreshDuration(int overrideDuration, bool keepMaximal = true)
|
|||
|
|
{
|
|||
|
|
if (isInfinite)
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
maximumCount = keepMaximal ? Mathf.Max(maximumCount, overrideDuration) : overrideDuration;
|
|||
|
|
remainingCount = maximumCount;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 增加持续时间和剩余时间。
|
|||
|
|
/// </summary>
|
|||
|
|
public void AddDuration(int additionalDuration)
|
|||
|
|
{
|
|||
|
|
if (isInfinite)
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
maximumCount += additionalDuration;
|
|||
|
|
remainingCount += additionalDuration;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 仅增加剩余时间,不改变总持续时间。
|
|||
|
|
/// 如果增加后剩余时间超过总持续时间,则剩余时间等于总持续时间。
|
|||
|
|
/// </summary>
|
|||
|
|
public void AddTime(int additionalTime)
|
|||
|
|
{
|
|||
|
|
if (isInfinite)
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
remainingCount += additionalTime;
|
|||
|
|
remainingCount = Mathf.Min(remainingCount, maximumCount);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Buff叠加模块,叠加层数统一。
|
|||
|
|
/// </summary>
|
|||
|
|
public class UnitedStackSubmodule : BuffSubmodule
|
|||
|
|
{
|
|||
|
|
public bool willRemoveOnZero; //是否在层数为0时移除Buff
|
|||
|
|
public int stackAmount; //当前层数
|
|||
|
|
public int stackUpperLimit; //层数上限,-1表示无限制
|
|||
|
|
|
|||
|
|
public UnitedStackSubmodule(BuffBase<T> 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();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Buff独立叠加模块,每一层的持续时间和层数可以不同。
|
|||
|
|
/// </summary>
|
|||
|
|
public class IndependentStackSubmodule : BuffSubmodule
|
|||
|
|
{
|
|||
|
|
public bool willRemoveOnZero;
|
|||
|
|
public List<IndependentStackUnit> independentStacks;
|
|||
|
|
public int totalStackAmount;
|
|||
|
|
|
|||
|
|
public IndependentStackSubmodule(BuffBase<T> buff, bool willRemoveOnZero) : base(buff)
|
|||
|
|
{
|
|||
|
|
this.willRemoveOnZero = willRemoveOnZero;
|
|||
|
|
independentStacks = new List<IndependentStackUnit>();
|
|||
|
|
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<IndependentStackUnit>
|
|||
|
|
{
|
|||
|
|
public int stackAmount;
|
|||
|
|
public int duration;
|
|||
|
|
public int remainingTime;
|
|||
|
|
public Dictionary<string, float> 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<string, float>();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public int CompareTo(IndependentStackUnit other)
|
|||
|
|
{
|
|||
|
|
return remainingTime.CompareTo(other.remainingTime);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|