summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/bind/core_bind.cpp2
-rw-r--r--core/io/marshalls.cpp12
-rw-r--r--doc/classes/AudioStreamPlayer.xml2
-rw-r--r--doc/classes/AudioStreamPlayer2D.xml2
-rw-r--r--doc/classes/AudioStreamPlayer3D.xml2
-rw-r--r--doc/classes/Engine.xml3
-rw-r--r--doc/classes/HScrollBar.xml11
-rw-r--r--doc/classes/LineEdit.xml17
-rw-r--r--doc/classes/OS.xml9
-rw-r--r--doc/classes/ProjectSettings.xml2
-rw-r--r--doc/classes/ScriptCreateDialog.xml2
-rw-r--r--doc/classes/ScrollBar.xml1
-rw-r--r--doc/classes/VScrollBar.xml12
-rw-r--r--doc/classes/VisibilityEnabler.xml2
-rw-r--r--doc/classes/VisibilityEnabler2D.xml3
-rw-r--r--editor/animation_track_editor.cpp5
-rw-r--r--editor/filesystem_dock.cpp2
-rw-r--r--editor/groups_editor.cpp12
-rw-r--r--editor/plugins/script_editor_plugin.cpp2
-rw-r--r--editor/plugins/tile_set_editor_plugin.cpp28
-rw-r--r--editor/script_create_dialog.cpp40
-rw-r--r--editor/script_create_dialog.h3
-rw-r--r--main/main.cpp30
-rw-r--r--modules/gdnative/gdnative/gdnative.cpp4
-rw-r--r--modules/gdnative/gdnative_api.json7
-rw-r--r--modules/gdnative/include/gdnative/gdnative.h3
-rw-r--r--modules/gdscript/gdscript_compiler.cpp16
-rw-r--r--modules/gdscript/gdscript_compiler.h6
-rw-r--r--modules/gdscript/gdscript_function.cpp7
-rw-r--r--modules/gdscript/gdscript_parser.cpp4
-rw-r--r--modules/gdscript/language_server/gdscript_text_document.cpp2
-rw-r--r--modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml2
-rw-r--r--platform/android/dir_access_jandroid.cpp1
-rw-r--r--platform/android/export/export.cpp12
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotLib.java10
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotView.java5
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java106
-rw-r--r--platform/android/java_godot_lib_jni.cpp14
-rw-r--r--platform/android/java_godot_lib_jni.h2
-rw-r--r--platform/android/os_android.cpp20
-rw-r--r--platform/android/os_android.h3
-rw-r--r--platform/osx/export/export.cpp31
-rw-r--r--platform/x11/crash_handler_x11.cpp2
-rw-r--r--scene/2d/animated_sprite.cpp2
-rw-r--r--scene/2d/animated_sprite.h2
-rw-r--r--scene/2d/back_buffer_copy.cpp2
-rw-r--r--scene/2d/back_buffer_copy.h2
-rw-r--r--scene/2d/canvas_item.cpp7
-rw-r--r--scene/2d/canvas_item.h3
-rw-r--r--scene/2d/collision_polygon_2d.cpp2
-rw-r--r--scene/2d/collision_polygon_2d.h10
-rw-r--r--scene/2d/light_2d.cpp2
-rw-r--r--scene/2d/light_2d.h2
-rw-r--r--scene/2d/light_occluder_2d.cpp5
-rw-r--r--scene/2d/light_occluder_2d.h4
-rw-r--r--scene/2d/line_2d.cpp2
-rw-r--r--scene/2d/line_2d.h6
-rw-r--r--scene/2d/mesh_instance_2d.cpp2
-rw-r--r--scene/2d/mesh_instance_2d.h6
-rw-r--r--scene/2d/multimesh_instance_2d.cpp2
-rw-r--r--scene/2d/multimesh_instance_2d.h6
-rw-r--r--scene/2d/navigation_polygon.cpp5
-rw-r--r--scene/2d/navigation_polygon.h4
-rw-r--r--scene/2d/node_2d.cpp3
-rw-r--r--scene/2d/node_2d.h2
-rw-r--r--scene/2d/path_2d.cpp2
-rw-r--r--scene/2d/path_2d.h2
-rw-r--r--scene/2d/physics_body_2d.cpp31
-rw-r--r--scene/2d/physics_body_2d.h6
-rw-r--r--scene/2d/polygon_2d.cpp2
-rw-r--r--scene/2d/polygon_2d.h2
-rw-r--r--scene/2d/position_2d.cpp2
-rw-r--r--scene/2d/position_2d.h2
-rw-r--r--scene/2d/sprite.cpp12
-rw-r--r--scene/2d/sprite.h6
-rw-r--r--scene/2d/tile_map.cpp2
-rw-r--r--scene/2d/tile_map.h2
-rw-r--r--scene/2d/touch_screen_button.cpp12
-rw-r--r--scene/2d/touch_screen_button.h7
-rw-r--r--scene/2d/visibility_notifier_2d.cpp19
-rw-r--r--scene/2d/visibility_notifier_2d.h2
-rw-r--r--scene/3d/camera.cpp4
-rw-r--r--scene/3d/physics_body.cpp33
-rw-r--r--scene/3d/physics_body.h6
-rw-r--r--scene/gui/base_button.cpp2
-rw-r--r--scene/gui/control.cpp11
-rw-r--r--scene/gui/control.h2
-rw-r--r--scene/gui/label.cpp8
-rw-r--r--servers/visual/shader_language.cpp18
89 files changed, 577 insertions, 160 deletions
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index 0eacffeb88..4586dc6d14 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -1393,7 +1393,7 @@ void _OS::_bind_methods() {
ADD_PROPERTY_DEFAULT("current_screen", 0);
ADD_PROPERTY_DEFAULT("exit_code", 0);
ADD_PROPERTY_DEFAULT("vsync_enabled", true);
- ADD_PROPERTY_DEFAULT("vsync_via_compositor", false);
+ ADD_PROPERTY_DEFAULT("vsync_via_compositor", true);
ADD_PROPERTY_DEFAULT("low_processor_usage_mode", false);
ADD_PROPERTY_DEFAULT("low_processor_usage_mode_sleep_usec", 6900);
ADD_PROPERTY_DEFAULT("keep_screen_on", true);
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp
index 8c8f65c3a0..e847a9cf0c 100644
--- a/core/io/marshalls.cpp
+++ b/core/io/marshalls.cpp
@@ -803,6 +803,18 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
}
} break;
case Variant::OBJECT: {
+#ifdef DEBUG_ENABLED
+ // Test for potential wrong values sent by the debugger when it breaks.
+ Object *obj = p_variant;
+ if (!obj || !ObjectDB::instance_validate(obj)) {
+ // Object is invalid, send a NULL instead.
+ if (buf) {
+ encode_uint32(Variant::NIL, buf);
+ }
+ r_len += 4;
+ return OK;
+ }
+#endif // DEBUG_ENABLED
if (!p_full_objects) {
flags |= ENCODE_FLAG_OBJECT_AS_ID;
}
diff --git a/doc/classes/AudioStreamPlayer.xml b/doc/classes/AudioStreamPlayer.xml
index 89fc18476b..0eadf27c4d 100644
--- a/doc/classes/AudioStreamPlayer.xml
+++ b/doc/classes/AudioStreamPlayer.xml
@@ -21,6 +21,7 @@
<return type="AudioStreamPlayback">
</return>
<description>
+ Returns the [AudioStreamPlayback] object associated with this [AudioStreamPlayer].
</description>
</method>
<method name="play">
@@ -69,6 +70,7 @@
The [AudioStream] object to be played.
</member>
<member name="stream_paused" type="bool" setter="set_stream_paused" getter="get_stream_paused" default="false">
+ If [code]true[/code], the playback is paused. You can resume it by setting [code]stream_paused[/code] to [code]false[/code].
</member>
<member name="volume_db" type="float" setter="set_volume_db" getter="get_volume_db" default="0.0">
Volume of sound, in dB.
diff --git a/doc/classes/AudioStreamPlayer2D.xml b/doc/classes/AudioStreamPlayer2D.xml
index 4734aff770..ec3b7872b7 100644
--- a/doc/classes/AudioStreamPlayer2D.xml
+++ b/doc/classes/AudioStreamPlayer2D.xml
@@ -21,6 +21,7 @@
<return type="AudioStreamPlayback">
</return>
<description>
+ Returns the [AudioStreamPlayback] object associated with this [AudioStreamPlayer2D].
</description>
</method>
<method name="play">
@@ -75,6 +76,7 @@
The [AudioStream] object to be played.
</member>
<member name="stream_paused" type="bool" setter="set_stream_paused" getter="get_stream_paused" default="false">
+ If [code]true[/code], the playback is paused. You can resume it by setting [code]stream_paused[/code] to [code]false[/code].
</member>
<member name="volume_db" type="float" setter="set_volume_db" getter="get_volume_db" default="0.0">
Base volume without dampening.
diff --git a/doc/classes/AudioStreamPlayer3D.xml b/doc/classes/AudioStreamPlayer3D.xml
index a73f96d082..5e12e06650 100644
--- a/doc/classes/AudioStreamPlayer3D.xml
+++ b/doc/classes/AudioStreamPlayer3D.xml
@@ -21,6 +21,7 @@
<return type="AudioStreamPlayback">
</return>
<description>
+ Returns the [AudioStreamPlayback] object associated with this [AudioStreamPlayer3D].
</description>
</method>
<method name="play">
@@ -99,6 +100,7 @@
The [AudioStream] object to be played.
</member>
<member name="stream_paused" type="bool" setter="set_stream_paused" getter="get_stream_paused" default="false">
+ If [code]true[/code], the playback is paused. You can resume it by setting [code]stream_paused[/code] to [code]false[/code].
</member>
<member name="unit_db" type="float" setter="set_unit_db" getter="get_unit_db" default="0.0">
Base sound level unaffected by dampening, in dB.
diff --git a/doc/classes/Engine.xml b/doc/classes/Engine.xml
index 187e13d7bd..04e203793b 100644
--- a/doc/classes/Engine.xml
+++ b/doc/classes/Engine.xml
@@ -85,6 +85,7 @@
<argument index="0" name="name" type="String">
</argument>
<description>
+ Returns a global singleton with given [code]name[/code]. Often used for plugins, e.g. GodotPayments.
</description>
</method>
<method name="get_version_info" qualifiers="const">
@@ -116,6 +117,7 @@
<argument index="0" name="name" type="String">
</argument>
<description>
+ Returns [code]true[/code] if a singleton with given [code]name[/code] exists in global scope.
</description>
</method>
<method name="is_in_physics_frame" qualifiers="const">
@@ -134,6 +136,7 @@
The number of fixed iterations per second (for fixed process and physics).
</member>
<member name="physics_jitter_fix" type="float" setter="set_physics_jitter_fix" getter="get_physics_jitter_fix" default="0.5">
+ Controls how much physic ticks are synchronized with real time. For 0 or less, the ticks are synchronized. Such values are recommended for network games, where clock synchronization matters. Higher values cause higher deviation of in-game clock and real clock, but allows to smooth out framerate jitters. The default value of 0.5 should be fine for most; values above 2 could cause the game to react to dropped frames with a noticeable delay and are not recommended.
</member>
<member name="target_fps" type="int" setter="set_target_fps" getter="get_target_fps" default="0">
The desired frames per second. If the hardware cannot keep up, this setting may not be respected. A value of 0 means no limit.
diff --git a/doc/classes/HScrollBar.xml b/doc/classes/HScrollBar.xml
index 14ace8bc76..90f14dd344 100644
--- a/doc/classes/HScrollBar.xml
+++ b/doc/classes/HScrollBar.xml
@@ -4,7 +4,7 @@
Horizontal scroll bar.
</brief_description>
<description>
- Horizontal scroll bar. See [ScrollBar]. This one goes from left (min) to right (max).
+ Horizontal version of [ScrollBar], which goes from left (min) to right (max).
</description>
<tutorials>
</tutorials>
@@ -14,22 +14,31 @@
</constants>
<theme_items>
<theme_item name="decrement" type="Texture">
+ Icon used as a button to scroll the [ScrollBar] left. Supports custom step using the [member ScrollBar.custom_step] property.
</theme_item>
<theme_item name="decrement_highlight" type="Texture">
+ Displayed when the mouse cursor hovers over the decrement button.
</theme_item>
<theme_item name="grabber" type="StyleBox">
+ Used as texture for the grabber, the draggable element representing current scroll.
</theme_item>
<theme_item name="grabber_highlight" type="StyleBox">
+ Used when the mouse hovers over the grabber.
</theme_item>
<theme_item name="grabber_pressed" type="StyleBox">
+ Used when the grabber is being dragged.
</theme_item>
<theme_item name="increment" type="Texture">
+ Icon used as a button to scroll the [ScrollBar] right. Supports custom step using the [member ScrollBar.custom_step] property.
</theme_item>
<theme_item name="increment_highlight" type="Texture">
+ Displayed when the mouse cursor hovers over the increment button.
</theme_item>
<theme_item name="scroll" type="StyleBox">
+ Used as background of this [ScrollBar].
</theme_item>
<theme_item name="scroll_focus" type="StyleBox">
+ Used as background when the [ScrollBar] has the GUI focus.
</theme_item>
</theme_items>
</class>
diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml
index 78459d2839..a360010b7e 100644
--- a/doc/classes/LineEdit.xml
+++ b/doc/classes/LineEdit.xml
@@ -96,7 +96,7 @@
The cursor's position inside the [LineEdit]. When set, the text may scroll to accommodate it.
</member>
<member name="clear_button_enabled" type="bool" setter="set_clear_button_enabled" getter="is_clear_button_enabled" default="false">
- If [code]true[/code], the [LineEdit] will show a clear button if [code]text[/code] is not empty.
+ If [code]true[/code], the [LineEdit] will show a clear button if [code]text[/code] is not empty, which can be used to clear the text quickly.
</member>
<member name="context_menu_enabled" type="bool" setter="set_context_menu_enabled" getter="is_context_menu_enabled" default="true">
If [code]true[/code], the context menu will appear when right-clicked.
@@ -128,8 +128,10 @@
The character to use to mask secret input (defaults to "*"). Only a single character can be used as the secret character.
</member>
<member name="selecting_enabled" type="bool" setter="set_selecting_enabled" getter="is_selecting_enabled" default="true">
+ If [code]false[/code], it's impossible to select the text using mouse nor keyboard.
</member>
<member name="shortcut_keys_enabled" type="bool" setter="set_shortcut_keys_enabled" getter="is_shortcut_keys_enabled" default="true">
+ If [code]false[/code], using shortcuts will be disabled.
</member>
<member name="text" type="String" setter="set_text" getter="get_text" default="&quot;&quot;">
String value of the [LineEdit].
@@ -192,30 +194,43 @@
</constants>
<theme_items>
<theme_item name="clear" type="Texture">
+ Texture for the clear button. See [member clear_button_enabled].
</theme_item>
<theme_item name="clear_button_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )">
+ Color used as default tint for the clear button.
</theme_item>
<theme_item name="clear_button_color_pressed" type="Color" default="Color( 1, 1, 1, 1 )">
+ Color used for the clear button when it's pressed.
</theme_item>
<theme_item name="cursor_color" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )">
+ Color of the [LineEdit]'s visual cursor (caret).
</theme_item>
<theme_item name="focus" type="StyleBox">
+ Background used when [LineEdit] has GUI focus.
</theme_item>
<theme_item name="font" type="Font">
+ Font used for the text.
</theme_item>
<theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )">
+ Default font color.
</theme_item>
<theme_item name="font_color_selected" type="Color" default="Color( 0, 0, 0, 1 )">
+ Font color for selected text (inside the selection rectangle).
</theme_item>
<theme_item name="font_color_uneditable" type="Color" default="Color( 0.88, 0.88, 0.88, 0.5 )">
+ Font color when editing is disabled.
</theme_item>
<theme_item name="minimum_spaces" type="int" default="12">
+ Minimum horizontal space for the text (not counting the clear button and content margins).
</theme_item>
<theme_item name="normal" type="StyleBox">
+ Default background for the [LineEdit].
</theme_item>
<theme_item name="read_only" type="StyleBox">
+ Background used when [LineEdit] is in read-only mode ([member editable] is set to [code]false[/code]).
</theme_item>
<theme_item name="selection_color" type="Color" default="Color( 0.49, 0.49, 0.49, 1 )">
+ Color of the selection rectangle.
</theme_item>
</theme_items>
</class>
diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml
index 71d0c1a6fe..2236c42094 100644
--- a/doc/classes/OS.xml
+++ b/doc/classes/OS.xml
@@ -613,9 +613,9 @@
<return type="bool">
</return>
<description>
- Returns [code]true[/code] if the build is a debug build.
- Returns [code]true[/code] when running in the editor.
- Returns [code]false[/code] if the build is a release build.
+ Returns [code]true[/code] if the Godot binary used to run the project is a [i]debug[/i] export template, or when running in the editor.
+ Returns [code]false[/code] if the Godot binary used to run the project is a [i]release[/i] export template.
+ To check whether the Godot binary used to run the project is an export template (debug or release), use [code]OS.has_feature("standalone")[/code] instead.
</description>
</method>
<method name="is_ok_left_and_cancel_right" qualifiers="const">
@@ -937,8 +937,9 @@
<member name="vsync_enabled" type="bool" setter="set_use_vsync" getter="is_vsync_enabled" default="true">
If [code]true[/code], vertical synchronization (Vsync) is enabled.
</member>
- <member name="vsync_via_compositor" type="bool" setter="set_vsync_via_compositor" getter="is_vsync_via_compositor_enabled" default="false">
+ <member name="vsync_via_compositor" type="bool" setter="set_vsync_via_compositor" getter="is_vsync_via_compositor_enabled" default="true">
If [code]true[/code] and [code]vsync_enabled[/code] is true, the operating system's window compositor will be used for vsync when the compositor is enabled and the game is in windowed mode.
+ [b]Note:[/b] This property is only implemented on Windows.
</member>
<member name="window_borderless" type="bool" setter="set_borderless_window" getter="get_borderless_window" default="false">
If [code]true[/code], removes the window frame.
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 126f11a4ed..1bc43dc964 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -437,7 +437,7 @@
<member name="display/window/vsync/use_vsync" type="bool" setter="" getter="" default="true">
If [code]true[/code], enables vertical synchronization. This eliminates tearing that may appear in moving scenes, at the cost of higher input latency and stuttering at lower framerates. If [code]false[/code], vertical synchronization will be disabled, however, many platforms will enforce it regardless (such as mobile platforms and HTML5).
</member>
- <member name="display/window/vsync/vsync_via_compositor" type="bool" setter="" getter="" default="false">
+ <member name="display/window/vsync/vsync_via_compositor" type="bool" setter="" getter="" default="true">
If [code]Use Vsync[/code] is enabled and this setting is [code]true[/code], enables vertical synchronization via the operating system's window compositor when in windowed mode and the compositor is enabled. This will prevent stutter in certain situations. (Windows only.)
</member>
<member name="editor/script_templates_search_path" type="String" setter="" getter="" default="&quot;res://script_templates&quot;">
diff --git a/doc/classes/ScriptCreateDialog.xml b/doc/classes/ScriptCreateDialog.xml
index 3d0fa9a0d5..2991d76bec 100644
--- a/doc/classes/ScriptCreateDialog.xml
+++ b/doc/classes/ScriptCreateDialog.xml
@@ -24,6 +24,8 @@
</argument>
<argument index="2" name="built_in_enabled" type="bool" default="true">
</argument>
+ <argument index="3" name="load_enabled" type="bool" default="true">
+ </argument>
<description>
Prefills required fields to configure the ScriptCreateDialog for use.
</description>
diff --git a/doc/classes/ScrollBar.xml b/doc/classes/ScrollBar.xml
index ea30b9d48c..e4ace8e8ae 100644
--- a/doc/classes/ScrollBar.xml
+++ b/doc/classes/ScrollBar.xml
@@ -12,6 +12,7 @@
</methods>
<members>
<member name="custom_step" type="float" setter="set_custom_step" getter="get_custom_step" default="-1.0">
+ Overrides the step used when clicking increment and decrement buttons or when using arrow keys when the [ScrollBar] is focused.
</member>
<member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" override="true" default="0" />
<member name="step" type="float" setter="set_step" getter="get_step" override="true" default="0.0" />
diff --git a/doc/classes/VScrollBar.xml b/doc/classes/VScrollBar.xml
index 6240178b82..add695ef2c 100644
--- a/doc/classes/VScrollBar.xml
+++ b/doc/classes/VScrollBar.xml
@@ -1,9 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VScrollBar" inherits="ScrollBar" category="Core" version="3.2">
<brief_description>
- Vertical version of [ScrollBar], which goes from top (min) to bottom (max).
+ Vertical scroll bar.
</brief_description>
<description>
+ Vertical version of [ScrollBar], which goes from top (min) to bottom (max).
</description>
<tutorials>
</tutorials>
@@ -17,22 +18,31 @@
</constants>
<theme_items>
<theme_item name="decrement" type="Texture">
+ Icon used as a button to scroll the [ScrollBar] up. Supports custom step using the [member ScrollBar.custom_step] property.
</theme_item>
<theme_item name="decrement_highlight" type="Texture">
+ Displayed when the mouse cursor hovers over the decrement button.
</theme_item>
<theme_item name="grabber" type="StyleBox">
+ Used as texture for the grabber, the draggable element representing current scroll.
</theme_item>
<theme_item name="grabber_highlight" type="StyleBox">
+ Used when the mouse hovers over the grabber.
</theme_item>
<theme_item name="grabber_pressed" type="StyleBox">
+ Used when the grabber is being dragged.
</theme_item>
<theme_item name="increment" type="Texture">
+ Icon used as a button to scroll the [ScrollBar] down. Supports custom step using the [member ScrollBar.custom_step] property.
</theme_item>
<theme_item name="increment_highlight" type="Texture">
+ Displayed when the mouse cursor hovers over the increment button.
</theme_item>
<theme_item name="scroll" type="StyleBox">
+ Used as background of this [ScrollBar].
</theme_item>
<theme_item name="scroll_focus" type="StyleBox">
+ Used as background when the [ScrollBar] has the GUI focus.
</theme_item>
</theme_items>
</class>
diff --git a/doc/classes/VisibilityEnabler.xml b/doc/classes/VisibilityEnabler.xml
index e3c7d05fce..56fa7b77a9 100644
--- a/doc/classes/VisibilityEnabler.xml
+++ b/doc/classes/VisibilityEnabler.xml
@@ -15,6 +15,7 @@
<argument index="0" name="enabler" type="int" enum="VisibilityEnabler.Enabler">
</argument>
<description>
+ Returns whether the enabler identified by given [enum Enabler] constant is active.
</description>
</method>
<method name="set_enabler">
@@ -25,6 +26,7 @@
<argument index="1" name="enabled" type="bool">
</argument>
<description>
+ Sets active state of the enabler identified by given [enum Enabler] constant.
</description>
</method>
</methods>
diff --git a/doc/classes/VisibilityEnabler2D.xml b/doc/classes/VisibilityEnabler2D.xml
index 96f6a42cdf..547793c385 100644
--- a/doc/classes/VisibilityEnabler2D.xml
+++ b/doc/classes/VisibilityEnabler2D.xml
@@ -15,6 +15,7 @@
<argument index="0" name="enabler" type="int" enum="VisibilityEnabler2D.Enabler">
</argument>
<description>
+ Returns whether the enabler identified by given [enum Enabler] constant is active.
</description>
</method>
<method name="set_enabler">
@@ -25,6 +26,7 @@
<argument index="1" name="enabled" type="bool">
</argument>
<description>
+ Sets active state of the enabler identified by given [enum Enabler] constant.
</description>
</method>
</methods>
@@ -65,6 +67,7 @@
This enabler will stop the parent's _physics_process function.
</constant>
<constant name="ENABLER_PAUSE_ANIMATED_SPRITES" value="5" enum="Enabler">
+ This enabler will stop [AnimatedSprite] nodes animations.
</constant>
<constant name="ENABLER_MAX" value="6" enum="Enabler">
Represents the size of the [enum Enabler] enum.
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index cd19ceb868..f6d5312fc7 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -3790,8 +3790,9 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari
value = p_value; //all good
} else {
String tpath = animation->track_get_path(i);
- if (NodePath(tpath.get_basename()) == np) {
- String subindex = tpath.get_extension();
+ int index = tpath.find_last(":");
+ if (NodePath(tpath.substr(0, index + 1)) == np) {
+ String subindex = tpath.substr(index + 1, tpath.length() - index);
value = p_value.get(subindex);
} else {
continue;
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index f74cadf67e..93e9cc58fb 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -1761,7 +1761,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
if (!fpath.ends_with("/")) {
fpath = fpath.get_base_dir();
}
- make_script_dialog->config("Node", fpath.plus_file("new_script.gd"), false);
+ make_script_dialog->config("Node", fpath.plus_file("new_script.gd"), false, false);
make_script_dialog->popup_centered();
} break;
diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp
index c19bee321a..83259afb35 100644
--- a/editor/groups_editor.cpp
+++ b/editor/groups_editor.cpp
@@ -215,7 +215,7 @@ void GroupDialog::_group_renamed() {
return;
}
- String name = renamed_group->get_text(0).strip_edges();
+ const String name = renamed_group->get_text(0).strip_edges();
for (TreeItem *E = groups_root->get_children(); E; E = E->get_next()) {
if (E != renamed_group && E->get_text(0) == name) {
renamed_group->set_text(0, selected_group);
@@ -232,6 +232,8 @@ void GroupDialog::_group_renamed() {
return;
}
+ renamed_group->set_text(0, name); // Spaces trimmed.
+
undo_redo->create_action(TTR("Rename Group"));
List<Node *> nodes;
@@ -254,8 +256,8 @@ void GroupDialog::_group_renamed() {
undo_redo->add_undo_method(this, "_delete_group_item", selected_group);
}
- undo_redo->add_do_method(this, "_rename_group_item", selected_group, renamed_group->get_text(0));
- undo_redo->add_undo_method(this, "_rename_group_item", renamed_group->get_text(0), selected_group);
+ undo_redo->add_do_method(this, "_rename_group_item", selected_group, name);
+ undo_redo->add_undo_method(this, "_rename_group_item", name, selected_group);
undo_redo->add_do_method(this, "_group_selected");
undo_redo->add_undo_method(this, "_group_selected");
undo_redo->add_do_method(this, "emit_signal", "group_edited");
@@ -550,8 +552,8 @@ void GroupsEditor::_add_group(const String &p_group) {
if (!node)
return;
- String name = group_name->get_text();
- if (name.strip_edges() == "")
+ const String name = group_name->get_text().strip_edges();
+ if (name.empty())
return;
if (node->is_in_group(name))
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index d0bd57d658..f13abd47a9 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -1004,7 +1004,7 @@ void ScriptEditor::_menu_option(int p_option) {
ScriptEditorBase *current = _get_current_editor();
switch (p_option) {
case FILE_NEW: {
- script_create_dialog->config("Node", "new_script", false);
+ script_create_dialog->config("Node", "new_script", false, false);
script_create_dialog->popup_centered();
} break;
case FILE_NEW_TEXTFILE: {
diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp
index b64ff6119c..b24d5add9f 100644
--- a/editor/plugins/tile_set_editor_plugin.cpp
+++ b/editor/plugins/tile_set_editor_plugin.cpp
@@ -1303,12 +1303,14 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
Size2 tile_workspace_size = edited_region.position + edited_region.size + WORKSPACE_MARGIN * 2;
Size2 workspace_minsize = workspace->get_custom_minimum_size();
- if (tile_workspace_size.x > workspace_minsize.x && tile_workspace_size.y > workspace_minsize.y) {
- undo_redo->add_do_method(workspace, "set_custom_minimum_size", tile_workspace_size);
+ // If the new region is bigger, just directly change the workspace size to avoid checking all other tiles.
+ if (tile_workspace_size.x > workspace_minsize.x || tile_workspace_size.y > workspace_minsize.y) {
+ Size2 max_workspace_size = Size2(MAX(tile_workspace_size.x, workspace_minsize.x), MAX(tile_workspace_size.y, workspace_minsize.y));
+ undo_redo->add_do_method(workspace, "set_custom_minimum_size", max_workspace_size);
undo_redo->add_undo_method(workspace, "set_custom_minimum_size", workspace_minsize);
- undo_redo->add_do_method(workspace_container, "set_custom_minimum_size", tile_workspace_size);
+ undo_redo->add_do_method(workspace_container, "set_custom_minimum_size", max_workspace_size);
undo_redo->add_undo_method(workspace_container, "set_custom_minimum_size", workspace_minsize);
- undo_redo->add_do_method(workspace_overlay, "set_custom_minimum_size", tile_workspace_size);
+ undo_redo->add_do_method(workspace_overlay, "set_custom_minimum_size", max_workspace_size);
undo_redo->add_undo_method(workspace_overlay, "set_custom_minimum_size", workspace_minsize);
} else if (workspace_minsize.x > get_current_texture()->get_size().x + WORKSPACE_MARGIN.x * 2 || workspace_minsize.y > get_current_texture()->get_size().y + WORKSPACE_MARGIN.y * 2) {
undo_redo->add_do_method(this, "update_workspace_minsize");
@@ -1803,8 +1805,6 @@ void TileSetEditor::_on_tool_clicked(int p_tool) {
Ref<ConvexPolygonShape2D> _convex = memnew(ConvexPolygonShape2D);
edited_collision_shape = _convex;
_set_edited_shape_points(_get_collision_shape_points(concave));
- } else {
- // Shouldn't happen
}
for (int i = 0; i < sd.size(); i++) {
if (sd[i].get("shape") == previous_shape) {
@@ -3267,12 +3267,16 @@ void TileSetEditor::update_workspace_minsize() {
List<int> *tiles = new List<int>();
tileset->get_tile_list(tiles);
for (List<int>::Element *E = tiles->front(); E; E = E->next()) {
- if (tileset->tile_get_texture(E->get())->get_rid() == current_texture_rid) {
- Rect2i region = tileset->tile_get_region(E->get());
- if (region.position.x + region.size.x > workspace_min_size.x)
- workspace_min_size.x = region.position.x + region.size.x;
- if (region.position.y + region.size.y > workspace_min_size.y)
- workspace_min_size.y = region.position.y + region.size.y;
+ if (tileset->tile_get_texture(E->get())->get_rid() != current_texture_rid) {
+ continue;
+ }
+
+ Rect2i region = tileset->tile_get_region(E->get());
+ if (region.position.x + region.size.x > workspace_min_size.x) {
+ workspace_min_size.x = region.position.x + region.size.x;
+ }
+ if (region.position.y + region.size.y > workspace_min_size.y) {
+ workspace_min_size.y = region.position.y + region.size.y;
}
}
delete tiles;
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index 25bc13033c..35d5fe5f70 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -99,7 +99,7 @@ bool ScriptCreateDialog::_can_be_built_in() {
return (supports_built_in && built_in_enabled);
}
-void ScriptCreateDialog::config(const String &p_base_name, const String &p_base_path, bool p_built_in_enabled) {
+void ScriptCreateDialog::config(const String &p_base_name, const String &p_base_path, bool p_built_in_enabled, bool p_load_enabled) {
class_name->set_text("");
class_name->deselect();
@@ -117,6 +117,7 @@ void ScriptCreateDialog::config(const String &p_base_name, const String &p_base_
file_path->deselect();
built_in_enabled = p_built_in_enabled;
+ load_enabled = p_load_enabled;
_lang_changed(current_language);
_class_name_changed("");
@@ -623,12 +624,12 @@ void ScriptCreateDialog::_msg_path_valid(bool valid, const String &p_msg) {
void ScriptCreateDialog::_update_dialog() {
+ /* "Add Script Dialog" GUI logic and script checks. */
+
bool script_ok = true;
- /* "Add Script Dialog" gui logic and script checks */
+ // Is script path/name valid (order from top to bottom)?
- // Is Script Valid (order from top to bottom)
- get_ok()->set_disabled(true);
if (!is_built_in && !is_path_valid) {
_msg_script_valid(false, TTR("Invalid path."));
script_ok = false;
@@ -641,12 +642,12 @@ void ScriptCreateDialog::_update_dialog() {
_msg_script_valid(false, TTR("Invalid inherited parent name or path."));
script_ok = false;
}
+
if (script_ok) {
_msg_script_valid(true, TTR("Script is valid."));
- get_ok()->set_disabled(false);
}
- /* Does script have named classes */
+ // Does script have named classes?
if (has_named_classes) {
if (is_new_script_created) {
@@ -663,7 +664,7 @@ void ScriptCreateDialog::_update_dialog() {
class_name->set_text("");
}
- /* Is script Built-in */
+ // Is script Built-in?
if (is_built_in) {
file_path->set_editable(false);
@@ -683,7 +684,7 @@ void ScriptCreateDialog::_update_dialog() {
}
internal->set_disabled(!_can_be_built_in());
- /* Is Script created or loaded from existing file */
+ // Is Script created or loaded from existing file?
if (is_built_in) {
get_ok()->set_text(TTR("Create"));
@@ -692,7 +693,8 @@ void ScriptCreateDialog::_update_dialog() {
parent_browse_button->set_disabled(!can_inherit_from_file);
_msg_path_valid(true, TTR("Built-in script (into scene file)."));
} else if (is_new_script_created) {
- // New Script Created
+ // New script created.
+
get_ok()->set_text(TTR("Create"));
parent_name->set_editable(true);
parent_search_button->set_disabled(false);
@@ -700,8 +702,9 @@ void ScriptCreateDialog::_update_dialog() {
if (is_path_valid) {
_msg_path_valid(true, TTR("Will create a new script file."));
}
- } else {
- // Script Loaded
+ } else if (load_enabled) {
+ // Script loaded.
+
get_ok()->set_text(TTR("Load"));
parent_name->set_editable(false);
parent_search_button->set_disabled(true);
@@ -709,7 +712,17 @@ void ScriptCreateDialog::_update_dialog() {
if (is_path_valid) {
_msg_path_valid(true, TTR("Will load an existing script file."));
}
+ } else {
+ get_ok()->set_text(TTR("Create"));
+ parent_name->set_editable(true);
+ parent_search_button->set_disabled(false);
+ parent_browse_button->set_disabled(!can_inherit_from_file);
+ _msg_path_valid(false, TTR("Script file already exists."));
+
+ script_ok = false;
}
+
+ get_ok()->set_disabled(!script_ok);
}
void ScriptCreateDialog::_bind_methods() {
@@ -727,7 +740,7 @@ void ScriptCreateDialog::_bind_methods() {
ClassDB::bind_method("_create", &ScriptCreateDialog::_create);
ClassDB::bind_method("_browse_class_in_tree", &ScriptCreateDialog::_browse_class_in_tree);
- ClassDB::bind_method(D_METHOD("config", "inherits", "path", "built_in_enabled"), &ScriptCreateDialog::config, DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("config", "inherits", "path", "built_in_enabled", "load_enabled"), &ScriptCreateDialog::config, DEFVAL(true), DEFVAL(true));
ADD_SIGNAL(MethodInfo("script_created", PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script")));
}
@@ -884,8 +897,9 @@ ScriptCreateDialog::ScriptCreateDialog() {
has_named_classes = false;
supports_built_in = false;
can_inherit_from_file = false;
- built_in_enabled = true;
is_built_in = false;
+ built_in_enabled = true;
+ load_enabled = true;
is_new_script_created = true;
}
diff --git a/editor/script_create_dialog.h b/editor/script_create_dialog.h
index 91d6315a78..00f642fcf7 100644
--- a/editor/script_create_dialog.h
+++ b/editor/script_create_dialog.h
@@ -74,6 +74,7 @@ class ScriptCreateDialog : public ConfirmationDialog {
bool is_class_name_valid;
bool is_built_in;
bool built_in_enabled;
+ bool load_enabled;
int current_language;
int default_language;
bool re_check_path;
@@ -126,7 +127,7 @@ protected:
static void _bind_methods();
public:
- void config(const String &p_base_name, const String &p_base_path, bool p_built_in_enabled = true);
+ void config(const String &p_base_name, const String &p_base_path, bool p_built_in_enabled = true, bool p_load_enabled = true);
void set_inheritance_base_type(const String &p_base);
ScriptCreateDialog();
};
diff --git a/main/main.cpp b/main/main.cpp
index c29a5a0aa6..5cfab3dc4a 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -815,6 +815,13 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
I = N;
}
+#ifdef TOOLS_ENABLED
+ if (editor && project_manager) {
+ OS::get_singleton()->print("Error: Command line arguments implied opening both editor and project manager, which is not possible. Aborting.\n");
+ goto error;
+ }
+#endif
+
// Network file system needs to be configured before globals, since globals are based on the
// 'project.godot' file which will only be available through the network if this is enabled
FileAccessNetwork::configure();
@@ -930,7 +937,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}
}
- if (!project_manager) {
+ if (!project_manager && !editor) {
// Determine if the project manager should be requested
project_manager = main_args.size() == 0 && !found_project;
}
@@ -1028,7 +1035,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
// window compositor ("--enable-vsync-via-compositor" or
// "--disable-vsync-via-compositor") was present then it overrides the
// project setting.
- video_mode.vsync_via_compositor = GLOBAL_DEF("display/window/vsync/vsync_via_compositor", false);
+ video_mode.vsync_via_compositor = GLOBAL_DEF("display/window/vsync/vsync_via_compositor", true);
}
OS::get_singleton()->_vsync_via_compositor = video_mode.vsync_via_compositor;
@@ -1395,6 +1402,7 @@ bool Main::start() {
bool hasicon = false;
String doc_tool;
List<String> removal_docs;
+ String positional_arg;
String game_path;
String script;
String test;
@@ -1422,8 +1430,18 @@ bool Main::start() {
} else if (args[i] == "-p" || args[i] == "--project-manager") {
project_manager = true;
#endif
- } else if (args[i].length() && args[i][0] != '-' && game_path == "") {
- game_path = args[i];
+ } else if (args[i].length() && args[i][0] != '-' && positional_arg == "") {
+ positional_arg = args[i];
+
+ if (args[i].ends_with(".scn") || args[i].ends_with(".tscn") || args[i].ends_with(".escn")) {
+ // Only consider the positional argument to be a scene path if it ends with
+ // a file extension associated with Godot scenes. This makes it possible
+ // for projects to parse command-line arguments for custom CLI arguments
+ // or other file extensions without trouble. This can be used to implement
+ // "drag-and-drop onto executable" logic, which can prove helpful
+ // for non-game applications.
+ game_path = args[i];
+ }
}
//parameters that have an argument to the right
else if (i < (args.size() - 1)) {
@@ -1518,7 +1536,7 @@ bool Main::start() {
}
if (_export_preset != "") {
- if (game_path == "") {
+ if (positional_arg == "") {
String err = "Command line includes export parameter option, but no destination path was given.\n";
err += "Please specify the binary's file path to export to. Aborting export.";
ERR_PRINT(err);
@@ -1709,7 +1727,7 @@ bool Main::start() {
sml->get_root()->add_child(editor_node);
if (_export_preset != "") {
- editor_node->export_preset(_export_preset, game_path, export_debug, export_pack_only);
+ editor_node->export_preset(_export_preset, positional_arg, export_debug, export_pack_only);
game_path = ""; // Do not load anything.
}
}
diff --git a/modules/gdnative/gdnative/gdnative.cpp b/modules/gdnative/gdnative/gdnative.cpp
index 6ef1f2f4b9..06334556d9 100644
--- a/modules/gdnative/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative/gdnative.cpp
@@ -170,6 +170,10 @@ bool GDAPI godot_is_instance_valid(const godot_object *p_object) {
return ObjectDB::instance_validate((Object *)p_object);
}
+godot_object GDAPI *godot_instance_from_id(godot_int p_instance_id) {
+ return (godot_object *)ObjectDB::get_instance((ObjectID)p_instance_id);
+}
+
void *godot_get_class_tag(const godot_string_name *p_class) {
StringName class_name = *(StringName *)p_class;
ClassDB::ClassInfo *class_info = ClassDB::classes.getptr(class_name);
diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json
index 7e2ca49f8d..8ccb8d2286 100644
--- a/modules/gdnative/gdnative_api.json
+++ b/modules/gdnative/gdnative_api.json
@@ -155,6 +155,13 @@
["const godot_object *", "p_object"],
["void *", "p_class_tag"]
]
+ },
+ {
+ "name": "godot_instance_from_id",
+ "return_type": "godot_object *",
+ "arguments": [
+ ["godot_int", "p_instance_id"]
+ ]
}
]
},
diff --git a/modules/gdnative/include/gdnative/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h
index 2fe59b8a73..e19a2ec149 100644
--- a/modules/gdnative/include/gdnative/gdnative.h
+++ b/modules/gdnative/include/gdnative/gdnative.h
@@ -290,6 +290,9 @@ bool GDAPI godot_is_instance_valid(const godot_object *p_object);
void GDAPI *godot_get_class_tag(const godot_string_name *p_class);
godot_object GDAPI *godot_object_cast_to(const godot_object *p_object, void *p_class_tag);
+// equivalent of GDScript's instance_from_id
+godot_object GDAPI *godot_instance_from_id(godot_int p_instance_id);
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index 11e015b473..7b3175d9cd 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -90,11 +90,11 @@ bool GDScriptCompiler::_create_unary_operator(CodeGen &codegen, const GDScriptPa
return true;
}
-bool GDScriptCompiler::_create_binary_operator(CodeGen &codegen, const GDScriptParser::OperatorNode *on, Variant::Operator op, int p_stack_level, bool p_initializer) {
+bool GDScriptCompiler::_create_binary_operator(CodeGen &codegen, const GDScriptParser::OperatorNode *on, Variant::Operator op, int p_stack_level, bool p_initializer, int p_index_addr) {
ERR_FAIL_COND_V(on->arguments.size() != 2, false);
- int src_address_a = _parse_expression(codegen, on->arguments[0], p_stack_level, false, p_initializer);
+ int src_address_a = _parse_expression(codegen, on->arguments[0], p_stack_level, false, p_initializer, p_index_addr);
if (src_address_a < 0)
return false;
if (src_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS)
@@ -171,7 +171,7 @@ GDScriptDataType GDScriptCompiler::_gdtype_from_datatype(const GDScriptParser::D
return result;
}
-int GDScriptCompiler::_parse_assign_right_expression(CodeGen &codegen, const GDScriptParser::OperatorNode *p_expression, int p_stack_level) {
+int GDScriptCompiler::_parse_assign_right_expression(CodeGen &codegen, const GDScriptParser::OperatorNode *p_expression, int p_stack_level, int p_index_addr) {
Variant::Operator var_op = Variant::OP_MAX;
@@ -205,7 +205,7 @@ int GDScriptCompiler::_parse_assign_right_expression(CodeGen &codegen, const GDS
return _parse_expression(codegen, p_expression->arguments[1], p_stack_level, false, initializer);
}
- if (!_create_binary_operator(codegen, p_expression, var_op, p_stack_level, initializer))
+ if (!_create_binary_operator(codegen, p_expression, var_op, p_stack_level, initializer, p_index_addr))
return -1;
int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
@@ -214,7 +214,7 @@ int GDScriptCompiler::_parse_assign_right_expression(CodeGen &codegen, const GDS
return dst_addr;
}
-int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::Node *p_expression, int p_stack_level, bool p_root, bool p_initializer) {
+int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::Node *p_expression, int p_stack_level, bool p_root, bool p_initializer, int p_index_addr) {
switch (p_expression->type) {
//should parse variable declaration and adjust stack accordingly...
@@ -704,7 +704,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
return from;
int index;
- if (named) {
+ if (p_index_addr != 0) {
+ index = p_index_addr;
+ } else if (named) {
if (on->arguments[0]->type == GDScriptParser::Node::TYPE_SELF && codegen.script && codegen.function_node && !codegen.function_node->_static) {
GDScriptParser::IdentifierNode *identifier = static_cast<GDScriptParser::IdentifierNode *>(on->arguments[1]);
@@ -1091,7 +1093,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
codegen.alloc_stack(slevel);
}
- int set_value = _parse_assign_right_expression(codegen, on, slevel + 1);
+ int set_value = _parse_assign_right_expression(codegen, on, slevel + 1, named ? 0 : set_index);
if (set_value < 0) //error
return set_value;
diff --git a/modules/gdscript/gdscript_compiler.h b/modules/gdscript/gdscript_compiler.h
index bb3ee881f8..7d5234a023 100644
--- a/modules/gdscript/gdscript_compiler.h
+++ b/modules/gdscript/gdscript_compiler.h
@@ -140,12 +140,12 @@ class GDScriptCompiler {
void _set_error(const String &p_error, const GDScriptParser::Node *p_node);
bool _create_unary_operator(CodeGen &codegen, const GDScriptParser::OperatorNode *on, Variant::Operator op, int p_stack_level);
- bool _create_binary_operator(CodeGen &codegen, const GDScriptParser::OperatorNode *on, Variant::Operator op, int p_stack_level, bool p_initializer = false);
+ bool _create_binary_operator(CodeGen &codegen, const GDScriptParser::OperatorNode *on, Variant::Operator op, int p_stack_level, bool p_initializer = false, int p_index_addr = 0);
GDScriptDataType _gdtype_from_datatype(const GDScriptParser::DataType &p_datatype) const;
- int _parse_assign_right_expression(CodeGen &codegen, const GDScriptParser::OperatorNode *p_expression, int p_stack_level);
- int _parse_expression(CodeGen &codegen, const GDScriptParser::Node *p_expression, int p_stack_level, bool p_root = false, bool p_initializer = false);
+ int _parse_assign_right_expression(CodeGen &codegen, const GDScriptParser::OperatorNode *p_expression, int p_stack_level, int p_index_addr = 0);
+ int _parse_expression(CodeGen &codegen, const GDScriptParser::Node *p_expression, int p_stack_level, bool p_root = false, bool p_initializer = false, int p_index_addr = 0);
Error _parse_block(CodeGen &codegen, const GDScriptParser::BlockNode *p_block, int p_stack_level = 0, int p_break_addr = -1, int p_continue_addr = -1);
Error _parse_function(GDScript *p_script, const GDScriptParser::ClassNode *p_class, const GDScriptParser::FunctionNode *p_func, bool p_for_ready = false);
Error _parse_class_level(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state);
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index a01a7397fe..eef39da8b5 100644
--- a/modules/gdscript/gdscript_function.cpp
+++ b/modules/gdscript/gdscript_function.cpp
@@ -500,6 +500,13 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
Object *obj_A = *a;
Object *obj_B = *b;
+#ifdef DEBUG_ENABLED
+ if (!ObjectDB::instance_validate(obj_A)) {
+ err_text = "Left operand of 'is' was already freed.";
+ OPCODE_BREAK;
+ }
+#endif // DEBUG_ENABLED
+
GDScript *scr_B = Object::cast_to<GDScript>(obj_B);
if (scr_B) {
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index a33d20e433..4350a8042a 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -7867,12 +7867,12 @@ void GDScriptParser::_check_function_types(FunctionNode *p_function) {
def_type.is_constant = false;
p_function->argument_types.write[i] = def_type;
} else {
- p_function->return_type = _resolve_type(p_function->return_type, p_function->line);
+ p_function->argument_types.write[i] = _resolve_type(p_function->argument_types[i], p_function->line);
if (!_is_type_compatible(p_function->argument_types[i], def_type, true)) {
String arg_name = p_function->arguments[i];
_set_error("Value type (" + def_type.to_string() + ") doesn't match the type of argument '" +
- arg_name + "' (" + p_function->arguments[i] + ").",
+ arg_name + "' (" + p_function->argument_types[i].to_string() + ").",
p_function->line);
}
}
diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp
index 33ca4a5d15..0572c5f746 100644
--- a/modules/gdscript/language_server/gdscript_text_document.cpp
+++ b/modules/gdscript/language_server/gdscript_text_document.cpp
@@ -269,7 +269,7 @@ Dictionary GDScriptTextDocument::resolve(const Dictionary &p_params) {
if ((item.kind == lsp::CompletionItemKind::Method || item.kind == lsp::CompletionItemKind::Function) && !item.label.ends_with("):")) {
item.insertText = item.label + "(";
- if (symbol && symbol->detail.find(",") == -1) {
+ if (symbol && symbol->children.empty()) {
item.insertText += ")";
}
} else if (item.kind == lsp::CompletionItemKind::Event) {
diff --git a/modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml b/modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml
index 9403199398..102a9b4236 100644
--- a/modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml
+++ b/modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml
@@ -15,8 +15,10 @@
Contains the audio data in bytes.
</member>
<member name="loop" type="bool" setter="set_loop" getter="has_loop" default="false">
+ If [code]true[/code], the stream will automatically loop when it reaches the end.
</member>
<member name="loop_offset" type="float" setter="set_loop_offset" getter="get_loop_offset" default="0.0">
+ Time in seconds at which the stream starts after being looped.
</member>
</members>
<constants>
diff --git a/platform/android/dir_access_jandroid.cpp b/platform/android/dir_access_jandroid.cpp
index 69178317f7..f52b511522 100644
--- a/platform/android/dir_access_jandroid.cpp
+++ b/platform/android/dir_access_jandroid.cpp
@@ -110,7 +110,6 @@ String DirAccessJAndroid::get_drive(int p_drive) {
Error DirAccessJAndroid::change_dir(String p_dir) {
JNIEnv *env = ThreadAndroid::get_env();
- p_dir = p_dir.simplify_path();
if (p_dir == "" || p_dir == "." || (p_dir == ".." && current_dir == ""))
return OK;
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index d7a72779e6..b4b38ac450 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -883,10 +883,10 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
ns_android_string = string_table.size() - 1;
}
- int32_t attr_uses_permission_string = string_table.find("uses-feature");
- if (attr_uses_permission_string == -1) {
+ int32_t attr_uses_feature_string = string_table.find("uses-feature");
+ if (attr_uses_feature_string == -1) {
string_table.push_back("uses-feature");
- attr_uses_permission_string = string_table.size() - 1;
+ attr_uses_feature_string = string_table.size() - 1;
}
int32_t attr_required_string = string_table.find("required");
@@ -928,7 +928,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
{
- manifest_cur_size += 96 + 20; // node and three attrs + end node
+ manifest_cur_size += 96 + 24; // node and three attrs + end node
p_manifest.resize(manifest_cur_size);
// start tag
@@ -938,7 +938,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
encode_uint32(0, &p_manifest.write[ofs + 8]); // lineno
encode_uint32(-1, &p_manifest.write[ofs + 12]); // comment
encode_uint32(-1, &p_manifest.write[ofs + 16]); // ns
- encode_uint32(attr_uses_permission_string, &p_manifest.write[ofs + 20]); // name
+ encode_uint32(attr_uses_feature_string, &p_manifest.write[ofs + 20]); // name
encode_uint16(20, &p_manifest.write[ofs + 24]); // attr_start
encode_uint16(20, &p_manifest.write[ofs + 26]); // attr_size
encode_uint16(3, &p_manifest.write[ofs + 28]); // num_attrs
@@ -982,7 +982,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
encode_uint32(0, &p_manifest.write[ofs + 8]); // lineno
encode_uint32(-1, &p_manifest.write[ofs + 12]); // comment
encode_uint32(-1, &p_manifest.write[ofs + 16]); // ns
- encode_uint32(attr_uses_permission_string, &p_manifest.write[ofs + 20]); // name
+ encode_uint32(attr_uses_feature_string, &p_manifest.write[ofs + 20]); // name
ofs += 24;
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
index 8447af10e4..0ff37e3c37 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
@@ -100,6 +100,16 @@ public class GodotLib {
public static native void hover(int type, int x, int y);
/**
+ * Forward double_tap events from the main thread to the GL thread.
+ */
+ public static native void double_tap(int x, int y);
+
+ /**
+ * Forward scroll events from the main thread to the GL thread.
+ */
+ public static native void scroll(int x, int y);
+
+ /**
* Forward accelerometer sensor events from the main thread to the GL thread.
* @see android.hardware.SensorEventListener#onSensorChanged(SensorEvent)
*/
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotView.java
index 78f3763d84..f938583082 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotView.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotView.java
@@ -32,8 +32,10 @@ package org.godotengine.godot;
import android.annotation.SuppressLint;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView;
+import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.MotionEvent;
+import org.godotengine.godot.input.GodotGestureHandler;
import org.godotengine.godot.input.GodotInputHandler;
import org.godotengine.godot.utils.GLUtils;
import org.godotengine.godot.xr.XRMode;
@@ -68,6 +70,7 @@ public class GodotView extends GLSurfaceView {
private final Godot activity;
private final GodotInputHandler inputHandler;
+ private final GestureDetector detector;
private final GodotRenderer godotRenderer;
public GodotView(Godot activity, XRMode xrMode, boolean p_use_gl3, boolean p_use_32_bits, boolean p_use_debug_opengl) {
@@ -78,6 +81,7 @@ public class GodotView extends GLSurfaceView {
this.activity = activity;
this.inputHandler = new GodotInputHandler(this);
+ this.detector = new GestureDetector(activity, new GodotGestureHandler(this));
this.godotRenderer = new GodotRenderer();
init(xrMode, false, 16, 0);
}
@@ -90,6 +94,7 @@ public class GodotView extends GLSurfaceView {
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
+ this.detector.onTouchEvent(event);
return activity.gotTouchEvent(event);
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
new file mode 100644
index 0000000000..b42b13894c
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
@@ -0,0 +1,106 @@
+/*************************************************************************/
+/* GodotGestureHandler.java */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+package org.godotengine.godot.input;
+
+import android.util.Log;
+import android.view.GestureDetector;
+import android.view.MotionEvent;
+import org.godotengine.godot.GodotLib;
+import org.godotengine.godot.GodotView;
+
+/**
+ * Handles gesture input related events for the {@link GodotView} view.
+ * https://developer.android.com/reference/android/view/GestureDetector.SimpleOnGestureListener
+ */
+public class GodotGestureHandler extends GestureDetector.SimpleOnGestureListener {
+
+ private final GodotView godotView;
+
+ public GodotGestureHandler(GodotView godotView) {
+ this.godotView = godotView;
+ }
+
+ private void queueEvent(Runnable task) {
+ godotView.queueEvent(task);
+ }
+
+ @Override
+ public boolean onDown(MotionEvent event) {
+ super.onDown(event);
+ //Log.i("GodotGesture", "onDown");
+ return true;
+ }
+
+ @Override
+ public boolean onSingleTapConfirmed(MotionEvent event) {
+ super.onSingleTapConfirmed(event);
+ return true;
+ }
+
+ @Override
+ public void onLongPress(MotionEvent event) {
+ //Log.i("GodotGesture", "onLongPress");
+ }
+
+ @Override
+ public boolean onDoubleTap(MotionEvent event) {
+ //Log.i("GodotGesture", "onDoubleTap");
+ final int x = Math.round(event.getX());
+ final int y = Math.round(event.getY());
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.double_tap(x, y);
+ }
+ });
+ return true;
+ }
+
+ @Override
+ public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
+ //Log.i("GodotGesture", "onScroll");
+ final int x = Math.round(distanceX);
+ final int y = Math.round(distanceY);
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.scroll(x, y);
+ }
+ });
+ return true;
+ }
+
+ @Override
+ public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) {
+ //Log.i("GodotGesture", "onFling");
+ return true;
+ }
+}
diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp
index 0a32f4423b..d3bc216608 100644
--- a/platform/android/java_godot_lib_jni.cpp
+++ b/platform/android/java_godot_lib_jni.cpp
@@ -835,6 +835,20 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jo
os_android->process_hover(p_type, Point2(p_x, p_y));
}
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_double_tap(JNIEnv *env, jobject obj, jint p_x, jint p_y) {
+ if (step == 0)
+ return;
+
+ os_android->process_double_tap(Point2(p_x, p_y));
+}
+
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_scroll(JNIEnv *env, jobject obj, jint p_x, jint p_y) {
+ if (step == 0)
+ return;
+
+ os_android->process_scroll(Point2(p_x, p_y));
+}
+
/*
* Android Key codes.
*/
diff --git a/platform/android/java_godot_lib_jni.h b/platform/android/java_godot_lib_jni.h
index 8c18c52d2b..08029c3c30 100644
--- a/platform/android/java_godot_lib_jni.h
+++ b/platform/android/java_godot_lib_jni.h
@@ -46,6 +46,8 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, jobject obj);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jobject obj, jint ev, jint pointer, jint count, jintArray positions);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jobject obj, jint p_type, jint p_x, jint p_y);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_double_tap(JNIEnv *env, jobject obj, jint p_x, jint p_y);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_scroll(JNIEnv *env, jobject obj, jint p_x, jint p_y);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jobject obj, jint p_scancode, jint p_unicode_char, jboolean p_pressed);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jobject obj, jint p_device, jint p_button, jboolean p_pressed);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jobject obj, jint p_device, jint p_axis, jfloat p_value);
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 4c560273e8..bbea5e3699 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -502,6 +502,26 @@ void OS_Android::process_hover(int p_type, Point2 p_pos) {
}
}
+void OS_Android::process_double_tap(Point2 p_pos) {
+ Ref<InputEventMouseButton> ev;
+ ev.instance();
+ ev->set_position(p_pos);
+ ev->set_global_position(p_pos);
+ ev->set_pressed(true);
+ ev->set_doubleclick(true);
+ ev->set_button_index(1);
+ input->parse_input_event(ev);
+}
+
+void OS_Android::process_scroll(Point2 p_pos) {
+ Ref<InputEventPanGesture> ev;
+ ev.instance();
+ ev->set_position(p_pos);
+ ev->set_delta(p_pos - scroll_prev_pos);
+ input->parse_input_event(ev);
+ scroll_prev_pos = p_pos;
+}
+
void OS_Android::process_accelerometer(const Vector3 &p_accelerometer) {
input->set_accelerometer(p_accelerometer);
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index 5ac50ddef2..1cf64a2e84 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -70,6 +70,7 @@ public:
private:
Vector<TouchPos> touch;
Point2 hover_prev_pos; // needed to calculate the relative position on hover events
+ Point2 scroll_prev_pos; // needed to calculate the relative position on scroll events
bool use_gl2;
bool use_apk_expansion;
@@ -187,6 +188,8 @@ public:
void process_gyroscope(const Vector3 &p_gyroscope);
void process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points);
void process_hover(int p_type, Point2 p_pos);
+ void process_double_tap(Point2 p_pos);
+ void process_scroll(Point2 p_pos);
void process_joy_event(JoypadEvent p_event);
void process_event(Ref<InputEvent> p_event);
void init_video_mode(int p_video_width, int p_video_height);
diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp
index ce7b47c414..1cb72943fc 100644
--- a/platform/osx/export/export.cpp
+++ b/platform/osx/export/export.cpp
@@ -509,12 +509,13 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
io2.opaque = &dst_f;
zipFile dst_pkg_zip = NULL;
+ DirAccess *tmp_app_path = NULL;
String export_format = use_dmg() && p_path.ends_with("dmg") ? "dmg" : "zip";
if (export_format == "dmg") {
// We're on OSX so we can export to DMG, but first we create our application bundle
tmp_app_path_name = EditorSettings::get_singleton()->get_cache_dir().plus_file(pkg_name + ".app");
print_line("Exporting to " + tmp_app_path_name);
- DirAccess *tmp_app_path = DirAccess::create_for_path(tmp_app_path_name);
+ tmp_app_path = DirAccess::create_for_path(tmp_app_path_name);
if (!tmp_app_path) {
err = ERR_CANT_CREATE;
}
@@ -617,19 +618,23 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
if (export_format == "dmg") {
// write it into our application bundle
file = tmp_app_path_name.plus_file(file);
-
- // write the file, need to add chmod
- FileAccess *f = FileAccess::open(file, FileAccess::WRITE);
- if (f) {
- f->store_buffer(data.ptr(), data.size());
- f->close();
- if (is_execute) {
- // Chmod with 0755 if the file is executable
- FileAccess::set_unix_permissions(file, 0755);
+ if (err == OK) {
+ err = tmp_app_path->make_dir_recursive(file.get_base_dir());
+ }
+ if (err == OK) {
+ // write the file, need to add chmod
+ FileAccess *f = FileAccess::open(file, FileAccess::WRITE);
+ if (f) {
+ f->store_buffer(data.ptr(), data.size());
+ f->close();
+ if (is_execute) {
+ // Chmod with 0755 if the file is executable
+ FileAccess::set_unix_permissions(file, 0755);
+ }
+ memdelete(f);
+ } else {
+ err = ERR_CANT_CREATE;
}
- memdelete(f);
- } else {
- err = ERR_CANT_CREATE;
}
} else {
// add it to our zip file
diff --git a/platform/x11/crash_handler_x11.cpp b/platform/x11/crash_handler_x11.cpp
index 3a91c62546..19c8f71d0e 100644
--- a/platform/x11/crash_handler_x11.cpp
+++ b/platform/x11/crash_handler_x11.cpp
@@ -107,7 +107,7 @@ static void handle_crash(int sig) {
output.erase(output.length() - 1, 1);
}
- fprintf(stderr, "[%ld] %s (%ls)\n", i, fname, output.c_str());
+ fprintf(stderr, "[%ld] %s (%ls)\n", (long int)i, fname, output.c_str());
}
free(strings);
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp
index 28a8c4d658..917ced5feb 100644
--- a/scene/2d/animated_sprite.cpp
+++ b/scene/2d/animated_sprite.cpp
@@ -35,6 +35,7 @@
#define NORMAL_SUFFIX "_normal"
+#ifdef TOOLS_ENABLED
Dictionary AnimatedSprite::_edit_get_state() const {
Dictionary state = Node2D::_edit_get_state();
state["offset"] = offset;
@@ -72,6 +73,7 @@ bool AnimatedSprite::_edit_use_rect() const {
t = frames->get_frame(animation, frame);
return t.is_valid();
}
+#endif
Rect2 AnimatedSprite::get_anchorable_rect() const {
return _get_rect();
diff --git a/scene/2d/animated_sprite.h b/scene/2d/animated_sprite.h
index 2017c62a48..cd00a4e181 100644
--- a/scene/2d/animated_sprite.h
+++ b/scene/2d/animated_sprite.h
@@ -156,6 +156,7 @@ protected:
virtual void _validate_property(PropertyInfo &property) const;
public:
+#ifdef TOOLS_ENABLED
virtual Dictionary _edit_get_state() const;
virtual void _edit_set_state(const Dictionary &p_state);
@@ -164,6 +165,7 @@ public:
virtual bool _edit_use_pivot() const;
virtual Rect2 _edit_get_rect() const;
virtual bool _edit_use_rect() const;
+#endif
virtual Rect2 get_anchorable_rect() const;
diff --git a/scene/2d/back_buffer_copy.cpp b/scene/2d/back_buffer_copy.cpp
index 1a6f30e0fd..faeb6b7169 100644
--- a/scene/2d/back_buffer_copy.cpp
+++ b/scene/2d/back_buffer_copy.cpp
@@ -50,6 +50,7 @@ void BackBufferCopy::_update_copy_mode() {
}
}
+#ifdef TOOLS_ENABLED
Rect2 BackBufferCopy::_edit_get_rect() const {
return rect;
@@ -58,6 +59,7 @@ Rect2 BackBufferCopy::_edit_get_rect() const {
bool BackBufferCopy::_edit_use_rect() const {
return true;
}
+#endif
Rect2 BackBufferCopy::get_anchorable_rect() const {
diff --git a/scene/2d/back_buffer_copy.h b/scene/2d/back_buffer_copy.h
index 91acd81e00..4b26bf1bdc 100644
--- a/scene/2d/back_buffer_copy.h
+++ b/scene/2d/back_buffer_copy.h
@@ -53,8 +53,10 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
Rect2 _edit_get_rect() const;
virtual bool _edit_use_rect() const;
+#endif
void set_rect(const Rect2 &p_rect);
Rect2 get_rect() const;
diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp
index 9895dba027..5631aa3355 100644
--- a/scene/2d/canvas_item.cpp
+++ b/scene/2d/canvas_item.cpp
@@ -351,7 +351,7 @@ CanvasItemMaterial::~CanvasItemMaterial() {
}
///////////////////////////////////////////////////////////////////
-
+#ifdef TOOLS_ENABLED
bool CanvasItem::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
if (_edit_use_rect()) {
return _edit_get_rect().has_point(p_point);
@@ -363,6 +363,7 @@ bool CanvasItem::_edit_is_selected_on_click(const Point2 &p_point, double p_tole
Transform2D CanvasItem::_edit_get_transform() const {
return Transform2D(_edit_get_rotation(), _edit_get_position() + _edit_get_pivot());
}
+#endif
bool CanvasItem::is_visible_in_tree() const {
@@ -1121,9 +1122,10 @@ void CanvasItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("_toplevel_raise_self"), &CanvasItem::_toplevel_raise_self);
ClassDB::bind_method(D_METHOD("_update_callback"), &CanvasItem::_update_callback);
+
+#ifdef TOOLS_ENABLED
ClassDB::bind_method(D_METHOD("_edit_set_state", "state"), &CanvasItem::_edit_set_state);
ClassDB::bind_method(D_METHOD("_edit_get_state"), &CanvasItem::_edit_get_state);
-
ClassDB::bind_method(D_METHOD("_edit_set_position", "position"), &CanvasItem::_edit_set_position);
ClassDB::bind_method(D_METHOD("_edit_get_position"), &CanvasItem::_edit_get_position);
ClassDB::bind_method(D_METHOD("_edit_set_scale", "scale"), &CanvasItem::_edit_set_scale);
@@ -1138,6 +1140,7 @@ void CanvasItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("_edit_get_pivot"), &CanvasItem::_edit_get_pivot);
ClassDB::bind_method(D_METHOD("_edit_use_pivot"), &CanvasItem::_edit_use_pivot);
ClassDB::bind_method(D_METHOD("_edit_get_transform"), &CanvasItem::_edit_get_transform);
+#endif
ClassDB::bind_method(D_METHOD("get_canvas_item"), &CanvasItem::get_canvas_item);
diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h
index 82645051e8..8814d99edd 100644
--- a/scene/2d/canvas_item.h
+++ b/scene/2d/canvas_item.h
@@ -249,7 +249,7 @@ public:
};
/* EDITOR */
-
+#ifdef TOOLS_ENABLED
// Select the node
virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
@@ -282,6 +282,7 @@ public:
virtual Point2 _edit_get_pivot() const { return Point2(); };
virtual Transform2D _edit_get_transform() const;
+#endif
/* VISIBILITY */
diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp
index 3090c9956e..d9cc94c6eb 100644
--- a/scene/2d/collision_polygon_2d.cpp
+++ b/scene/2d/collision_polygon_2d.cpp
@@ -227,6 +227,7 @@ CollisionPolygon2D::BuildMode CollisionPolygon2D::get_build_mode() const {
return build_mode;
}
+#ifdef TOOLS_ENABLED
Rect2 CollisionPolygon2D::_edit_get_rect() const {
return aabb;
@@ -240,6 +241,7 @@ bool CollisionPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, doubl
return Geometry::is_point_in_polygon(p_point, Variant(polygon));
}
+#endif
String CollisionPolygon2D::get_configuration_warning() const {
diff --git a/scene/2d/collision_polygon_2d.h b/scene/2d/collision_polygon_2d.h
index e5e18b2674..d8dfec8fd2 100644
--- a/scene/2d/collision_polygon_2d.h
+++ b/scene/2d/collision_polygon_2d.h
@@ -67,16 +67,18 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
+ virtual Rect2 _edit_get_rect() const;
+ virtual bool _edit_use_rect() const;
+ virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+#endif
+
void set_build_mode(BuildMode p_mode);
BuildMode get_build_mode() const;
void set_polygon(const Vector<Point2> &p_polygon);
Vector<Point2> get_polygon() const;
- virtual Rect2 _edit_get_rect() const;
- virtual bool _edit_use_rect() const;
- virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
-
virtual String get_configuration_warning() const;
void set_disabled(bool p_disabled);
diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp
index 1843cbed67..eb66265010 100644
--- a/scene/2d/light_2d.cpp
+++ b/scene/2d/light_2d.cpp
@@ -33,6 +33,7 @@
#include "core/engine.h"
#include "servers/visual_server.h"
+#ifdef TOOLS_ENABLED
Dictionary Light2D::_edit_get_state() const {
Dictionary state = Node2D::_edit_get_state();
state["offset"] = get_texture_offset();
@@ -68,6 +69,7 @@ Rect2 Light2D::_edit_get_rect() const {
bool Light2D::_edit_use_rect() const {
return !texture.is_null();
}
+#endif
Rect2 Light2D::get_anchorable_rect() const {
if (texture.is_null())
diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h
index f8476e8389..65db5c6ee6 100644
--- a/scene/2d/light_2d.h
+++ b/scene/2d/light_2d.h
@@ -85,6 +85,7 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
virtual Dictionary _edit_get_state() const;
virtual void _edit_set_state(const Dictionary &p_state);
@@ -93,6 +94,7 @@ public:
virtual bool _edit_use_pivot() const;
virtual Rect2 _edit_get_rect() const;
virtual bool _edit_use_rect() const;
+#endif
virtual Rect2 get_anchorable_rect() const;
diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp
index 6a930683d1..0e8e8f6679 100644
--- a/scene/2d/light_occluder_2d.cpp
+++ b/scene/2d/light_occluder_2d.cpp
@@ -33,6 +33,8 @@
#include "core/engine.h"
#define LINE_GRAB_WIDTH 8
+
+#ifdef TOOLS_ENABLED
Rect2 OccluderPolygon2D::_edit_get_rect() const {
if (rect_cache_dirty) {
@@ -80,6 +82,7 @@ bool OccluderPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, double
return false;
}
}
+#endif
void OccluderPolygon2D::set_polygon(const PoolVector<Vector2> &p_polygon) {
@@ -215,6 +218,7 @@ void LightOccluder2D::_notification(int p_what) {
}
}
+#ifdef TOOLS_ENABLED
Rect2 LightOccluder2D::_edit_get_rect() const {
return occluder_polygon.is_valid() ? occluder_polygon->_edit_get_rect() : Rect2();
@@ -224,6 +228,7 @@ bool LightOccluder2D::_edit_is_selected_on_click(const Point2 &p_point, double p
return occluder_polygon.is_valid() ? occluder_polygon->_edit_is_selected_on_click(p_point, p_tolerance) : false;
}
+#endif
void LightOccluder2D::set_occluder_polygon(const Ref<OccluderPolygon2D> &p_polygon) {
diff --git a/scene/2d/light_occluder_2d.h b/scene/2d/light_occluder_2d.h
index 32d527093d..b20e347c35 100644
--- a/scene/2d/light_occluder_2d.h
+++ b/scene/2d/light_occluder_2d.h
@@ -57,8 +57,10 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
virtual Rect2 _edit_get_rect() const;
virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+#endif
void set_polygon(const PoolVector<Vector2> &p_polygon);
PoolVector<Vector2> get_polygon() const;
@@ -91,8 +93,10 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
virtual Rect2 _edit_get_rect() const;
virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+#endif
void set_occluder_polygon(const Ref<OccluderPolygon2D> &p_polygon);
Ref<OccluderPolygon2D> get_occluder_polygon() const;
diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp
index 4a022f0a9c..c31840c8e1 100644
--- a/scene/2d/line_2d.cpp
+++ b/scene/2d/line_2d.cpp
@@ -50,6 +50,7 @@ Line2D::Line2D() {
_antialiased = false;
}
+#ifdef TOOLS_ENABLED
Rect2 Line2D::_edit_get_rect() const {
if (_points.size() == 0)
@@ -79,6 +80,7 @@ bool Line2D::_edit_is_selected_on_click(const Point2 &p_point, double p_toleranc
return false;
}
+#endif
void Line2D::set_points(const PoolVector<Vector2> &p_points) {
_points = p_points;
diff --git a/scene/2d/line_2d.h b/scene/2d/line_2d.h
index bc2deba8c6..3c7239f67c 100644
--- a/scene/2d/line_2d.h
+++ b/scene/2d/line_2d.h
@@ -56,11 +56,13 @@ public:
LINE_TEXTURE_STRETCH
};
- Line2D();
-
+#ifdef TOOLS_ENABLED
virtual Rect2 _edit_get_rect() const;
virtual bool _edit_use_rect() const;
virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+#endif
+
+ Line2D();
void set_points(const PoolVector<Vector2> &p_points);
PoolVector<Vector2> get_points() const;
diff --git a/scene/2d/mesh_instance_2d.cpp b/scene/2d/mesh_instance_2d.cpp
index 8f9c4e2a4d..93432ec40b 100644
--- a/scene/2d/mesh_instance_2d.cpp
+++ b/scene/2d/mesh_instance_2d.cpp
@@ -94,6 +94,7 @@ Ref<Texture> MeshInstance2D::get_texture() const {
return texture;
}
+#ifdef TOOLS_ENABLED
Rect2 MeshInstance2D::_edit_get_rect() const {
if (mesh.is_valid()) {
@@ -103,6 +104,7 @@ Rect2 MeshInstance2D::_edit_get_rect() const {
return Node2D::_edit_get_rect();
}
+#endif
MeshInstance2D::MeshInstance2D() {
}
diff --git a/scene/2d/mesh_instance_2d.h b/scene/2d/mesh_instance_2d.h
index e7f8b7c0c3..51f75a3ead 100644
--- a/scene/2d/mesh_instance_2d.h
+++ b/scene/2d/mesh_instance_2d.h
@@ -46,6 +46,10 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
+ virtual Rect2 _edit_get_rect() const;
+#endif
+
void set_mesh(const Ref<Mesh> &p_mesh);
Ref<Mesh> get_mesh() const;
@@ -55,8 +59,6 @@ public:
void set_normal_map(const Ref<Texture> &p_texture);
Ref<Texture> get_normal_map() const;
- virtual Rect2 _edit_get_rect() const;
-
MeshInstance2D();
};
diff --git a/scene/2d/multimesh_instance_2d.cpp b/scene/2d/multimesh_instance_2d.cpp
index 69d687229b..028459e778 100644
--- a/scene/2d/multimesh_instance_2d.cpp
+++ b/scene/2d/multimesh_instance_2d.cpp
@@ -94,6 +94,7 @@ Ref<Texture> MultiMeshInstance2D::get_normal_map() const {
return normal_map;
}
+#ifdef TOOLS_ENABLED
Rect2 MultiMeshInstance2D::_edit_get_rect() const {
if (multimesh.is_valid()) {
@@ -103,6 +104,7 @@ Rect2 MultiMeshInstance2D::_edit_get_rect() const {
return Node2D::_edit_get_rect();
}
+#endif
MultiMeshInstance2D::MultiMeshInstance2D() {
}
diff --git a/scene/2d/multimesh_instance_2d.h b/scene/2d/multimesh_instance_2d.h
index 253f4c77ca..c3f3e52920 100644
--- a/scene/2d/multimesh_instance_2d.h
+++ b/scene/2d/multimesh_instance_2d.h
@@ -47,6 +47,10 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
+ virtual Rect2 _edit_get_rect() const;
+#endif
+
void set_multimesh(const Ref<MultiMesh> &p_multimesh);
Ref<MultiMesh> get_multimesh() const;
@@ -56,8 +60,6 @@ public:
void set_normal_map(const Ref<Texture> &p_texture);
Ref<Texture> get_normal_map() const;
- virtual Rect2 _edit_get_rect() const;
-
MultiMeshInstance2D();
~MultiMeshInstance2D();
};
diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp
index bd930bdda5..ea79f89dd9 100644
--- a/scene/2d/navigation_polygon.cpp
+++ b/scene/2d/navigation_polygon.cpp
@@ -36,6 +36,7 @@
#include "thirdparty/misc/triangulator.h"
+#ifdef TOOLS_ENABLED
Rect2 NavigationPolygon::_edit_get_rect() const {
if (rect_cache_dirty) {
@@ -75,6 +76,7 @@ bool NavigationPolygon::_edit_is_selected_on_click(const Point2 &p_point, double
}
return false;
}
+#endif
void NavigationPolygon::set_vertices(const PoolVector<Vector2> &p_vertices) {
@@ -357,7 +359,7 @@ bool NavigationPolygonInstance::is_enabled() const {
}
/////////////////////////////
-
+#ifdef TOOLS_ENABLED
Rect2 NavigationPolygonInstance::_edit_get_rect() const {
return navpoly.is_valid() ? navpoly->_edit_get_rect() : Rect2();
@@ -367,6 +369,7 @@ bool NavigationPolygonInstance::_edit_is_selected_on_click(const Point2 &p_point
return navpoly.is_valid() ? navpoly->_edit_is_selected_on_click(p_point, p_tolerance) : false;
}
+#endif
void NavigationPolygonInstance::_notification(int p_what) {
diff --git a/scene/2d/navigation_polygon.h b/scene/2d/navigation_polygon.h
index 9bbaa864f4..cbc1711a32 100644
--- a/scene/2d/navigation_polygon.h
+++ b/scene/2d/navigation_polygon.h
@@ -57,8 +57,10 @@ protected:
Array _get_outlines() const;
public:
+#ifdef TOOLS_ENABLED
Rect2 _edit_get_rect() const;
bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+#endif
void set_vertices(const PoolVector<Vector2> &p_vertices);
PoolVector<Vector2> get_vertices() const;
@@ -100,8 +102,10 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
virtual Rect2 _edit_get_rect() const;
virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+#endif
void set_enabled(bool p_enabled);
bool is_enabled() const;
diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp
index ad04dc8d9e..7bbc7577ed 100644
--- a/scene/2d/node_2d.cpp
+++ b/scene/2d/node_2d.cpp
@@ -35,6 +35,7 @@
#include "scene/main/viewport.h"
#include "servers/visual_server.h"
+#ifdef TOOLS_ENABLED
Dictionary Node2D::_edit_get_state() const {
Dictionary state;
@@ -44,6 +45,7 @@ Dictionary Node2D::_edit_get_state() const {
return state;
}
+
void Node2D::_edit_set_state(const Dictionary &p_state) {
pos = p_state["position"];
@@ -119,6 +121,7 @@ void Node2D::_edit_set_rect(const Rect2 &p_edit_rect) {
_change_notify("scale");
_change_notify("position");
}
+#endif
void Node2D::_update_xform_values() {
diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h
index a03ccc5a80..00202481a6 100644
--- a/scene/2d/node_2d.h
+++ b/scene/2d/node_2d.h
@@ -55,6 +55,7 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
virtual Dictionary _edit_get_state() const;
virtual void _edit_set_state(const Dictionary &p_state);
@@ -69,6 +70,7 @@ public:
virtual bool _edit_use_rotation() const;
virtual void _edit_set_rect(const Rect2 &p_edit_rect);
+#endif
void set_position(const Point2 &p_pos);
void set_rotation(float p_radians);
diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp
index e6ae95af89..e9296b0fe7 100644
--- a/scene/2d/path_2d.cpp
+++ b/scene/2d/path_2d.cpp
@@ -37,6 +37,7 @@
#include "editor/editor_scale.h"
#endif
+#ifdef TOOLS_ENABLED
Rect2 Path2D::_edit_get_rect() const {
if (!curve.is_valid() || curve->get_point_count() == 0)
@@ -85,6 +86,7 @@ bool Path2D::_edit_is_selected_on_click(const Point2 &p_point, double p_toleranc
return false;
}
+#endif
void Path2D::_notification(int p_what) {
diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h
index 21cb4374bd..35cf8211f4 100644
--- a/scene/2d/path_2d.h
+++ b/scene/2d/path_2d.h
@@ -47,9 +47,11 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
virtual Rect2 _edit_get_rect() const;
virtual bool _edit_use_rect() const;
virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+#endif
void set_curve(const Ref<Curve2D> &p_curve);
Ref<Curve2D> get_curve() const;
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 3fd0bef7e9..90663bd675 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -1212,7 +1212,7 @@ bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_
//so, if you pass 45 as limit, avoid numerical precision errors when angle is 45.
#define FLOOR_ANGLE_THRESHOLD 0.01
-Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
+Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
Vector2 body_velocity = p_linear_velocity;
Vector2 body_velocity_normal = body_velocity.normalized();
@@ -1234,6 +1234,7 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
on_ceiling = false;
on_wall = false;
colliders.clear();
+ floor_normal = p_up_direction;
floor_velocity = Vector2();
while (p_max_slides) {
@@ -1262,25 +1263,26 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
colliders.push_back(collision);
motion = collision.remainder;
- if (p_floor_direction == Vector2()) {
+ if (p_up_direction == Vector2()) {
//all is a wall
on_wall = true;
} else {
- if (Math::acos(collision.normal.dot(p_floor_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor
+ if (Math::acos(collision.normal.dot(p_up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor
on_floor = true;
+ floor_normal = collision.normal;
on_floor_body = collision.collider_rid;
floor_velocity = collision.collider_vel;
if (p_stop_on_slope) {
- if ((body_velocity_normal + p_floor_direction).length() < 0.01 && collision.travel.length() < 1) {
+ if ((body_velocity_normal + p_up_direction).length() < 0.01 && collision.travel.length() < 1) {
Transform2D gt = get_global_transform();
- gt.elements[2] -= collision.travel.slide(p_floor_direction);
+ gt.elements[2] -= collision.travel.slide(p_up_direction);
set_global_transform(gt);
return Vector2();
}
}
- } else if (Math::acos(collision.normal.dot(-p_floor_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling
+ } else if (Math::acos(collision.normal.dot(-p_up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling
on_ceiling = true;
} else {
on_wall = true;
@@ -1301,11 +1303,11 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
return body_velocity;
}
-Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_floor_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
+Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
bool was_on_floor = on_floor;
- Vector2 ret = move_and_slide(p_linear_velocity, p_floor_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia);
+ Vector2 ret = move_and_slide(p_linear_velocity, p_up_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia);
if (!was_on_floor || p_snap == Vector2()) {
return ret;
}
@@ -1315,15 +1317,16 @@ Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_veloci
if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) {
bool apply = true;
- if (p_floor_direction != Vector2()) {
- if (Math::acos(p_floor_direction.normalized().dot(col.normal)) < p_floor_max_angle) {
+ if (p_up_direction != Vector2()) {
+ if (Math::acos(p_up_direction.normalized().dot(col.normal)) < p_floor_max_angle) {
on_floor = true;
+ floor_normal = col.normal;
on_floor_body = col.collider_rid;
floor_velocity = col.collider_vel;
if (p_stop_on_slope) {
// move and collide may stray the object a bit because of pre un-stucking,
// so only ensure that motion happens on floor direction in this case.
- col.travel = p_floor_direction * p_floor_direction.dot(col.travel);
+ col.travel = p_up_direction * p_up_direction.dot(col.travel);
}
} else {
@@ -1353,6 +1356,11 @@ bool KinematicBody2D::is_on_ceiling() const {
return on_ceiling;
}
+Vector2 KinematicBody2D::get_floor_normal() const {
+
+ return floor_normal;
+}
+
Vector2 KinematicBody2D::get_floor_velocity() const {
return floor_velocity;
@@ -1473,6 +1481,7 @@ void KinematicBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_on_floor"), &KinematicBody2D::is_on_floor);
ClassDB::bind_method(D_METHOD("is_on_ceiling"), &KinematicBody2D::is_on_ceiling);
ClassDB::bind_method(D_METHOD("is_on_wall"), &KinematicBody2D::is_on_wall);
+ ClassDB::bind_method(D_METHOD("get_floor_normal"), &KinematicBody2D::get_floor_normal);
ClassDB::bind_method(D_METHOD("get_floor_velocity"), &KinematicBody2D::get_floor_velocity);
ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody2D::set_safe_margin);
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index 7f2b42b554..6766bafde3 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -306,6 +306,7 @@ public:
private:
float margin;
+ Vector2 floor_normal;
Vector2 floor_velocity;
RID on_floor_body;
bool on_floor;
@@ -339,11 +340,12 @@ public:
void set_safe_margin(float p_margin);
float get_safe_margin() const;
- Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
- Vector2 move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_floor_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
+ Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_up_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
+ Vector2 move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
bool is_on_floor() const;
bool is_on_wall() const;
bool is_on_ceiling() const;
+ Vector2 get_floor_normal() const;
Vector2 get_floor_velocity() const;
int get_slide_count() const;
diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp
index 7b03193fe0..c480423eca 100644
--- a/scene/2d/polygon_2d.cpp
+++ b/scene/2d/polygon_2d.cpp
@@ -33,6 +33,7 @@
#include "core/math/geometry.h"
#include "skeleton_2d.h"
+#ifdef TOOLS_ENABLED
Dictionary Polygon2D::_edit_get_state() const {
Dictionary state = Node2D::_edit_get_state();
state["offset"] = offset;
@@ -87,6 +88,7 @@ bool Polygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_toler
}
return Geometry::is_point_in_polygon(p_point - get_offset(), polygon2d);
}
+#endif
void Polygon2D::_skeleton_bone_setup_changed() {
update();
diff --git a/scene/2d/polygon_2d.h b/scene/2d/polygon_2d.h
index 84ad221760..07b8828532 100644
--- a/scene/2d/polygon_2d.h
+++ b/scene/2d/polygon_2d.h
@@ -77,6 +77,7 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
virtual Dictionary _edit_get_state() const;
virtual void _edit_set_state(const Dictionary &p_state);
@@ -87,6 +88,7 @@ public:
virtual bool _edit_use_rect() const;
virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+#endif
void set_polygon(const PoolVector<Vector2> &p_polygon);
PoolVector<Vector2> get_polygon() const;
diff --git a/scene/2d/position_2d.cpp b/scene/2d/position_2d.cpp
index 49ef92b861..cdeb905c0c 100644
--- a/scene/2d/position_2d.cpp
+++ b/scene/2d/position_2d.cpp
@@ -43,6 +43,7 @@ void Position2D::_draw_cross() {
draw_line(Point2(0, -extents), Point2(0, +extents), Color(0.53, 0.84, 0.01));
}
+#ifdef TOOLS_ENABLED
Rect2 Position2D::_edit_get_rect() const {
float extents = get_gizmo_extents();
@@ -52,6 +53,7 @@ Rect2 Position2D::_edit_get_rect() const {
bool Position2D::_edit_use_rect() const {
return false;
}
+#endif
void Position2D::_notification(int p_what) {
diff --git a/scene/2d/position_2d.h b/scene/2d/position_2d.h
index 711c4ec02f..3ea636171d 100644
--- a/scene/2d/position_2d.h
+++ b/scene/2d/position_2d.h
@@ -44,8 +44,10 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
virtual Rect2 _edit_get_rect() const;
virtual bool _edit_use_rect() const;
+#endif
void set_gizmo_extents(float p_extents);
float get_gizmo_extents() const;
diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp
index 837444532c..55daed0585 100644
--- a/scene/2d/sprite.cpp
+++ b/scene/2d/sprite.cpp
@@ -34,6 +34,7 @@
#include "scene/main/viewport.h"
#include "scene/scene_string_names.h"
+#ifdef TOOLS_ENABLED
Dictionary Sprite::_edit_get_state() const {
Dictionary state = Node2D::_edit_get_state();
state["offset"] = offset;
@@ -58,6 +59,11 @@ bool Sprite::_edit_use_pivot() const {
return true;
}
+bool Sprite::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
+
+ return is_pixel_opaque(p_point);
+}
+
Rect2 Sprite::_edit_get_rect() const {
return get_rect();
}
@@ -65,6 +71,7 @@ Rect2 Sprite::_edit_get_rect() const {
bool Sprite::_edit_use_rect() const {
return texture.is_valid();
}
+#endif
Rect2 Sprite::get_anchorable_rect() const {
return get_rect();
@@ -305,11 +312,6 @@ int Sprite::get_hframes() const {
return hframes;
}
-bool Sprite::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
- return is_pixel_opaque(p_point);
-}
-
bool Sprite::is_pixel_opaque(const Point2 &p_point) const {
if (texture.is_null())
diff --git a/scene/2d/sprite.h b/scene/2d/sprite.h
index 2fd97f6611..d72bf3168d 100644
--- a/scene/2d/sprite.h
+++ b/scene/2d/sprite.h
@@ -67,6 +67,7 @@ protected:
virtual void _validate_property(PropertyInfo &property) const;
public:
+#ifdef TOOLS_ENABLED
virtual Dictionary _edit_get_state() const;
virtual void _edit_set_state(const Dictionary &p_state);
@@ -75,10 +76,11 @@ public:
virtual bool _edit_use_pivot() const;
virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
- bool is_pixel_opaque(const Point2 &p_point) const;
-
virtual Rect2 _edit_get_rect() const;
virtual bool _edit_use_rect() const;
+#endif
+
+ bool is_pixel_opaque(const Point2 &p_point) const;
void set_texture(const Ref<Texture> &p_texture);
Ref<Texture> get_texture() const;
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 04ec13e415..b6db025d44 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -1282,6 +1282,7 @@ PoolVector<int> TileMap::_get_tile_data() const {
return data;
}
+#ifdef TOOLS_ENABLED
Rect2 TileMap::_edit_get_rect() const {
if (pending_update) {
const_cast<TileMap *>(this)->update_dirty_quadrants();
@@ -1290,6 +1291,7 @@ Rect2 TileMap::_edit_get_rect() const {
}
return rect_cache;
}
+#endif
void TileMap::set_collision_layer(uint32_t p_layer) {
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index 53bb696ba2..0875d197eb 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -244,7 +244,9 @@ public:
INVALID_CELL = -1
};
+#ifdef TOOLS_ENABLED
virtual Rect2 _edit_get_rect() const;
+#endif
void set_tileset(const Ref<TileSet> &p_tileset);
Ref<TileSet> get_tileset() const;
diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp
index f6a888fa09..42d9f88a60 100644
--- a/scene/2d/touch_screen_button.cpp
+++ b/scene/2d/touch_screen_button.cpp
@@ -135,7 +135,9 @@ void TouchScreenButton::_notification(int p_what) {
return;
if (shape.is_valid()) {
Color draw_col = get_tree()->get_debug_collisions_color();
- Vector2 pos = shape_centered ? _edit_get_rect().size * 0.5f : Vector2();
+
+ Vector2 size = texture.is_null() ? shape->get_rect().size : texture->get_size();
+ Vector2 pos = shape_centered ? size * 0.5f : Vector2();
draw_set_transform_matrix(get_canvas_transform().translated(pos));
shape->draw(get_canvas_item(), draw_col);
}
@@ -251,9 +253,7 @@ void TouchScreenButton::_input(const Ref<InputEvent> &p_event) {
}
bool TouchScreenButton::_is_point_inside(const Point2 &p_point) {
-
Point2 coord = (get_global_transform_with_canvas()).affine_inverse().xform(p_point);
- Rect2 item_rect = _edit_get_rect();
bool touched = false;
bool check_rect = true;
@@ -261,7 +261,7 @@ bool TouchScreenButton::_is_point_inside(const Point2 &p_point) {
if (shape.is_valid()) {
check_rect = false;
- Transform2D xform = shape_centered ? Transform2D().translated(item_rect.size * 0.5f) : Transform2D();
+ Transform2D xform = shape_centered ? Transform2D().translated(shape->get_rect().size * 0.5f) : Transform2D();
touched = shape->collide(xform, unit_rect, Transform2D(0, coord + Vector2(0.5, 0.5)));
}
@@ -277,7 +277,7 @@ bool TouchScreenButton::_is_point_inside(const Point2 &p_point) {
if (!touched && check_rect) {
if (texture.is_valid())
- touched = item_rect.has_point(coord);
+ touched = Rect2(Size2(), texture->get_size()).has_point(coord);
}
return touched;
@@ -324,6 +324,7 @@ void TouchScreenButton::_release(bool p_exiting_tree) {
}
}
+#ifdef TOOLS_ENABLED
Rect2 TouchScreenButton::_edit_get_rect() const {
if (texture.is_null())
return CanvasItem::_edit_get_rect();
@@ -334,6 +335,7 @@ Rect2 TouchScreenButton::_edit_get_rect() const {
bool TouchScreenButton::_edit_use_rect() const {
return !texture.is_null();
}
+#endif
Rect2 TouchScreenButton::get_anchorable_rect() const {
if (texture.is_null())
diff --git a/scene/2d/touch_screen_button.h b/scene/2d/touch_screen_button.h
index 9c9fc6125a..28dba59402 100644
--- a/scene/2d/touch_screen_button.h
+++ b/scene/2d/touch_screen_button.h
@@ -74,6 +74,11 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
+ virtual Rect2 _edit_get_rect() const;
+ virtual bool _edit_use_rect() const;
+#endif
+
void set_texture(const Ref<Texture> &p_texture);
Ref<Texture> get_texture() const;
@@ -103,8 +108,6 @@ public:
bool is_pressed() const;
- virtual Rect2 _edit_get_rect() const;
- virtual bool _edit_use_rect() const;
virtual Rect2 get_anchorable_rect() const;
TouchScreenButton();
diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp
index 223e57f39f..0ac725b7dd 100644
--- a/scene/2d/visibility_notifier_2d.cpp
+++ b/scene/2d/visibility_notifier_2d.cpp
@@ -38,6 +38,16 @@
#include "scene/main/viewport.h"
#include "scene/scene_string_names.h"
+#ifdef TOOLS_ENABLED
+Rect2 VisibilityNotifier2D::_edit_get_rect() const {
+ return rect;
+}
+
+bool VisibilityNotifier2D::_edit_use_rect() const {
+ return true;
+}
+#endif
+
void VisibilityNotifier2D::_enter_viewport(Viewport *p_viewport) {
ERR_FAIL_COND(viewports.has(p_viewport));
@@ -84,15 +94,6 @@ void VisibilityNotifier2D::set_rect(const Rect2 &p_rect) {
_change_notify("rect");
}
-Rect2 VisibilityNotifier2D::_edit_get_rect() const {
-
- return rect;
-}
-
-bool VisibilityNotifier2D::_edit_use_rect() const {
- return true;
-}
-
Rect2 VisibilityNotifier2D::get_rect() const {
return rect;
diff --git a/scene/2d/visibility_notifier_2d.h b/scene/2d/visibility_notifier_2d.h
index f9d4c238eb..a3b79d29e9 100644
--- a/scene/2d/visibility_notifier_2d.h
+++ b/scene/2d/visibility_notifier_2d.h
@@ -55,8 +55,10 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
virtual Rect2 _edit_get_rect() const;
virtual bool _edit_use_rect() const;
+#endif
void set_rect(const Rect2 &p_rect);
Rect2 get_rect() const;
diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp
index 289dc0ba07..3a30755f7f 100644
--- a/scene/3d/camera.cpp
+++ b/scene/3d/camera.cpp
@@ -398,9 +398,9 @@ Vector3 Camera::project_position(const Point2 &p_point, float p_z_depth) const {
CameraMatrix cm;
if (mode == PROJECTION_ORTHOGONAL)
- cm.set_orthogonal(size, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH);
+ cm.set_orthogonal(size, viewport_size.aspect(), p_z_depth, far, keep_aspect == KEEP_WIDTH);
else
- cm.set_perspective(fov, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH);
+ cm.set_perspective(fov, viewport_size.aspect(), p_z_depth, far, keep_aspect == KEEP_WIDTH);
Size2 vp_size;
cm.get_viewport_size(vp_size.x, vp_size.y);
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index c2860c25d8..999f39c841 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -1140,7 +1140,7 @@ bool KinematicBody::move_and_collide(const Vector3 &p_motion, bool p_infinite_in
//so, if you pass 45 as limit, avoid numerical precision errors when angle is 45.
#define FLOOR_ANGLE_THRESHOLD 0.01
-Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
+Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
Vector3 body_velocity = p_linear_velocity;
Vector3 body_velocity_normal = body_velocity.normalized();
@@ -1159,6 +1159,7 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve
on_ceiling = false;
on_wall = false;
colliders.clear();
+ floor_normal = p_up_direction;
floor_velocity = Vector3();
while (p_max_slides) {
@@ -1187,25 +1188,26 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve
colliders.push_back(collision);
motion = collision.remainder;
- if (p_floor_direction == Vector3()) {
+ if (p_up_direction == Vector3()) {
//all is a wall
on_wall = true;
} else {
- if (Math::acos(collision.normal.dot(p_floor_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor
+ if (Math::acos(collision.normal.dot(p_up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor
on_floor = true;
+ floor_normal = collision.normal;
on_floor_body = collision.collider_rid;
floor_velocity = collision.collider_vel;
if (p_stop_on_slope) {
- if ((body_velocity_normal + p_floor_direction).length() < 0.01 && collision.travel.length() < 1) {
+ if ((body_velocity_normal + p_up_direction).length() < 0.01 && collision.travel.length() < 1) {
Transform gt = get_global_transform();
- gt.origin -= collision.travel.slide(p_floor_direction);
+ gt.origin -= collision.travel.slide(p_up_direction);
set_global_transform(gt);
return Vector3();
}
}
- } else if (Math::acos(collision.normal.dot(-p_floor_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling
+ } else if (Math::acos(collision.normal.dot(-p_up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling
on_ceiling = true;
} else {
on_wall = true;
@@ -1232,11 +1234,11 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve
return body_velocity;
}
-Vector3 KinematicBody::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_floor_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
+Vector3 KinematicBody::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
bool was_on_floor = on_floor;
- Vector3 ret = move_and_slide(p_linear_velocity, p_floor_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia);
+ Vector3 ret = move_and_slide(p_linear_velocity, p_up_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia);
if (!was_on_floor || p_snap == Vector3()) {
return ret;
}
@@ -1247,15 +1249,16 @@ Vector3 KinematicBody::move_and_slide_with_snap(const Vector3 &p_linear_velocity
if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) {
bool apply = true;
- if (p_floor_direction != Vector3()) {
- if (Math::acos(p_floor_direction.normalized().dot(col.normal)) < p_floor_max_angle) {
+ if (p_up_direction != Vector3()) {
+ if (Math::acos(p_up_direction.normalized().dot(col.normal)) < p_floor_max_angle) {
on_floor = true;
+ floor_normal = col.normal;
on_floor_body = col.collider_rid;
floor_velocity = col.collider_vel;
if (p_stop_on_slope) {
// move and collide may stray the object a bit because of pre un-stucking,
// so only ensure that motion happens on floor direction in this case.
- col.travel = col.travel.project(p_floor_direction);
+ col.travel = col.travel.project(p_up_direction);
}
} else {
apply = false; //snapped with floor direction, but did not snap to a floor, do not snap.
@@ -1284,6 +1287,11 @@ bool KinematicBody::is_on_ceiling() const {
return on_ceiling;
}
+Vector3 KinematicBody::get_floor_normal() const {
+
+ return floor_normal;
+}
+
Vector3 KinematicBody::get_floor_velocity() const {
return floor_velocity;
@@ -1392,7 +1400,7 @@ void KinematicBody::_notification(int p_what) {
void KinematicBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false));
- ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "floor_normal", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide_with_snap, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody::test_move, DEFVAL(true));
@@ -1400,6 +1408,7 @@ void KinematicBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_on_floor"), &KinematicBody::is_on_floor);
ClassDB::bind_method(D_METHOD("is_on_ceiling"), &KinematicBody::is_on_ceiling);
ClassDB::bind_method(D_METHOD("is_on_wall"), &KinematicBody::is_on_wall);
+ ClassDB::bind_method(D_METHOD("get_floor_normal"), &KinematicBody::get_floor_normal);
ClassDB::bind_method(D_METHOD("get_floor_velocity"), &KinematicBody::get_floor_velocity);
ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &KinematicBody::set_axis_lock);
diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h
index 06b31804b2..05bcbe22f0 100644
--- a/scene/3d/physics_body.h
+++ b/scene/3d/physics_body.h
@@ -300,6 +300,7 @@ private:
float margin;
+ Vector3 floor_normal;
Vector3 floor_velocity;
RID on_floor_body;
bool on_floor;
@@ -330,11 +331,12 @@ public:
void set_safe_margin(float p_margin);
float get_safe_margin() const;
- Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
- Vector3 move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_floor_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
+ Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
+ Vector3 move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
bool is_on_floor() const;
bool is_on_wall() const;
bool is_on_ceiling() const;
+ Vector3 get_floor_normal() const;
Vector3 get_floor_velocity() const;
int get_slide_count() const;
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index 65912c1c07..b2020d44e8 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -165,7 +165,7 @@ void BaseButton::on_action_event(Ref<InputEvent> p_event) {
_pressed();
}
} else {
- if (!p_event->is_pressed()) {
+ if ((p_event->is_pressed() && action_mode == ACTION_MODE_BUTTON_PRESS) || (!p_event->is_pressed() && action_mode == ACTION_MODE_BUTTON_RELEASE)) {
_pressed();
}
}
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 5e656eea70..9a67745e0d 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -47,6 +47,7 @@
#include "editor/plugins/canvas_item_editor_plugin.h"
#endif
+#ifdef TOOLS_ENABLED
Dictionary Control::_edit_get_state() const {
Dictionary s;
@@ -155,6 +156,11 @@ bool Control::_edit_use_pivot() const {
return true;
}
+Size2 Control::_edit_get_minimum_size() const {
+ return get_combined_minimum_size();
+}
+#endif
+
void Control::set_custom_minimum_size(const Size2 &p_custom) {
if (p_custom == data.custom_minimum_size)
@@ -193,11 +199,6 @@ Size2 Control::get_combined_minimum_size() const {
return data.minimum_size_cache;
}
-Size2 Control::_edit_get_minimum_size() const {
-
- return get_combined_minimum_size();
-}
-
Transform2D Control::_get_internal_transform() const {
Transform2D rot_scale;
diff --git a/scene/gui/control.h b/scene/gui/control.h
index a9831b9793..357858beb6 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -279,6 +279,7 @@ public:
};
/* EDITOR */
+#ifdef TOOLS_ENABLED
virtual Dictionary _edit_get_state() const;
virtual void _edit_set_state(const Dictionary &p_state);
@@ -301,6 +302,7 @@ public:
virtual bool _edit_use_pivot() const;
virtual Size2 _edit_get_minimum_size() const;
+#endif
void accept_event();
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index 6b12947651..77913efd1c 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -35,9 +35,17 @@
void Label::set_autowrap(bool p_autowrap) {
+ if (autowrap == p_autowrap) {
+ return;
+ }
+
autowrap = p_autowrap;
word_cache_dirty = true;
update();
+
+ if (clip) {
+ minimum_size_changed();
+ }
}
bool Label::has_autowrap() const {
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index 9505c0af39..225b382524 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -4542,8 +4542,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
}
p_block->statements.push_back(flow);
- if (p_block->block_type == BlockNode::BLOCK_TYPE_CASE || p_block->block_type == BlockNode::BLOCK_TYPE_DEFAULT) {
- return OK;
+
+ BlockNode *block = p_block;
+ while (block) {
+ if (block->block_type == BlockNode::BLOCK_TYPE_CASE || block->block_type == BlockNode::BLOCK_TYPE_DEFAULT) {
+ return OK;
+ }
+ block = block->parent_block;
}
} else if (tk.type == TK_CF_DISCARD) {
@@ -4591,8 +4596,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
}
p_block->statements.push_back(flow);
- if (p_block->block_type == BlockNode::BLOCK_TYPE_CASE || p_block->block_type == BlockNode::BLOCK_TYPE_DEFAULT) {
- return OK;
+
+ BlockNode *block = p_block;
+ while (block) {
+ if (block->block_type == BlockNode::BLOCK_TYPE_CASE || block->block_type == BlockNode::BLOCK_TYPE_DEFAULT) {
+ return OK;
+ }
+ block = block->parent_block;
}
} else if (tk.type == TK_CF_CONTINUE) {