Files
Cielonos/Assets/Opsive/BehaviorDesigner/Add-Ons/CielonosPack/Conditionals/CheckBuff.cs

164 lines
6.2 KiB
C#
Raw Normal View History

2026-03-20 12:07:44 -04:00
using System;
using Cielonos.MainGame.Buffs.Character;
using Opsive.BehaviorDesigner.Runtime.Tasks;
using Opsive.GraphDesigner.Runtime;
using Opsive.GraphDesigner.Runtime.Variables;
using Opsive.Shared.Utility;
using UnityEngine;
namespace Cielonos.MainGame.Characters.AI
{
[Description("模块化地检测目标身上是否满足指定的 Buff 状态(默认检测存在性,可选择开启堆叠或时间检测)。所有开启的条件必须同时满足。")]
[NodeIcon("Assets/Sprites/Icon/Condition.png")]
[Category("Cielonos/Buffs")]
public class CheckBuff : AutomataConditionalBase
{
public enum Operation
{
LessThan,
LessThanOrEqualTo,
EqualTo,
NotEqualTo,
GreaterThanOrEqualTo,
GreaterThan
}
[Tooltip("目标对象。留空则默认检测 AI 自身。")]
public SharedVariable<GameObject> target;
[Tooltip("选择要检测的 Buff 类型。")]
[SerializeReference]
public ICharacterBuffFactory buffFactory;
[Tooltip("True 意味着该 Buff 必须存在且符合所有开启的具体指标False 意味着该 Buff 绝不能存在。")]
public bool checkExist = true;
[Tooltip("开启:检测统一堆叠模块(UnitedStackSubmodule) 的层数")]
public bool checkUnitedStack = false;
public Operation unitedStackOperation = Operation.GreaterThanOrEqualTo;
[Tooltip("所需的堆叠层数 (UnitedStack)")]
public SharedVariable<int> unitedStackThreshold = 1;
[Tooltip("开启:检测独立堆叠模块(IndependentStackSubmodule) 的总层数")]
public bool checkIndependentStack = false;
public Operation independentStackOperation = Operation.GreaterThanOrEqualTo;
[Tooltip("所需的堆叠总层数 (IndependentStack)")]
public SharedVariable<int> independentStackThreshold = 1;
[Tooltip("开启:检测时间模块(TimeSubmodule) 的剩余时间")]
public bool checkTimeSubmodule = false;
public Operation timeOperation = Operation.LessThanOrEqualTo;
[Tooltip("所需的剩余时间")]
public SharedVariable<float> timeThreshold = 3f;
private CharacterBase GetTarget()
{
if (target != null && target.Value != null)
return target.Value.GetComponent<CharacterBase>();
return self;
}
public override TaskStatus OnUpdate()
{
if (buffFactory == null)
{
Debug.LogWarning("[CheckBuff] 未配置检测的 Buff 类型。");
return TaskStatus.Failure;
}
var character = GetTarget();
if (character == null) return TaskStatus.Failure;
CharacterBuffBase dummyBuff = buffFactory.Create();
Type targetBuffType = dummyBuff.GetType();
CharacterBuffBase existingBuff = character.buffSm.buffList.Find(x => x.GetType() == targetBuffType);
// ============================================
// 1. 存在性判定(最高优先级的决断)
// ============================================
if (checkExist == false)
{
// 期望 Buff 不存在。如果它确实不存在,返回 Success反之失败。
return existingBuff == null ? TaskStatus.Success : TaskStatus.Failure;
}
// 从这里往下,期望 Buff【必须存在】
if (existingBuff == null)
{
return TaskStatus.Failure;
}
// ============================================
// 2. 深入各个子模块检测(只检查开启项,且必须 ALL AND
// ============================================
// 统一堆叠检查
if (checkUnitedStack)
{
if (existingBuff.unitedStackSubmodule == null)
return TaskStatus.Failure;
if (!Compare(existingBuff.unitedStackSubmodule.stackAmount, unitedStackOperation, unitedStackThreshold.Value))
return TaskStatus.Failure;
}
// 独立堆叠检查
if (checkIndependentStack)
{
if (existingBuff.independentStackSubmodule == null)
return TaskStatus.Failure;
if (!Compare(existingBuff.independentStackSubmodule.totalStackAmount, independentStackOperation, independentStackThreshold.Value))
return TaskStatus.Failure;
}
// 剩余时间检查
if (checkTimeSubmodule)
{
if (existingBuff.timeSubmodule == null)
return TaskStatus.Failure;
if (!Compare(existingBuff.timeSubmodule.timeLeft, timeOperation, timeThreshold.Value))
return TaskStatus.Failure;
}
// 全部过关了
return TaskStatus.Success;
}
private bool Compare(float value1, Operation operation, float value2)
{
switch (operation)
{
case Operation.LessThan: return value1 < value2;
case Operation.LessThanOrEqualTo: return value1 <= value2;
case Operation.EqualTo: return Mathf.Approximately(value1, value2);
case Operation.NotEqualTo: return !Mathf.Approximately(value1, value2);
case Operation.GreaterThanOrEqualTo: return value1 >= value2;
case Operation.GreaterThan: return value1 > value2;
}
return false;
}
public override void Reset()
{
base.Reset();
target = null;
buffFactory = null;
checkExist = true;
checkUnitedStack = false;
unitedStackOperation = Operation.GreaterThanOrEqualTo;
unitedStackThreshold = 1;
checkIndependentStack = false;
independentStackOperation = Operation.GreaterThanOrEqualTo;
independentStackThreshold = 1;
checkTimeSubmodule = false;
timeOperation = Operation.LessThanOrEqualTo;
timeThreshold = 3f;
}
}
}