diff options
30 files changed, 214 insertions, 114 deletions
diff --git a/doc/classes/EditorScenePostImport.xml b/doc/classes/EditorScenePostImport.xml index 2bf2accf17..d2ad8d1bed 100644 --- a/doc/classes/EditorScenePostImport.xml +++ b/doc/classes/EditorScenePostImport.xml @@ -28,12 +28,12 @@ // This sample changes all node names. // Called right after the scene is imported and gets the root node. [Tool] - public class NodeRenamer : EditorScenePostImport + public partial class NodeRenamer : EditorScenePostImport { - public override Object PostImport(Object scene) + public override Object _PostImport(Node scene) { // Change all node names to "modified_[oldnodename]" - Iterate(scene as Node); + Iterate(scene); return scene; // Remember to return the imported scene } public void Iterate(Node node) diff --git a/doc/classes/TileSet.xml b/doc/classes/TileSet.xml index 5a24483774..7fc6ba8161 100644 --- a/doc/classes/TileSet.xml +++ b/doc/classes/TileSet.xml @@ -616,6 +616,7 @@ </constant> <constant name="TILE_SHAPE_ISOMETRIC" value="1" enum="TileShape"> Diamond tile shape (for isometric look). + [b]Note:[/b] Isometric [TileSet] works best if [TileMap] and all its layers have Y-sort enabled. </constant> <constant name="TILE_SHAPE_HALF_OFFSET_SQUARE" value="2" enum="TileShape"> Rectangular tile shape with one row/column out of two offset by half a tile. diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index fa68f0063f..1b922fa726 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -503,8 +503,7 @@ multiview_data; /* clang-format on */ -//directional light data - +// Directional light data. #ifndef DISABLE_LIGHT_DIRECTIONAL struct DirectionalLightData { @@ -520,11 +519,12 @@ layout(std140) uniform DirectionalLights { // ubo:7 DirectionalLightData directional_lights[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS]; }; -#endif +#endif // !DISABLE_LIGHT_DIRECTIONAL + +// Omni and spot light data. +#if !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) -// omni and spot -#if !defined(DISABLE_LIGHT_OMNI) && !defined(DISABLE_LIGHT_SPOT) -struct LightData { //this structure needs to be as packed as possible +struct LightData { // This structure needs to be as packed as possible. highp vec3 position; highp float inv_radius; @@ -539,9 +539,9 @@ struct LightData { //this structure needs to be as packed as possible mediump float specular_amount; mediump float shadow_opacity; }; + #ifndef DISABLE_LIGHT_OMNI layout(std140) uniform OmniLightData { // ubo:5 - LightData omni_lights[MAX_LIGHT_DATA_STRUCTS]; }; uniform uint omni_light_indices[MAX_FORWARD_LIGHTS]; @@ -549,9 +549,7 @@ uniform uint omni_light_count; #endif #ifndef DISABLE_LIGHT_SPOT - layout(std140) uniform SpotLightData { // ubo:6 - LightData spot_lights[MAX_LIGHT_DATA_STRUCTS]; }; uniform uint spot_light_indices[MAX_FORWARD_LIGHTS]; @@ -562,7 +560,7 @@ uniform uint spot_light_count; uniform highp samplerCubeShadow positional_shadow; // texunit:-4 #endif -#endif // !defined(DISABLE_LIGHT_OMNI) && !defined(DISABLE_LIGHT_SPOT) +#endif // !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) #ifdef USE_MULTIVIEW uniform highp sampler2DArray depth_buffer; // texunit:-6 @@ -585,6 +583,7 @@ vec3 F0(float metallic, float specular, vec3 albedo) { } #if !defined(DISABLE_LIGHT_DIRECTIONAL) || !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) + float D_GGX(float cos_theta_m, float alpha) { float a = cos_theta_m * alpha; float k = alpha / (1.0 - cos_theta_m * cos_theta_m + a * a); @@ -641,7 +640,6 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte /* clang-format off */ - #CODE : LIGHT /* clang-format on */ @@ -672,11 +670,8 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte // https://web.archive.org/web/20210228210901/http://blog.stevemcauley.com/2011/12/03/energy-conserving-wrapped-diffuse/ diffuse_brdf_NL = max(0.0, (NdotL + roughness) / ((1.0 + roughness) * (1.0 + roughness))) * (1.0 / M_PI); #elif defined(DIFFUSE_TOON) - diffuse_brdf_NL = smoothstep(-roughness, max(roughness, 0.01), NdotL) * (1.0 / M_PI); - #elif defined(DIFFUSE_BURLEY) - { float FD90_minus_1 = 2.0 * cLdotH * cLdotH * roughness - 0.5; float FdV = 1.0 + FD90_minus_1 * SchlickFresnel(cNdotV); @@ -684,7 +679,7 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte diffuse_brdf_NL = (1.0 / M_PI) * FdV * FdL * cNdotL; } #else - // lambert + // Lambert diffuse_brdf_NL = cNdotL * (1.0 / M_PI); #endif @@ -720,7 +715,6 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte // shlick+ggx as default float alpha_ggx = roughness * roughness; #if defined(LIGHT_ANISOTROPY_USED) - float aspect = sqrt(1.0 - anisotropy * 0.9); float ax = alpha_ggx / aspect; float ay = alpha_ggx * aspect; @@ -728,7 +722,7 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte float YdotH = dot(B, H); float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH); float G = V_GGX_anisotropic(ax, ay, dot(T, V), dot(T, L), dot(B, V), dot(B, L), cNdotV, cNdotL); -#else // LIGHT_ANISOTROPY_USED +#else float D = D_GGX(cNdotH, alpha_ggx); float G = V_GGX(cNdotL, cNdotV, alpha_ggx); #endif // LIGHT_ANISOTROPY_USED @@ -768,10 +762,10 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte alpha = min(alpha, clamp(1.0 - attenuation, 0.0, 1.0)); #endif -#endif //defined(LIGHT_CODE_USED) +#endif // LIGHT_CODE_USED } -float get_omni_attenuation(float distance, float inv_range, float decay) { +float get_omni_spot_attenuation(float distance, float inv_range, float decay) { float nd = distance * inv_range; nd *= nd; nd *= nd; // nd^4 @@ -779,6 +773,7 @@ float get_omni_attenuation(float distance, float inv_range, float decay) { nd *= nd; // nd^2 return nd * pow(max(distance, 0.0001), -decay); } + #ifndef DISABLE_LIGHT_OMNI void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f0, float roughness, float metallic, float shadow, vec3 albedo, inout float alpha, #ifdef LIGHT_BACKLIGHT_USED @@ -796,7 +791,7 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f inout vec3 diffuse_light, inout vec3 specular_light) { vec3 light_rel_vec = omni_lights[idx].position - vertex; float light_length = length(light_rel_vec); - float omni_attenuation = get_omni_attenuation(light_length, omni_lights[idx].inv_radius, omni_lights[idx].attenuation); + float omni_attenuation = get_omni_spot_attenuation(light_length, omni_lights[idx].inv_radius, omni_lights[idx].attenuation); vec3 color = omni_lights[idx].color; float size_A = 0.0; @@ -842,7 +837,7 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f vec3 light_rel_vec = spot_lights[idx].position - vertex; float light_length = length(light_rel_vec); - float spot_attenuation = get_omni_attenuation(light_length, spot_lights[idx].inv_radius, spot_lights[idx].attenuation); + float spot_attenuation = get_omni_spot_attenuation(light_length, spot_lights[idx].inv_radius, spot_lights[idx].attenuation); vec3 spot_dir = spot_lights[idx].direction; float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_lights[idx].cone_angle); float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_lights[idx].cone_angle)); @@ -872,7 +867,8 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f diffuse_light, specular_light); } #endif // !DISABLE_LIGHT_SPOT -#endif // !defined(DISABLE_LIGHT_DIRECTIONAL) || !defined(DISABLE_LIGHT_OMNI) && !defined(DISABLE_LIGHT_SPOT) + +#endif // !defined(DISABLE_LIGHT_DIRECTIONAL) || !defined(DISABLE_LIGHT_OMNI) || !defined(DISABLE_LIGHT_SPOT) #ifndef MODE_RENDER_DEPTH vec4 fog_process(vec3 vertex) { @@ -1070,15 +1066,11 @@ void main() { fog = fog_process(vertex); } #endif // !DISABLE_FOG -#endif //!CUSTOM_FOG_USED +#endif // !CUSTOM_FOG_USED uint fog_rg = packHalf2x16(fog.rg); uint fog_ba = packHalf2x16(fog.ba); -#endif //!MODE_RENDER_DEPTH - -#ifndef MODE_RENDER_DEPTH - // Convert colors to linear albedo = srgb_to_linear(albedo); emission = srgb_to_linear(emission); @@ -1199,7 +1191,7 @@ void main() { diffuse_light, specular_light); } -#endif //!DISABLE_LIGHT_DIRECTIONAL +#endif // !DISABLE_LIGHT_DIRECTIONAL #ifndef DISABLE_LIGHT_OMNI for (uint i = 0u; i < MAX_FORWARD_LIGHTS; i++) { @@ -1246,9 +1238,10 @@ void main() { #endif diffuse_light, specular_light); } - #endif // !DISABLE_LIGHT_SPOT + #endif // !MODE_UNSHADED + #endif // !MODE_RENDER_DEPTH #if defined(USE_SHADOW_TO_OPACITY) diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index 2adab089e4..5292b51032 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -284,8 +284,9 @@ void CreateDialog::_configure_search_option_item(TreeItem *r_item, const String bool can_instantiate = (p_type_category == TypeCategory::CPP_TYPE && ClassDB::can_instantiate(p_type)) || p_type_category == TypeCategory::OTHER_TYPE; + bool is_virtual = ClassDB::class_exists(p_type) && ClassDB::is_virtual(p_type); - if (can_instantiate && !ClassDB::is_virtual(p_type)) { + if (can_instantiate && !is_virtual) { r_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type, icon_fallback)); } else { r_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type, "NodeDisabled")); diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp index 57e8046f32..aec43290f9 100644 --- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp @@ -41,6 +41,7 @@ #include "scene/gui/menu_button.h" #include "scene/resources/concave_polygon_shape_3d.h" #include "scene/resources/convex_polygon_shape_3d.h" +#include "scene/scene_string_names.h" void MeshInstance3DEditor::_node_removed(Node *p_node) { if (p_node == node) { @@ -87,8 +88,8 @@ void MeshInstance3DEditor::_menu_option(int p_option) { ur->add_do_method(node, "add_child", body, true); ur->add_do_method(body, "set_owner", owner); ur->add_do_method(cshape, "set_owner", owner); - ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", body); - ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", cshape); + ur->add_do_method(Node3DEditor::get_singleton(), SceneStringNames::get_singleton()->_request_gizmo, body); + ur->add_do_method(Node3DEditor::get_singleton(), SceneStringNames::get_singleton()->_request_gizmo, cshape); ur->add_do_reference(body); ur->add_undo_method(node, "remove_child", body); ur->commit_action(); @@ -123,8 +124,8 @@ void MeshInstance3DEditor::_menu_option(int p_option) { ur->add_do_method(instance, "add_child", body, true); ur->add_do_method(body, "set_owner", owner); ur->add_do_method(cshape, "set_owner", owner); - ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", body); - ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", cshape); + ur->add_do_method(Node3DEditor::get_singleton(), SceneStringNames::get_singleton()->_request_gizmo, body); + ur->add_do_method(Node3DEditor::get_singleton(), SceneStringNames::get_singleton()->_request_gizmo, cshape); ur->add_do_reference(body); ur->add_undo_method(instance, "remove_child", body); } @@ -158,7 +159,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) { ur->add_do_method(node->get_parent(), "add_child", cshape, true); ur->add_do_method(node->get_parent(), "move_child", cshape, node->get_index() + 1); ur->add_do_method(cshape, "set_owner", owner); - ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", cshape); + ur->add_do_method(Node3DEditor::get_singleton(), SceneStringNames::get_singleton()->_request_gizmo, cshape); ur->add_do_reference(cshape); ur->add_undo_method(node->get_parent(), "remove_child", cshape); ur->commit_action(); @@ -198,7 +199,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) { ur->add_do_method(node->get_parent(), "add_child", cshape, true); ur->add_do_method(node->get_parent(), "move_child", cshape, node->get_index() + 1); ur->add_do_method(cshape, "set_owner", owner); - ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", cshape); + ur->add_do_method(Node3DEditor::get_singleton(), SceneStringNames::get_singleton()->_request_gizmo, cshape); ur->add_do_reference(cshape); ur->add_undo_method(node->get_parent(), "remove_child", cshape); @@ -237,7 +238,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) { ur->add_do_method(node->get_parent(), "add_child", cshape); ur->add_do_method(node->get_parent(), "move_child", cshape, node->get_index() + 1); ur->add_do_method(cshape, "set_owner", owner); - ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", cshape); + ur->add_do_method(Node3DEditor::get_singleton(), SceneStringNames::get_singleton()->_request_gizmo, cshape); ur->add_do_reference(cshape); ur->add_undo_method(node->get_parent(), "remove_child", cshape); } @@ -263,7 +264,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) { ur->add_do_method(node, "add_child", nmi, true); ur->add_do_method(nmi, "set_owner", owner); - ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", nmi); + ur->add_do_method(Node3DEditor::get_singleton(), SceneStringNames::get_singleton()->_request_gizmo, nmi); ur->add_do_reference(nmi); ur->add_undo_method(node, "remove_child", nmi); @@ -498,7 +499,7 @@ void MeshInstance3DEditor::_create_outline_mesh() { ur->add_do_method(node, "add_child", mi, true); ur->add_do_method(mi, "set_owner", owner); - ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", mi); + ur->add_do_method(Node3DEditor::get_singleton(), SceneStringNames::get_singleton()->_request_gizmo, mi); ur->add_do_reference(mi); ur->add_undo_method(node, "remove_child", mi); diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp index e8bbfd1b91..f79a001efb 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_3d_editor_plugin.cpp @@ -47,6 +47,7 @@ #include "scene/resources/skeleton_profile.h" #include "scene/resources/sphere_shape_3d.h" #include "scene/resources/surface_tool.h" +#include "scene/scene_string_names.h" void BoneTransformEditor::create_editors() { const Color section_color = get_theme_color(SNAME("prop_subsection"), SNAME("Editor")); @@ -399,8 +400,8 @@ void Skeleton3DEditor::create_physical_skeleton() { ur->add_do_method(physical_bone, "set_joint_type", PhysicalBone3D::JOINT_TYPE_PIN); } - ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", physical_bone); - ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", collision_shape); + ur->add_do_method(Node3DEditor::get_singleton(), SceneStringNames::get_singleton()->_request_gizmo, physical_bone); + ur->add_do_method(Node3DEditor::get_singleton(), SceneStringNames::get_singleton()->_request_gizmo, collision_shape); ur->add_do_reference(physical_bone); ur->add_undo_method(skeleton, "remove_child", physical_bone); diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index b7feedaeaa..91f31174dd 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -701,6 +701,7 @@ bool GDScript::_update_exports(bool *r_err, bool p_recursive_call, PlaceHolderSc Variant default_value; if (member.variable->initializer && member.variable->initializer->is_constant) { default_value = member.variable->initializer->reduced_value; + GDScriptCompiler::convert_to_initializer_type(default_value, member.variable); } member_default_values_cache[member.variable->identifier->name] = default_value; } break; diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 103085bc3d..81e50d6b79 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -2171,7 +2171,7 @@ void GDScriptAnalyzer::reduce_binary_op(GDScriptParser::BinaryOpNode *p_binary_o GDScriptParser::DataType test_type = right_type; test_type.is_meta_type = false; - if (!is_type_compatible(test_type, p_binary_op->left_operand->get_datatype(), false)) { + if (!is_type_compatible(test_type, left_type, false)) { push_error(vformat(R"(Expression is of type "%s" so it can't be of type "%s".)"), p_binary_op->left_operand); p_binary_op->reduced_value = false; } else { @@ -2205,11 +2205,11 @@ void GDScriptAnalyzer::reduce_binary_op(GDScriptParser::BinaryOpNode *p_binary_o GDScriptParser::DataType test_type = right_type; test_type.is_meta_type = false; - if (!is_type_compatible(test_type, p_binary_op->left_operand->get_datatype(), false)) { + if (!is_type_compatible(test_type, left_type, false)) { // Test reverse as well to consider for subtypes. - if (!is_type_compatible(p_binary_op->left_operand->get_datatype(), test_type, false)) { - if (p_binary_op->left_operand->get_datatype().is_hard_type()) { - push_error(vformat(R"(Expression is of type "%s" so it can't be of type "%s".)", p_binary_op->left_operand->get_datatype().to_string(), test_type.to_string()), p_binary_op->left_operand); + if (!is_type_compatible(left_type, test_type, false)) { + if (left_type.is_hard_type()) { + push_error(vformat(R"(Expression is of type "%s" so it can't be of type "%s".)", left_type.to_string(), test_type.to_string()), p_binary_op->left_operand); } else { // TODO: Warning. mark_node_unsafe(p_binary_op); @@ -3640,6 +3640,7 @@ void GDScriptAnalyzer::reduce_ternary_op(GDScriptParser::TernaryOpNode *p_ternar void GDScriptAnalyzer::reduce_unary_op(GDScriptParser::UnaryOpNode *p_unary_op) { reduce_expression(p_unary_op->operand); + GDScriptParser::DataType operand_type = p_unary_op->operand->get_datatype(); GDScriptParser::DataType result; if (p_unary_op->operand == nullptr) { @@ -3652,15 +3653,17 @@ void GDScriptAnalyzer::reduce_unary_op(GDScriptParser::UnaryOpNode *p_unary_op) p_unary_op->is_constant = true; p_unary_op->reduced_value = Variant::evaluate(p_unary_op->variant_op, p_unary_op->operand->reduced_value, Variant()); result = type_from_variant(p_unary_op->reduced_value, p_unary_op); - } else if (p_unary_op->operand->get_datatype().is_variant()) { + } + + if (operand_type.is_variant()) { result.kind = GDScriptParser::DataType::VARIANT; mark_node_unsafe(p_unary_op); } else { bool valid = false; - result = get_operation_type(p_unary_op->variant_op, p_unary_op->operand->get_datatype(), valid, p_unary_op); + result = get_operation_type(p_unary_op->variant_op, operand_type, valid, p_unary_op); if (!valid) { - push_error(vformat(R"(Invalid operand of type "%s" for unary operator "%s".)", p_unary_op->operand->get_datatype().to_string(), Variant::get_operator_name(p_unary_op->variant_op)), p_unary_op->operand); + push_error(vformat(R"(Invalid operand of type "%s" for unary operator "%s".)", operand_type.to_string(), Variant::get_operator_name(p_unary_op->variant_op)), p_unary_op); } } diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index c0539c7e45..2a98b856ce 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -2389,6 +2389,7 @@ Error GDScriptCompiler::_populate_class_members(GDScript *p_script, const GDScri #ifdef TOOLS_ENABLED if (variable->initializer != nullptr && variable->initializer->is_constant) { p_script->member_default_values[name] = variable->initializer->reduced_value; + GDScriptCompiler::convert_to_initializer_type(p_script->member_default_values[name], variable); } else { p_script->member_default_values.erase(name); } @@ -2646,6 +2647,20 @@ Error GDScriptCompiler::_compile_class(GDScript *p_script, const GDScriptParser: return OK; } +void GDScriptCompiler::convert_to_initializer_type(Variant &p_variant, const GDScriptParser::VariableNode *p_node) { + // Set p_variant to the value of p_node's initializer, with the type of p_node's variable. + GDScriptParser::DataType member_t = p_node->datatype; + GDScriptParser::DataType init_t = p_node->initializer->datatype; + if (member_t.is_hard_type() && init_t.is_hard_type() && + member_t.kind == GDScriptParser::DataType::BUILTIN && init_t.kind == GDScriptParser::DataType::BUILTIN) { + if (Variant::can_convert_strict(init_t.builtin_type, member_t.builtin_type)) { + Variant *v = &p_node->initializer->reduced_value; + Callable::CallError ce; + Variant::construct(member_t.builtin_type, p_variant, const_cast<const Variant **>(&v), 1, ce); + } + } +} + void GDScriptCompiler::make_scripts(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state) { p_script->fully_qualified_name = p_class->fqcn; p_script->name = p_class->identifier ? p_class->identifier->name : ""; diff --git a/modules/gdscript/gdscript_compiler.h b/modules/gdscript/gdscript_compiler.h index cba585e5a5..fc5aa05190 100644 --- a/modules/gdscript/gdscript_compiler.h +++ b/modules/gdscript/gdscript_compiler.h @@ -140,6 +140,7 @@ class GDScriptCompiler { bool within_await = false; public: + static void convert_to_initializer_type(Variant &p_variant, const GDScriptParser::VariableNode *p_node); static void make_scripts(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state); Error compile(const GDScriptParser *p_parser, GDScript *p_script, bool p_keep_state = false); diff --git a/modules/gltf/doc_classes/GLTFDocumentExtension.xml b/modules/gltf/doc_classes/GLTFDocumentExtension.xml index ac638a8962..6004de32f1 100644 --- a/modules/gltf/doc_classes/GLTFDocumentExtension.xml +++ b/modules/gltf/doc_classes/GLTFDocumentExtension.xml @@ -42,7 +42,8 @@ </method> <method name="_export_preflight" qualifiers="virtual"> <return type="int" /> - <param index="0" name="root" type="Node" /> + <param index="0" name="state" type="GLTFState" /> + <param index="1" name="root" type="Node" /> <description> Part of the export process. This method is run first, before all other parts of the export process. The return value is used to determine if this [GLTFDocumentExtension] instance should be used for exporting a given GLTF file. If [constant OK], the export will use this [GLTFDocumentExtension] instance. If not overridden, [constant OK] is returned. diff --git a/modules/gltf/extensions/gltf_document_extension.cpp b/modules/gltf/extensions/gltf_document_extension.cpp index f997fe8f66..630a62ba5c 100644 --- a/modules/gltf/extensions/gltf_document_extension.cpp +++ b/modules/gltf/extensions/gltf_document_extension.cpp @@ -40,7 +40,7 @@ void GLTFDocumentExtension::_bind_methods() { GDVIRTUAL_BIND(_import_node, "state", "gltf_node", "json", "node"); GDVIRTUAL_BIND(_import_post, "state", "root"); // Export process. - GDVIRTUAL_BIND(_export_preflight, "root"); + GDVIRTUAL_BIND(_export_preflight, "state", "root"); GDVIRTUAL_BIND(_convert_scene_node, "state", "gltf_node", "scene_node"); GDVIRTUAL_BIND(_export_node, "state", "gltf_node", "json", "node"); GDVIRTUAL_BIND(_export_post, "state"); @@ -102,10 +102,10 @@ Error GLTFDocumentExtension::import_post(Ref<GLTFState> p_state, Node *p_root) { } // Export process. -Error GLTFDocumentExtension::export_preflight(Node *p_root) { +Error GLTFDocumentExtension::export_preflight(Ref<GLTFState> p_state, Node *p_root) { ERR_FAIL_NULL_V(p_root, ERR_INVALID_PARAMETER); int err = OK; - GDVIRTUAL_CALL(_export_preflight, p_root, err); + GDVIRTUAL_CALL(_export_preflight, p_state, p_root, err); return Error(err); } diff --git a/modules/gltf/extensions/gltf_document_extension.h b/modules/gltf/extensions/gltf_document_extension.h index 7cc9ca592f..66cb9a3c33 100644 --- a/modules/gltf/extensions/gltf_document_extension.h +++ b/modules/gltf/extensions/gltf_document_extension.h @@ -49,7 +49,7 @@ public: virtual Error import_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Dictionary &r_json, Node *p_node); virtual Error import_post(Ref<GLTFState> p_state, Node *p_node); // Export process. - virtual Error export_preflight(Node *p_state); + virtual Error export_preflight(Ref<GLTFState> p_state, Node *p_root); virtual void convert_scene_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Node *p_scene_node); virtual Error export_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Dictionary &r_json, Node *p_node); virtual Error export_post(Ref<GLTFState> p_state); @@ -63,7 +63,7 @@ public: GDVIRTUAL4R(int, _import_node, Ref<GLTFState>, Ref<GLTFNode>, Dictionary, Node *); GDVIRTUAL2R(int, _import_post, Ref<GLTFState>, Node *); // Export process. - GDVIRTUAL1R(int, _export_preflight, Node *); + GDVIRTUAL2R(int, _export_preflight, Ref<GLTFState>, Node *); GDVIRTUAL3(_convert_scene_node, Ref<GLTFState>, Ref<GLTFNode>, Node *); GDVIRTUAL4R(int, _export_node, Ref<GLTFState>, Ref<GLTFNode>, Dictionary, Node *); GDVIRTUAL1R(int, _export_post, Ref<GLTFState>); diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 2cb2d21854..f4db576b0c 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -6930,7 +6930,7 @@ Error GLTFDocument::append_from_scene(Node *p_node, Ref<GLTFState> p_state, uint document_extensions.clear(); for (Ref<GLTFDocumentExtension> ext : all_document_extensions) { ERR_CONTINUE(ext.is_null()); - Error err = ext->export_preflight(p_node); + Error err = ext->export_preflight(p_state, p_node); if (err == OK) { document_extensions.push_back(ext); } diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs index 5b3f677f87..6dac120d15 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs @@ -304,7 +304,12 @@ namespace Godot.SourceGenerators { return marshalType switch { - // For generic Godot collections, VariantUtils.ConvertTo<T> is slower, so we need this special case + // We need a special case for GodotObjectOrDerived[], because it's not supported by VariantUtils.ConvertTo<T> + MarshalType.GodotObjectOrDerivedArray => + source.Append(VariantUtils, ".ConvertToSystemArrayOfGodotObject<", + ((IArrayTypeSymbol)typeSymbol).ElementType.FullQualifiedNameIncludeGlobal(), ">(", + inputExpr, ")"), + // We need a special case for generic Godot collections and GodotObjectOrDerived[], because VariantUtils.ConvertTo<T> is slower MarshalType.GodotGenericDictionary => source.Append(VariantUtils, ".ConvertToDictionaryObject<", ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedNameIncludeGlobal(), ", ", @@ -324,7 +329,10 @@ namespace Godot.SourceGenerators { return marshalType switch { - // For generic Godot collections, VariantUtils.CreateFrom<T> is slower, so we need this special case + // We need a special case for GodotObjectOrDerived[], because it's not supported by VariantUtils.CreateFrom<T> + MarshalType.GodotObjectOrDerivedArray => + source.Append(VariantUtils, ".CreateFromSystemArrayOfGodotObject(", inputExpr, ")"), + // We need a special case for generic Godot collections and GodotObjectOrDerived[], because VariantUtils.CreateFrom<T> is slower MarshalType.GodotGenericDictionary => source.Append(VariantUtils, ".CreateFromDictionary(", inputExpr, ")"), MarshalType.GodotGenericArray => @@ -339,7 +347,11 @@ namespace Godot.SourceGenerators { return marshalType switch { - // For generic Godot collections, Variant.As<T> is slower, so we need this special case + // We need a special case for GodotObjectOrDerived[], because it's not supported by Variant.As<T> + MarshalType.GodotObjectOrDerivedArray => + source.Append(inputExpr, ".AsGodotObjectArray<", + ((IArrayTypeSymbol)typeSymbol).ElementType.FullQualifiedNameIncludeGlobal(), ">()"), + // We need a special case for generic Godot collections and GodotObjectOrDerived[], because Variant.As<T> is slower MarshalType.GodotGenericDictionary => source.Append(inputExpr, ".AsGodotDictionary<", ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedNameIncludeGlobal(), ", ", @@ -357,7 +369,10 @@ namespace Godot.SourceGenerators { return marshalType switch { - // For generic Godot collections, Variant.From<T> is slower, so we need this special case + // We need a special case for GodotObjectOrDerived[], because it's not supported by Variant.From<T> + MarshalType.GodotObjectOrDerivedArray => + source.Append("global::Godot.Variant.CreateFrom(", inputExpr, ")"), + // We need a special case for generic Godot collections, because Variant.From<T> is slower MarshalType.GodotGenericDictionary or MarshalType.GodotGenericArray => source.Append("global::Godot.Variant.CreateFrom(", inputExpr, ")"), _ => source.Append("global::Godot.Variant.From<", diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs index b7d633517a..acdae83d2e 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs @@ -1,20 +1,32 @@ using System; +using System.Diagnostics.CodeAnalysis; #nullable enable namespace Godot { /// <summary> - /// An attribute that determines if an assembly has scripts. If so, what types of scripts the assembly has. + /// Attribute that determines that the assembly contains Godot scripts and, optionally, the + /// collection of types that implement scripts; otherwise, retrieving the types requires lookup. /// </summary> [AttributeUsage(AttributeTargets.Assembly)] public class AssemblyHasScriptsAttribute : Attribute { + /// <summary> + /// If the Godot scripts contained in the assembly require lookup + /// and can't rely on <see cref="ScriptTypes"/>. + /// </summary> + [MemberNotNullWhen(false, nameof(ScriptTypes))] public bool RequiresLookup { get; } + + /// <summary> + /// The collection of types that implement a Godot script. + /// </summary> public Type[]? ScriptTypes { get; } /// <summary> - /// Constructs a new AssemblyHasScriptsAttribute instance. + /// Constructs a new AssemblyHasScriptsAttribute instance + /// that requires lookup to get the Godot scripts. /// </summary> public AssemblyHasScriptsAttribute() { @@ -23,9 +35,10 @@ namespace Godot } /// <summary> - /// Constructs a new AssemblyHasScriptsAttribute instance. + /// Constructs a new AssemblyHasScriptsAttribute instance + /// that includes the Godot script types and requires no lookup. /// </summary> - /// <param name="scriptTypes">The specified type(s) of scripts.</param> + /// <param name="scriptTypes">The collection of types that implement a Godot script.</param> public AssemblyHasScriptsAttribute(Type[] scriptTypes) { RequiresLookup = false; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportAttribute.cs index 3d204bdf9f..a48d79091f 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportAttribute.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportAttribute.cs @@ -3,23 +3,30 @@ using System; namespace Godot { /// <summary> - /// An attribute used to export objects. + /// Exports the annotated member as a property of the Godot Object. /// </summary> [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] public sealed class ExportAttribute : Attribute { - private PropertyHint hint; - private string hintString; + /// <summary> + /// Optional hint that determines how the property should be handled by the editor. + /// </summary> + public PropertyHint Hint { get; } + + /// <summary> + /// Optional string that can contain additional metadata for the <see cref="Hint"/>. + /// </summary> + public string HintString { get; } /// <summary> /// Constructs a new ExportAttribute Instance. /// </summary> - /// <param name="hint">A hint to the exported object.</param> - /// <param name="hintString">A string representing the exported object.</param> + /// <param name="hint">The hint for the exported property.</param> + /// <param name="hintString">A string that may contain additional metadata for the hint.</param> public ExportAttribute(PropertyHint hint = PropertyHint.None, string hintString = "") { - this.hint = hint; - this.hintString = hintString; + Hint = hint; + HintString = hintString; } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportCategoryAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportCategoryAttribute.cs index 101e56f8d3..2ae55acd3e 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportCategoryAttribute.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportCategoryAttribute.cs @@ -8,7 +8,10 @@ namespace Godot [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] public sealed class ExportCategoryAttribute : Attribute { - private string name; + /// <summary> + /// Name of the category. + /// </summary> + public string Name { get; } /// <summary> /// Define a new category for the following exported properties. @@ -16,7 +19,7 @@ namespace Godot /// <param name="name">The name of the category.</param> public ExportCategoryAttribute(string name) { - this.name = name; + Name = name; } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportGroupAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportGroupAttribute.cs index 3bd532cec1..82bd446640 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportGroupAttribute.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportGroupAttribute.cs @@ -1,5 +1,7 @@ using System; +#nullable enable + namespace Godot { /// <summary> @@ -8,8 +10,15 @@ namespace Godot [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] public sealed class ExportGroupAttribute : Attribute { - private string name; - private string prefix; + /// <summary> + /// Name of the group. + /// </summary> + public string Name { get; } + + /// <summary> + /// If provided, the prefix that all properties must have to be considered part of the group. + /// </summary> + public string? Prefix { get; } /// <summary> /// Define a new group for the following exported properties. @@ -18,8 +27,8 @@ namespace Godot /// <param name="prefix">If provided, the group would make group to only consider properties that have this prefix.</param> public ExportGroupAttribute(string name, string prefix = "") { - this.name = name; - this.prefix = prefix; + Name = name; + Prefix = prefix; } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportSubgroupAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportSubgroupAttribute.cs index 2ae6eb0b68..3282b466f6 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportSubgroupAttribute.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportSubgroupAttribute.cs @@ -1,5 +1,7 @@ using System; +#nullable enable + namespace Godot { /// <summary> @@ -8,8 +10,15 @@ namespace Godot [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] public sealed class ExportSubgroupAttribute : Attribute { - private string name; - private string prefix; + /// <summary> + /// Name of the subgroup. + /// </summary> + public string Name { get; } + + /// <summary> + /// If provided, the prefix that all properties must have to be considered part of the subgroup. + /// </summary> + public string? Prefix { get; } /// <summary> /// Define a new subgroup for the following exported properties. This helps to organize properties in the Inspector dock. @@ -18,8 +27,8 @@ namespace Godot /// <param name="prefix">If provided, the subgroup would make group to only consider properties that have this prefix.</param> public ExportSubgroupAttribute(string name, string prefix = "") { - this.name = name; - this.prefix = prefix; + Name = name; + Prefix = prefix; } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttribute.cs index fb37838ffa..afee926464 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttribute.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttribute.cs @@ -19,17 +19,17 @@ namespace Godot /// <summary> /// If the method will also be called locally; otherwise, it is only called remotely. /// </summary> - public bool CallLocal { get; set; } = false; + public bool CallLocal { get; init; } = false; /// <summary> /// Transfer mode for the annotated method. /// </summary> - public MultiplayerPeer.TransferModeEnum TransferMode { get; set; } = MultiplayerPeer.TransferModeEnum.Reliable; + public MultiplayerPeer.TransferModeEnum TransferMode { get; init; } = MultiplayerPeer.TransferModeEnum.Reliable; /// <summary> /// Transfer channel for the annotated mode. /// </summary> - public int TransferChannel { get; set; } = 0; + public int TransferChannel { get; init; } = 0; /// <summary> /// Constructs a <see cref="RPCAttribute"/> instance. diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs index 2c8a53ae1c..f05bcdac38 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs @@ -8,6 +8,9 @@ namespace Godot [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public class ScriptPathAttribute : Attribute { + /// <summary> + /// File path to the script. + /// </summary> public string Path { get; } /// <summary> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs index a3cfecfaa6..2a7a9e2026 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs @@ -739,6 +739,26 @@ namespace Godot if (typeof(Godot.Object).IsAssignableFrom(type)) return Convert.ChangeType(VariantUtils.ConvertTo<Godot.Object>(variant), type); + if (typeof(Godot.Object[]).IsAssignableFrom(type)) + { + static Godot.Object[] ConvertToSystemArrayOfGodotObject(in godot_array nativeArray, Type type) + { + var array = Collections.Array.CreateTakingOwnershipOfDisposableValue( + NativeFuncs.godotsharp_array_new_copy(nativeArray)); + + int length = array.Count; + var ret = (Godot.Object[])Activator.CreateInstance(type, length)!; + + for (int i = 0; i < length; i++) + ret[i] = array[i].AsGodotObject(); + + return ret; + } + + using var godotArray = NativeFuncs.godotsharp_variant_as_array(variant); + return Convert.ChangeType(ConvertToSystemArrayOfGodotObject(godotArray, type), type); + } + if (type.IsEnum) { var enumUnderlyingType = type.GetEnumUnderlyingType(); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs index 6176093bc1..ab3d3ef60f 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs @@ -333,22 +333,6 @@ namespace Godot.NativeInterop return ret; } - // TODO: This needs reflection. Look for an alternative. - internal static Godot.Object[] ConvertNativeGodotArrayToSystemArrayOfGodotObjectType(in godot_array p_array, - Type type) - { - var array = Collections.Array.CreateTakingOwnershipOfDisposableValue( - NativeFuncs.godotsharp_array_new_copy(p_array)); - - int length = array.Count; - var ret = (Godot.Object[])Activator.CreateInstance(type, length)!; - - for (int i = 0; i < length; i++) - ret[i] = array[i].AsGodotObject(); - - return ret; - } - internal static StringName[] ConvertNativeGodotArrayToSystemArrayOfStringName(in godot_array p_array) { var array = Collections.Array.CreateTakingOwnershipOfDisposableValue( diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs index ba8e7a6c65..11f1e31384 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs @@ -594,12 +594,5 @@ namespace Godot.NativeInterop using var godotArray = NativeFuncs.godotsharp_variant_as_array(p_var); return Marshaling.ConvertNativeGodotArrayToSystemArrayOfGodotObjectType<T>(godotArray); } - - // ReSharper disable once RedundantNameQualifier - public static Godot.Object[] ConvertToSystemArrayOfGodotObject(in godot_variant p_var, Type type) - { - using var godotArray = NativeFuncs.godotsharp_variant_as_array(p_var); - return Marshaling.ConvertNativeGodotArrayToSystemArrayOfGodotObjectType(godotArray, type); - } } } diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index cf77d0ed7f..512643867b 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -6196,6 +6196,9 @@ String TextServerAdvanced::_strip_diacritics(const String &p_string) const { } String TextServerAdvanced::_string_to_upper(const String &p_string, const String &p_language) const { + if (p_string.is_empty()) { + return p_string; + } const String lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language; // Convert to UTF-16. @@ -6215,6 +6218,9 @@ String TextServerAdvanced::_string_to_upper(const String &p_string, const String } String TextServerAdvanced::_string_to_lower(const String &p_string, const String &p_language) const { + if (p_string.is_empty()) { + return p_string; + } const String lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language; // Convert to UTF-16. Char16String utf16 = p_string.utf16(); diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 06ec1d6eca..61f45114de 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -755,6 +755,7 @@ void TileMap::set_y_sort_enabled(bool p_enable) { _clear_internals(); _recreate_internals(); emit_signal(SNAME("changed")); + update_configuration_warnings(); } Vector2i TileMap::_coords_to_quadrant_coords(int p_layer, const Vector2i &p_coords) const { @@ -3958,6 +3959,22 @@ PackedStringArray TileMap::get_configuration_warnings() const { } } + if (tile_set.is_valid() && tile_set->get_tile_shape() == TileSet::TILE_SHAPE_ISOMETRIC) { + bool warn = !is_y_sort_enabled(); + if (!warn) { + for (int layer = 0; layer < (int)layers.size(); layer++) { + if (!layers[layer].y_sort_enabled) { + warn = true; + break; + } + } + } + + if (warn) { + warnings.push_back(RTR("Isometric TileSet will likely not look as intended without Y-sort enabled for the TileMap and all of its layers.")); + } + } + return warnings; } @@ -4054,6 +4071,7 @@ void TileMap::_tile_set_changed() { _tile_set_changed_deferred_update_needed = true; instantiated_scenes.clear(); call_deferred(SNAME("_tile_set_changed_deferred_update")); + update_configuration_warnings(); } void TileMap::_tile_set_changed_deferred_update() { diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index eca73fbd10..cc6fadd9b2 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -956,8 +956,8 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double } if (player->is_playing()) { - player->play(anim_name); player->seek(at_anim_pos); + player->play(anim_name); nc->animation_playing = true; playing_caches.insert(nc); } else { @@ -985,8 +985,8 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double nc->animation_playing = false; } } else { + player->seek(0.0); player->play(anim_name); - player->seek(0.0, true); nc->animation_playing = true; playing_caches.insert(nc); } diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index c2d584b52f..fbc85bd5e1 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -1584,8 +1584,8 @@ void AnimationTree::_process_graph(double p_delta) { } if (player2->is_playing() || seeked) { - player2->play(anim_name); player2->seek(at_anim_pos); + player2->play(anim_name); t->playing = true; playing_caches.insert(t); } else { diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 9e22a414ed..35cc29d080 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -4218,7 +4218,9 @@ Tree::SelectMode Tree::get_select_mode() const { void Tree::deselect_all() { TreeItem *item = get_next_selected(get_root()); while (item) { - item->deselect(selected_col); + for (int i = 0; i < columns.size(); i++) { + item->deselect(i); + } TreeItem *prev_item = item; item = get_next_selected(get_root()); ERR_FAIL_COND(item == prev_item); |