Merge pull request #83343 from warriormaster12/node-property-duplication
Fix export variable of type Node pointing to a wrong child node when duplicating
This commit is contained in:
commit
13305d31b5
2 changed files with 77 additions and 38 deletions
|
@ -2528,44 +2528,6 @@ Node *Node::_duplicate(int p_flags, HashMap<const Node *, Node *> *r_duplimap) c
|
|||
}
|
||||
}
|
||||
|
||||
for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) {
|
||||
Node *current_node = node->get_node(get_path_to(N->get()));
|
||||
ERR_CONTINUE(!current_node);
|
||||
|
||||
if (p_flags & DUPLICATE_SCRIPTS) {
|
||||
bool is_valid = false;
|
||||
Variant scr = N->get()->get(script_property_name, &is_valid);
|
||||
if (is_valid) {
|
||||
current_node->set(script_property_name, scr);
|
||||
}
|
||||
}
|
||||
|
||||
List<PropertyInfo> plist;
|
||||
N->get()->get_property_list(&plist);
|
||||
|
||||
for (const PropertyInfo &E : plist) {
|
||||
if (!(E.usage & PROPERTY_USAGE_STORAGE)) {
|
||||
continue;
|
||||
}
|
||||
String name = E.name;
|
||||
if (name == script_property_name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Variant value = N->get()->get(name).duplicate(true);
|
||||
|
||||
if (E.usage & PROPERTY_USAGE_ALWAYS_DUPLICATE) {
|
||||
Resource *res = Object::cast_to<Resource>(value);
|
||||
if (res) { // Duplicate only if it's a resource
|
||||
current_node->set(name, res->duplicate());
|
||||
}
|
||||
|
||||
} else {
|
||||
current_node->set(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (get_name() != String()) {
|
||||
node->set_name(get_name());
|
||||
}
|
||||
|
@ -2631,6 +2593,62 @@ Node *Node::_duplicate(int p_flags, HashMap<const Node *, Node *> *r_duplimap) c
|
|||
}
|
||||
}
|
||||
|
||||
for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) {
|
||||
Node *current_node = node->get_node(get_path_to(N->get()));
|
||||
ERR_CONTINUE(!current_node);
|
||||
|
||||
if (p_flags & DUPLICATE_SCRIPTS) {
|
||||
bool is_valid = false;
|
||||
Variant scr = N->get()->get(script_property_name, &is_valid);
|
||||
if (is_valid) {
|
||||
current_node->set(script_property_name, scr);
|
||||
}
|
||||
}
|
||||
|
||||
List<PropertyInfo> plist;
|
||||
N->get()->get_property_list(&plist);
|
||||
|
||||
for (const PropertyInfo &E : plist) {
|
||||
if (!(E.usage & PROPERTY_USAGE_STORAGE)) {
|
||||
continue;
|
||||
}
|
||||
String name = E.name;
|
||||
if (name == script_property_name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Variant value = N->get()->get(name).duplicate(true);
|
||||
|
||||
if (E.usage & PROPERTY_USAGE_ALWAYS_DUPLICATE) {
|
||||
Resource *res = Object::cast_to<Resource>(value);
|
||||
if (res) { // Duplicate only if it's a resource
|
||||
current_node->set(name, res->duplicate());
|
||||
}
|
||||
|
||||
} else {
|
||||
// If property points to a node which is owned by a node we are duplicating, update its path.
|
||||
if (value.get_type() == Variant::OBJECT) {
|
||||
Node *property_node = Object::cast_to<Node>(value);
|
||||
if (property_node && is_ancestor_of(property_node)) {
|
||||
value = current_node->get_node_or_null(get_path_to(property_node));
|
||||
}
|
||||
} else if (value.get_type() == Variant::ARRAY) {
|
||||
Array arr = value;
|
||||
if (arr.get_typed_builtin() == Variant::OBJECT) {
|
||||
for (int i = 0; i < arr.size(); i++) {
|
||||
Node *property_node = Object::cast_to<Node>(arr[i]);
|
||||
if (property_node && is_ancestor_of(property_node)) {
|
||||
arr[i] = current_node->get_node_or_null(get_path_to(property_node));
|
||||
}
|
||||
}
|
||||
value = arr;
|
||||
}
|
||||
}
|
||||
current_node->set(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
|
|
@ -74,10 +74,31 @@ Variant PropertyUtils::get_property_default_value(const Object *p_object, const
|
|||
const SceneState::PackState &ia = states_stack[i];
|
||||
bool found = false;
|
||||
Variant value_in_ancestor = ia.state->get_property_value(ia.node, p_property, found);
|
||||
const Vector<String> &deferred_properties = ia.state->get_node_deferred_nodepath_properties(ia.node);
|
||||
if (found) {
|
||||
if (r_is_valid) {
|
||||
*r_is_valid = true;
|
||||
}
|
||||
// Replace properties stored as NodePaths with actual Nodes.
|
||||
// Otherwise, the property value would be considered as overridden.
|
||||
if (deferred_properties.has(p_property)) {
|
||||
if (value_in_ancestor.get_type() == Variant::ARRAY) {
|
||||
Array paths = value_in_ancestor;
|
||||
|
||||
bool valid = false;
|
||||
Array array = node->get(p_property, &valid);
|
||||
ERR_CONTINUE(!valid);
|
||||
array = array.duplicate();
|
||||
|
||||
array.resize(paths.size());
|
||||
for (int j = 0; j < array.size(); j++) {
|
||||
array.set(j, node->get_node_or_null(paths[j]));
|
||||
}
|
||||
value_in_ancestor = array;
|
||||
} else {
|
||||
value_in_ancestor = node->get_node_or_null(value_in_ancestor);
|
||||
}
|
||||
}
|
||||
return value_in_ancestor;
|
||||
}
|
||||
// Save script for later
|
||||
|
|
Loading…
Reference in a new issue