summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/actions/godot-deps/action.yml2
-rw-r--r--core/math/random_pcg.h12
-rw-r--r--doc/classes/Node.xml1
-rw-r--r--doc/classes/OS.xml1
-rw-r--r--doc/classes/SceneTree.xml2
-rw-r--r--doc/classes/String.xml4
-rw-r--r--doc/classes/Tween.xml6
-rw-r--r--drivers/gles3/storage/material_storage.cpp20
-rw-r--r--editor/project_converter_3_to_4.cpp250
-rw-r--r--editor/project_converter_3_to_4.h30
-rw-r--r--editor/renames_map_3_to_4.cpp12
-rw-r--r--modules/gdscript/gdscript_compiler.cpp12
-rw-r--r--modules/gdscript/gdscript_compiler.h2
-rw-r--r--modules/gltf/gltf_document.cpp14
-rw-r--r--modules/mono/csharp_script.cpp5
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props1
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Godot.SourceGenerators.Sample.csproj1
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs26
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.props1
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs13
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs2
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs6
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs2
-rw-r--r--modules/mono/editor/bindings_generator.cpp6
-rw-r--r--platform/ios/godot_view.mm2
-rw-r--r--platform/linuxbsd/detect.py3
-rw-r--r--scene/2d/back_buffer_copy.cpp1
-rw-r--r--scene/2d/camera_2d.cpp14
-rw-r--r--scene/2d/camera_2d.h2
-rw-r--r--servers/rendering/shader_language.cpp8
30 files changed, 321 insertions, 140 deletions
diff --git a/.github/actions/godot-deps/action.yml b/.github/actions/godot-deps/action.yml
index e99167ff2b..38731db5d6 100644
--- a/.github/actions/godot-deps/action.yml
+++ b/.github/actions/godot-deps/action.yml
@@ -23,5 +23,5 @@ runs:
shell: bash
run: |
python -c "import sys; print(sys.version)"
- python -m pip install scons
+ python -m pip install scons==4.4.0
scons --version
diff --git a/core/math/random_pcg.h b/core/math/random_pcg.h
index fe40e7f76a..cc22b23b70 100644
--- a/core/math/random_pcg.h
+++ b/core/math/random_pcg.h
@@ -126,10 +126,18 @@ public:
}
_FORCE_INLINE_ double randfn(double p_mean, double p_deviation) {
- return p_mean + p_deviation * (cos(Math_TAU * randd()) * sqrt(-2.0 * log(randd()))); // Box-Muller transform
+ double temp = randd();
+ if (temp < CMP_EPSILON) {
+ temp += CMP_EPSILON; // To prevent generating of INF value in log function, resulting to return NaN value from this function.
+ }
+ return p_mean + p_deviation * (cos(Math_TAU * randd()) * sqrt(-2.0 * log(temp))); // Box-Muller transform.
}
_FORCE_INLINE_ float randfn(float p_mean, float p_deviation) {
- return p_mean + p_deviation * (cos((float)Math_TAU * randf()) * sqrt(-2.0 * log(randf()))); // Box-Muller transform
+ float temp = randf();
+ if (temp < CMP_EPSILON) {
+ temp += CMP_EPSILON; // To prevent generating of INF value in log function, resulting to return NaN value from this function.
+ }
+ return p_mean + p_deviation * (cos((float)Math_TAU * randf()) * sqrt(-2.0 * log(temp))); // Box-Muller transform.
}
double random(double p_from, double p_to);
diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml
index 6ad4d94d15..3146b9d3af 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -188,6 +188,7 @@
GetTree().CreateTween().BindNode(this);
[/csharp]
[/codeblocks]
+ The Tween will start automatically on the next process frame or physics frame (depending on [enum Tween.TweenProcessMode]).
</description>
</method>
<method name="duplicate" qualifiers="const">
diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml
index 6ac1d2ca56..1dce0b1632 100644
--- a/doc/classes/OS.xml
+++ b/doc/classes/OS.xml
@@ -634,6 +634,7 @@
- [code]OS.shell_open("https://godotengine.org")[/code] opens the default web browser on the official Godot website.
- [code]OS.shell_open("mailto:example@example.com")[/code] opens the default email client with the "To" field set to [code]example@example.com[/code]. See [url=https://datatracker.ietf.org/doc/html/rfc2368]RFC 2368 - The [code]mailto[/code] URL scheme[/url] for a list of fields that can be added.
Use [method ProjectSettings.globalize_path] to convert a [code]res://[/code] or [code]user://[/code] path into a system path for use with this method.
+ [b]Note:[/b] Use [method String.uri_encode] to encode characters within URLs in a URL-safe, portable way. This is especially required for line breaks. Otherwise, [method shell_open] may not work correctly in a project exported to the Web platform.
[b]Note:[/b] This method is implemented on Android, iOS, Web, Linux, macOS and Windows.
</description>
</method>
diff --git a/doc/classes/SceneTree.xml b/doc/classes/SceneTree.xml
index 1adf17f10e..c88acd8950 100644
--- a/doc/classes/SceneTree.xml
+++ b/doc/classes/SceneTree.xml
@@ -88,7 +88,7 @@
<method name="create_tween">
<return type="Tween" />
<description>
- Creates and returns a new [Tween].
+ Creates and returns a new [Tween]. The Tween will start automatically on the next process frame or physics frame (depending on [enum Tween.TweenProcessMode]).
</description>
</method>
<method name="get_first_node_in_group">
diff --git a/doc/classes/String.xml b/doc/classes/String.xml
index dba1cbb052..d629a31bca 100644
--- a/doc/classes/String.xml
+++ b/doc/classes/String.xml
@@ -970,7 +970,7 @@
<method name="uri_decode" qualifiers="const">
<return type="String" />
<description>
- Decodes the string from its URL-encoded format. This method is meant to properly decode the parameters in a URL when receiving an HTTP request.
+ Decodes the string from its URL-encoded format. This method is meant to properly decode the parameters in a URL when receiving an HTTP request. See also [method uri_encode].
[codeblocks]
[gdscript]
var url = "$DOCS_URL/?highlight=Godot%20Engine%3%docs"
@@ -986,7 +986,7 @@
<method name="uri_encode" qualifiers="const">
<return type="String" />
<description>
- Encodes the string to URL-friendly format. This method is meant to properly encode the parameters in a URL when sending an HTTP request.
+ Encodes the string to URL-friendly format. This method is meant to properly encode the parameters in a URL when sending an HTTP request. See also [method uri_decode].
[codeblocks]
[gdscript]
var prefix = "$DOCS_URL/?highlight="
diff --git a/doc/classes/Tween.xml b/doc/classes/Tween.xml
index 31cff3f64a..f091ce66f8 100644
--- a/doc/classes/Tween.xml
+++ b/doc/classes/Tween.xml
@@ -89,8 +89,8 @@
[/codeblocks]
Some [Tweener]s use transitions and eases. The first accepts a [enum TransitionType] constant, and refers to the way the timing of the animation is handled (see [url=https://easings.net/]easings.net[/url] for some examples). The second accepts an [enum EaseType] constant, and controls where the [code]trans_type[/code] is applied to the interpolation (in the beginning, the end, or both). If you don't know which transition and easing to pick, you can try different [enum TransitionType] constants with [constant EASE_IN_OUT], and use the one that looks best.
[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]
- [b]Note:[/b] All [Tween]s will automatically start by default. To prevent a [Tween] from autostarting, you can call [method stop] immediately after it is created.
- [b]Note:[/b] [Tween]s are processing after all of nodes in the current frame, i.e. after [method Node._process] or [method Node._physics_process] (depending on [enum TweenProcessMode]).
+ [b]Note:[/b] Tweens are not designed to be re-used and trying to do so results in an undefined behavior. Create a new Tween for each animation and every time you replay an animation from start. Keep in mind that Tweens start immediately, so only create a Tween when you want to start animating.
+ [b]Note:[/b] Tweens are processing after all of nodes in the current frame, i.e. after [method Node._process] or [method Node._physics_process] (depending on [enum TweenProcessMode]).
</description>
<tutorials>
</tutorials>
@@ -129,7 +129,6 @@
<description>
Processes the [Tween] by the given [param delta] value, in seconds. This is mostly useful for manual control when the [Tween] is paused. It can also be used to end the [Tween] animation immediately, by setting [param delta] longer than the whole duration of the [Tween] animation.
Returns [code]true[/code] if the [Tween] still has [Tweener]s that haven't finished.
- [b]Note:[/b] The [Tween] will become invalid in the next processing frame after its animation finishes. Calling [method stop] after performing [method custom_step] instead keeps and resets the [Tween].
</description>
</method>
<method name="get_total_elapsed_time" qualifiers="const">
@@ -432,7 +431,6 @@
<signal name="finished">
<description>
Emitted when the [Tween] has finished all tweening. Never emitted when the [Tween] is set to infinite looping (see [method set_loops]).
- [b]Note:[/b] The [Tween] is removed (invalidated) in the next processing frame after this signal is emitted. Calling [method stop] inside the signal callback will prevent the [Tween] from being removed.
</description>
</signal>
<signal name="loop_finished">
diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp
index 6379c9bd4a..1736ad1d42 100644
--- a/drivers/gles3/storage/material_storage.cpp
+++ b/drivers/gles3/storage/material_storage.cpp
@@ -1066,6 +1066,12 @@ static const RS::CanvasItemTextureRepeat repeat_from_uniform[ShaderLanguage::REP
RS::CanvasItemTextureRepeat::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED, // ShaderLanguage::TextureRepeat::REPEAT_DEFAULT,
};
+static const RS::CanvasItemTextureRepeat repeat_from_uniform_canvas[ShaderLanguage::REPEAT_DEFAULT + 1] = {
+ RS::CanvasItemTextureRepeat::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED, // ShaderLanguage::TextureRepeat::REPEAT_DISABLE,
+ RS::CanvasItemTextureRepeat::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED, // ShaderLanguage::TextureRepeat::REPEAT_ENABLE,
+ RS::CanvasItemTextureRepeat::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED, // ShaderLanguage::TextureRepeat::REPEAT_DEFAULT,
+};
+
static const RS::CanvasItemTextureFilter filter_from_uniform[ShaderLanguage::FILTER_DEFAULT + 1] = {
RS::CanvasItemTextureFilter::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, // ShaderLanguage::TextureFilter::FILTER_NEAREST,
RS::CanvasItemTextureFilter::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, // ShaderLanguage::TextureFilter::FILTER_LINEAR,
@@ -1076,6 +1082,16 @@ static const RS::CanvasItemTextureFilter filter_from_uniform[ShaderLanguage::FIL
RS::CanvasItemTextureFilter::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, // ShaderLanguage::TextureFilter::FILTER_DEFAULT,
};
+static const RS::CanvasItemTextureFilter filter_from_uniform_canvas[ShaderLanguage::FILTER_DEFAULT + 1] = {
+ RS::CanvasItemTextureFilter::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, // ShaderLanguage::TextureFilter::FILTER_NEAREST,
+ RS::CanvasItemTextureFilter::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, // ShaderLanguage::TextureFilter::FILTER_LINEAR,
+ RS::CanvasItemTextureFilter::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, // ShaderLanguage::TextureFilter::FILTER_NEAREST_MIPMAP,
+ RS::CanvasItemTextureFilter::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, // ShaderLanguage::TextureFilter::FILTER_LINEAR_MIPMAP,
+ RS::CanvasItemTextureFilter::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, // ShaderLanguage::TextureFilter::FILTER_NEAREST_MIPMAP_ANISOTROPIC,
+ RS::CanvasItemTextureFilter::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, // ShaderLanguage::TextureFilter::FILTER_LINEAR_MIPMAP_ANISOTROPIC,
+ RS::CanvasItemTextureFilter::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, // ShaderLanguage::TextureFilter::FILTER_DEFAULT,
+};
+
void MaterialData::update_uniform_buffer(const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const HashMap<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color) {
MaterialStorage *material_storage = MaterialStorage::get_singleton();
bool uses_global_buffer = false;
@@ -3061,8 +3077,8 @@ void CanvasMaterialData::bind_uniforms() {
texture->render_target->used_in_frame = true;
}
- texture->gl_set_filter(filter_from_uniform[int(texture_uniforms[ti].filter)]);
- texture->gl_set_repeat(repeat_from_uniform[int(texture_uniforms[ti].repeat)]);
+ texture->gl_set_filter(filter_from_uniform_canvas[int(texture_uniforms[ti].filter)]);
+ texture->gl_set_repeat(repeat_from_uniform_canvas[int(texture_uniforms[ti].repeat)]);
}
}
diff --git a/editor/project_converter_3_to_4.cpp b/editor/project_converter_3_to_4.cpp
index 16fd025d52..5a45fd9c4b 100644
--- a/editor/project_converter_3_to_4.cpp
+++ b/editor/project_converter_3_to_4.cpp
@@ -122,6 +122,9 @@ public:
RegEx keyword_gdscript_master = RegEx("^master func");
RegEx keyword_gdscript_mastersync = RegEx("^mastersync func");
+ RegEx gdscript_comment = RegEx("^\\s*#");
+ RegEx csharp_comment = RegEx("^\\s*\\/\\/");
+
// CSharp keywords.
RegEx keyword_csharp_remote = RegEx("\\[Remote(Attribute)?(\\(\\))?\\]");
RegEx keyword_csharp_remotesync = RegEx("\\[(Remote)?Sync(Attribute)?(\\(\\))?\\]");
@@ -337,17 +340,21 @@ bool ProjectConverter3To4::convert() {
// Check file by file.
for (int i = 0; i < collected_files.size(); i++) {
String file_name = collected_files[i];
- Vector<String> lines;
+ Vector<SourceLine> source_lines;
uint32_t ignored_lines = 0;
{
Ref<FileAccess> file = FileAccess::open(file_name, FileAccess::READ);
ERR_CONTINUE_MSG(file.is_null(), vformat("Unable to read content of \"%s\".", file_name));
while (!file->eof_reached()) {
String line = file->get_line();
- lines.append(line);
+
+ SourceLine source_line;
+ source_line.line = line;
+ source_line.is_comment = reg_container.gdscript_comment.search_all(line).size() > 0 || reg_container.csharp_comment.search_all(line).size() > 0;
+ source_lines.append(source_line);
}
}
- String file_content_before = collect_string_from_vector(lines);
+ String file_content_before = collect_string_from_vector(source_lines);
uint64_t hash_before = file_content_before.hash();
uint64_t file_size = file_content_before.size();
print_line(vformat("Trying to convert\t%d/%d file - \"%s\" with size - %d KB", i + 1, collected_files.size(), file_name.trim_prefix("res://"), file_size / 1024));
@@ -364,68 +371,69 @@ bool ProjectConverter3To4::convert() {
if (file_size < uint64_t(maximum_file_size)) {
// ".tscn" must work exactly the same as ".gd" files because they may contain built-in Scripts.
if (file_name.ends_with(".gd")) {
- rename_classes(lines, reg_container); // Using only specialized function.
+ rename_classes(source_lines, reg_container); // Using only specialized function.
- rename_common(RenamesMap3To4::enum_renames, reg_container.enum_regexes, lines);
- rename_colors(lines, reg_container); // Require to additional rename.
+ rename_common(RenamesMap3To4::enum_renames, reg_container.enum_regexes, source_lines);
+ rename_colors(source_lines, reg_container); // Require to additional rename.
- rename_common(RenamesMap3To4::gdscript_function_renames, reg_container.gdscript_function_regexes, lines);
- rename_gdscript_functions(lines, reg_container, false); // Require to additional rename.
+ rename_common(RenamesMap3To4::gdscript_function_renames, reg_container.gdscript_function_regexes, source_lines);
+ rename_gdscript_functions(source_lines, reg_container, false); // Require to additional rename.
- rename_common(RenamesMap3To4::project_settings_renames, reg_container.project_settings_regexes, lines);
- rename_gdscript_keywords(lines, reg_container);
- rename_common(RenamesMap3To4::gdscript_properties_renames, reg_container.gdscript_properties_regexes, lines);
- rename_common(RenamesMap3To4::gdscript_signals_renames, reg_container.gdscript_signals_regexes, lines);
- rename_common(RenamesMap3To4::shaders_renames, reg_container.shaders_regexes, lines);
- rename_common(RenamesMap3To4::builtin_types_renames, reg_container.builtin_types_regexes, lines);
+ rename_common(RenamesMap3To4::project_settings_renames, reg_container.project_settings_regexes, source_lines);
+ rename_gdscript_keywords(source_lines, reg_container);
+ rename_common(RenamesMap3To4::gdscript_properties_renames, reg_container.gdscript_properties_regexes, source_lines);
+ rename_common(RenamesMap3To4::gdscript_signals_renames, reg_container.gdscript_signals_regexes, source_lines);
+ rename_common(RenamesMap3To4::shaders_renames, reg_container.shaders_regexes, source_lines);
+ rename_common(RenamesMap3To4::builtin_types_renames, reg_container.builtin_types_regexes, source_lines);
- custom_rename(lines, "\\.shader", ".gdshader");
+ custom_rename(source_lines, "\\.shader", ".gdshader");
} else if (file_name.ends_with(".tscn")) {
- rename_classes(lines, reg_container); // Using only specialized function.
+ rename_classes(source_lines, reg_container); // Using only specialized function.
- rename_common(RenamesMap3To4::enum_renames, reg_container.enum_regexes, lines);
- rename_colors(lines, reg_container); // Require to do additional renames.
+ rename_common(RenamesMap3To4::enum_renames, reg_container.enum_regexes, source_lines);
+ rename_colors(source_lines, reg_container); // Require to do additional renames.
- rename_common(RenamesMap3To4::gdscript_function_renames, reg_container.gdscript_function_regexes, lines);
- rename_gdscript_functions(lines, reg_container, true); // Require to do additional renames.
+ rename_common(RenamesMap3To4::gdscript_function_renames, reg_container.gdscript_function_regexes, source_lines);
+ rename_gdscript_functions(source_lines, reg_container, true); // Require to do additional renames.
- rename_common(RenamesMap3To4::project_settings_renames, reg_container.project_settings_regexes, lines);
- rename_gdscript_keywords(lines, reg_container);
- rename_common(RenamesMap3To4::gdscript_properties_renames, reg_container.gdscript_properties_regexes, lines);
- rename_common(RenamesMap3To4::gdscript_signals_renames, reg_container.gdscript_signals_regexes, lines);
- rename_common(RenamesMap3To4::shaders_renames, reg_container.shaders_regexes, lines);
- rename_common(RenamesMap3To4::builtin_types_renames, reg_container.builtin_types_regexes, lines);
+ rename_common(RenamesMap3To4::project_settings_renames, reg_container.project_settings_regexes, source_lines);
+ rename_gdscript_keywords(source_lines, reg_container);
+ rename_common(RenamesMap3To4::gdscript_properties_renames, reg_container.gdscript_properties_regexes, source_lines);
+ rename_common(RenamesMap3To4::gdscript_signals_renames, reg_container.gdscript_signals_regexes, source_lines);
+ rename_common(RenamesMap3To4::shaders_renames, reg_container.shaders_regexes, source_lines);
+ rename_common(RenamesMap3To4::builtin_types_renames, reg_container.builtin_types_regexes, source_lines);
- custom_rename(lines, "\\.shader", ".gdshader");
+ custom_rename(source_lines, "\\.shader", ".gdshader");
} else if (file_name.ends_with(".cs")) { // TODO, C# should use different methods.
- rename_classes(lines, reg_container); // Using only specialized function.
- rename_common(RenamesMap3To4::csharp_function_renames, reg_container.csharp_function_regexes, lines);
- rename_common(RenamesMap3To4::builtin_types_renames, reg_container.builtin_types_regexes, lines);
- rename_common(RenamesMap3To4::csharp_properties_renames, reg_container.csharp_properties_regexes, lines);
- rename_common(RenamesMap3To4::csharp_signals_renames, reg_container.csharp_signal_regexes, lines);
- rename_csharp_functions(lines, reg_container);
- rename_csharp_attributes(lines, reg_container);
- custom_rename(lines, "public class ", "public partial class ");
+ rename_classes(source_lines, reg_container); // Using only specialized function.
+ rename_common(RenamesMap3To4::csharp_function_renames, reg_container.csharp_function_regexes, source_lines);
+ rename_common(RenamesMap3To4::builtin_types_renames, reg_container.builtin_types_regexes, source_lines);
+ rename_common(RenamesMap3To4::csharp_properties_renames, reg_container.csharp_properties_regexes, source_lines);
+ rename_common(RenamesMap3To4::csharp_signals_renames, reg_container.csharp_signal_regexes, source_lines);
+ rename_csharp_functions(source_lines, reg_container);
+ rename_csharp_attributes(source_lines, reg_container);
+ custom_rename(source_lines, "public class ", "public partial class ");
} else if (file_name.ends_with(".gdshader") || file_name.ends_with(".shader")) {
- rename_common(RenamesMap3To4::shaders_renames, reg_container.shaders_regexes, lines);
+ rename_common(RenamesMap3To4::shaders_renames, reg_container.shaders_regexes, source_lines);
} else if (file_name.ends_with("tres")) {
- rename_classes(lines, reg_container); // Using only specialized function.
+ rename_classes(source_lines, reg_container); // Using only specialized function.
- rename_common(RenamesMap3To4::shaders_renames, reg_container.shaders_regexes, lines);
- rename_common(RenamesMap3To4::builtin_types_renames, reg_container.builtin_types_regexes, lines);
+ rename_common(RenamesMap3To4::shaders_renames, reg_container.shaders_regexes, source_lines);
+ rename_common(RenamesMap3To4::builtin_types_renames, reg_container.builtin_types_regexes, source_lines);
- custom_rename(lines, "\\.shader", ".gdshader");
+ custom_rename(source_lines, "\\.shader", ".gdshader");
} else if (file_name.ends_with("project.godot")) {
- rename_common(RenamesMap3To4::project_godot_renames, reg_container.project_godot_regexes, lines);
- rename_common(RenamesMap3To4::builtin_types_renames, reg_container.builtin_types_regexes, lines);
- rename_input_map_scancode(lines, reg_container);
- rename_common(RenamesMap3To4::input_map_renames, reg_container.input_map_regexes, lines);
+ rename_common(RenamesMap3To4::project_godot_renames, reg_container.project_godot_regexes, source_lines);
+ rename_common(RenamesMap3To4::builtin_types_renames, reg_container.builtin_types_regexes, source_lines);
+ rename_input_map_scancode(source_lines, reg_container);
+ rename_common(RenamesMap3To4::input_map_renames, reg_container.input_map_regexes, source_lines);
} else if (file_name.ends_with(".csproj")) {
// TODO
} else if (file_name.ends_with(".import")) {
- for (int x = 0; x < lines.size(); x++) {
- if (lines[x].contains("nodes/root_type=\"Spatial\"")) {
- lines.set(x, "nodes/root_type=\"Node3D\"");
+ for (SourceLine &source_line : source_lines) {
+ String &line = source_line.line;
+ if (line.contains("nodes/root_type=\"Spatial\"")) {
+ line = "nodes/root_type=\"Node3D\"";
}
}
} else {
@@ -433,7 +441,12 @@ bool ProjectConverter3To4::convert() {
continue;
}
- for (String &line : lines) {
+ for (SourceLine &source_line : source_lines) {
+ if (source_line.is_comment) {
+ continue;
+ }
+
+ String &line = source_line.line;
if (uint64_t(line.length()) > maximum_line_length) {
ignored_lines += 1;
}
@@ -448,7 +461,7 @@ bool ProjectConverter3To4::convert() {
String end_message = vformat(" Checking file took %d ms.", end_time - start_time);
print_line(end_message);
} else {
- String file_content_after = collect_string_from_vector(lines);
+ String file_content_after = collect_string_from_vector(source_lines);
uint64_t hash_after = file_content_after.hash64();
// Don't need to save file without any changes.
// Save if this is a shader, because it was renamed.
@@ -679,9 +692,23 @@ Vector<String> ProjectConverter3To4::check_for_files() {
return collected_files;
}
+Vector<SourceLine> ProjectConverter3To4::split_lines(const String &text) {
+ Vector<String> lines = text.split("\n");
+ Vector<SourceLine> source_lines;
+ for (String &line : lines) {
+ SourceLine source_line;
+ source_line.line = line;
+ source_line.is_comment = false;
+
+ source_lines.append(source_line);
+ }
+ return source_lines;
+}
+
// Test expected results of gdscript
-bool ProjectConverter3To4::test_conversion_gdscript_builtin(String name, String expected, void (ProjectConverter3To4::*func)(Vector<String> &, const RegExContainer &, bool), String what, const RegExContainer &reg_container, bool builtin_script) {
- Vector<String> got = name.split("\n");
+bool ProjectConverter3To4::test_conversion_gdscript_builtin(String name, String expected, void (ProjectConverter3To4::*func)(Vector<SourceLine> &, const RegExContainer &, bool), String what, const RegExContainer &reg_container, bool builtin_script) {
+ Vector<SourceLine> got = split_lines(name);
+
(this->*func)(got, reg_container, builtin_script);
String got_str = collect_string_from_vector(got);
ERR_FAIL_COND_V_MSG(expected != got_str, false, vformat("Failed to convert %s \"%s\" to \"%s\", got instead \"%s\"", what, name, expected, got_str));
@@ -689,8 +716,9 @@ bool ProjectConverter3To4::test_conversion_gdscript_builtin(String name, String
return true;
}
-bool ProjectConverter3To4::test_conversion_with_regex(String name, String expected, void (ProjectConverter3To4::*func)(Vector<String> &, const RegExContainer &), String what, const RegExContainer &reg_container) {
- Vector<String> got = name.split("\n");
+bool ProjectConverter3To4::test_conversion_with_regex(String name, String expected, void (ProjectConverter3To4::*func)(Vector<SourceLine> &, const RegExContainer &), String what, const RegExContainer &reg_container) {
+ Vector<SourceLine> got = split_lines(name);
+
(this->*func)(got, reg_container);
String got_str = collect_string_from_vector(got);
ERR_FAIL_COND_V_MSG(expected != got_str, false, vformat("Failed to convert %s \"%s\" to \"%s\", got instead \"%s\"", what, name, expected, got_str));
@@ -699,7 +727,8 @@ bool ProjectConverter3To4::test_conversion_with_regex(String name, String expect
}
bool ProjectConverter3To4::test_conversion_basic(String name, String expected, const char *array[][2], LocalVector<RegEx *> &regex_cache, String what) {
- Vector<String> got = name.split("\n");
+ Vector<SourceLine> got = split_lines(name);
+
rename_common(array, regex_cache, got);
String got_str = collect_string_from_vector(got);
ERR_FAIL_COND_V_MSG(expected != got_str, false, vformat("Failed to convert %s \"%s\" to \"%s\", got instead \"%s\"", what, name, expected, got_str));
@@ -889,7 +918,10 @@ bool ProjectConverter3To4::test_conversion(RegExContainer &reg_container) {
valid = valid && test_conversion_gdscript_builtin("(tween_callback(A,B,[C,D]).foo())", "(tween_callback(Callable(A, B).bind(C,D)).foo())", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
valid = valid && test_conversion_gdscript_builtin("func _init(", "func _init(", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
- valid = valid && test_conversion_gdscript_builtin("func _init(p_x:int)->void:", "func _init(p_x:int):", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("func _init(a,b,c).(d,e,f):", "func _init(a,b,c):\n\tsuper(d,e,f)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("func _init(a,b,c).(a.b(),c.d()):", "func _init(a,b,c):\n\tsuper(a.b(),c.d())", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("func _init(p_x:int)->void:", "func _init(p_x:int)->void:", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
+ valid = valid && test_conversion_gdscript_builtin("func _init(a: int).(d,e,f) -> void:", "func _init(a: int) -> void:\n\tsuper(d,e,f)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
valid = valid && test_conversion_gdscript_builtin("q_PackedDataContainer._iter_init(variable1)", "q_PackedDataContainer._iter_init(variable1)", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
valid = valid && test_conversion_gdscript_builtin("assert(speed < 20, str(randi()%10))", "assert(speed < 20) #,str(randi()%10))", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false);
@@ -927,7 +959,9 @@ bool ProjectConverter3To4::test_conversion(RegExContainer &reg_container) {
String from = "instance";
String to = "instantiate";
String name = "AA.instance()";
- Vector<String> got = String("AA.instance()").split("\n");
+
+ Vector<SourceLine> got = split_lines(name);
+
String expected = "AA.instantiate()";
custom_rename(got, from, to);
String got_str = collect_string_from_vector(got);
@@ -1351,8 +1385,13 @@ String ProjectConverter3To4::get_object_of_execution(const String &line) const {
return line.substr(variable_start, (end - variable_start));
}
-void ProjectConverter3To4::rename_colors(Vector<String> &lines, const RegExContainer &reg_container) {
- for (String &line : lines) {
+void ProjectConverter3To4::rename_colors(Vector<SourceLine> &source_lines, const RegExContainer &reg_container) {
+ for (SourceLine &source_line : source_lines) {
+ if (source_line.is_comment) {
+ continue;
+ }
+
+ String &line = source_line.line;
if (uint64_t(line.length()) <= maximum_line_length) {
if (line.contains("Color.")) {
for (unsigned int current_index = 0; RenamesMap3To4::color_renames[current_index][0]; current_index++) {
@@ -1384,8 +1423,13 @@ Vector<String> ProjectConverter3To4::check_for_rename_colors(Vector<String> &lin
return found_renames;
}
-void ProjectConverter3To4::rename_classes(Vector<String> &lines, const RegExContainer &reg_container) {
- for (String &line : lines) {
+void ProjectConverter3To4::rename_classes(Vector<SourceLine> &source_lines, const RegExContainer &reg_container) {
+ for (SourceLine &source_line : source_lines) {
+ if (source_line.is_comment) {
+ continue;
+ }
+
+ String &line = source_line.line;
if (uint64_t(line.length()) <= maximum_line_length) {
for (unsigned int current_index = 0; RenamesMap3To4::class_renames[current_index][0]; current_index++) {
if (line.contains(RenamesMap3To4::class_renames[current_index][0])) {
@@ -1452,8 +1496,13 @@ Vector<String> ProjectConverter3To4::check_for_rename_classes(Vector<String> &li
return found_renames;
}
-void ProjectConverter3To4::rename_gdscript_functions(Vector<String> &lines, const RegExContainer &reg_container, bool builtin) {
- for (String &line : lines) {
+void ProjectConverter3To4::rename_gdscript_functions(Vector<SourceLine> &source_lines, const RegExContainer &reg_container, bool builtin) {
+ for (SourceLine &source_line : source_lines) {
+ if (source_line.is_comment) {
+ continue;
+ }
+
+ String &line = source_line.line;
if (uint64_t(line.length()) <= maximum_line_length) {
process_gdscript_line(line, reg_container, builtin);
}
@@ -1943,17 +1992,18 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai
}
}
}
- // -- func _init(p_x:int)->void: -> func _init(p_x:int): Object # https://github.com/godotengine/godot/issues/50589
- if (line.contains(" _init(")) {
- int start = line.find(" _init(");
- if (line.contains(":")) {
- int end = line.rfind(":") + 1;
- if (end > -1) {
- Vector<String> parts = parse_arguments(line.substr(start, end));
- line = line.substr(0, start) + " _init(" + connect_arguments(parts, 0) + "):" + line.substr(end + start);
- }
+ // -- func _init(p_x:int).(p_x): -> func _init(p_x:int):\n\tsuper(p_x) Object # https://github.com/godotengine/godot/issues/70542
+ if (line.contains(" _init(") && line.rfind(":") > 0) {
+ // func _init(p_arg1).(super4, super5, super6)->void:
+ // ^--^indent ^super_start super_end^
+ int indent = line.count("\t", 0, line.find("func"));
+ int super_start = line.find(".(");
+ int super_end = line.rfind(")");
+ if (super_start > 0 && super_end > super_start) {
+ line = line.substr(0, super_start) + line.substr(super_end + 1) + "\n" + String("\t").repeat(indent + 1) + "super" + line.substr(super_start + 1, super_end - super_start);
}
}
+
// assert(speed < 20, str(randi()%10)) -> assert(speed < 20) #,str(randi()%10)) GDScript - GDScript bug constant message
if (line.contains("assert(")) {
int start = line.find("assert(");
@@ -2258,8 +2308,13 @@ void ProjectConverter3To4::process_csharp_line(String &line, const RegExContaine
}
}
-void ProjectConverter3To4::rename_csharp_functions(Vector<String> &lines, const RegExContainer &reg_container) {
- for (String &line : lines) {
+void ProjectConverter3To4::rename_csharp_functions(Vector<SourceLine> &source_lines, const RegExContainer &reg_container) {
+ for (SourceLine &source_line : source_lines) {
+ if (source_line.is_comment) {
+ continue;
+ }
+
+ String &line = source_line.line;
if (uint64_t(line.length()) <= maximum_line_length) {
process_csharp_line(line, reg_container);
}
@@ -2284,10 +2339,15 @@ Vector<String> ProjectConverter3To4::check_for_rename_csharp_functions(Vector<St
return found_renames;
}
-void ProjectConverter3To4::rename_csharp_attributes(Vector<String> &lines, const RegExContainer &reg_container) {
+void ProjectConverter3To4::rename_csharp_attributes(Vector<SourceLine> &source_lines, const RegExContainer &reg_container) {
static String error_message = "The master and mastersync rpc behavior is not officially supported anymore. Try using another keyword or making custom logic using Multiplayer.GetRemoteSenderId()\n";
- for (String &line : lines) {
+ for (SourceLine &source_line : source_lines) {
+ if (source_line.is_comment) {
+ continue;
+ }
+
+ String &line = source_line.line;
if (uint64_t(line.length()) <= maximum_line_length) {
line = reg_container.keyword_csharp_remote.sub(line, "[RPC(MultiplayerAPI.RPCMode.AnyPeer)]", true);
line = reg_container.keyword_csharp_remotesync.sub(line, "[RPC(MultiplayerAPI.RPCMode.AnyPeer, CallLocal = true)]", true);
@@ -2349,10 +2409,15 @@ Vector<String> ProjectConverter3To4::check_for_rename_csharp_attributes(Vector<S
return found_renames;
}
-void ProjectConverter3To4::rename_gdscript_keywords(Vector<String> &lines, const RegExContainer &reg_container) {
+void ProjectConverter3To4::rename_gdscript_keywords(Vector<SourceLine> &source_lines, const RegExContainer &reg_container) {
static String error_message = "The master and mastersync rpc behavior is not officially supported anymore. Try using another keyword or making custom logic using get_multiplayer().get_remote_sender_id()\n";
- for (String &line : lines) {
+ for (SourceLine &source_line : source_lines) {
+ if (source_line.is_comment) {
+ continue;
+ }
+
+ String &line = source_line.line;
if (uint64_t(line.length()) <= maximum_line_length) {
if (line.contains("tool")) {
line = reg_container.keyword_gdscript_tool.sub(line, "@tool", true);
@@ -2504,11 +2569,16 @@ Vector<String> ProjectConverter3To4::check_for_rename_gdscript_keywords(Vector<S
return found_renames;
}
-void ProjectConverter3To4::rename_input_map_scancode(Vector<String> &lines, const RegExContainer &reg_container) {
+void ProjectConverter3To4::rename_input_map_scancode(Vector<SourceLine> &source_lines, const RegExContainer &reg_container) {
// The old Special Key, now colliding with CMD_OR_CTRL.
const int old_spkey = (1 << 24);
- for (String &line : lines) {
+ for (SourceLine &source_line : source_lines) {
+ if (source_line.is_comment) {
+ continue;
+ }
+
+ String &line = source_line.line;
if (uint64_t(line.length()) <= maximum_line_length) {
TypedArray<RegExMatch> reg_match = reg_container.input_map_keycode.search_all(line);
@@ -2557,10 +2627,15 @@ Vector<String> ProjectConverter3To4::check_for_rename_input_map_scancode(Vector<
return found_renames;
}
-void ProjectConverter3To4::custom_rename(Vector<String> &lines, String from, String to) {
+void ProjectConverter3To4::custom_rename(Vector<SourceLine> &source_lines, String from, String to) {
RegEx reg = RegEx(String("\\b") + from + "\\b");
CRASH_COND(!reg.is_valid());
- for (String &line : lines) {
+ for (SourceLine &source_line : source_lines) {
+ if (source_line.is_comment) {
+ continue;
+ }
+
+ String &line = source_line.line;
if (uint64_t(line.length()) <= maximum_line_length) {
line = reg.sub(line, to, true);
}
@@ -2586,8 +2661,13 @@ Vector<String> ProjectConverter3To4::check_for_custom_rename(Vector<String> &lin
return found_renames;
}
-void ProjectConverter3To4::rename_common(const char *array[][2], LocalVector<RegEx *> &cached_regexes, Vector<String> &lines) {
- for (String &line : lines) {
+void ProjectConverter3To4::rename_common(const char *array[][2], LocalVector<RegEx *> &cached_regexes, Vector<SourceLine> &source_lines) {
+ for (SourceLine &source_line : source_lines) {
+ if (source_line.is_comment) {
+ continue;
+ }
+
+ String &line = source_line.line;
if (uint64_t(line.length()) <= maximum_line_length) {
for (unsigned int current_index = 0; current_index < cached_regexes.size(); current_index++) {
if (line.contains(array[current_index][0])) {
@@ -2657,10 +2737,10 @@ String ProjectConverter3To4::simple_line_formatter(int current_line, String old_
}
// Collects string from vector strings
-String ProjectConverter3To4::collect_string_from_vector(Vector<String> &vector) {
+String ProjectConverter3To4::collect_string_from_vector(Vector<SourceLine> &vector) {
String string = "";
for (int i = 0; i < vector.size(); i++) {
- string += vector[i];
+ string += vector[i].line;
if (i != vector.size() - 1) {
string += "\n";
diff --git a/editor/project_converter_3_to_4.h b/editor/project_converter_3_to_4.h
index 90c05c22d2..b2adfac395 100644
--- a/editor/project_converter_3_to_4.h
+++ b/editor/project_converter_3_to_4.h
@@ -58,6 +58,11 @@ public:
#include "core/templates/local_vector.h"
#include "core/templates/vector.h"
+struct SourceLine {
+ String line;
+ bool is_comment;
+};
+
class RegEx;
class ProjectConverter3To4 {
@@ -66,33 +71,33 @@ class ProjectConverter3To4 {
uint64_t maximum_file_size;
uint64_t maximum_line_length;
- void rename_colors(Vector<String> &lines, const RegExContainer &reg_container);
+ void rename_colors(Vector<SourceLine> &source_lines, const RegExContainer &reg_container);
Vector<String> check_for_rename_colors(Vector<String> &lines, const RegExContainer &reg_container);
- void rename_classes(Vector<String> &lines, const RegExContainer &reg_container);
+ void rename_classes(Vector<SourceLine> &source_lines, const RegExContainer &reg_container);
Vector<String> check_for_rename_classes(Vector<String> &lines, const RegExContainer &reg_container);
- void rename_gdscript_functions(Vector<String> &lines, const RegExContainer &reg_container, bool builtin);
+ void rename_gdscript_functions(Vector<SourceLine> &source_lines, const RegExContainer &reg_container, bool builtin);
Vector<String> check_for_rename_gdscript_functions(Vector<String> &lines, const RegExContainer &reg_container, bool builtin);
void process_gdscript_line(String &line, const RegExContainer &reg_container, bool builtin);
- void rename_csharp_functions(Vector<String> &lines, const RegExContainer &reg_container);
+ void rename_csharp_functions(Vector<SourceLine> &source_lines, const RegExContainer &reg_container);
Vector<String> check_for_rename_csharp_functions(Vector<String> &lines, const RegExContainer &reg_container);
void process_csharp_line(String &line, const RegExContainer &reg_container);
- void rename_csharp_attributes(Vector<String> &lines, const RegExContainer &reg_container);
+ void rename_csharp_attributes(Vector<SourceLine> &source_lines, const RegExContainer &reg_container);
Vector<String> check_for_rename_csharp_attributes(Vector<String> &lines, const RegExContainer &reg_container);
- void rename_gdscript_keywords(Vector<String> &lines, const RegExContainer &reg_container);
+ void rename_gdscript_keywords(Vector<SourceLine> &source_lines, const RegExContainer &reg_container);
Vector<String> check_for_rename_gdscript_keywords(Vector<String> &lines, const RegExContainer &reg_container);
- void rename_input_map_scancode(Vector<String> &lines, const RegExContainer &reg_container);
+ void rename_input_map_scancode(Vector<SourceLine> &source_lines, const RegExContainer &reg_container);
Vector<String> check_for_rename_input_map_scancode(Vector<String> &lines, const RegExContainer &reg_container);
- void custom_rename(Vector<String> &lines, String from, String to);
+ void custom_rename(Vector<SourceLine> &source_lines, String from, String to);
Vector<String> check_for_custom_rename(Vector<String> &lines, String from, String to);
- void rename_common(const char *array[][2], LocalVector<RegEx *> &cached_regexes, Vector<String> &lines);
+ void rename_common(const char *array[][2], LocalVector<RegEx *> &cached_regexes, Vector<SourceLine> &source_lines);
Vector<String> check_for_rename_common(const char *array[][2], LocalVector<RegEx *> &cached_regexes, Vector<String> &lines);
Vector<String> check_for_files();
@@ -105,11 +110,12 @@ class ProjectConverter3To4 {
String line_formatter(int current_line, String from, String to, String line);
String simple_line_formatter(int current_line, String old_line, String line);
- String collect_string_from_vector(Vector<String> &vector);
+ String collect_string_from_vector(Vector<SourceLine> &vector);
+ Vector<SourceLine> split_lines(const String &text);
bool test_single_array(const char *array[][2], bool ignore_second_check = false);
- bool test_conversion_gdscript_builtin(String name, String expected, void (ProjectConverter3To4::*func)(Vector<String> &, const RegExContainer &, bool), String what, const RegExContainer &reg_container, bool builtin);
- bool test_conversion_with_regex(String name, String expected, void (ProjectConverter3To4::*func)(Vector<String> &, const RegExContainer &), String what, const RegExContainer &reg_container);
+ bool test_conversion_gdscript_builtin(String name, String expected, void (ProjectConverter3To4::*func)(Vector<SourceLine> &, const RegExContainer &, bool), String what, const RegExContainer &reg_container, bool builtin);
+ bool test_conversion_with_regex(String name, String expected, void (ProjectConverter3To4::*func)(Vector<SourceLine> &, const RegExContainer &), String what, const RegExContainer &reg_container);
bool test_conversion_basic(String name, String expected, const char *array[][2], LocalVector<RegEx *> &regex_cache, String what);
bool test_array_names();
bool test_conversion(RegExContainer &reg_container);
diff --git a/editor/renames_map_3_to_4.cpp b/editor/renames_map_3_to_4.cpp
index 90c8709c3b..3c61b81e5d 100644
--- a/editor/renames_map_3_to_4.cpp
+++ b/editor/renames_map_3_to_4.cpp
@@ -721,7 +721,7 @@ const char *RenamesMap3To4::csharp_function_renames[][2] = {
{ "GetEndianSwap", "IsBigEndian" }, // File
{ "GetErrorString", "GetErrorMessage" }, // JSON
{ "GetFocusNeighbour", "GetFocusNeighbor" }, // Control
- { "GetFollowSmoothing", "GetFollowSmoothingSpeed" }, // Camera2D
+ { "GetFollowSmoothing", "GetPositionSmoothingSpeed" }, // Camera2D
{ "GetFontTypes", "GetFontTypeList" }, // Theme
{ "GetFrameColor", "GetColor" }, // ColorRect
{ "GetGlobalRateScale", "GetPlaybackSpeedScale" }, // AudioServer
@@ -907,12 +907,12 @@ const char *RenamesMap3To4::csharp_function_renames[][2] = {
{ "SetDepthBiasEnable", "SetDepthBiasEnabled" }, // RDPipelineRasterizationState
{ "SetDevice", "SetOutputDevice" }, // AudioServer
{ "SetDoubleclick", "SetDoubleClick" }, // InputEventMouseButton
- { "SetEnableFollowSmoothing", "SetFollowSmoothingEnabled" }, // Camera2D
+ { "SetEnableFollowSmoothing", "SetPositionSmoothingEnabled" }, // Camera2D
{ "SetEnabledFocusMode", "SetFocusMode" }, // BaseButton
{ "SetEndianSwap", "SetBigEndian" }, // File
{ "SetExpandToTextLength", "SetExpandToTextLengthEnabled" }, // LineEdit
{ "SetFocusNeighbour", "SetFocusNeighbor" }, // Control
- { "SetFollowSmoothing", "SetFollowSmoothingSpeed" }, // Camera2D
+ { "SetFollowSmoothing", "SetPositionSmoothingSpeed" }, // Camera2D
{ "SetFrameColor", "SetColor" }, // ColorRect
{ "SetGlobalRateScale", "SetPlaybackSpeedScale" }, // AudioServer
{ "SetGravityDistanceScale", "SetGravityPointDistanceScale" }, // Area2D
@@ -1122,7 +1122,7 @@ const char *RenamesMap3To4::gdscript_properties_renames[][2] = {
{ "selectedframe", "selected_frame" }, // Theme
{ "size_override_stretch", "size_2d_override_stretch" }, // SubViewport
{ "slips_on_slope", "slide_on_slope" }, // SeparationRayShape2D
- { "smoothing_enabled", "follow_smoothing_enabled" }, // Camera2D
+ { "smoothing_enabled", "position_smoothing_enabled" }, // Camera2D
{ "smoothing_speed", "position_smoothing_speed" }, // Camera2D
{ "ss_reflections_depth_tolerance", "ssr_depth_tolerance" }, // Environment
{ "ss_reflections_enabled", "ssr_enabled" }, // Environment
@@ -1215,8 +1215,8 @@ const char *RenamesMap3To4::csharp_properties_renames[][2] = {
{ "Selectedframe", "SelectedFrame" }, // Theme
{ "SizeOverrideStretch", "Size2dOverrideStretch" }, // SubViewport
{ "SlipsOnSlope", "SlideOnSlope" }, // SeparationRayShape2D
- { "SmoothingEnabled", "FollowSmoothingEnabled" }, // Camera2D
- { "SmoothingSpeed", "FollowSmoothingSpeed" }, // Camera2D
+ { "SmoothingEnabled", "PositionSmoothingEnabled" }, // Camera2D
+ { "SmoothingSpeed", "PositionSmoothingSpeed" }, // Camera2D
{ "SsReflectionsDepthTolerance", "SsrDepthTolerance" }, // Environment
{ "SsReflectionsEnabled", "SsrEnabled" }, // Environment
{ "SsReflectionsFadeIn", "SsrFadeIn" }, // Environment
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index d0c2cb43a6..e27b977e9d 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -511,6 +511,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
} break;
case GDScriptParser::Node::CALL: {
const GDScriptParser::CallNode *call = static_cast<const GDScriptParser::CallNode *>(p_expression);
+ bool is_awaited = p_expression == awaited_node;
GDScriptDataType type = _gdtype_from_datatype(call->get_datatype(), codegen.script);
GDScriptCodeGenerator::Address result;
if (p_root) {
@@ -565,13 +566,13 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
} else if ((codegen.function_node && codegen.function_node->is_static) || call->function_name == "new") {
GDScriptCodeGenerator::Address self;
self.mode = GDScriptCodeGenerator::Address::CLASS;
- if (within_await) {
+ if (is_awaited) {
gen->write_call_async(result, self, call->function_name, arguments);
} else {
gen->write_call(result, self, call->function_name, arguments);
}
} else {
- if (within_await) {
+ if (is_awaited) {
gen->write_call_self_async(result, call->function_name, arguments);
} else {
gen->write_call_self(result, call->function_name, arguments);
@@ -593,7 +594,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
if (r_error) {
return GDScriptCodeGenerator::Address();
}
- if (within_await) {
+ if (is_awaited) {
gen->write_call_async(result, base, call->function_name, arguments);
} else if (base.type.has_type && base.type.kind != GDScriptDataType::BUILTIN) {
// Native method, use faster path.
@@ -666,9 +667,10 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
const GDScriptParser::AwaitNode *await = static_cast<const GDScriptParser::AwaitNode *>(p_expression);
GDScriptCodeGenerator::Address result = codegen.add_temporary(_gdtype_from_datatype(p_expression->get_datatype(), codegen.script));
- within_await = true;
+ GDScriptParser::ExpressionNode *previous_awaited_node = awaited_node;
+ awaited_node = await->to_await;
GDScriptCodeGenerator::Address argument = _parse_expression(codegen, r_error, await->to_await);
- within_await = false;
+ awaited_node = previous_awaited_node;
if (r_error) {
return GDScriptCodeGenerator::Address();
}
diff --git a/modules/gdscript/gdscript_compiler.h b/modules/gdscript/gdscript_compiler.h
index 17c6cc8d2f..5328c17c73 100644
--- a/modules/gdscript/gdscript_compiler.h
+++ b/modules/gdscript/gdscript_compiler.h
@@ -137,7 +137,7 @@ class GDScriptCompiler {
int err_column = 0;
StringName source;
String error;
- bool within_await = false;
+ GDScriptParser::ExpressionNode *awaited_node = nullptr;
public:
static void convert_to_initializer_type(Variant &p_variant, const GDScriptParser::VariableNode *p_node);
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index e3ba290eb2..d93485a800 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -3748,6 +3748,14 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> p_state) {
d["alphaMode"] = "BLEND";
}
+ Dictionary extensions;
+ if (base_material->get_shading_mode() == BaseMaterial3D::SHADING_MODE_UNSHADED) {
+ Dictionary mat_unlit;
+ extensions["KHR_materials_unlit"] = mat_unlit;
+ p_state->add_used_extension("KHR_materials_unlit");
+ }
+ d["extensions"] = extensions;
+
materials.push_back(d);
}
if (!materials.size()) {
@@ -3780,6 +3788,11 @@ Error GLTFDocument::_parse_materials(Ref<GLTFState> p_state) {
if (d.has("extensions")) {
pbr_spec_gloss_extensions = d["extensions"];
}
+
+ if (pbr_spec_gloss_extensions.has("KHR_materials_unlit")) {
+ material->set_shading_mode(BaseMaterial3D::SHADING_MODE_UNSHADED);
+ }
+
if (pbr_spec_gloss_extensions.has("KHR_materials_pbrSpecularGlossiness")) {
WARN_PRINT("Material uses a specular and glossiness workflow. Textures will be converted to roughness and metallic workflow, which may not be 100% accurate.");
Dictionary sgm = pbr_spec_gloss_extensions["KHR_materials_pbrSpecularGlossiness"];
@@ -7440,6 +7453,7 @@ Error GLTFDocument::_parse_gltf_extensions(Ref<GLTFState> p_state) {
supported_extensions.insert("KHR_lights_punctual");
supported_extensions.insert("KHR_materials_pbrSpecularGlossiness");
supported_extensions.insert("KHR_texture_transform");
+ supported_extensions.insert("KHR_materials_unlit");
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
ERR_CONTINUE(ext.is_null());
Vector<String> ext_supported_extensions = ext->get_supported_extensions();
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index d3c2415755..932e97c46b 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -58,6 +58,7 @@
#include "godotsharp_dirs.h"
#include "managed_callable.h"
#include "mono_gd/gd_mono_cache.h"
+#include "servers/text_server.h"
#include "signal_awaiter_utils.h"
#include "utils/macros.h"
#include "utils/naming_utils.h"
@@ -374,6 +375,10 @@ String CSharpLanguage::validate_path(const String &p_path) const {
if (keywords.find(class_name)) {
return RTR("Class name can't be a reserved keyword");
}
+ if (!TS->is_valid_identifier(class_name)) {
+ return RTR("Class name must be a valid identifier");
+ }
+
return "";
}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props
index 0d0889c491..eea7520b05 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props
@@ -14,6 +14,7 @@
<GodotProjectDir Condition=" '$(GodotProjectDir)' == '' ">$(MSBuildProjectDirectory)</GodotProjectDir>
<GodotProjectDir>$([MSBuild]::EnsureTrailingSlash('$(GodotProjectDir)'))</GodotProjectDir>
+ <GodotProjectDirBase64>$([MSBuild]::ConvertToBase64('$(GodotProjectDir)'))</GodotProjectDirBase64>
<!-- Custom output paths for Godot projects. In brief, 'bin\' and 'obj\' are moved to '$(GodotProjectDir)\.godot\mono\temp\'. -->
<BaseOutputPath>$(GodotProjectDir).godot\mono\temp\bin\</BaseOutputPath>
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Godot.SourceGenerators.Sample.csproj b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Godot.SourceGenerators.Sample.csproj
index 8e78e0385d..2df838cfb8 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Godot.SourceGenerators.Sample.csproj
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Godot.SourceGenerators.Sample.csproj
@@ -7,6 +7,7 @@
<PropertyGroup>
<!-- $(GodotProjectDir) would normally be defined by the Godot.NET.Sdk -->
<GodotProjectDir>$(MSBuildProjectDirectory)</GodotProjectDir>
+ <GodotProjectDirBase64>$([MSBuild]::ConvertToBase64('$(GodotProjectDir)'))</GodotProjectDirBase64>
<!-- For compiling GetGodotPropertyDefaultValues. -->
<DefineConstants>$(DefineConstants);TOOLS</DefineConstants>
</PropertyGroup>
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs
index 41bf89e6d8..8be1151142 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs
@@ -194,6 +194,32 @@ namespace Godot.SourceGenerators
location?.SourceTree?.FilePath));
}
+ public static void ReportExportedMemberIsExplicitInterfaceImplementation(
+ GeneratorExecutionContext context,
+ ISymbol exportedMemberSymbol
+ )
+ {
+ var locations = exportedMemberSymbol.Locations;
+ var location = locations.FirstOrDefault(l => l.SourceTree != null) ?? locations.FirstOrDefault();
+
+ string message = $"Attempted to export explicit interface property implementation: " +
+ $"'{exportedMemberSymbol.ToDisplayString()}'";
+
+ string description = $"{message}. Explicit interface implementations can't be exported." +
+ " Remove the '[Export]' attribute.";
+
+ context.ReportDiagnostic(Diagnostic.Create(
+ new DiagnosticDescriptor(id: "GD0106",
+ title: message,
+ messageFormat: message,
+ category: "Usage",
+ DiagnosticSeverity.Error,
+ isEnabledByDefault: true,
+ description),
+ location,
+ location?.SourceTree?.FilePath));
+ }
+
public static void ReportSignalDelegateMissingSuffix(
GeneratorExecutionContext context,
INamedTypeSymbol delegateSymbol)
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.props b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.props
index 7881ed0a8c..2a8ae7f958 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.props
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.props
@@ -2,6 +2,7 @@
<ItemGroup>
<!-- $(GodotProjectDir) is defined by Godot.NET.Sdk -->
<CompilerVisibleProperty Include="GodotProjectDir" />
+ <CompilerVisibleProperty Include="GodotProjectDirBase64" />
<CompilerVisibleProperty Include="GodotSourceGenerators" />
<CompilerVisibleProperty Include="IsGodotToolsProject" />
</ItemGroup>
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs
index eae7e41da8..d14e3c3781 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs
@@ -22,10 +22,17 @@ namespace Godot.SourceGenerators
// NOTE: NotNullWhen diagnostics don't work on projects targeting .NET Standard 2.0
// ReSharper disable once ReplaceWithStringIsNullOrEmpty
- if (!context.TryGetGlobalAnalyzerProperty("GodotProjectDir", out string? godotProjectDir)
- || godotProjectDir!.Length == 0)
+ if (!context.TryGetGlobalAnalyzerProperty("GodotProjectDirBase64", out string? godotProjectDir) || godotProjectDir!.Length == 0)
{
- throw new InvalidOperationException("Property 'GodotProjectDir' is null or empty.");
+ if (!context.TryGetGlobalAnalyzerProperty("GodotProjectDir", out godotProjectDir) || godotProjectDir!.Length == 0)
+ {
+ throw new InvalidOperationException("Property 'GodotProjectDir' is null or empty.");
+ }
+ }
+ else
+ {
+ // Workaround for https://github.com/dotnet/roslyn/issues/51692
+ godotProjectDir = Encoding.UTF8.GetString(Convert.FromBase64String(godotProjectDir));
}
Dictionary<INamedTypeSymbol, IEnumerable<ClassDeclarationSyntax>> godotClasses = context
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs
index b720fb93a3..d333c24451 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs
@@ -113,7 +113,7 @@ namespace Godot.SourceGenerators
var propertySymbols = members
.Where(s => !s.IsStatic && s.Kind == SymbolKind.Property)
.Cast<IPropertySymbol>()
- .Where(s => !s.IsIndexer);
+ .Where(s => !s.IsIndexer && s.ExplicitInterfaceImplementations.Length == 0);
var fieldSymbols = members
.Where(s => !s.IsStatic && s.Kind == SymbolKind.Field && !s.IsImplicitlyDeclared)
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
index 99a4c95e73..089ee3f196 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
@@ -151,6 +151,12 @@ namespace Godot.SourceGenerators
continue;
}
+ if (property.ExplicitInterfaceImplementations.Length > 0)
+ {
+ Common.ReportExportedMemberIsExplicitInterfaceImplementation(context, property);
+ continue;
+ }
+
var propertyType = property.Type;
var marshalType = MarshalUtils.ConvertManagedTypeToMarshalType(propertyType, typeCache);
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs
index 821f3af75f..d8c6f3a196 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs
@@ -113,7 +113,7 @@ namespace Godot.SourceGenerators
var propertySymbols = members
.Where(s => !s.IsStatic && s.Kind == SymbolKind.Property)
.Cast<IPropertySymbol>()
- .Where(s => !s.IsIndexer);
+ .Where(s => !s.IsIndexer && s.ExplicitInterfaceImplementations.Length == 0);
var fieldSymbols = members
.Where(s => !s.IsStatic && s.Kind == SymbolKind.Field && !s.IsImplicitlyDeclared)
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index cbe5266f7e..83101c1443 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -1483,9 +1483,9 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
output << MEMBER_BEGIN "public static GodotObject " CS_PROPERTY_SINGLETON "\n" INDENT1 "{\n"
<< INDENT2 "get\n" INDENT2 "{\n" INDENT3 "if (singleton == null)\n"
- << INDENT4 "singleton = " C_METHOD_ENGINE_GET_SINGLETON "(typeof("
- << itype.proxy_name
- << ").Name);\n" INDENT3 "return singleton;\n" INDENT2 "}\n" INDENT1 "}\n";
+ << INDENT4 "singleton = " C_METHOD_ENGINE_GET_SINGLETON "(\""
+ << itype.name
+ << "\");\n" INDENT3 "return singleton;\n" INDENT2 "}\n" INDENT1 "}\n";
output.append(MEMBER_BEGIN "private static readonly StringName " BINDINGS_NATIVE_NAME_FIELD " = \"");
output.append(itype.name);
diff --git a/platform/ios/godot_view.mm b/platform/ios/godot_view.mm
index fafec79bf6..67e47092d8 100644
--- a/platform/ios/godot_view.mm
+++ b/platform/ios/godot_view.mm
@@ -39,7 +39,7 @@
#import <CoreMotion/CoreMotion.h>
-static const int max_touches = 8;
+static const int max_touches = 32;
static const float earth_gravity = 9.80665;
@interface GodotView () {
diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py
index 3f713d2db3..e203dca005 100644
--- a/platform/linuxbsd/detect.py
+++ b/platform/linuxbsd/detect.py
@@ -277,11 +277,10 @@ def configure(env: "Environment"):
env.Prepend(CPPPATH=["/usr/include/recastnavigation"])
env.Append(LIBS=["Recast"])
- if not env["builtin_embree"]:
+ if not env["builtin_embree"] and env["arch"] in ["x86_64", "arm64"]:
# No pkgconfig file so far, hardcode expected lib name.
env.Append(LIBS=["embree3"])
- ## Flags
if env["fontconfig"]:
if not env["use_sowrap"]:
if os.system("pkg-config --exists fontconfig") == 0: # 0 means found
diff --git a/scene/2d/back_buffer_copy.cpp b/scene/2d/back_buffer_copy.cpp
index 60b344b002..4cae1affc3 100644
--- a/scene/2d/back_buffer_copy.cpp
+++ b/scene/2d/back_buffer_copy.cpp
@@ -62,6 +62,7 @@ Rect2 BackBufferCopy::get_anchorable_rect() const {
void BackBufferCopy::set_rect(const Rect2 &p_rect) {
rect = p_rect;
_update_copy_mode();
+ item_rect_changed();
}
Rect2 BackBufferCopy::get_rect() const {
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index 2b90a3702f..fdd709c3cb 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -158,7 +158,7 @@ Transform2D Camera2D::get_camera_transform() {
}
}
- if (follow_smoothing_enabled && !Engine::get_singleton()->is_editor_hint()) {
+ if (position_smoothing_enabled && !Engine::get_singleton()->is_editor_hint()) {
real_t c = position_smoothing_speed * (process_callback == CAMERA2D_PROCESS_PHYSICS ? get_physics_process_delta_time() : get_process_delta_time());
smoothed_camera_pos = ((camera_pos - smoothed_camera_pos) * c) + smoothed_camera_pos;
ret_camera_pos = smoothed_camera_pos;
@@ -186,7 +186,7 @@ Transform2D Camera2D::get_camera_transform() {
Rect2 screen_rect(-screen_offset + ret_camera_pos, screen_size * zoom_scale);
- if (!follow_smoothing_enabled || !limit_smoothing_enabled) {
+ if (!position_smoothing_enabled || !limit_smoothing_enabled) {
if (screen_rect.position.x < limit[SIDE_LEFT]) {
screen_rect.position.x = limit[SIDE_LEFT];
}
@@ -617,18 +617,18 @@ real_t Camera2D::get_drag_horizontal_offset() const {
void Camera2D::_set_old_smoothing(real_t p_enable) {
//compatibility
if (p_enable > 0) {
- follow_smoothing_enabled = true;
+ position_smoothing_enabled = true;
set_position_smoothing_speed(p_enable);
}
}
void Camera2D::set_position_smoothing_enabled(bool p_enabled) {
- follow_smoothing_enabled = p_enabled;
+ position_smoothing_enabled = p_enabled;
notify_property_list_changed();
}
bool Camera2D::is_position_smoothing_enabled() const {
- return follow_smoothing_enabled;
+ return position_smoothing_enabled;
}
void Camera2D::set_custom_viewport(Node *p_viewport) {
@@ -699,7 +699,7 @@ bool Camera2D::is_margin_drawing_enabled() const {
}
void Camera2D::_validate_property(PropertyInfo &p_property) const {
- if (!follow_smoothing_enabled && p_property.name == "smoothing_speed") {
+ if (!position_smoothing_enabled && p_property.name == "position_smoothing_speed") {
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
}
if (!rotation_smoothing_enabled && p_property.name == "rotation_smoothing_speed") {
@@ -801,7 +801,7 @@ void Camera2D::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::INT, "limit_bottom", PROPERTY_HINT_NONE, "suffix:px"), "set_limit", "get_limit", SIDE_BOTTOM);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "limit_smoothed"), "set_limit_smoothing_enabled", "is_limit_smoothing_enabled");
- ADD_GROUP("Follow Smoothing", "follow_smoothing_");
+ ADD_GROUP("Position Smoothing", "position_smoothing_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "position_smoothing_enabled"), "set_position_smoothing_enabled", "is_position_smoothing_enabled");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "position_smoothing_speed", PROPERTY_HINT_NONE, "suffix:px/s"), "set_position_smoothing_speed", "get_position_smoothing_speed");
diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h
index 2417953691..808529b0fb 100644
--- a/scene/2d/camera_2d.h
+++ b/scene/2d/camera_2d.h
@@ -67,7 +67,7 @@ protected:
bool ignore_rotation = true;
bool enabled = true;
real_t position_smoothing_speed = 5.0;
- bool follow_smoothing_enabled = false;
+ bool position_smoothing_enabled = false;
real_t camera_angle = 0.0;
real_t rotation_smoothing_speed = 5.0;
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index 958e960ab2..084fb64a53 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -8798,11 +8798,19 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
_set_error(RTR("'hint_normal_roughness_texture' is not supported in gl_compatibility shaders."));
return ERR_PARSE_ERROR;
}
+ if (String(shader_type_identifier) != "spatial") {
+ _set_error(vformat(RTR("'hint_normal_roughness_texture' is not supported in '%s' shaders."), shader_type_identifier));
+ return ERR_PARSE_ERROR;
+ }
} break;
case TK_HINT_DEPTH_TEXTURE: {
new_hint = ShaderNode::Uniform::HINT_DEPTH_TEXTURE;
--texture_uniforms;
--texture_binding;
+ if (String(shader_type_identifier) != "spatial") {
+ _set_error(vformat(RTR("'hint_depth_texture' is not supported in '%s' shaders."), shader_type_identifier));
+ return ERR_PARSE_ERROR;
+ }
} break;
case TK_FILTER_NEAREST: {
new_filter = FILTER_NEAREST;