Storyline+Dialog初步

This commit is contained in:
SoulliesOfficial
2026-07-05 16:08:23 -04:00
parent afa8a56e1d
commit d031afd075
464 changed files with 25716 additions and 4209 deletions

View File

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