Browse Source

Stop pasted child nodes being assigned an owner when previously unowned

Make copy and pasting match duplication's ownership transferral behavior by storing ownership information in the duplicated nodes on the node clipboard, then checking that information when setting owners for pasted nodes.
SnailRhymer 3 years ago
parent
commit
526d299623
1 changed files with 16 additions and 1 deletions
  1. 16 1
      editor/scene_tree_dock.cpp

+ 16 - 1
editor/scene_tree_dock.cpp

@@ -482,6 +482,20 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
 
 
 				ERR_CONTINUE(!dup);
 				ERR_CONTINUE(!dup);
 
 
+				// Preserve ownership relations ready for pasting.
+				List<Node *> owned;
+				node->get_owned_by(node->get_owner(), &owned);
+
+				for (Node *F : owned) {
+					if (!duplimap.has(F) || F == node) {
+						continue;
+					}
+					Node *d = duplimap[F];
+					// Only use this as a marker that ownership needs to be assigned when pasting.
+					// The actual owner doesn't matter.
+					d->set_owner(dup);
+				}
+
 				node_clipboard.push_back(dup);
 				node_clipboard.push_back(dup);
 			}
 			}
 
 
@@ -3239,7 +3253,8 @@ List<Node *> SceneTreeDock::paste_nodes() {
 
 
 		for (KeyValue<const Node *, Node *> &E2 : duplimap) {
 		for (KeyValue<const Node *, Node *> &E2 : duplimap) {
 			Node *d = E2.value;
 			Node *d = E2.value;
-			if (d != dup) {
+			// When copying, all nodes that should have an owner assigned here were given node as an owner.
+			if (d != dup && E2.key->get_owner() == node) {
 				ur->add_do_method(d, "set_owner", owner);
 				ur->add_do_method(d, "set_owner", owner);
 			}
 			}
 		}
 		}