Files
RuinAdventurer/Scripts/DSL/Nodes/ProgramNode.cs
T

126 lines
3.0 KiB
C#

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<string, ProgramNode> 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<Godot.Collections.Dictionary> connections,
Dictionary<StringName, ProgramNode> availableNodes
)
{
nextNode = null;
if (connections.Count <= 0) return;
nextNode = GetConnectedNode(connections[0], availableNodes);
}
protected void SetBranchNodes(
List<Godot.Collections.Dictionary> connections,
Dictionary<StringName, ProgramNode> 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<StringName, ProgramNode> availableNodes
)
{
StringName nodeName = connection["to_node"].AsStringName();
if (!availableNodes.ContainsKey(nodeName)) return null;
return availableNodes[nodeName];
}
private ProgramNode GetSavedConnection(
string nodeId,
Dictionary<string, ProgramNode> availableNodes
)
{
if (string.IsNullOrEmpty(nodeId)) return null;
if (!availableNodes.ContainsKey(nodeId)) return null;
return availableNodes[nodeId];
}
}