Files
Continentis/Assets/Scripts/MainGame/Base/Buff/BuffSubmodules.cs
SoulliesOfficial 9b1b5ca93f initial
2025-10-03 00:02:43 -04:00

267 lines
8.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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);
}
}
}
}
}