using System.Collections.Generic; using GeometryTD.Procedure; namespace GeometryTD.UI { public sealed class NodeMapFormUseCase : IUIUseCase { private RunState _runState; public void SetRunState(RunState runState) { _runState = runState; } public NodeMapFormRawData CreateInitialModel() { return BuildRawData(_runState); } public bool TryRequestEnterNode(int sequenceIndex, out NodeMapNodeRawData selectedNode, out NodeMapFormRawData latestRawData) { latestRawData = BuildRawData(_runState); selectedNode = null; if (_runState == null || _runState.IsCompleted) { return false; } RunNodeState currentNode = _runState.CurrentNode; if (currentNode == null || currentNode.SequenceIndex != sequenceIndex || !_runState.CanEnterCurrentNode) { return false; } RunNodeState targetNode = _runState.GetNodeBySequenceIndex(sequenceIndex); if (targetNode == null || targetNode.Status != RunNodeStatus.Available) { return false; } selectedNode = BuildNodeRawData(_runState.RunId, targetNode, currentNode.SequenceIndex); return selectedNode != null && selectedNode.CanEnter; } private static NodeMapFormRawData BuildRawData(RunState runState) { if (runState == null) { return new NodeMapFormRawData { Title = "节点地图", ProgressText = "0 / 0", CurrentNodeText = "当前节点: 无", IsRunCompleted = true, Nodes = new List() }; } List nodes = new List(runState.NodeCount); int currentSequenceIndex = runState.CurrentNode != null ? runState.CurrentNode.SequenceIndex : -1; foreach (RunNodeState node in runState.Nodes) { NodeMapNodeRawData nodeRawData = BuildNodeRawData(runState.RunId, node, currentSequenceIndex); if (nodeRawData != null) { nodes.Add(nodeRawData); } } string currentNodeText = runState.IsCompleted ? "当前节点: 已完成" : $"当前节点: {BuildNodeTitle(runState.CurrentNode)}"; return new NodeMapFormRawData { RunId = runState.RunId, Title = "节点地图", ProgressText = $"{runState.CompletedNodeCount} / {runState.NodeCount}", CurrentNodeText = currentNodeText, IsRunCompleted = runState.IsCompleted, Nodes = nodes }; } private static NodeMapNodeRawData BuildNodeRawData(string runId, RunNodeState node, int currentSequenceIndex) { if (node == null) { return null; } bool isCurrentNode = node.SequenceIndex == currentSequenceIndex; bool canEnter = isCurrentNode && node.Status == RunNodeStatus.Available; return new NodeMapNodeRawData { RunId = runId, NodeId = node.NodeId, SequenceIndex = node.SequenceIndex, NodeType = node.NodeType, Status = node.Status, IsCurrentNode = isCurrentNode, CanEnter = canEnter, Title = BuildNodeTitle(node), StatusText = BuildStatusText(node.Status, canEnter) }; } private static string BuildNodeTitle(RunNodeState node) { return node == null ? "未知节点" : BuildNodeTitle(node.NodeType); } private static string BuildNodeTitle(RunNodeType nodeType) { switch (nodeType) { case RunNodeType.Combat: return "战斗"; case RunNodeType.Event: return "事件"; case RunNodeType.Shop: return "商店"; case RunNodeType.BossCombat: return "Boss"; default: return "未知节点"; } } private static string BuildStatusText(RunNodeStatus status, bool canEnter) { if (canEnter) { return "当前"; } switch (status) { case RunNodeStatus.Locked: return "未解锁"; case RunNodeStatus.Available: return "可进入"; case RunNodeStatus.Completed: return "已完成"; case RunNodeStatus.Failed: return "失败"; case RunNodeStatus.Skipped: return "跳过"; default: return string.Empty; } } } }