summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/classes/KinematicBody.xml2
-rw-r--r--doc/classes/KinematicBody2D.xml2
-rw-r--r--doc/classes/Sprite.xml3
-rw-r--r--doc/classes/Sprite3D.xml3
-rw-r--r--modules/gdscript/gdscript_tokenizer.cpp36
-rw-r--r--modules/gdscript/gdscript_tokenizer.h6
-rw-r--r--scene/2d/sprite.cpp16
-rw-r--r--scene/2d/sprite.h3
-rw-r--r--scene/3d/sprite_3d.cpp18
-rw-r--r--scene/3d/sprite_3d.h3
-rw-r--r--scene/gui/control.cpp2
11 files changed, 89 insertions, 5 deletions
diff --git a/doc/classes/KinematicBody.xml b/doc/classes/KinematicBody.xml
index b7c4200b95..2fab689f89 100644
--- a/doc/classes/KinematicBody.xml
+++ b/doc/classes/KinematicBody.xml
@@ -5,7 +5,7 @@
</brief_description>
<description>
Kinematic bodies are special types of bodies that are meant to be user-controlled. They are not affected by physics at all; to other types of bodies, such as a character or a rigid body, these are the same as a static body. However, they have two main uses:
- [b]Simulated motion:[/b] When these bodies are moved manually, either from code or from an AnimationPlayer (with process mode set to fixed), the physics will automatically compute an estimate of their linear and angular velocity. This makes them very useful for moving platforms or other AnimationPlayer-controlled objects (like a door, a bridge that opens, etc).
+ [b]Simulated motion:[/b] When these bodies are moved manually, either from code or from an [AnimationPlayer] (with [member AnimationPlayer.playback_process_mode] set to "physics"), the physics will automatically compute an estimate of their linear and angular velocity. This makes them very useful for moving platforms or other AnimationPlayer-controlled objects (like a door, a bridge that opens, etc).
[b]Kinematic characters:[/b] KinematicBody also has an API for moving objects (the [method move_and_collide] and [method move_and_slide] methods) while performing collision tests. This makes them really useful to implement characters that collide against a world, but that don't require advanced physics.
</description>
<tutorials>
diff --git a/doc/classes/KinematicBody2D.xml b/doc/classes/KinematicBody2D.xml
index 22db9e3960..99a83765eb 100644
--- a/doc/classes/KinematicBody2D.xml
+++ b/doc/classes/KinematicBody2D.xml
@@ -5,7 +5,7 @@
</brief_description>
<description>
Kinematic bodies are special types of bodies that are meant to be user-controlled. They are not affected by physics at all; to other types of bodies, such as a character or a rigid body, these are the same as a static body. However, they have two main uses:
- [b]Simulated motion:[/b] When these bodies are moved manually, either from code or from an AnimationPlayer (with process mode set to fixed), the physics will automatically compute an estimate of their linear and angular velocity. This makes them very useful for moving platforms or other AnimationPlayer-controlled objects (like a door, a bridge that opens, etc).
+ [b]Simulated motion:[/b] When these bodies are moved manually, either from code or from an [AnimationPlayer] (with [member AnimationPlayer.playback_process_mode] set to "physics"), the physics will automatically compute an estimate of their linear and angular velocity. This makes them very useful for moving platforms or other AnimationPlayer-controlled objects (like a door, a bridge that opens, etc).
[b]Kinematic characters:[/b] KinematicBody2D also has an API for moving objects (the [method move_and_collide] and [method move_and_slide] methods) while performing collision tests. This makes them really useful to implement characters that collide against a world, but that don't require advanced physics.
</description>
<tutorials>
diff --git a/doc/classes/Sprite.xml b/doc/classes/Sprite.xml
index e5aea961f4..35db0b3762 100644
--- a/doc/classes/Sprite.xml
+++ b/doc/classes/Sprite.xml
@@ -46,6 +46,9 @@
<member name="frame" type="int" setter="set_frame" getter="get_frame" default="0">
Current frame to display from sprite sheet. [member vframes] or [member hframes] must be greater than 1.
</member>
+ <member name="frame_coords" type="Vector2" setter="set_frame_coords" getter="get_frame_coords">
+ Coordinates of the frame to display from sprite sheet. This is as an alias for the [member frame] property. [member vframes] or [member hframes] must be greater than 1.
+ </member>
<member name="hframes" type="int" setter="set_hframes" getter="get_hframes" default="1">
The number of columns in the sprite sheet.
</member>
diff --git a/doc/classes/Sprite3D.xml b/doc/classes/Sprite3D.xml
index 9a51302bf1..be15b066aa 100644
--- a/doc/classes/Sprite3D.xml
+++ b/doc/classes/Sprite3D.xml
@@ -14,6 +14,9 @@
<member name="frame" type="int" setter="set_frame" getter="get_frame" default="0">
Current frame to display from sprite sheet. [member vframes] or [member hframes] must be greater than 1.
</member>
+ <member name="frame_coords" type="Vector2" setter="set_frame_coords" getter="get_frame_coords">
+ Coordinates of the frame to display from sprite sheet. This is as an alias for the [member frame] property. [member vframes] or [member hframes] must be greater than 1.
+ </member>
<member name="hframes" type="int" setter="set_hframes" getter="get_hframes" default="1">
The number of columns in the sprite sheet.
</member>
diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp
index 95715ab648..59b53b5f9a 100644
--- a/modules/gdscript/gdscript_tokenizer.cpp
+++ b/modules/gdscript/gdscript_tokenizer.cpp
@@ -517,7 +517,22 @@ void GDScriptTokenizerText::_advance() {
INCPOS(1);
column = 1;
int i = 0;
- while (GETCHAR(i) == ' ' || GETCHAR(i) == '\t') {
+ while (true) {
+ if (GETCHAR(i) == ' ') {
+ if (file_indent_type == INDENT_NONE) file_indent_type = INDENT_SPACES;
+ if (file_indent_type != INDENT_SPACES) {
+ _make_error("Spaces used for indentation in tab-indented file!");
+ return;
+ }
+ } else if (GETCHAR(i) == '\t') {
+ if (file_indent_type == INDENT_NONE) file_indent_type = INDENT_TABS;
+ if (file_indent_type != INDENT_TABS) {
+ _make_error("Tabs used for indentation in space-indented file!");
+ return;
+ }
+ } else {
+ break; // not indentation anymore
+ }
i++;
}
@@ -555,9 +570,25 @@ void GDScriptTokenizerText::_advance() {
column = 1;
line++;
int i = 0;
- while (GETCHAR(i) == ' ' || GETCHAR(i) == '\t') {
+ while (true) {
+ if (GETCHAR(i) == ' ') {
+ if (file_indent_type == INDENT_NONE) file_indent_type = INDENT_SPACES;
+ if (file_indent_type != INDENT_SPACES) {
+ _make_error("Spaces used for indentation in tab-indented file!");
+ return;
+ }
+ } else if (GETCHAR(i) == '\t') {
+ if (file_indent_type == INDENT_NONE) file_indent_type = INDENT_TABS;
+ if (file_indent_type != INDENT_TABS) {
+ _make_error("Tabs used for indentation in space-indented file!");
+ return;
+ }
+ } else {
+ break; // not indentation anymore
+ }
i++;
}
+
_make_newline(i);
return;
@@ -1082,6 +1113,7 @@ void GDScriptTokenizerText::set_code(const String &p_code) {
ignore_warnings = false;
#endif // DEBUG_ENABLED
last_error = "";
+ file_indent_type = INDENT_NONE;
for (int i = 0; i < MAX_LOOKAHEAD + 1; i++)
_advance();
}
diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h
index 7b977ff67c..89d586b912 100644
--- a/modules/gdscript/gdscript_tokenizer.h
+++ b/modules/gdscript/gdscript_tokenizer.h
@@ -222,6 +222,12 @@ class GDScriptTokenizerText : public GDScriptTokenizer {
int tk_rb_pos;
String last_error;
bool error_flag;
+ enum {
+ INDENT_NONE,
+ INDENT_SPACES,
+ INDENT_TABS,
+ } file_indent_type;
+
#ifdef DEBUG_ENABLED
Vector<Pair<int, String> > warning_skips;
Set<String> warning_global_skips;
diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp
index dbe47e89ec..d7a8005187 100644
--- a/scene/2d/sprite.cpp
+++ b/scene/2d/sprite.cpp
@@ -259,6 +259,7 @@ void Sprite::set_frame(int p_frame) {
frame = p_frame;
_change_notify("frame");
+ _change_notify("frame_coords");
emit_signal(SceneStringNames::get_singleton()->frame_changed);
}
@@ -267,6 +268,17 @@ int Sprite::get_frame() const {
return frame;
}
+void Sprite::set_frame_coords(const Vector2 &p_coord) {
+ ERR_FAIL_INDEX(int(p_coord.x), vframes);
+ ERR_FAIL_INDEX(int(p_coord.y), hframes);
+
+ set_frame(int(p_coord.y) * hframes + int(p_coord.x));
+}
+
+Vector2 Sprite::get_frame_coords() const {
+ return Vector2(frame % hframes, frame / hframes);
+}
+
void Sprite::set_vframes(int p_amount) {
ERR_FAIL_COND(p_amount < 1);
@@ -420,6 +432,9 @@ void Sprite::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_frame", "frame"), &Sprite::set_frame);
ClassDB::bind_method(D_METHOD("get_frame"), &Sprite::get_frame);
+ ClassDB::bind_method(D_METHOD("set_frame_coords", "coords"), &Sprite::set_frame_coords);
+ ClassDB::bind_method(D_METHOD("get_frame_coords"), &Sprite::get_frame_coords);
+
ClassDB::bind_method(D_METHOD("set_vframes", "vframes"), &Sprite::set_vframes);
ClassDB::bind_method(D_METHOD("get_vframes"), &Sprite::get_vframes);
@@ -442,6 +457,7 @@ void Sprite::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes");
ADD_PROPERTY(PropertyInfo(Variant::INT, "hframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_hframes", "get_hframes");
ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frame_coords", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_frame_coords", "get_frame_coords");
ADD_GROUP("Region", "region_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "region_enabled"), "set_region", "is_region");
diff --git a/scene/2d/sprite.h b/scene/2d/sprite.h
index e38db3a299..490db31cdb 100644
--- a/scene/2d/sprite.h
+++ b/scene/2d/sprite.h
@@ -110,6 +110,9 @@ public:
void set_frame(int p_frame);
int get_frame() const;
+ void set_frame_coords(const Vector2 &p_row);
+ Vector2 get_frame_coords() const;
+
void set_vframes(int p_amount);
int get_vframes() const;
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp
index b39762fde8..fc5523633d 100644
--- a/scene/3d/sprite_3d.cpp
+++ b/scene/3d/sprite_3d.cpp
@@ -564,6 +564,9 @@ void Sprite3D::set_frame(int p_frame) {
frame = p_frame;
_queue_update();
+
+ _change_notify("frame");
+ _change_notify("frame_coords");
emit_signal(SceneStringNames::get_singleton()->frame_changed);
}
@@ -572,6 +575,17 @@ int Sprite3D::get_frame() const {
return frame;
}
+void Sprite3D::set_frame_coords(const Vector2 &p_coord) {
+ ERR_FAIL_INDEX(int(p_coord.x), vframes);
+ ERR_FAIL_INDEX(int(p_coord.y), hframes);
+
+ set_frame(int(p_coord.y) * hframes + int(p_coord.x));
+}
+
+Vector2 Sprite3D::get_frame_coords() const {
+ return Vector2(frame % hframes, frame / hframes);
+}
+
void Sprite3D::set_vframes(int p_amount) {
ERR_FAIL_COND(p_amount < 1);
@@ -648,6 +662,9 @@ void Sprite3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_frame", "frame"), &Sprite3D::set_frame);
ClassDB::bind_method(D_METHOD("get_frame"), &Sprite3D::get_frame);
+ ClassDB::bind_method(D_METHOD("set_frame_coords", "coords"), &Sprite3D::set_frame_coords);
+ ClassDB::bind_method(D_METHOD("get_frame_coords"), &Sprite3D::get_frame_coords);
+
ClassDB::bind_method(D_METHOD("set_vframes", "vframes"), &Sprite3D::set_vframes);
ClassDB::bind_method(D_METHOD("get_vframes"), &Sprite3D::get_vframes);
@@ -659,6 +676,7 @@ void Sprite3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes");
ADD_PROPERTY(PropertyInfo(Variant::INT, "hframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_hframes", "get_hframes");
ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frame_coords", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_frame_coords", "get_frame_coords");
ADD_GROUP("Region", "region_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "region_enabled"), "set_region", "is_region");
ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect");
diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h
index 0e086ef31e..5ae9b153f9 100644
--- a/scene/3d/sprite_3d.h
+++ b/scene/3d/sprite_3d.h
@@ -173,6 +173,9 @@ public:
void set_frame(int p_frame);
int get_frame() const;
+ void set_frame_coords(const Vector2 &p_row);
+ Vector2 get_frame_coords() const;
+
void set_vframes(int p_amount);
int get_vframes() const;
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 1d6f3dc782..5ec6c68163 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -289,7 +289,7 @@ void Control::_update_minimum_size() {
Size2 minsize = get_combined_minimum_size();
if (minsize.x > data.size_cache.x ||
minsize.y > data.size_cache.y) {
- set_size(data.size_cache);
+ _size_changed();
}
data.updating_last_minimum_size = false;