using Opsive.BehaviorDesigner.Runtime.Tasks; using Opsive.GraphDesigner.Runtime.Variables; using Opsive.GraphDesigner.Runtime; using Opsive.Shared.Utility; using UnityEngine; namespace Cielonos.MainGame.Characters.AI { [Description("检查 AI 是否在近期收到了特定的上下文事件。极度稳定,完美支持BD下沉式条件打断(Conditional Aborts)。")] [NodeIcon("e6fc90c130121da4f9067b5e15b02975", "69959064b54a0cb4cb077dbb6967a3e1")] [Category("Cielonos/Events")] public class HasReceivedContextEvent : AutomataConditionalBase { [Tooltip("订阅的事件名称")] public SharedVariable eventName; [Tooltip("事件判定的有效窗口期(秒)。超出此时长的事件将被视为过期无视。")] public float validWindow = 0.2f; [RequireShared] public SharedVariable storedValue1; [RequireShared] public SharedVariable storedValue2; [RequireShared] public SharedVariable storedValue3; public override void OnStart() { base.OnStart(); if (behaviorSc != null && behaviorSc.EventMemory.TryGetValue(eventName.Value, out var e)) { if (!e.IsValid(validWindow)) { // 如果在条件开始时就已经有事件了,但它已经过期了,那就直接丢掉它,免得后续一直误触发。 behaviorSc.EventMemory.Remove(eventName.Value); } } } public override TaskStatus OnUpdate() { if (Evaluate(out BehaviorSubcontroller.AutomataEvent e)) { TryAssignValues(e); behaviorSc.EventMemory.Remove(eventName.Value); return TaskStatus.Success; } return TaskStatus.Failure; } public override TaskStatus OnReevaluateUpdate() { return Evaluate(out _) ? TaskStatus.Success : TaskStatus.Failure; } private bool Evaluate(out BehaviorSubcontroller.AutomataEvent e) { if (behaviorSc == null || string.IsNullOrEmpty(eventName.Value)) { e = null; return false; } if (behaviorSc.EventMemory.TryGetValue(eventName.Value, out e)) { if (e.IsValid(validWindow)) { return true; } } return false; } private void TryAssignValues(BehaviorSubcontroller.AutomataEvent e) { if (storedValue1 != null && storedValue1.IsShared) storedValue1.SetValue(e.Arg1); if (storedValue2 != null && storedValue2.IsShared) storedValue2.SetValue(e.Arg2); if (storedValue3 != null && storedValue3.IsShared) storedValue3.SetValue(e.Arg3); } } }