using System; using System.Collections.Generic; using Sirenix.OdinInspector; using UnityEngine; namespace Ichni.Story { /// /// 解锁条件树的节点基类。通过多态组合出"与 / 或 / 非 + 叶子条件"的复合表达式。 /// 由 借助 [SerializeReference] 序列化持有, /// Odin 会以类型下拉框展示可选的节点类型。 /// [Serializable] public abstract class StoryConditionNode { /// /// 对该节点求值。 /// /// 按变量名返回其整型值的委托。 /// 按 blockId 判断该 block 是否已完成的委托。 public abstract bool Evaluate(Func getVariable, Func isBlockCompleted); } /// /// 复合节点(逻辑与 AND):所有子条件均满足时才满足。子列表为空视为满足。 /// [Serializable] [LabelText("All Of (AND)")] public class AllOfCondition : StoryConditionNode { [HideLabel] [SerializeReference] [ListDrawerSettings(ShowFoldout = true, DefaultExpandedState = true)] public List conditions = new List(); public override bool Evaluate(Func getVariable, Func isBlockCompleted) { foreach (StoryConditionNode child in conditions) { if (child != null && !child.Evaluate(getVariable, isBlockCompleted)) return false; } return true; } } /// /// 复合节点(逻辑或 OR):任一子条件满足即满足。子列表为空视为不满足。 /// [Serializable] [LabelText("Any Of (OR)")] public class AnyOfCondition : StoryConditionNode { [HideLabel] [SerializeReference] [ListDrawerSettings(ShowFoldout = true, DefaultExpandedState = true)] public List conditions = new List(); public override bool Evaluate(Func getVariable, Func isBlockCompleted) { if (conditions.Count == 0) return false; foreach (StoryConditionNode child in conditions) { if (child != null && child.Evaluate(getVariable, isBlockCompleted)) return true; } return false; } } /// /// 复合节点(逻辑非 NOT):对子条件取反。子条件为空视为满足(等价于"非 假")。 /// [Serializable] [LabelText("Not")] public class NotCondition : StoryConditionNode { [HideLabel] [SerializeReference] public StoryConditionNode condition; public override bool Evaluate(Func getVariable, Func isBlockCompleted) { return condition == null || !condition.Evaluate(getVariable, isBlockCompleted); } } /// /// 叶子节点:指定 block 已完成时满足。 /// [Serializable] [LabelText("Block Completed")] public class BlockCompletedCondition : StoryConditionNode { [LabelText("Block ID")] public string blockId; public override bool Evaluate(Func getVariable, Func isBlockCompleted) { return !string.IsNullOrEmpty(blockId) && isBlockCompleted(blockId); } } /// /// 叶子节点:将指定变量的当前值与目标值按比较方式求值。 /// [Serializable] [LabelText("Variable Compare")] public class VariableCondition : StoryConditionNode { [LabelText("Variable Name")] public string variableName; [LabelText("Comparison")] public VariableComparison comparison; [LabelText("Value")] public int value; public override bool Evaluate(Func getVariable, Func isBlockCompleted) { int actual = getVariable(variableName); return comparison switch { VariableComparison.Equal => actual == value, VariableComparison.NotEqual => actual != value, VariableComparison.Greater => actual > value, VariableComparison.GreaterOrEqual => actual >= value, VariableComparison.Less => actual < value, VariableComparison.LessOrEqual => actual <= value, _ => false }; } } }