固定 10 节点大关的生成层,但还没有接入主流程

- 新增了 FixedRunNodeSequenceBuilder.cs,现在 Plain 主题会固定生成 1战 2事 3战 4店 5战 6事 7战 8店 9事 10Boss。普通战斗节点的 LinkedLevelId 固定映射为 1 -> 2 -> 3 -> 1,第 10 个 Boss 节点固定绑定 Level 4。

- RunStateFactory.cs 增加了 CreateFixedRun(...),可以直接创建带 10 节点固定序列的 RunState。RunModel.cs 也补了几个只读查询:NodeCount、GetNodeBySequenceIndex(...)、IsBossNode(...),方便后面接真实流程。
This commit is contained in:
2026-03-07 21:52:39 +08:00
parent 5afcaafff7
commit 2b86582ff7
5 changed files with 167 additions and 0 deletions
@@ -0,0 +1,52 @@
using System.Collections.Generic;
using GeometryTD.Definition;
namespace GeometryTD.Procedure
{
public static class FixedRunNodeSequenceBuilder
{
private const int FixedNodeCount = 10;
private static readonly int[] PlainCombatLevelCycle = { 1, 2, 3, 1 };
public static IReadOnlyList<RunNodeSeed> Build(LevelThemeType themeType)
{
if (themeType != LevelThemeType.Plain)
{
return new List<RunNodeSeed>();
}
List<RunNodeSeed> nodeSeeds = new List<RunNodeSeed>(FixedNodeCount)
{
CreateNodeSeed(1, 0, RunNodeType.Combat, themeType, PlainCombatLevelCycle[0]),
CreateNodeSeed(2, 1, RunNodeType.Event, themeType, 0),
CreateNodeSeed(3, 2, RunNodeType.Combat, themeType, PlainCombatLevelCycle[1]),
CreateNodeSeed(4, 3, RunNodeType.Shop, themeType, 0),
CreateNodeSeed(5, 4, RunNodeType.Combat, themeType, PlainCombatLevelCycle[2]),
CreateNodeSeed(6, 5, RunNodeType.Event, themeType, 0),
CreateNodeSeed(7, 6, RunNodeType.Combat, themeType, PlainCombatLevelCycle[3]),
CreateNodeSeed(8, 7, RunNodeType.Shop, themeType, 0),
CreateNodeSeed(9, 8, RunNodeType.Event, themeType, 0),
CreateNodeSeed(10, 9, RunNodeType.BossCombat, themeType, 4)
};
return nodeSeeds;
}
private static RunNodeSeed CreateNodeSeed(
int nodeId,
int sequenceIndex,
RunNodeType nodeType,
LevelThemeType themeType,
int linkedLevelId)
{
return new RunNodeSeed
{
NodeId = nodeId,
SequenceIndex = sequenceIndex,
NodeType = nodeType,
ThemeType = themeType,
LinkedLevelId = linkedLevelId
};
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 650d0ca3526d4b3db552d70292267456
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -88,6 +88,8 @@ namespace GeometryTD.Procedure
public IReadOnlyList<RunNodeState> Nodes => _nodes;
public int NodeCount => _nodes.Count;
public RunNodeState CurrentNode
{
get
@@ -103,6 +105,29 @@ namespace GeometryTD.Procedure
public bool CanEnterCurrentNode => !IsCompleted && CurrentNode != null && CurrentNode.Status == RunNodeStatus.Available;
public RunNodeState GetNodeBySequenceIndex(int sequenceIndex)
{
if (sequenceIndex < 0)
{
return null;
}
foreach (RunNodeState nodeState in _nodes)
{
if (nodeState.SequenceIndex == sequenceIndex)
{
return nodeState;
}
}
return null;
}
public static bool IsBossNode(RunNodeState nodeState)
{
return nodeState != null && nodeState.NodeType == RunNodeType.BossCombat;
}
public int CompletedNodeCount
{
get
@@ -5,6 +5,15 @@ namespace GeometryTD.Procedure
{
public static class RunStateFactory
{
public static RunState CreateFixedRun(
LevelThemeType themeType,
BackpackInventoryData initialInventorySnapshot,
string runId = null)
{
IReadOnlyList<RunNodeSeed> fixedNodeSeeds = FixedRunNodeSequenceBuilder.Build(themeType);
return Create(themeType, initialInventorySnapshot, fixedNodeSeeds, runId);
}
public static RunState Create(
LevelThemeType themeType,
BackpackInventoryData initialInventorySnapshot,