From e1c907ec732997991232cd930c7d897cea9cf041 Mon Sep 17 00:00:00 2001 From: Will Nations Date: Fri, 13 Oct 2017 17:03:33 -0500 Subject: [PATCH] Node.duplicate(): instanced node's descendants' properties now update w/ original's runtime values. --- scene/main/node.cpp | 64 ++++++++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 21 deletions(-) mode change 100755 => 100644 scene/main/node.cpp diff --git a/scene/main/node.cpp b/scene/main/node.cpp old mode 100755 new mode 100644 index 30b831adfcf..31d423c8083 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -2104,37 +2104,59 @@ Node *Node::_duplicate(int p_flags, Map *r_duplimap) const ERR_FAIL_COND_V(!node, NULL); } - List plist; - - get_property_list(&plist); + if (get_filename() != "") { //an instance + node->set_filename(get_filename()); + } StringName script_property_name = CoreStringNames::get_singleton()->_script; - if (p_flags & DUPLICATE_SCRIPTS) { - bool is_valid = false; - Variant script = get(script_property_name, &is_valid); - if (is_valid) { - node->set(script_property_name, script); + List node_tree; + node_tree.push_front(this); + + if (instanced) { + for (List::Element *N = node_tree.front(); N; N = N->next()) { + for (int i = 0; i < N->get()->get_child_count(); ++i) { + node_tree.push_back(N->get()->get_child(i)); + } } } - for (List::Element *E = plist.front(); E; E = E->next()) { + for (List::Element *N = node_tree.front(); N; N = N->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) - continue; - String name = E->get().name; - if (name == script_property_name) - continue; + Node *current_node = node->get_node(get_path_to(N->get())); - 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(); + if (p_flags & DUPLICATE_SCRIPTS) { + bool is_valid = false; + Variant script = N->get()->get(script_property_name, &is_valid); + if (is_valid) { + current_node->set(script_property_name, script); + } } - node->set(name, value); + List plist; + N->get()->get_property_list(&plist); + + if (!current_node) + continue; + + for (List::Element *E = plist.front(); E; E = E->next()) { + + if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) + continue; + String name = E->get().name; + if (name == script_property_name) + continue; + + Variant value = N->get()->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(); + } + + current_node->set(name, value); + } } node->set_name(get_name());