Browse Source

Fix duplication of nodes resulting in shared metadata

Fixes #9547
Bojidar Marinov 8 years ago
parent
commit
ebee9898ca
2 changed files with 27 additions and 3 deletions
  1. 8 1
      editor/scene_tree_dock.cpp
  2. 19 2
      scene/main/node.cpp

+ 8 - 1
editor/scene_tree_dock.cpp

@@ -823,7 +823,14 @@ Node *SceneTreeDock::_duplicate(Node *p_node, Map<Node *, Node *> &duplimap) {
 		if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
 			continue;
 		String name = E->get().name;
-		node->set(name, p_node->get(name));
+		Variant value = p_node->get(name);
+		// Duplicate dictionaries and arrays, mainly needed for __meta__
+		if (value.get_type() == Variant::DICTIONARY) {
+			value = Dictionary(value).copy();
+		} else if (value.get_type() == Variant::ARRAY) {
+			value = Array(value).duplicate();
+		}
+		node->set(name, value);
 	}
 
 	List<Node::GroupInfo> group_info;

+ 19 - 2
scene/main/node.cpp

@@ -2117,7 +2117,15 @@ Node *Node::_duplicate(int p_flags) const {
 		if (!(p_flags & DUPLICATE_SCRIPTS) && name == "script/script")
 			continue;
 
-		node->set(name, get(name));
+		Variant value = get(name);
+		// Duplicate dictionaries and arrays, mainly needed for __meta__
+		if (value.get_type() == Variant::DICTIONARY) {
+			value = Dictionary(value).copy();
+		} else if (value.get_type() == Variant::ARRAY) {
+			value = Array(value).duplicate();
+		}
+
+		node->set(name, value);
 	}
 
 	node->set_name(get_name());
@@ -2199,7 +2207,16 @@ void Node::_duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p
 		if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
 			continue;
 		String name = E->get().name;
-		node->set(name, get(name));
+
+		Variant value = get(name);
+		// Duplicate dictionaries and arrays, mainly needed for __meta__
+		if (value.get_type() == Variant::DICTIONARY) {
+			value = Dictionary(value).copy();
+		} else if (value.get_type() == Variant::ARRAY) {
+			value = Array(value).duplicate();
+		}
+
+		node->set(name, value);
 	}
 
 	node->set_name(get_name());