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
};
}
}
}