From 68109eb86e7bce7c205f243a60587d457b34817d Mon Sep 17 00:00:00 2001 From: Metious <71298690+Metious@users.noreply.github.com> Date: Sat, 19 Oct 2024 20:29:22 +0330 Subject: [PATCH] fix: Duplicated nodes each time a craft tree is accessed (#559) Fixed nodes getting duplicated everytime --- Nautilus/Patchers/CraftTreePatcher.cs | 51 +++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/Nautilus/Patchers/CraftTreePatcher.cs b/Nautilus/Patchers/CraftTreePatcher.cs index a28fcd86..764348d7 100644 --- a/Nautilus/Patchers/CraftTreePatcher.cs +++ b/Nautilus/Patchers/CraftTreePatcher.cs @@ -21,6 +21,8 @@ internal class CraftTreePatcher #endregion + private static Dictionary _originalTrees = new(); + #region Patches internal static void Patch(Harmony harmony) @@ -28,15 +30,14 @@ internal static void Patch(Harmony harmony) harmony.PatchAll(typeof(CraftTreePatcher)); InternalLogger.Log($"CraftTreePatcher is done.", LogLevel.Debug); } - [HarmonyPostfix] [HarmonyPatch(typeof(CraftTree), nameof(CraftTree.GetTree))] private static void GetTreePreFix(CraftTree.Type treeType, ref CraftTree __result) { - __result ??= !CustomTrees.TryGetValue(treeType, out var customRoot) ? __result : customRoot.CustomCraftingTree; + var craftTree = !CustomTrees.TryGetValue(treeType, out var customRoot) ? __result : customRoot.CustomCraftingTree; - if (__result == null) + if (craftTree == null) { // The game actually has a few CraftTree.Type that are not used... // None, Unused1, Unused2, etc... @@ -45,14 +46,23 @@ private static void GetTreePreFix(CraftTree.Type treeType, ref CraftTree __resul return; } + if (!_originalTrees.TryGetValue(treeType, out var originalTree)) + { + originalTree = CopyTree(craftTree); + _originalTrees.Add(treeType, originalTree); + } + + var treeCopy = CopyTree(originalTree); + #if BELOWZERO if (treeType is CraftTree.Type.SeaTruckFabricator) { - PatchCraftTree(ref __result, CraftTree.Type.Fabricator); + PatchCraftTree(ref treeCopy, CraftTree.Type.Fabricator); } #endif - PatchCraftTree(ref __result, treeType); - CraftTree.AddToCraftableTech(__result); + PatchCraftTree(ref treeCopy, treeType); + CraftTree.AddToCraftableTech(treeCopy); + __result = treeCopy; } #endregion @@ -149,6 +159,35 @@ private static void RemoveNodes(ref CraftTree tree, ref List nodesToRemove } } + private static CraftTree CopyTree(CraftTree tree) + { + return new CraftTree(tree.id, (CraftNode)CopyCraftNode(tree.nodes)); + } + + /// + /// Copy the specified node and it's inner nodes recursively. + /// + /// The node to begin this operation on. Can be used on any node. + /// A complete copy of the passed node. + private static TreeNode CopyCraftNode(TreeNode treeNode) + { + var copiedNode = treeNode.Copy(); + copiedNode.nodes = treeNode.nodes.ToList(); + + if (copiedNode.nodes.Count == 0) + { + return copiedNode; + } + + for (var i = 0; i < copiedNode.nodes.Count; i++) + { + treeNode.nodes[i] = CopyCraftNode(treeNode.nodes[i]); + treeNode.nodes[i].parent = copiedNode; + } + + return copiedNode; + } + private static bool TraverseTree(TreeNode nodes, string[] path, out TreeNode currentNode) { currentNode = nodes;