summaryrefslogtreecommitdiff
path: root/scene/2d
diff options
context:
space:
mode:
Diffstat (limited to 'scene/2d')
-rw-r--r--scene/2d/animated_sprite.cpp5
-rw-r--r--scene/2d/area_2d.cpp19
-rw-r--r--scene/2d/camera_2d.cpp19
-rw-r--r--scene/2d/camera_2d.h3
-rw-r--r--scene/2d/canvas_item.cpp99
-rw-r--r--scene/2d/collision_object_2d.cpp7
-rw-r--r--scene/2d/cpu_particles_2d.cpp4
-rw-r--r--scene/2d/cpu_particles_2d.h4
-rw-r--r--scene/2d/line_builder.cpp2
-rw-r--r--scene/2d/navigation_2d.cpp4
-rw-r--r--scene/2d/parallax_layer.cpp3
-rw-r--r--scene/2d/path_2d.cpp2
-rw-r--r--scene/2d/physics_body_2d.cpp59
-rw-r--r--scene/2d/sprite.cpp16
-rw-r--r--scene/2d/sprite.h3
-rw-r--r--scene/2d/tile_map.cpp15
16 files changed, 119 insertions, 145 deletions
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp
index 83cc1eeb46..0b20b781f0 100644
--- a/scene/2d/animated_sprite.cpp
+++ b/scene/2d/animated_sprite.cpp
@@ -642,9 +642,8 @@ void AnimatedSprite::_reset_timeout() {
void AnimatedSprite::set_animation(const StringName &p_animation) {
- ERR_EXPLAIN(vformat("There is no animation with name '%s'.", p_animation));
- ERR_FAIL_COND(frames == NULL);
- ERR_FAIL_COND(frames->get_animation_names().find(p_animation) == -1);
+ ERR_FAIL_COND_MSG(frames == NULL, vformat("There is no animation with name '%s'.", p_animation));
+ ERR_FAIL_COND_MSG(frames->get_animation_names().find(p_animation) == -1, vformat("There is no animation with name '%s'.", p_animation));
if (animation == p_animation)
return;
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp
index b701e84a9c..a636eea285 100644
--- a/scene/2d/area_2d.cpp
+++ b/scene/2d/area_2d.cpp
@@ -321,10 +321,7 @@ void Area2D::_area_inout(int p_status, const RID &p_area, int p_instance, int p_
void Area2D::_clear_monitoring() {
- if (locked) {
- ERR_EXPLAIN("This function can't be used during the in/out signal.");
- }
- ERR_FAIL_COND(locked);
+ ERR_FAIL_COND_MSG(locked, "This function can't be used during the in/out signal.");
{
Map<ObjectID, BodyState> bmcopy = body_map;
@@ -401,10 +398,7 @@ void Area2D::set_monitoring(bool p_enable) {
if (p_enable == monitoring)
return;
- if (locked) {
- ERR_EXPLAIN("Function blocked during in/out signal. Use set_deferred(\"monitoring\",true/false)");
- }
- ERR_FAIL_COND(locked);
+ ERR_FAIL_COND_MSG(locked, "Function blocked during in/out signal. Use set_deferred(\"monitoring\", true/false).");
monitoring = p_enable;
@@ -427,10 +421,7 @@ bool Area2D::is_monitoring() const {
void Area2D::set_monitorable(bool p_enable) {
- if (locked || (is_inside_tree() && Physics2DServer::get_singleton()->is_flushing_queries())) {
- ERR_EXPLAIN("Function blocked during in/out signal. Use set_deferred(\"monitorable\",true/false)");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(locked || (is_inside_tree() && Physics2DServer::get_singleton()->is_flushing_queries()), "Function blocked during in/out signal. Use set_deferred(\"monitorable\", true/false).");
if (p_enable == monitorable)
return;
@@ -672,8 +663,8 @@ void Area2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_distance_scale", PROPERTY_HINT_EXP_RANGE, "0,1024,0.001,or_greater"), "set_gravity_distance_scale", "get_gravity_distance_scale");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "gravity_vec"), "set_gravity_vector", "get_gravity_vector");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity", PROPERTY_HINT_RANGE, "-1024,1024,0.001"), "set_gravity", "get_gravity");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_linear_damp", "get_linear_damp");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_angular_damp", "get_angular_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp");
ADD_PROPERTY(PropertyInfo(Variant::INT, "priority", PROPERTY_HINT_RANGE, "0,128,1"), "set_priority", "get_priority");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitoring"), "set_monitoring", "is_monitoring");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitorable"), "set_monitorable", "is_monitorable");
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index 6011941142..3e8902314c 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -106,7 +106,7 @@ Transform2D Camera2D::get_camera_transform() {
if (anchor_mode == ANCHOR_MODE_DRAG_CENTER) {
- if (h_drag_enabled && !Engine::get_singleton()->is_editor_hint()) {
+ if (h_drag_enabled && !Engine::get_singleton()->is_editor_hint() && !h_offset_changed) {
camera_pos.x = MIN(camera_pos.x, (new_camera_pos.x + screen_size.x * 0.5 * zoom.x * drag_margin[MARGIN_LEFT]));
camera_pos.x = MAX(camera_pos.x, (new_camera_pos.x - screen_size.x * 0.5 * zoom.x * drag_margin[MARGIN_RIGHT]));
} else {
@@ -116,9 +116,11 @@ Transform2D Camera2D::get_camera_transform() {
} else {
camera_pos.x = new_camera_pos.x + screen_size.x * 0.5 * drag_margin[MARGIN_LEFT] * h_ofs;
}
+
+ h_offset_changed = false;
}
- if (v_drag_enabled && !Engine::get_singleton()->is_editor_hint()) {
+ if (v_drag_enabled && !Engine::get_singleton()->is_editor_hint() && !v_offset_changed) {
camera_pos.y = MIN(camera_pos.y, (new_camera_pos.y + screen_size.y * 0.5 * zoom.y * drag_margin[MARGIN_TOP]));
camera_pos.y = MAX(camera_pos.y, (new_camera_pos.y - screen_size.y * 0.5 * zoom.y * drag_margin[MARGIN_BOTTOM]));
@@ -130,6 +132,8 @@ Transform2D Camera2D::get_camera_transform() {
} else {
camera_pos.y = new_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_BOTTOM] * v_ofs;
}
+
+ v_offset_changed = false;
}
} else if (anchor_mode == ANCHOR_MODE_FIXED_TOP_LEFT) {
@@ -554,6 +558,7 @@ bool Camera2D::is_v_drag_enabled() const {
void Camera2D::set_v_offset(float p_offset) {
v_ofs = p_offset;
+ v_offset_changed = true;
_update_scroll();
}
@@ -565,6 +570,7 @@ float Camera2D::get_v_offset() const {
void Camera2D::set_h_offset(float p_offset) {
h_ofs = p_offset;
+ h_offset_changed = true;
_update_scroll();
}
float Camera2D::get_h_offset() const {
@@ -750,8 +756,8 @@ void Camera2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "smoothing_speed"), "set_follow_smoothing", "get_follow_smoothing");
ADD_GROUP("Offset", "offset_");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset_v", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_v_offset", "get_v_offset");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset_h", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_h_offset", "get_h_offset");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset_v", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_v_offset", "get_v_offset");
ADD_GROUP("Drag Margin", "drag_margin_");
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "drag_margin_left", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", MARGIN_LEFT);
@@ -799,9 +805,12 @@ Camera2D::Camera2D() {
limit_drawing_enabled = false;
margin_drawing_enabled = false;
- h_drag_enabled = true;
- v_drag_enabled = true;
+ h_drag_enabled = false;
+ v_drag_enabled = false;
h_ofs = 0;
v_ofs = 0;
+ h_offset_changed = false;
+ v_offset_changed = false;
+
set_notify_transform(true);
}
diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h
index 7f16ecff41..bb3c76b30c 100644
--- a/scene/2d/camera_2d.h
+++ b/scene/2d/camera_2d.h
@@ -77,6 +77,9 @@ protected:
float h_ofs;
float v_ofs;
+ bool h_offset_changed;
+ bool v_offset_changed;
+
Point2 camera_screen_center;
void _update_process_mode();
void _update_scroll();
diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp
index 7368efd21a..fc5e5cbba2 100644
--- a/scene/2d/canvas_item.cpp
+++ b/scene/2d/canvas_item.cpp
@@ -641,6 +641,9 @@ void CanvasItem::update() {
void CanvasItem::set_modulate(const Color &p_modulate) {
+ if (modulate == p_modulate)
+ return;
+
modulate = p_modulate;
VisualServer::get_singleton()->canvas_item_set_modulate(canvas_item, modulate);
}
@@ -679,6 +682,9 @@ CanvasItem *CanvasItem::get_parent_item() const {
void CanvasItem::set_self_modulate(const Color &p_self_modulate) {
+ if (self_modulate == p_self_modulate)
+ return;
+
self_modulate = p_self_modulate;
VisualServer::get_singleton()->canvas_item_set_self_modulate(canvas_item, self_modulate);
}
@@ -689,6 +695,9 @@ Color CanvasItem::get_self_modulate() const {
void CanvasItem::set_light_mask(int p_light_mask) {
+ if (light_mask == p_light_mask)
+ return;
+
light_mask = p_light_mask;
VS::get_singleton()->canvas_item_set_light_mask(canvas_item, p_light_mask);
}
@@ -707,20 +716,14 @@ void CanvasItem::item_rect_changed(bool p_size_changed) {
void CanvasItem::draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width, bool p_antialiased) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
VisualServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width, p_antialiased);
}
void CanvasItem::draw_polyline(const Vector<Point2> &p_points, const Color &p_color, float p_width, bool p_antialiased) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
Vector<Color> colors;
colors.push_back(p_color);
@@ -729,20 +732,14 @@ void CanvasItem::draw_polyline(const Vector<Point2> &p_points, const Color &p_co
void CanvasItem::draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width, bool p_antialiased) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
VisualServer::get_singleton()->canvas_item_add_polyline(canvas_item, p_points, p_colors, p_width, p_antialiased);
}
void CanvasItem::draw_multiline(const Vector<Point2> &p_points, const Color &p_color, float p_width, bool p_antialiased) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
Vector<Color> colors;
colors.push_back(p_color);
@@ -751,20 +748,14 @@ void CanvasItem::draw_multiline(const Vector<Point2> &p_points, const Color &p_c
void CanvasItem::draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width, bool p_antialiased) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
VisualServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, p_colors, p_width, p_antialiased);
}
void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled, float p_width, bool p_antialiased) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
if (p_filled) {
if (p_width != 1.0) {
@@ -819,20 +810,14 @@ void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_fil
void CanvasItem::draw_circle(const Point2 &p_pos, float p_radius, const Color &p_color) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
VisualServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius, p_color);
}
void CanvasItem::draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos, const Color &p_modulate, const Ref<Texture> &p_normal_map) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND(p_texture.is_null());
@@ -841,29 +826,20 @@ void CanvasItem::draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos
void CanvasItem::draw_texture_rect(const Ref<Texture> &p_texture, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND(p_texture.is_null());
p_texture->draw_rect(canvas_item, p_rect, p_tile, p_modulate, p_transpose, p_normal_map);
}
void CanvasItem::draw_texture_rect_region(const Ref<Texture> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND(p_texture.is_null());
p_texture->draw_rect_region(canvas_item, p_rect, p_src_rect, p_modulate, p_transpose, p_normal_map, p_clip_uv);
}
void CanvasItem::draw_style_box(const Ref<StyleBox> &p_style_box, const Rect2 &p_rect) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND(p_style_box.is_null());
@@ -871,10 +847,7 @@ void CanvasItem::draw_style_box(const Ref<StyleBox> &p_style_box, const Rect2 &p
}
void CanvasItem::draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture, float p_width, const Ref<Texture> &p_normal_map) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
RID rid_normal = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
@@ -883,10 +856,7 @@ void CanvasItem::draw_primitive(const Vector<Point2> &p_points, const Vector<Col
}
void CanvasItem::draw_set_transform(const Point2 &p_offset, float p_rot, const Size2 &p_scale) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
Transform2D xform(p_rot, p_offset);
xform.scale_basis(p_scale);
@@ -895,20 +865,14 @@ void CanvasItem::draw_set_transform(const Point2 &p_offset, float p_rot, const S
void CanvasItem::draw_set_transform_matrix(const Transform2D &p_matrix) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
VisualServer::get_singleton()->canvas_item_add_set_transform(canvas_item, p_matrix);
}
void CanvasItem::draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture, const Ref<Texture> &p_normal_map, bool p_antialiased) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
RID rid_normal = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
@@ -918,10 +882,7 @@ void CanvasItem::draw_polygon(const Vector<Point2> &p_points, const Vector<Color
void CanvasItem::draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs, Ref<Texture> p_texture, const Ref<Texture> &p_normal_map, bool p_antialiased) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
Vector<Color> colors;
colors.push_back(p_color);
@@ -949,10 +910,7 @@ void CanvasItem::draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Tex
void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, const Color &p_modulate, int p_clip_w) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND(p_font.is_null());
p_font->draw(canvas_item, p_pos, p_text, p_modulate, p_clip_w);
@@ -960,10 +918,7 @@ void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const
float CanvasItem::draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next, const Color &p_modulate) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL_V(0);
- }
+ ERR_FAIL_COND_V_MSG(!drawing, 0, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND_V(p_char.length() != 1, 0);
ERR_FAIL_COND_V(p_font.is_null(), 0);
diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp
index 202c7c9cf2..228b67990c 100644
--- a/scene/2d/collision_object_2d.cpp
+++ b/scene/2d/collision_object_2d.cpp
@@ -376,11 +376,12 @@ void CollisionObject2D::set_only_update_transform_changes(bool p_enable) {
void CollisionObject2D::_update_pickable() {
if (!is_inside_tree())
return;
- bool pickable = this->pickable && is_inside_tree() && is_visible_in_tree();
+
+ bool is_pickable = pickable && is_visible_in_tree();
if (area)
- Physics2DServer::get_singleton()->area_set_pickable(rid, pickable);
+ Physics2DServer::get_singleton()->area_set_pickable(rid, is_pickable);
else
- Physics2DServer::get_singleton()->body_set_pickable(rid, pickable);
+ Physics2DServer::get_singleton()->body_set_pickable(rid, is_pickable);
}
String CollisionObject2D::get_configuration_warning() const {
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index 4b309a93b5..f9f273d494 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -962,9 +962,13 @@ void CPUParticles2D::_set_redraw(bool p_redraw) {
if (redraw) {
VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread");
VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), true);
+
+ VS::get_singleton()->multimesh_set_visible_instances(multimesh, -1);
} else {
VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread");
VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), false);
+
+ VS::get_singleton()->multimesh_set_visible_instances(multimesh, 0);
}
#ifndef NO_THREADS
update_mutex->unlock();
diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h
index 1cd22df9e7..da668664b9 100644
--- a/scene/2d/cpu_particles_2d.h
+++ b/scene/2d/cpu_particles_2d.h
@@ -35,10 +35,6 @@
#include "scene/2d/node_2d.h"
#include "scene/resources/texture.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class CPUParticles2D : public Node2D {
private:
GDCLASS(CPUParticles2D, Node2D);
diff --git a/scene/2d/line_builder.cpp b/scene/2d/line_builder.cpp
index 9fe5fb98b6..6436b3878f 100644
--- a/scene/2d/line_builder.cpp
+++ b/scene/2d/line_builder.cpp
@@ -155,7 +155,7 @@ void LineBuilder::build() {
texture_mode == Line2D::LINE_TEXTURE_STRETCH;
if (distance_required) {
total_distance = calculate_total_distance(points);
- //Ajust totalDistance.
+ //Adjust totalDistance.
// The line's outer length will be a little higher due to begin and end caps
if (begin_cap_mode == Line2D::LINE_CAP_BOX || begin_cap_mode == Line2D::LINE_CAP_ROUND) {
if (retrieve_curve)
diff --git a/scene/2d/navigation_2d.cpp b/scene/2d/navigation_2d.cpp
index f644db462b..5cf28d6c89 100644
--- a/scene/2d/navigation_2d.cpp
+++ b/scene/2d/navigation_2d.cpp
@@ -551,7 +551,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect
left_poly = p;
portal_left = apex_point;
portal_right = apex_point;
- if (!path.size() || !Math::is_zero_approx(path[path.size() - 1].distance_to(apex_point)))
+ if (!path.size() || path[path.size() - 1] != apex_point)
path.push_back(apex_point);
skip = true;
}
@@ -569,7 +569,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect
right_poly = p;
portal_right = apex_point;
portal_left = apex_point;
- if (!path.size() || !Math::is_zero_approx(path[path.size() - 1].distance_to(apex_point)))
+ if (!path.size() || path[path.size() - 1] != apex_point)
path.push_back(apex_point);
}
}
diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp
index 9a6b63b9a3..0823e09110 100644
--- a/scene/2d/parallax_layer.cpp
+++ b/scene/2d/parallax_layer.cpp
@@ -69,6 +69,9 @@ Size2 ParallaxLayer::get_motion_offset() const {
void ParallaxLayer::_update_mirroring() {
+ if (!is_inside_tree())
+ return;
+
ParallaxBackground *pb = Object::cast_to<ParallaxBackground>(get_parent());
if (pb) {
diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp
index f2f53d4354..55c8c7f229 100644
--- a/scene/2d/path_2d.cpp
+++ b/scene/2d/path_2d.cpp
@@ -110,7 +110,7 @@ void Path2D::_notification(int p_what) {
real_t frac = j / 8.0;
Vector2 p = curve->interpolate(i, frac);
- draw_line(prev_p, p, color, line_width);
+ draw_line(prev_p, p, color, line_width, true);
prev_p = p;
}
}
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 39b3375f09..28f7243c44 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -157,10 +157,7 @@ void PhysicsBody2D::add_collision_exception_with(Node *p_node) {
ERR_FAIL_NULL(p_node);
PhysicsBody2D *physics_body = Object::cast_to<PhysicsBody2D>(p_node);
- if (!physics_body) {
- ERR_EXPLAIN("Collision exception only works between two objects of PhysicsBody type");
- }
- ERR_FAIL_COND(!physics_body);
+ ERR_FAIL_COND_MSG(!physics_body, "Collision exception only works between two objects of PhysicsBody type.");
Physics2DServer::get_singleton()->body_add_collision_exception(get_rid(), physics_body->get_rid());
}
@@ -168,10 +165,7 @@ void PhysicsBody2D::remove_collision_exception_with(Node *p_node) {
ERR_FAIL_NULL(p_node);
PhysicsBody2D *physics_body = Object::cast_to<PhysicsBody2D>(p_node);
- if (!physics_body) {
- ERR_EXPLAIN("Collision exception only works between two objects of PhysicsBody type");
- }
- ERR_FAIL_COND(!physics_body);
+ ERR_FAIL_COND_MSG(!physics_body, "Collision exception only works between two objects of PhysicsBody type.");
Physics2DServer::get_singleton()->body_remove_collision_exception(get_rid(), physics_body->get_rid());
}
@@ -203,8 +197,7 @@ void StaticBody2D::set_friction(real_t p_friction) {
return;
}
- ERR_EXPLAIN("The method set_friction has been deprecated and will be removed in the future, use physics material instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The method set_friction has been deprecated and will be removed in the future, use physics material instead.");
ERR_FAIL_COND(p_friction < 0 || p_friction > 1);
@@ -217,8 +210,7 @@ void StaticBody2D::set_friction(real_t p_friction) {
real_t StaticBody2D::get_friction() const {
- ERR_EXPLAIN("The method get_friction has been deprecated and will be removed in the future, use physics material instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The method get_friction has been deprecated and will be removed in the future, use physics material instead.");
if (physics_material_override.is_null()) {
return 1;
@@ -233,8 +225,7 @@ void StaticBody2D::set_bounce(real_t p_bounce) {
return;
}
- ERR_EXPLAIN("The method set_bounce has been deprecated and will be removed in the future, use physics material instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The method set_bounce has been deprecated and will be removed in the future, use physics material instead.");
ERR_FAIL_COND(p_bounce < 0 || p_bounce > 1);
@@ -247,8 +238,7 @@ void StaticBody2D::set_bounce(real_t p_bounce) {
real_t StaticBody2D::get_bounce() const {
- ERR_EXPLAIN("The method get_bounce has been deprecated and will be removed in the future, use physics material instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The method get_bounce has been deprecated and will be removed in the future, use physics material instead.");
if (physics_material_override.is_null()) {
return 0;
@@ -604,7 +594,7 @@ real_t RigidBody2D::get_mass() const {
void RigidBody2D::set_inertia(real_t p_inertia) {
- ERR_FAIL_COND(p_inertia <= 0);
+ ERR_FAIL_COND(p_inertia < 0);
Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_INERTIA, p_inertia);
}
@@ -630,8 +620,7 @@ void RigidBody2D::set_friction(real_t p_friction) {
return;
}
- ERR_EXPLAIN("The method set_friction has been deprecated and will be removed in the future, use physics material instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The method set_friction has been deprecated and will be removed in the future, use physics material instead.");
ERR_FAIL_COND(p_friction < 0 || p_friction > 1);
@@ -643,8 +632,7 @@ void RigidBody2D::set_friction(real_t p_friction) {
}
real_t RigidBody2D::get_friction() const {
- ERR_EXPLAIN("The method get_friction has been deprecated and will be removed in the future, use physics material instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The method get_friction has been deprecated and will be removed in the future, use physics material instead.");
if (physics_material_override.is_null()) {
return 1;
@@ -659,8 +647,7 @@ void RigidBody2D::set_bounce(real_t p_bounce) {
return;
}
- ERR_EXPLAIN("The method set_bounce has been deprecated and will be removed in the future, use physics material instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The method set_bounce has been deprecated and will be removed in the future, use physics material instead.");
ERR_FAIL_COND(p_bounce < 0 || p_bounce > 1);
@@ -672,8 +659,7 @@ void RigidBody2D::set_bounce(real_t p_bounce) {
}
real_t RigidBody2D::get_bounce() const {
- ERR_EXPLAIN("The method get_bounce has been deprecated and will be removed in the future, use physics material instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The method get_bounce has been deprecated and will be removed in the future, use physics material instead.");
if (physics_material_override.is_null()) {
return 0;
@@ -905,10 +891,7 @@ void RigidBody2D::set_contact_monitor(bool p_enabled) {
if (!p_enabled) {
- if (contact_monitor->locked) {
- ERR_EXPLAIN("Can't disable contact monitoring during in/out callback. Use call_deferred(\"set_contact_monitor\",false) instead");
- }
- ERR_FAIL_COND(contact_monitor->locked);
+ ERR_FAIL_COND_MSG(contact_monitor->locked, "Can't disable contact monitoring during in/out callback. Use call_deferred(\"set_contact_monitor\", false) instead.");
for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) {
@@ -1074,10 +1057,10 @@ void RigidBody2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep");
ADD_GROUP("Linear", "linear_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "linear_velocity"), "set_linear_velocity", "get_linear_velocity");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "-1,128,0.01"), "set_linear_damp", "get_linear_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp");
ADD_GROUP("Angular", "angular_");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_velocity"), "set_angular_velocity", "get_angular_velocity");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "-1,128,0.01"), "set_angular_damp", "get_angular_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp");
ADD_GROUP("Applied Forces", "applied_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "applied_force"), "set_applied_force", "get_applied_force");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "applied_torque"), "set_applied_torque", "get_applied_torque");
@@ -1226,7 +1209,7 @@ bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_
return colliding;
}
-//so, if you pass 45 as limit, avoid numerical precision erros when angle is 45.
+//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) {
@@ -1283,7 +1266,7 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
//all is a wall
on_wall = true;
} else {
- if (collision.normal.dot(p_floor_direction) >= Math::cos(p_floor_max_angle + FLOOR_ANGLE_THRESHOLD)) { //floor
+ if (Math::acos(collision.normal.dot(p_floor_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor
on_floor = true;
on_floor_body = collision.collider_rid;
@@ -1298,7 +1281,7 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
}
}
- } else if (collision.normal.dot(-p_floor_direction) >= Math::cos(p_floor_max_angle + FLOOR_ANGLE_THRESHOLD)) { //ceiling
+ } else if (Math::acos(collision.normal.dot(-p_floor_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling
on_ceiling = true;
} else {
on_wall = true;
@@ -1463,6 +1446,14 @@ void KinematicBody2D::_direct_state_changed(Object *p_state) {
void KinematicBody2D::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
last_valid_transform = get_global_transform();
+
+ // Reset move_and_slide() data.
+ on_floor = false;
+ on_floor_body = RID();
+ on_ceiling = false;
+ on_wall = false;
+ colliders.clear();
+ floor_velocity = Vector2();
}
if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) {
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..5e6717a3f5 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_coord);
+ Vector2 get_frame_coords() const;
+
void set_vframes(int p_amount);
int get_vframes() const;
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index c79cd80e2e..15423f8c5e 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -1203,6 +1203,8 @@ void TileMap::clear() {
void TileMap::_set_tile_data(const PoolVector<int> &p_data) {
+ ERR_FAIL_COND(format > FORMAT_2);
+
int c = p_data.size();
PoolVector<int>::Read r = p_data.read();
@@ -1245,8 +1247,6 @@ void TileMap::_set_tile_data(const PoolVector<int> &p_data) {
set_cell(x, y, v, flip_h, flip_v, transpose, Vector2(coord_x, coord_y));
}
-
- format = FORMAT_2;
}
PoolVector<int> TileMap::_get_tile_data() const {
@@ -1255,7 +1255,7 @@ PoolVector<int> TileMap::_get_tile_data() const {
data.resize(tile_map.size() * 3);
PoolVector<int>::Write w = data.write();
- format = FORMAT_2;
+ // Save in highest format
int idx = 0;
for (const Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) {
@@ -1560,7 +1560,7 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) {
if (p_name == "format") {
if (p_value.get_type() == Variant::INT) {
- format = (DataFormat)(p_value.operator int64_t());
+ format = (DataFormat)(p_value.operator int64_t()); // Set format used for loading
return true;
}
} else if (p_name == "tile_data") {
@@ -1576,7 +1576,7 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) {
bool TileMap::_get(const StringName &p_name, Variant &r_ret) const {
if (p_name == "format") {
- r_ret = format;
+ r_ret = FORMAT_2; // When saving, always save highest format
return true;
} else if (p_name == "tile_data") {
r_ret = _get_tile_data();
@@ -1909,6 +1909,8 @@ void TileMap::_bind_methods() {
ADD_GROUP("Occluder", "occluder_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "occluder_light_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_occluder_light_mask", "get_occluder_light_mask");
+ ADD_PROPERTY_DEFAULT("format", FORMAT_1);
+
ADD_SIGNAL(MethodInfo("settings_changed"));
BIND_CONSTANT(INVALID_CELL);
@@ -1942,6 +1944,7 @@ TileMap::TileMap() {
quadrant_order_dirty = false;
quadrant_size = 16;
cell_size = Size2(64, 64);
+ custom_transform = Transform2D(64, 0, 0, 64, 0, 0);
collision_layer = 1;
collision_mask = 1;
friction = 1;
@@ -1957,7 +1960,7 @@ TileMap::TileMap() {
centered_textures = false;
occluder_light_mask = 1;
clip_uv = false;
- format = FORMAT_1; //Always initialize with the lowest format
+ format = FORMAT_1; // Assume lowest possible format if none is present
fp_adjust = 0.00001;
tile_origin = TILE_ORIGIN_TOP_LEFT;