Files
Continentis/Assets/Scripts/MainGame/Character/CharacterBuff/CharacterCombatBuffBase.cs
SoulliesOfficial ac98ec3aef 更新
2026-04-17 12:01:50 -04:00

202 lines
8.0 KiB
C#
Raw Permalink 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.Collections.Generic;
using System.Linq;
using Continentis.MainGame.Card;
using Continentis.MainGame.Combat;
using Continentis.MainGame.UI;
using SLSUtilities.General;
using UnityEngine;
namespace Continentis.MainGame.Character
{
public abstract partial class CharacterCombatBuffBase : CharacterBuffBase
{
public CardLogicBase sourceCard;
/// <summary>
/// 行动计数,每次行动开始时计数-1。
/// </summary>
public CountSubmodule actionCountSubmodule;
/// <summary>
/// 回合计数,每回合开始时计数-1。
/// </summary>
public CountSubmodule roundCountSubmodule;
/// <summary>
/// 首次行动计数,仅在角色本回合首次行动时计数-1。
/// </summary>
public CountSubmodule roundFirstActionCountSubmodule;
public UnitedStackSubmodule unitedStackSubmodule;
public IndependentStackSubmodule independentStackSubmodule;
public GeneralAttributeSubmodule generalAttributeSubmodule;
public StatusSubmodule statusSubmodule;
}
public partial class CharacterCombatBuffBase
{
/// <summary>
/// 基类的泛型签名由此层密封并桥接到强类型版本,子类请实现
/// <see cref="OnBuffApply(out CharacterCombatBuffBase)"/>。
/// </summary>
public sealed override bool OnBuffApply(out BuffBase<CharacterBase> existingBuff)
{
bool result = OnBuffApply(out CharacterCombatBuffBase typed);
existingBuff = typed;
return result;
}
/// <summary>
/// Buff被尝试添加到角色时调用。
/// 返回 true 表示这是全新 Buff返回 false 表示已有同类 Buff 存在(通过 out 参数返回)。
/// </summary>
public abstract bool OnBuffApply(out CharacterCombatBuffBase existingBuff);
public override void OnAfterFirstApply()
{
statusSubmodule?.AddStatus();
attachedCharacter.combatBuffSubmodule.buffList.Exclude(this).For(buff => buff.eventSubmodule?.onOtherBuffFirstApplied.Invoke(this));
}
public override void OnBuffRemove()
{
RefreshAttributes();
statusSubmodule?.RemoveStatus();
iconSubmodule?.Remove();
}
}
public partial class CharacterCombatBuffBase
{
protected bool FindExistingSameBuff<T>(out T existingBuff) where T : CharacterBuffBase
{
bool result = FindExistingSameBuffs(out List<T> existingBuffs, attachedCharacter.combatBuffSubmodule.buffList);
existingBuff = result ? existingBuffs[0] : null;
return result;
}
protected bool FindExistingSameBuffs<T>(out List<T> existingBuffs) where T : CharacterBuffBase
{
bool result = FindExistingSameBuffs(out existingBuffs, attachedCharacter.combatBuffSubmodule.buffList);
return result;
}
public override void Apply(CharacterBase attachedCharacter, CharacterBase sourceCharacter = null)
{
this.Apply(attachedCharacter, sourceCharacter, null);
}
public void Apply(CharacterBase attachedCharacter, CharacterBase sourceCharacter = null, CardLogicBase sourceCard = null)
{
this.attachedCharacter = attachedCharacter;
this.sourceCharacter = sourceCharacter;
this.sourceCard = sourceCard;
if (OnBuffApply(out CharacterCombatBuffBase existingBuff))
{
this.attachedCharacter.combatBuffSubmodule.buffList.AddByPriority(this);
OnAfterFirstApply();
if (iconSubmodule != null)
{
(attachedCharacter.characterView.hudContainer.enablingHUDs["CharacterBuffCollection"] as HUD_CharacterBuffCollection)
?.AddBuffIcon(this);
}
// 1.2c — 记录 Buff 首次施加日志
CombatLogs.Instance?.LogBuffApply(this, attachedCharacter);
}
else
{
existingBuff.iconSubmodule?.Update();
}
attachedCharacter.combatBuffSubmodule.buffList.Exclude(this).For(buff => buff.eventSubmodule?.onOtherBuffApplied.Invoke(this));
RefreshAttributes();
iconSubmodule?.Update();
attachedCharacter.deckSubmodule.GetAllCards().ForEach(card => card.RefreshCardAttributes());
}
public override void Remove()
{
// 1.2c — 记录 Buff 移除日志
CombatLogs.Instance?.LogBuffRemove(this);
OnBuffRemove();
if (iconSubmodule != null)
{
(attachedCharacter.characterView.hudContainer.enablingHUDs["CharacterBuffCollection"] as HUD_CharacterBuffCollection)
?.RemoveBuffIcon(this);
}
this.attachedCharacter.combatBuffSubmodule.buffList.Remove(this);
attachedCharacter.deckSubmodule.GetAllCards().ForEach(card => card.RefreshCardAttributes());
attachedCharacter.combatBuffSubmodule.buffList.Exclude(this).For(buff => buff.eventSubmodule?.onOtherBuffRemoved.Invoke(this));
}
public override void UntriggerRemove()
{
this.attachedCharacter.combatBuffSubmodule.buffList.Remove(this);
attachedCharacter.deckSubmodule.GetAllCards().ForEach(card => card.RefreshCardAttributes());
}
/// <summary>
/// 检查并处理专注类Buff的添加逻辑。
/// 如果已有相同Buff存在则返回true并通过out参数返回该Buff。
/// 如果没有相同Buff存在则返回false并在必要时移除优先级最低的专注类Buff以腾出空间。
/// </summary>
/// <param name="existingBuff"></param>
/// <returns></returns>
public bool FocusingCheck(out CharacterCombatBuffBase existingBuff)
{
if (buffType != BuffType.Focusing)
{
Debug.LogError("FocusingCheck只能用于专注类Buff");
existingBuff = null;
return false;
}
// 移除超出上限的专注类Buff
List<CharacterCombatBuffBase> focusingBuffs =
attachedCharacter.combatBuffSubmodule.buffList.Where(buff => buff.buffType == BuffType.Focusing).ToList();
focusingBuffs.Sort();
int maximumFocusingBuffAmount = attachedCharacter.GetAttribute("MaximumFocusingBuffAmount", 1);
for (int i = maximumFocusingBuffAmount; i < focusingBuffs.Count; i++)
{
focusingBuffs[i].Remove();
}
// 检查是否已有相同Buff存在
if (FindExistingSameBuff(out existingBuff))
{
return true;
}
// 如果没有相同Buff存在但已达上限则移除优先级最低的专注类Buff将由新Buff替代
if(focusingBuffs.Count >= maximumFocusingBuffAmount)
{
CharacterCombatBuffBase lowestPriorityBuff = focusingBuffs[focusingBuffs.Count - 1];
lowestPriorityBuff.Remove();
}
return false;
}
}
public partial class CharacterCombatBuffBase
{
private void RefreshAttributes()
{
generalAttributeSubmodule?.RefreshAllModifiedAttributes();
}
/// <summary>
/// 将一条命令加入 Reaction Lane确保 Buff 触发的动画/视觉效果
/// 在当前 Main Lane 命令完成后、下一条 Main Lane 命令执行前播放。
/// Buff 中需要动画的被动响应(反击、护盾反伤等)应使用此方法入队。
/// </summary>
protected void EnqueueReaction(CommandBase cmd)
{
CommandQueueManager.Instance.AddCommand(cmd, CommandLane.Reaction);
}
}
}