summaryrefslogtreecommitdiff
path: root/scene/main/node.cpp
diff options
context:
space:
mode:
authorWill Nations <willnationsdev@gmail.com>2017-10-13 17:03:33 -0500
committerWill Nations <willnationsdev@gmail.com>2017-11-21 23:04:40 -0600
commite1c907ec732997991232cd930c7d897cea9cf041 (patch)
treed6e97c6f1ecae02ee351fa50d8b37e0de8d68cd2 /scene/main/node.cpp
parent9638c9cb5d5b43a19df390fa0bf6e996e84903bc (diff)
Node.duplicate(): instanced node's descendants' properties now update
w/ original's runtime values.
Diffstat (limited to 'scene/main/node.cpp')
-rw-r--r--[-rwxr-xr-x]scene/main/node.cpp64
1 files changed, 43 insertions, 21 deletions
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 30b831adfc..31d423c808 100755..100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -2104,37 +2104,59 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
ERR_FAIL_COND_V(!node, NULL);
}
- List<PropertyInfo> 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<const Node *> node_tree;
+ node_tree.push_front(this);
+
+ if (instanced) {
+ for (List<const Node *>::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<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
+ for (List<const Node *>::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<PropertyInfo> plist;
+ N->get()->get_property_list(&plist);
+
+ if (!current_node)
+ continue;
+
+ for (List<PropertyInfo>::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());