using Godot; using System.Collections.Generic; public abstract class ProgramNode { public ProgramNode nextNode; public ProgramNode NegativeNode; public string EditorNodeId; public string DisplayText; public string TooltipText; public string lastExecutionMessage; public abstract NodeResult Execute(Robot robot, double delta); public abstract ProgramNode Duplicate(); public abstract string Save(); public virtual NodeSaveData CreateSaveData() { return new NodeSaveData { NodeType = DisplayText, EditorNodeId = EditorNodeId, NextEditorNodeId = nextNode?.EditorNodeId, NegativeEditorNodeId = NegativeNode?.EditorNodeId, NodeContent = Save(), LastExecutionMessage = lastExecutionMessage }; } public virtual void Load(NodeSaveData saveData) { EditorNodeId = saveData.EditorNodeId; lastExecutionMessage = saveData.LastExecutionMessage; } public void RestoreConnections( NodeSaveData saveData, Dictionary availableNodes ) { nextNode = GetSavedConnection(saveData.NextEditorNodeId, availableNodes); NegativeNode = GetSavedConnection(saveData.NegativeEditorNodeId, availableNodes); } public static ProgramNode CreateFromSaveData(NodeSaveData saveData) { return saveData.NodeType?.ToLower() switch { "start" => new StartNode(), "move" => new MoveNode(), "explore" => new ExploreNode(), "harvest" => new HarvestNode(), "craft" => new CraftNode(), "if" => new IfNode(), "while" => new WhileNode(), "for" => new ForNode(), "maintain" => new MaintainNode(), "sacrifice" => new SacrificeNode(), _ => null }; } public ProgramNode DuplicateForRuntime(string editorNodeId) { ProgramNode duplicate = Duplicate(); duplicate.EditorNodeId = editorNodeId; return duplicate; } public virtual void SetNextNode( List connections, Dictionary availableNodes ) { nextNode = null; if (connections.Count <= 0) return; nextNode = GetConnectedNode(connections[0], availableNodes); } protected void SetBranchNodes( List connections, Dictionary availableNodes ) { nextNode = null; NegativeNode = null; foreach (Godot.Collections.Dictionary connection in connections) { ProgramNode connectedNode = GetConnectedNode(connection, availableNodes); if ((int)connection["from_port"] == 0) { nextNode = connectedNode; } else { NegativeNode = connectedNode; } } } protected ProgramNode GetConnectedNode( Godot.Collections.Dictionary connection, Dictionary availableNodes ) { StringName nodeName = connection["to_node"].AsStringName(); if (!availableNodes.ContainsKey(nodeName)) return null; return availableNodes[nodeName]; } private ProgramNode GetSavedConnection( string nodeId, Dictionary availableNodes ) { if (string.IsNullOrEmpty(nodeId)) return null; if (!availableNodes.ContainsKey(nodeId)) return null; return availableNodes[nodeId]; } }