From ae3a47781845341bb160dec15fa578a07bf25713 Mon Sep 17 00:00:00 2001 From: Marcin Nowak Date: Wed, 4 Oct 2023 19:18:22 +0200 Subject: [PATCH] Fix #82756: Save branch as scene saves children without owner set --- editor/scene_tree_dock.cpp | 18 +++++++++++++----- editor/scene_tree_dock.h | 2 +- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index e7727aec4bc0..059172fbe600 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -2663,12 +2663,17 @@ void SceneTreeDock::_new_scene_from(String p_file) { Node *base = selection.front()->get(); HashMap duplimap; + HashMap inverse_duplimap; Node *copy = base->duplicate_from_editor(duplimap); + for (KeyValue item : duplimap) { + inverse_duplimap[item.value] = (Node *)item.key; + } + if (copy) { // Handle Unique Nodes. for (int i = 0; i < copy->get_child_count(false); i++) { - _set_node_owner_recursive(copy->get_child(i, false), copy); + _set_node_owner_recursive(copy->get_child(i, false), copy, inverse_duplimap); } // Root node cannot ever be unique name in its own Scene! copy->set_unique_name_in_owner(false); @@ -2702,13 +2707,16 @@ void SceneTreeDock::_new_scene_from(String p_file) { } } -void SceneTreeDock::_set_node_owner_recursive(Node *p_node, Node *p_owner) { - if (!p_node->get_owner()) { - p_node->set_owner(p_owner); +void SceneTreeDock::_set_node_owner_recursive(Node *p_node, Node *p_owner, HashMap &inverse_duplimap) { + if (inverse_duplimap.has(p_node)) { + Node *original = inverse_duplimap.get(p_node); + if (original->get_owner()) { + p_node->set_owner(p_owner); + } } for (int i = 0; i < p_node->get_child_count(false); i++) { - _set_node_owner_recursive(p_node->get_child(i, false), p_owner); + _set_node_owner_recursive(p_node->get_child(i, false), p_owner, inverse_duplimap); } } diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index 9c111bce71fa..79bf45f585cd 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -231,7 +231,7 @@ class SceneTreeDock : public VBoxContainer { virtual void shortcut_input(const Ref &p_event) override; void _new_scene_from(String p_file); - void _set_node_owner_recursive(Node *p_node, Node *p_owner); + void _set_node_owner_recursive(Node *p_node, Node *p_owner, HashMap &inverse_duplimap); bool _validate_no_foreign(); bool _validate_no_instance();