Fixed robot save mechanic to include nodes and their states.

This commit is contained in:
2026-06-28 14:00:11 +02:00
parent c29372ca51
commit c84fdf8a0b
10 changed files with 361 additions and 6 deletions
+64 -3
View File
@@ -23,6 +23,7 @@ public partial class TestRunner : Node
Run("Resource extraction and save data roundtrip", TestResourceSaveRoundtrip);
Run("Endless resources extract slower", TestEndlessResourcesExtractSlower);
Run("Robot save data roundtrip keeps robot state", TestRobotSaveRoundtrip);
Run("Robot save data roundtrip keeps running program", TestRobotProgramSaveRoundtrip);
Run("Maintain node consumes matching gear", TestMaintainNodeConsumesMatchingGear);
Run("Sacrifice node makes resource endless", TestSacrificeNodeMakesResourceEndless);
Run("No robot recovery detects loss", TestNoRobotRecoveryDetectsLoss);
@@ -229,6 +230,66 @@ public partial class TestRunner : Node
AssertTrue(loadedRobot.isCoolingDown, "robot cooling state");
}
private void TestRobotProgramSaveRoundtrip()
{
StartNode startNode = new StartNode { EditorNodeId = "start" };
ForNode forNode = new ForNode
{
EditorNodeId = "loop",
amount = 3,
amountExecuted = 2
};
CraftNode craftNode = new CraftNode
{
EditorNodeId = "craft",
selectedItem = new Item
{
data = GameData.availableItems["stone"],
elapsedCraftTime = 0.5,
amountCrafted = 1
},
amount = 2
};
HarvestNode harvestNode = new HarvestNode { EditorNodeId = "done" };
startNode.nextNode = forNode;
forNode.nextNode = craftNode;
forNode.NegativeNode = harvestNode;
craftNode.nextNode = forNode;
Robot robot = new Robot
{
Name = "Loop Bot",
currentProgram = "Looping",
isExecuting = true,
programStartNode = startNode,
currentNode = craftNode,
nodes = new List<ProgramNode> { startNode, forNode, craftNode, harvestNode }
};
RobotSaveData saveData = robot.CreateSaveData();
Robot loadedRobot = new Robot();
loadedRobot.LoadSaveData(saveData);
AssertTrue(loadedRobot.isExecuting, "loaded robot should still execute");
AssertEqual("craft", loadedRobot.currentNode.EditorNodeId, "current node id");
AssertEqual("start", loadedRobot.programStartNode.EditorNodeId, "start node id");
AssertEqual(4, loadedRobot.nodes.Count, "loaded node count");
ForNode loadedForNode = loadedRobot.nodes[1] as ForNode;
CraftNode loadedCraftNode = loadedRobot.nodes[2] as CraftNode;
AssertEqual(3, loadedForNode.amount, "for amount");
AssertEqual(2, loadedForNode.amountExecuted, "for amount executed");
AssertTrue(ReferenceEquals(loadedCraftNode, loadedForNode.nextNode), "for success branch");
AssertTrue(ReferenceEquals(loadedRobot.nodes[3], loadedForNode.NegativeNode), "for negative branch");
AssertTrue(ReferenceEquals(loadedForNode, loadedCraftNode.nextNode), "craft loops back");
AssertEqual("stone", loadedCraftNode.selectedItem.data.Id, "craft item");
AssertEqual(2, loadedCraftNode.amount, "craft amount");
AssertClose(0.5f, (float)loadedCraftNode.selectedItem.elapsedCraftTime, 0.001f, "craft elapsed");
AssertEqual(1, loadedCraftNode.selectedItem.amountCrafted, "craft crafted amount");
}
private void TestMaintainNodeConsumesMatchingGear()
{
Robot robot = new Robot
@@ -475,9 +536,9 @@ public partial class TestRunner : Node
amount = 2
};
AssertEqual(NodeResult.CONDITIONFALSE, node.Execute(null, 0), "first iteration");
AssertEqual(NodeResult.CONDITIONFALSE, node.Execute(null, 0), "second iteration");
AssertEqual(NodeResult.SUCCESS, node.Execute(null, 0), "loop finished");
AssertEqual(NodeResult.SUCCESS, node.Execute(null, 0), "first iteration");
AssertEqual(NodeResult.SUCCESS, node.Execute(null, 0), "second iteration");
AssertEqual(NodeResult.CONDITIONFALSE, node.Execute(null, 0), "loop finished");
}
private void TestRuntimeNodeKeepsEditorIdWithoutSharingState()