#if GRAPH_DESIGNER
using UnityEngine;
using Opsive.BehaviorDesigner.Runtime.Tasks;
using Opsive.BehaviorDesigner.Runtime.Tasks.Actions;
using BaseGames.Enemies;
using BaseGames.Enemies.Abilities;
namespace BaseGames.Enemies.AI
{
///
/// BD Action:等待指定能力执行结束后返回 Success。
/// 适用于需要同步等待某个由外部触发的能力(而非本节点触发)的场景。
///
/// 返回 Running:能力正在执行。
/// 返回 Success:能力执行完毕(IsRunning = false)。
/// 返回 Failure:能力不存在,或超时保护触发。
///
/// 典型用法:Sequence [ BD_UseAbility(A) → BD_WaitUntilAbilityEnd(B) ] 等待 B 被 A 内部链式触发后结束。
///
[TaskName("Wait Until Ability End")]
[TaskCategory("BaseGames/Enemy/Combat")]
[TaskDescription("等待指定能力执行完成后返回 Success")]
public sealed class BD_WaitUntilAbilityEnd : Action
{
[Tooltip("可直接拖拽 EnemyAbilitySO 资产(推荐),或填写裸字符串 ID 作为兜底")]
[SerializeField] private EnemyAbilitySO m_AbilitySO;
[SerializeField] private string m_AbilityId = "";
[Tooltip("超时保护(秒);0 = 永不超时")]
[SerializeField, Min(0f)] private float m_Timeout = 5f;
private EnemyBase _enemy;
private EnemyAbilityBase _ability;
private float _deadline;
public override void OnAwake() => _enemy = GetComponent();
public override void OnStart()
{
_ability = null;
_deadline = m_Timeout > 0f ? Time.time + m_Timeout : float.MaxValue;
if (_enemy == null) return;
string id = m_AbilitySO != null ? m_AbilitySO.abilityId : m_AbilityId;
if (!string.IsNullOrEmpty(id))
_ability = _enemy.Abilities?.Get(id);
}
public override TaskStatus OnUpdate()
{
if (_ability == null) return TaskStatus.Failure;
if (Time.time >= _deadline)
{
Debug.LogWarning($"[BD_WaitUntilAbilityEnd] 能力 '{_ability.Config?.abilityId}' 超时,强制中断", gameObject);
// 强制中断仍在运行的能力,防止 HitBox/动画协程泄漏
if (_ability.IsRunning)
_ability.Interrupt(InterruptReason.ExternalRequest);
return TaskStatus.Failure;
}
return _ability.IsRunning ? TaskStatus.Running : TaskStatus.Success;
}
public override void OnEnd() => _ability = null;
}
}
#endif