Files

147 lines
6.0 KiB
C#
Raw Permalink Normal View History

2025-12-08 05:27:53 -05:00
using System;
using System.Collections.Generic;
2026-07-18 03:16:20 -04:00
using System.Linq;
2026-03-20 12:07:44 -04:00
using Cielonos.MainGame.Buffs.Character;
2025-12-08 05:27:53 -05:00
using Cielonos.MainGame.Characters;
using Sirenix.OdinInspector;
using SLSUtilities.FunctionalAnimation;
2026-07-18 03:16:20 -04:00
using SLSUtilities.General;
2026-06-27 12:52:03 -04:00
using SLSUtilities.WwiseAssistance;
2026-07-18 03:16:20 -04:00
using SoftCircuits.Collections;
2025-12-08 05:27:53 -05:00
using UnityEngine;
using UnityEngine.Serialization;
namespace Cielonos.MainGame.FunctionalAnimation
{
2025-12-23 19:47:06 -05:00
[Serializable]
2025-12-08 05:27:53 -05:00
public class SetBreakthroughResistance : FuncAnimPayloadBase
{
2026-07-18 03:16:20 -04:00
/// <summary>
/// 在强力动作的原始抗性等级确定后、Buff 创建前调用的有序修正器。
/// 通过 key 管理注册和注销,并按 Priority 顺序将前一个结果传给后一个回调。
/// </summary>
public static readonly OrderedDictionary<string, PrioritizedFunc<Automata, Breakthrough.Type, Breakthrough.Type>>
onResolveBreakthroughableType = new();
2026-06-05 04:21:00 -04:00
public override bool IsCombatOnly => true;
2025-12-08 05:27:53 -05:00
[InfoBox("设置角色的突破抗性状态,同时开启或关闭轮廓线效果。\n角色会被突破类型相同或更高的攻击打断不会被低于该突破类型的攻击打断。")]
[FormerlySerializedAs("outlineSwitch")]
2026-05-23 08:27:50 -04:00
[Tooltip("是否开启")]
2025-12-08 05:27:53 -05:00
public bool isEnabling = true;
2026-06-27 12:52:03 -04:00
[FormerlySerializedAs("applyFXs")]
[ShowIf("isEnabling")]
[Tooltip("是否开启音效和特效特效默认为VFXData配置的WarningDisruption或WarningForced")]
public bool applyFx = true;
2025-12-08 05:27:53 -05:00
[Tooltip("是否从行为树参数获取突破类型")]
2026-06-27 12:52:03 -04:00
[ShowIf("isEnabling")]
2025-12-08 05:27:53 -05:00
public bool getFromBehaviorTree = true;
[Tooltip("突破类型")]
[HideIf("getFromBehaviorTree")]
2026-05-23 08:27:50 -04:00
public Breakthrough.Type breakthroughableType = Breakthrough.Type.Heavy;
2025-12-08 05:27:53 -05:00
[Tooltip("是否使用详细设置")]
public bool detailedSettings = false;
[Tooltip("轮廓线宽度")]
[ShowIf("@this.detailedSettings && this.isEnabling")]
public float outlineWidth = 0.05f;
[Tooltip("轮廓线淡入淡出时间")]
[ShowIf("detailedSettings")]
public float outlineFadeDuration = 0.1f;
public override void Invoke()
{
2026-06-05 04:21:00 -04:00
RenderSubcontrollerBase renderSc = Character.renderSc;
2026-07-18 03:16:20 -04:00
Breakthrough.Type resolvedBreakthroughableType = breakthroughableType;
2025-12-08 05:27:53 -05:00
if (getFromBehaviorTree)
{
2026-06-05 04:21:00 -04:00
BehaviorSubcontroller behaviorSc = (Character as Automata)!.behaviorSc;
2026-05-10 11:47:55 -04:00
string typeName = behaviorSc.mainBehaviorTree.GetVariable<string>("BreakthroughableType").Value;
2025-12-08 05:27:53 -05:00
if (string.IsNullOrEmpty(typeName))
{
2026-07-18 03:16:20 -04:00
resolvedBreakthroughableType = Breakthrough.Type.Heavy;
}
else
{
resolvedBreakthroughableType = Enum.TryParse(typeName, out Breakthrough.Type parsedType) ? parsedType : Breakthrough.Type.Heavy;
2025-12-08 05:27:53 -05:00
}
}
if (isEnabling)
{
2026-07-18 03:16:20 -04:00
if (Character is Automata automata)
{
resolvedBreakthroughableType = ResolveBreakthroughableType(automata, resolvedBreakthroughableType);
}
new BreakthroughResistanceModification(resolvedBreakthroughableType).Apply(Character);
2026-06-27 12:52:03 -04:00
if (applyFx)
{
2026-07-18 03:16:20 -04:00
if (resolvedBreakthroughableType == Breakthrough.Type.Heavy)
2026-06-27 12:52:03 -04:00
{
AudioManager.Post(AK.EVENTS.WARNING_ATTACK_HEAVYLEVEL, Character.gameObject);
Character.vfxData.SpawnVFX("WarningHeavy", Character, Character.transform);
}
2026-07-18 03:16:20 -04:00
else if (resolvedBreakthroughableType == Breakthrough.Type.Disruption)
2026-06-27 12:52:03 -04:00
{
AudioManager.Post(AK.EVENTS.WARNING_ATTACK_DISRUPTIONLEVEL, Character.gameObject);
Character.vfxData.SpawnVFX("WarningDisruption", Character, Character.transform);
}
2026-07-18 03:16:20 -04:00
else if (resolvedBreakthroughableType == Breakthrough.Type.Forced)
2026-06-27 12:52:03 -04:00
{
AudioManager.Post(AK.EVENTS.WARNING_ATTACK_FORCEDLEVEL, Character.gameObject);
Character.vfxData.SpawnVFX("WarningForced", Character, Character.transform);
}
}
2025-12-08 05:27:53 -05:00
}
else
{
2026-06-05 04:21:00 -04:00
Character.buffSm.GetBuff<BreakthroughResistanceModification>()?.Remove();
2025-12-08 05:27:53 -05:00
}
}
2026-07-18 03:16:20 -04:00
private static Breakthrough.Type ResolveBreakthroughableType(Automata target, Breakthrough.Type originalType)
{
// 多个修正器按 Priority 顺序串行处理,后一个修正器接收前一个的结果。
Breakthrough.Type resolvedType = originalType;
foreach (string key in onResolveBreakthroughableType.Keys.ToList())
{
PrioritizedFunc<Automata, Breakthrough.Type, Breakthrough.Type> resolver = onResolveBreakthroughableType[key];
resolvedType = resolver.Invoke(target, resolvedType);
if (resolver.ShouldRemove)
{
onResolveBreakthroughableType.Remove(key);
}
}
return resolvedType;
}
2025-12-08 05:27:53 -05:00
2026-05-23 08:27:50 -04:00
private void SetResistance(Breakthrough.Type type, bool isResistant)
2025-12-08 05:27:53 -05:00
{
foreach (var lowerType in Breakthrough.GetLowerTypes(type))
{
2026-06-05 04:21:00 -04:00
Character.reactionSc.breakthroughResistances[lowerType].Modify(isResistant);
2025-12-08 05:27:53 -05:00
}
2026-06-05 04:21:00 -04:00
Character.reactionSc.breakthroughResistances[type].Modify(!isResistant);
2025-12-08 05:27:53 -05:00
foreach (var higherType in Breakthrough.GetHigherTypes(type))
{
2026-06-05 04:21:00 -04:00
Character.reactionSc.breakthroughResistances[higherType].Modify(!isResistant);
2025-12-08 05:27:53 -05:00
}
}
}
2026-07-18 03:16:20 -04:00
}