summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/area_2d.cpp28
-rw-r--r--scene/2d/collision_object_2d.cpp24
-rw-r--r--scene/2d/physics_body_2d.cpp161
-rw-r--r--scene/2d/physics_body_2d.h33
-rw-r--r--scene/2d/tile_map.cpp140
-rw-r--r--scene/3d/area_3d.cpp28
-rw-r--r--scene/3d/collision_object_3d.cpp40
-rw-r--r--scene/3d/mesh_instance_3d.cpp4
-rw-r--r--scene/3d/physics_body_3d.cpp190
-rw-r--r--scene/3d/physics_body_3d.h24
-rw-r--r--scene/animation/animation_blend_tree.cpp54
-rw-r--r--scene/animation/animation_node_state_machine.cpp18
-rw-r--r--scene/animation/animation_player.cpp44
-rw-r--r--scene/debugger/scene_debugger.cpp16
-rw-r--r--scene/gui/code_edit.cpp16
-rw-r--r--scene/gui/graph_node.cpp12
-rw-r--r--scene/gui/grid_container.cpp20
-rw-r--r--scene/main/node.cpp26
-rw-r--r--scene/main/resource_preloader.cpp8
-rw-r--r--scene/resources/curve.cpp8
-rw-r--r--scene/resources/mesh.cpp4
-rw-r--r--scene/resources/mesh_library.cpp14
-rw-r--r--scene/resources/navigation_mesh.cpp8
-rw-r--r--scene/resources/packed_scene.cpp22
-rw-r--r--scene/resources/resource_format_text.cpp32
-rw-r--r--scene/resources/shader.cpp4
-rw-r--r--scene/resources/sprite_frames.cpp20
-rw-r--r--scene/resources/texture.cpp2
-rw-r--r--scene/resources/tile_set.cpp164
-rw-r--r--scene/resources/tile_set.h2
-rw-r--r--scene/resources/visual_shader.cpp52
31 files changed, 668 insertions, 550 deletions
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp
index d78b9847e6..33b1c7bcce 100644
--- a/scene/2d/area_2d.cpp
+++ b/scene/2d/area_2d.cpp
@@ -300,8 +300,8 @@ void Area2D::_clear_monitoring() {
body_map.clear();
//disconnect all monitored stuff
- for (Map<ObjectID, BodyState>::Element *E = bmcopy.front(); E; E = E->next()) {
- Object *obj = ObjectDB::get_instance(E->key());
+ for (const KeyValue<ObjectID, BodyState> &E : bmcopy) {
+ Object *obj = ObjectDB::get_instance(E.key);
Node *node = Object::cast_to<Node>(obj);
if (!node) { //node may have been deleted in previous frame or at other legitimate point
@@ -311,12 +311,12 @@ void Area2D::_clear_monitoring() {
node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_body_enter_tree));
node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_body_exit_tree));
- if (!E->get().in_tree) {
+ if (!E.value.in_tree) {
continue;
}
- for (int i = 0; i < E->get().shapes.size(); i++) {
- emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->get().rid, node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape);
+ for (int i = 0; i < E.value.shapes.size(); i++) {
+ emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E.value.rid, node, E.value.shapes[i].body_shape, E.value.shapes[i].area_shape);
}
emit_signal(SceneStringNames::get_singleton()->body_exited, obj);
@@ -328,8 +328,8 @@ void Area2D::_clear_monitoring() {
area_map.clear();
//disconnect all monitored stuff
- for (Map<ObjectID, AreaState>::Element *E = bmcopy.front(); E; E = E->next()) {
- Object *obj = ObjectDB::get_instance(E->key());
+ for (const KeyValue<ObjectID, AreaState> &E : bmcopy) {
+ Object *obj = ObjectDB::get_instance(E.key);
Node *node = Object::cast_to<Node>(obj);
if (!node) { //node may have been deleted in previous frame or at other legitimate point
@@ -339,12 +339,12 @@ void Area2D::_clear_monitoring() {
node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_area_enter_tree));
node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_area_exit_tree));
- if (!E->get().in_tree) {
+ if (!E.value.in_tree) {
continue;
}
- for (int i = 0; i < E->get().shapes.size(); i++) {
- emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E->get().rid, node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape);
+ for (int i = 0; i < E.value.shapes.size(); i++) {
+ emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E.value.rid, node, E.value.shapes[i].area_shape, E.value.shapes[i].self_shape);
}
emit_signal(SceneStringNames::get_singleton()->area_exited, obj);
@@ -404,8 +404,8 @@ TypedArray<Node2D> Area2D::get_overlapping_bodies() const {
TypedArray<Node2D> ret;
ret.resize(body_map.size());
int idx = 0;
- for (const Map<ObjectID, BodyState>::Element *E = body_map.front(); E; E = E->next()) {
- Object *obj = ObjectDB::get_instance(E->key());
+ for (const KeyValue<ObjectID, BodyState> &E : body_map) {
+ Object *obj = ObjectDB::get_instance(E.key);
if (!obj) {
ret.resize(ret.size() - 1); //ops
} else {
@@ -421,8 +421,8 @@ TypedArray<Area2D> Area2D::get_overlapping_areas() const {
TypedArray<Area2D> ret;
ret.resize(area_map.size());
int idx = 0;
- for (const Map<ObjectID, AreaState>::Element *E = area_map.front(); E; E = E->next()) {
- Object *obj = ObjectDB::get_instance(E->key());
+ for (const KeyValue<ObjectID, AreaState> &E : area_map) {
+ Object *obj = ObjectDB::get_instance(E.key);
if (!obj) {
ret.resize(ret.size() - 1); //ops
} else {
diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp
index 5d3a538f60..6916f832d0 100644
--- a/scene/2d/collision_object_2d.cpp
+++ b/scene/2d/collision_object_2d.cpp
@@ -342,15 +342,15 @@ real_t CollisionObject2D::get_shape_owner_one_way_collision_margin(uint32_t p_ow
}
void CollisionObject2D::get_shape_owners(List<uint32_t> *r_owners) {
- for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
- r_owners->push_back(E->key());
+ for (const KeyValue<uint32_t, ShapeData> &E : shapes) {
+ r_owners->push_back(E.key);
}
}
Array CollisionObject2D::_get_shape_owners() {
Array ret;
- for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
- ret.push_back(E->key());
+ for (const KeyValue<uint32_t, ShapeData> &E : shapes) {
+ ret.push_back(E.key);
}
return ret;
@@ -434,10 +434,10 @@ void CollisionObject2D::shape_owner_remove_shape(uint32_t p_owner, int p_shape)
shapes[p_owner].shapes.remove(p_shape);
- for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
- for (int i = 0; i < E->get().shapes.size(); i++) {
- if (E->get().shapes[i].index > index_to_remove) {
- E->get().shapes.write[i].index -= 1;
+ for (KeyValue<uint32_t, ShapeData> &E : shapes) {
+ for (int i = 0; i < E.value.shapes.size(); i++) {
+ if (E.value.shapes[i].index > index_to_remove) {
+ E.value.shapes.write[i].index -= 1;
}
}
}
@@ -456,10 +456,10 @@ void CollisionObject2D::shape_owner_clear_shapes(uint32_t p_owner) {
uint32_t CollisionObject2D::shape_find_owner(int p_shape_index) const {
ERR_FAIL_INDEX_V(p_shape_index, total_subshapes, 0);
- for (const Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
- for (int i = 0; i < E->get().shapes.size(); i++) {
- if (E->get().shapes[i].index == p_shape_index) {
- return E->key();
+ for (const KeyValue<uint32_t, ShapeData> &E : shapes) {
+ for (int i = 0; i < E.value.shapes.size(); i++) {
+ if (E.value.shapes[i].index == p_shape_index) {
+ return E.key;
}
}
}
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index d34a1e1c62..5f56f86029 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -462,9 +462,9 @@ void RigidDynamicBody2D::_body_state_changed(PhysicsDirectBodyState2D *p_state)
//untag all
int rc = 0;
- for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) {
- for (int i = 0; i < E->get().shapes.size(); i++) {
- E->get().shapes[i].tagged = false;
+ for (KeyValue<ObjectID, BodyState> &E : contact_monitor->body_map) {
+ for (int i = 0; i < E.value.shapes.size(); i++) {
+ E.value.shapes[i].tagged = false;
rc++;
}
}
@@ -508,12 +508,12 @@ void RigidDynamicBody2D::_body_state_changed(PhysicsDirectBodyState2D *p_state)
//put the ones to remove
- for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) {
- for (int i = 0; i < E->get().shapes.size(); i++) {
- if (!E->get().shapes[i].tagged) {
- toremove[toremove_count].rid = E->get().rid;
- toremove[toremove_count].body_id = E->key();
- toremove[toremove_count].pair = E->get().shapes[i];
+ for (const KeyValue<ObjectID, BodyState> &E : contact_monitor->body_map) {
+ for (int i = 0; i < E.value.shapes.size(); i++) {
+ if (!E.value.shapes[i].tagged) {
+ toremove[toremove_count].rid = E.value.rid;
+ toremove[toremove_count].body_id = E.key;
+ toremove[toremove_count].pair = E.value.shapes[i];
toremove_count++;
}
}
@@ -820,8 +820,8 @@ TypedArray<Node2D> RigidDynamicBody2D::get_colliding_bodies() const {
TypedArray<Node2D> ret;
ret.resize(contact_monitor->body_map.size());
int idx = 0;
- for (const Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) {
- Object *obj = ObjectDB::get_instance(E->key());
+ for (const KeyValue<ObjectID, BodyState> &E : contact_monitor->body_map) {
+ Object *obj = ObjectDB::get_instance(E.key);
if (!obj) {
ret.resize(ret.size() - 1); //ops
} else {
@@ -840,9 +840,9 @@ void RigidDynamicBody2D::set_contact_monitor(bool p_enabled) {
if (!p_enabled) {
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()) {
+ for (const KeyValue<ObjectID, BodyState> &E : contact_monitor->body_map) {
//clean up mess
- Object *obj = ObjectDB::get_instance(E->key());
+ Object *obj = ObjectDB::get_instance(E.key);
Node *node = Object::cast_to<Node>(obj);
if (node) {
@@ -1052,6 +1052,8 @@ bool CharacterBody2D::move_and_slide() {
double delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time();
Vector2 current_platform_velocity = platform_velocity;
+ Transform2D gt = get_global_transform();
+ previous_position = gt.elements[2];
if ((on_floor || on_wall) && platform_rid.is_valid()) {
bool excluded = false;
@@ -1064,7 +1066,6 @@ bool CharacterBody2D::move_and_slide() {
//this approach makes sure there is less delay between the actual body velocity and the one we saved
PhysicsDirectBodyState2D *bs = PhysicsServer2D::get_singleton()->body_get_direct_state(platform_rid);
if (bs) {
- Transform2D gt = get_global_transform();
Vector2 local_position = gt.elements[2] - bs->get_transform().elements[2];
current_platform_velocity = bs->get_velocity_at_local_position(local_position);
}
@@ -1074,6 +1075,7 @@ bool CharacterBody2D::move_and_slide() {
}
motion_results.clear();
+ last_motion = Vector2();
bool was_on_floor = on_floor;
on_floor = false;
@@ -1096,16 +1098,24 @@ bool CharacterBody2D::move_and_slide() {
_move_and_slide_free(delta);
}
- if (!on_floor && !on_wall) {
+ // Compute real velocity.
+ real_velocity = get_position_delta() / delta;
+
+ if (moving_platform_apply_velocity_on_leave != PLATFORM_VEL_ON_LEAVE_NEVER) {
// Add last platform velocity when just left a moving platform.
- linear_velocity += current_platform_velocity;
+ if (!on_floor && !on_wall) {
+ if (moving_platform_apply_velocity_on_leave == PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY && current_platform_velocity.dot(up_direction) < 0) {
+ current_platform_velocity = current_platform_velocity.slide(up_direction);
+ }
+ motion_velocity += current_platform_velocity;
+ }
}
return motion_results.size() > 0;
}
void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_floor, const Vector2 &p_prev_platform_velocity) {
- Vector2 motion = linear_velocity * p_delta;
+ Vector2 motion = motion_velocity * p_delta;
Vector2 motion_slide_up = motion.slide(up_direction);
Vector2 prev_floor_normal = floor_normal;
@@ -1121,8 +1131,10 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
bool sliding_enabled = !floor_stop_on_slope;
// Constant speed can be applied only the first time sliding is enabled.
bool can_apply_constant_speed = sliding_enabled;
+ // If the platform's ceiling push down the body.
+ bool apply_ceiling_velocity = false;
bool first_slide = true;
- bool vel_dir_facing_up = linear_velocity.dot(up_direction) > 0;
+ bool vel_dir_facing_up = motion_velocity.dot(up_direction) > 0;
Vector2 last_travel;
for (int iteration = 0; iteration < max_slides; ++iteration) {
@@ -1131,18 +1143,33 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
Vector2 prev_position = get_global_transform().elements[2];
bool collided = move_and_collide(motion, result, margin, false, !sliding_enabled);
+ last_motion = result.travel;
if (collided) {
motion_results.push_back(result);
_set_collision_direction(result);
- if (on_floor && floor_stop_on_slope && (linear_velocity.normalized() + up_direction).length() < 0.01) {
+ // If we hit a ceiling platform, we set the vertical motion_velocity to at least the platform one.
+ if (on_ceiling && result.collider_velocity != Vector2() && result.collider_velocity.dot(up_direction) < 0) {
+ // If ceiling sliding is on, only apply when the ceiling is flat or when the motion is upward.
+ if (!slide_on_ceiling || motion.dot(up_direction) < 0 || (result.collision_normal + up_direction).length() < 0.01) {
+ apply_ceiling_velocity = true;
+ Vector2 ceiling_vertical_velocity = up_direction * up_direction.dot(result.collider_velocity);
+ Vector2 motion_vertical_velocity = up_direction * up_direction.dot(motion_velocity);
+ if (motion_vertical_velocity.dot(up_direction) > 0 || ceiling_vertical_velocity.length_squared() > motion_vertical_velocity.length_squared()) {
+ motion_velocity = ceiling_vertical_velocity + motion_velocity.slide(up_direction);
+ }
+ }
+ }
+
+ if (on_floor && floor_stop_on_slope && (motion_velocity.normalized() + up_direction).length() < 0.01) {
Transform2D gt = get_global_transform();
if (result.travel.length() <= margin + CMP_EPSILON) {
gt.elements[2] -= result.travel;
}
set_global_transform(gt);
- linear_velocity = Vector2();
+ motion_velocity = Vector2();
+ last_motion = Vector2();
motion = Vector2();
break;
}
@@ -1168,7 +1195,8 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
platform_layer = prev_platform_layer;
platform_velocity = p_prev_platform_velocity;
floor_normal = prev_floor_normal;
- linear_velocity = Vector2();
+ motion_velocity = Vector2();
+ last_motion = Vector2();
motion = Vector2();
break;
}
@@ -1187,9 +1215,9 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
motion = motion_slide_norm * (motion_slide_up.length() - result.travel.slide(up_direction).length() - last_travel.slide(up_direction).length());
}
// Regular sliding, the last part of the test handle the case when you don't want to slide on the ceiling.
- else if ((sliding_enabled || !on_floor) && (!on_ceiling || slide_on_ceiling || !vel_dir_facing_up)) {
+ else if ((sliding_enabled || !on_floor) && (!on_ceiling || slide_on_ceiling || !vel_dir_facing_up) && !apply_ceiling_velocity) {
Vector2 slide_motion = result.remainder.slide(result.collision_normal);
- if (slide_motion.dot(linear_velocity) > 0.0) {
+ if (slide_motion.dot(motion_velocity) > 0.0) {
motion = slide_motion;
} else {
motion = Vector2();
@@ -1197,10 +1225,10 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
if (slide_on_ceiling && on_ceiling) {
// Apply slide only in the direction of the input motion, otherwise just stop to avoid jittering when moving against a wall.
if (vel_dir_facing_up) {
- linear_velocity = linear_velocity.slide(result.collision_normal);
+ motion_velocity = motion_velocity.slide(result.collision_normal);
} else {
// Avoid acceleration in slope when falling.
- linear_velocity = up_direction * up_direction.dot(linear_velocity);
+ motion_velocity = up_direction * up_direction.dot(motion_velocity);
}
}
}
@@ -1208,7 +1236,7 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
else {
motion = result.remainder;
if (on_ceiling && !slide_on_ceiling && vel_dir_facing_up) {
- linear_velocity = linear_velocity.slide(up_direction);
+ motion_velocity = motion_velocity.slide(up_direction);
motion = motion.slide(up_direction);
}
}
@@ -1242,12 +1270,12 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
// Reset the gravity accumulation when touching the ground.
if (on_floor && !vel_dir_facing_up) {
- linear_velocity = linear_velocity.slide(up_direction);
+ motion_velocity = motion_velocity.slide(up_direction);
}
}
void CharacterBody2D::_move_and_slide_free(double p_delta) {
- Vector2 motion = linear_velocity * p_delta;
+ Vector2 motion = motion_velocity * p_delta;
platform_rid = RID();
floor_normal = Vector2();
@@ -1258,12 +1286,18 @@ void CharacterBody2D::_move_and_slide_free(double p_delta) {
PhysicsServer2D::MotionResult result;
bool collided = move_and_collide(motion, result, margin, false, false);
+ last_motion = result.travel;
if (collided) {
motion_results.push_back(result);
_set_collision_direction(result);
- if (free_mode_min_slide_angle != 0 && result.get_angle(-linear_velocity.normalized()) < free_mode_min_slide_angle + FLOOR_ANGLE_THRESHOLD) {
+ if (result.remainder.is_equal_approx(Vector2())) {
+ motion = Vector2();
+ break;
+ }
+
+ if (free_mode_min_slide_angle != 0 && result.get_angle(-motion_velocity.normalized()) < free_mode_min_slide_angle + FLOOR_ANGLE_THRESHOLD) {
motion = Vector2();
} else if (first_slide) {
Vector2 motion_slide_norm = result.remainder.slide(result.collision_normal).normalized();
@@ -1272,16 +1306,16 @@ void CharacterBody2D::_move_and_slide_free(double p_delta) {
motion = result.remainder.slide(result.collision_normal);
}
- if (motion.dot(linear_velocity) <= 0.0) {
+ if (motion.dot(motion_velocity) <= 0.0) {
motion = Vector2();
}
}
- first_slide = false;
-
if (!collided || motion.is_equal_approx(Vector2())) {
break;
}
+
+ first_slide = false;
}
}
@@ -1349,6 +1383,7 @@ void CharacterBody2D::_set_collision_direction(const PhysicsServer2D::MotionResu
on_ceiling = true;
} else {
on_wall = true;
+ wall_normal = p_result.collision_normal;
// Don't apply wall velocity when the collider is a CharacterBody2D.
if (Object::cast_to<CharacterBody2D>(ObjectDB::get_instance(p_result.collider_id)) == nullptr) {
_set_platform_data(p_result);
@@ -1362,12 +1397,12 @@ void CharacterBody2D::_set_platform_data(const PhysicsServer2D::MotionResult &p_
platform_layer = PhysicsServer2D::get_singleton()->body_get_collision_layer(platform_rid);
}
-const Vector2 &CharacterBody2D::get_linear_velocity() const {
- return linear_velocity;
+const Vector2 &CharacterBody2D::get_motion_velocity() const {
+ return motion_velocity;
}
-void CharacterBody2D::set_linear_velocity(const Vector2 &p_velocity) {
- linear_velocity = p_velocity;
+void CharacterBody2D::set_motion_velocity(const Vector2 &p_velocity) {
+ motion_velocity = p_velocity;
}
bool CharacterBody2D::is_on_floor() const {
@@ -1394,16 +1429,32 @@ bool CharacterBody2D::is_on_ceiling_only() const {
return on_ceiling && !on_floor && !on_wall;
}
-Vector2 CharacterBody2D::get_floor_normal() const {
+const Vector2 &CharacterBody2D::get_floor_normal() const {
return floor_normal;
}
+const Vector2 &CharacterBody2D::get_wall_normal() const {
+ return wall_normal;
+}
+
+const Vector2 &CharacterBody2D::get_last_motion() const {
+ return last_motion;
+}
+
+Vector2 CharacterBody2D::get_position_delta() const {
+ return get_global_transform().elements[2] - previous_position;
+}
+
+const Vector2 &CharacterBody2D::get_real_velocity() const {
+ return real_velocity;
+}
+
real_t CharacterBody2D::get_floor_angle(const Vector2 &p_up_direction) const {
ERR_FAIL_COND_V(p_up_direction == Vector2(), 0);
return Math::acos(floor_normal.dot(p_up_direction));
}
-Vector2 CharacterBody2D::get_platform_velocity() const {
+const Vector2 &CharacterBody2D::get_platform_velocity() const {
return platform_velocity;
}
@@ -1503,6 +1554,14 @@ CharacterBody2D::MotionMode CharacterBody2D::get_motion_mode() const {
return motion_mode;
}
+void CharacterBody2D::set_moving_platform_apply_velocity_on_leave(MovingPlatformApplyVelocityOnLeave p_on_leave_apply_velocity) {
+ moving_platform_apply_velocity_on_leave = p_on_leave_apply_velocity;
+}
+
+CharacterBody2D::MovingPlatformApplyVelocityOnLeave CharacterBody2D::get_moving_platform_apply_velocity_on_leave() const {
+ return moving_platform_apply_velocity_on_leave;
+}
+
int CharacterBody2D::get_max_slides() const {
return max_slides;
}
@@ -1563,8 +1622,8 @@ void CharacterBody2D::_notification(int p_what) {
void CharacterBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("move_and_slide"), &CharacterBody2D::move_and_slide);
- ClassDB::bind_method(D_METHOD("set_linear_velocity", "linear_velocity"), &CharacterBody2D::set_linear_velocity);
- ClassDB::bind_method(D_METHOD("get_linear_velocity"), &CharacterBody2D::get_linear_velocity);
+ ClassDB::bind_method(D_METHOD("set_motion_velocity", "motion_velocity"), &CharacterBody2D::set_motion_velocity);
+ ClassDB::bind_method(D_METHOD("get_motion_velocity"), &CharacterBody2D::get_motion_velocity);
ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &CharacterBody2D::set_safe_margin);
ClassDB::bind_method(D_METHOD("get_safe_margin"), &CharacterBody2D::get_safe_margin);
@@ -1594,6 +1653,8 @@ void CharacterBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_up_direction", "up_direction"), &CharacterBody2D::set_up_direction);
ClassDB::bind_method(D_METHOD("set_motion_mode", "mode"), &CharacterBody2D::set_motion_mode);
ClassDB::bind_method(D_METHOD("get_motion_mode"), &CharacterBody2D::get_motion_mode);
+ ClassDB::bind_method(D_METHOD("set_moving_platform_apply_velocity_on_leave", "on_leave_apply_velocity"), &CharacterBody2D::set_moving_platform_apply_velocity_on_leave);
+ ClassDB::bind_method(D_METHOD("get_moving_platform_apply_velocity_on_leave"), &CharacterBody2D::get_moving_platform_apply_velocity_on_leave);
ClassDB::bind_method(D_METHOD("is_on_floor"), &CharacterBody2D::is_on_floor);
ClassDB::bind_method(D_METHOD("is_on_floor_only"), &CharacterBody2D::is_on_floor_only);
@@ -1602,6 +1663,10 @@ void CharacterBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_on_wall"), &CharacterBody2D::is_on_wall);
ClassDB::bind_method(D_METHOD("is_on_wall_only"), &CharacterBody2D::is_on_wall_only);
ClassDB::bind_method(D_METHOD("get_floor_normal"), &CharacterBody2D::get_floor_normal);
+ ClassDB::bind_method(D_METHOD("get_wall_normal"), &CharacterBody2D::get_wall_normal);
+ ClassDB::bind_method(D_METHOD("get_last_motion"), &CharacterBody2D::get_last_motion);
+ ClassDB::bind_method(D_METHOD("get_position_delta"), &CharacterBody2D::get_position_delta);
+ ClassDB::bind_method(D_METHOD("get_real_velocity"), &CharacterBody2D::get_real_velocity);
ClassDB::bind_method(D_METHOD("get_floor_angle", "up_direction"), &CharacterBody2D::get_floor_angle, DEFVAL(Vector2(0.0, -1.0)));
ClassDB::bind_method(D_METHOD("get_platform_velocity"), &CharacterBody2D::get_platform_velocity);
ClassDB::bind_method(D_METHOD("get_slide_collision_count"), &CharacterBody2D::get_slide_collision_count);
@@ -1609,10 +1674,11 @@ void CharacterBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_last_slide_collision"), &CharacterBody2D::_get_last_slide_collision);
ADD_PROPERTY(PropertyInfo(Variant::INT, "motion_mode", PROPERTY_HINT_ENUM, "Grounded,Free", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_motion_mode", "get_motion_mode");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "linear_velocity"), "set_linear_velocity", "get_linear_velocity");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "up_direction"), "set_up_direction", "get_up_direction");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "motion_velocity", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_motion_velocity", "get_motion_velocity");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slide_on_ceiling"), "set_slide_on_ceiling_enabled", "is_slide_on_ceiling_enabled");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_slides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_max_slides", "get_max_slides");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "up_direction"), "set_up_direction", "get_up_direction");
+
ADD_GROUP("Free Mode", "free_mode_");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "free_mode_min_slide_angle", PROPERTY_HINT_RANGE, "0,180,0.1,radians", PROPERTY_USAGE_DEFAULT), "set_free_mode_min_slide_angle", "get_free_mode_min_slide_angle");
ADD_GROUP("Floor", "floor_");
@@ -1622,12 +1688,17 @@ void CharacterBody2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_max_angle", PROPERTY_HINT_RANGE, "0,180,0.1,radians"), "set_floor_max_angle", "get_floor_max_angle");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_snap_length", PROPERTY_HINT_RANGE, "0,32,0.1,or_greater"), "set_floor_snap_length", "get_floor_snap_length");
ADD_GROUP("Moving platform", "moving_platform");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "moving_platform_apply_velocity_on_leave", PROPERTY_HINT_ENUM, "Always,Upward Only,Never", PROPERTY_USAGE_DEFAULT), "set_moving_platform_apply_velocity_on_leave", "get_moving_platform_apply_velocity_on_leave");
ADD_PROPERTY(PropertyInfo(Variant::INT, "moving_platform_floor_layers", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_moving_platform_floor_layers", "get_moving_platform_floor_layers");
ADD_PROPERTY(PropertyInfo(Variant::INT, "moving_platform_wall_layers", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_moving_platform_wall_layers", "get_moving_platform_wall_layers");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin");
BIND_ENUM_CONSTANT(MOTION_MODE_GROUNDED);
BIND_ENUM_CONSTANT(MOTION_MODE_FREE);
+
+ BIND_ENUM_CONSTANT(PLATFORM_VEL_ON_LEAVE_ALWAYS);
+ BIND_ENUM_CONSTANT(PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY);
+ BIND_ENUM_CONSTANT(PLATFORM_VEL_ON_LEAVE_NEVER);
}
void CharacterBody2D::_validate_property(PropertyInfo &property) const {
@@ -1722,10 +1793,6 @@ Vector2 KinematicCollision2D::get_collider_velocity() const {
return result.collider_velocity;
}
-Variant KinematicCollision2D::get_collider_metadata() const {
- return Variant();
-}
-
void KinematicCollision2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_position"), &KinematicCollision2D::get_position);
ClassDB::bind_method(D_METHOD("get_normal"), &KinematicCollision2D::get_normal);
@@ -1739,7 +1806,6 @@ void KinematicCollision2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_collider_shape"), &KinematicCollision2D::get_collider_shape);
ClassDB::bind_method(D_METHOD("get_collider_shape_index"), &KinematicCollision2D::get_collider_shape_index);
ClassDB::bind_method(D_METHOD("get_collider_velocity"), &KinematicCollision2D::get_collider_velocity);
- ClassDB::bind_method(D_METHOD("get_collider_metadata"), &KinematicCollision2D::get_collider_metadata);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "", "get_position");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "normal"), "", "get_normal");
@@ -1752,5 +1818,4 @@ void KinematicCollision2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider_shape"), "", "get_collider_shape");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_shape_index"), "", "get_collider_shape_index");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "collider_velocity"), "", "get_collider_velocity");
- ADD_PROPERTY(PropertyInfo(Variant::NIL, "collider_metadata", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "", "get_collider_metadata");
}
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index e789ac4cb7..70cc5cd9bf 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -310,10 +310,15 @@ public:
MOTION_MODE_GROUNDED,
MOTION_MODE_FREE,
};
+ enum MovingPlatformApplyVelocityOnLeave {
+ PLATFORM_VEL_ON_LEAVE_ALWAYS,
+ PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY,
+ PLATFORM_VEL_ON_LEAVE_NEVER,
+ };
bool move_and_slide();
- const Vector2 &get_linear_velocity() const;
- void set_linear_velocity(const Vector2 &p_velocity);
+ const Vector2 &get_motion_velocity() const;
+ void set_motion_velocity(const Vector2 &p_velocity);
bool is_on_floor() const;
bool is_on_floor_only() const;
@@ -321,9 +326,14 @@ public:
bool is_on_wall_only() const;
bool is_on_ceiling() const;
bool is_on_ceiling_only() const;
- Vector2 get_floor_normal() const;
+ const Vector2 &get_last_motion() const;
+ Vector2 get_position_delta() const;
+ const Vector2 &get_floor_normal() const;
+ const Vector2 &get_wall_normal() const;
+ const Vector2 &get_real_velocity() const;
+
real_t get_floor_angle(const Vector2 &p_up_direction = Vector2(0.0, -1.0)) const;
- Vector2 get_platform_velocity() const;
+ const Vector2 &get_platform_velocity() const;
int get_slide_collision_count() const;
PhysicsServer2D::MotionResult get_slide_collision(int p_bounce) const;
@@ -334,23 +344,29 @@ public:
private:
real_t margin = 0.08;
MotionMode motion_mode = MOTION_MODE_GROUNDED;
+ MovingPlatformApplyVelocityOnLeave moving_platform_apply_velocity_on_leave = PLATFORM_VEL_ON_LEAVE_ALWAYS;
bool floor_constant_speed = false;
bool floor_stop_on_slope = true;
bool floor_block_on_wall = true;
bool slide_on_ceiling = true;
int max_slides = 4;
- int platform_layer;
+ int platform_layer = 0;
real_t floor_max_angle = Math::deg2rad((real_t)45.0);
real_t floor_snap_length = 1;
real_t free_mode_min_slide_angle = Math::deg2rad((real_t)15.0);
Vector2 up_direction = Vector2(0.0, -1.0);
uint32_t moving_platform_floor_layers = UINT32_MAX;
uint32_t moving_platform_wall_layers = 0;
- Vector2 linear_velocity;
+ Vector2 motion_velocity;
Vector2 floor_normal;
Vector2 platform_velocity;
+ Vector2 wall_normal;
+ Vector2 last_motion;
+ Vector2 previous_position;
+ Vector2 real_velocity;
+
RID platform_rid;
bool on_floor = false;
bool on_ceiling = false;
@@ -395,6 +411,9 @@ private:
void set_motion_mode(MotionMode p_mode);
MotionMode get_motion_mode() const;
+ void set_moving_platform_apply_velocity_on_leave(MovingPlatformApplyVelocityOnLeave p_on_leave_velocity);
+ MovingPlatformApplyVelocityOnLeave get_moving_platform_apply_velocity_on_leave() const;
+
void _move_and_slide_free(double p_delta);
void _move_and_slide_grounded(double p_delta, bool p_was_on_floor, const Vector2 &p_prev_platform_velocity);
@@ -414,6 +433,7 @@ protected:
};
VARIANT_ENUM_CAST(CharacterBody2D::MotionMode);
+VARIANT_ENUM_CAST(CharacterBody2D::MovingPlatformApplyVelocityOnLeave);
class KinematicCollision2D : public RefCounted {
GDCLASS(KinematicCollision2D, RefCounted);
@@ -439,7 +459,6 @@ public:
Object *get_collider_shape() const;
int get_collider_shape_index() const;
Vector2 get_collider_velocity() const;
- Variant get_collider_metadata() const;
};
#endif // PHYSICS_BODY_2D_H
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 78d018ac53..222ec986b0 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -51,8 +51,8 @@ void TileMapPattern::remove_cell(const Vector2i &p_coords, bool p_update_size) {
pattern.erase(p_coords);
if (p_update_size) {
size = Vector2i();
- for (Map<Vector2i, TileMapCell>::Element *E = pattern.front(); E; E = E->next()) {
- size = size.max(E->key() + Vector2i(1, 1));
+ for (const KeyValue<Vector2i, TileMapCell> &E : pattern) {
+ size = size.max(E.key + Vector2i(1, 1));
}
}
}
@@ -80,8 +80,8 @@ TypedArray<Vector2i> TileMapPattern::get_used_cells() const {
TypedArray<Vector2i> a;
a.resize(pattern.size());
int i = 0;
- for (Map<Vector2i, TileMapCell>::Element *E = pattern.front(); E; E = E->next()) {
- Vector2i p(E->key().x, E->key().y);
+ for (const KeyValue<Vector2i, TileMapCell> &E : pattern) {
+ Vector2i p(E.key.x, E.key.y);
a[i++] = p;
}
@@ -93,8 +93,8 @@ Vector2i TileMapPattern::get_size() const {
}
void TileMapPattern::set_size(const Vector2i &p_size) {
- for (Map<Vector2i, TileMapCell>::Element *E = pattern.front(); E; E = E->next()) {
- Vector2i coords = E->key();
+ for (const KeyValue<Vector2i, TileMapCell> &E : pattern) {
+ Vector2i coords = E.key;
if (p_size.x <= coords.x || p_size.y <= coords.y) {
ERR_FAIL_MSG(vformat("Cannot set pattern size to %s, it contains a tile at %s. Size can only be increased.", p_size, coords));
};
@@ -538,9 +538,9 @@ void TileMap::_make_quadrant_dirty(Map<Vector2i, TileMapQuadrant>::Element *Q) {
void TileMap::_make_all_quadrants_dirty() {
// Make all quandrants dirty, then trigger an update later.
for (unsigned int layer = 0; layer < layers.size(); layer++) {
- for (Map<Vector2i, TileMapQuadrant>::Element *E = layers[layer].quadrant_map.front(); E; E = E->next()) {
- if (!E->value().dirty_list_element.in_list()) {
- layers[layer].dirty_quadrant_list.add(&E->value().dirty_list_element);
+ for (KeyValue<Vector2i, TileMapQuadrant> &E : layers[layer].quadrant_map) {
+ if (!E.value.dirty_list_element.in_list()) {
+ layers[layer].dirty_quadrant_list.add(&E.value.dirty_list_element);
}
}
}
@@ -622,8 +622,8 @@ void TileMap::_recreate_internals() {
// Recreate the quadrants.
const Map<Vector2i, TileMapCell> &tile_map = layers[layer].tile_map;
- for (Map<Vector2i, TileMapCell>::Element *E = tile_map.front(); E; E = E->next()) {
- Vector2i qk = _coords_to_quadrant_coords(layer, Vector2i(E->key().x, E->key().y));
+ for (const KeyValue<Vector2i, TileMapCell> &E : tile_map) {
+ Vector2i qk = _coords_to_quadrant_coords(layer, Vector2i(E.key.x, E.key.y));
Map<Vector2i, TileMapQuadrant>::Element *Q = layers[layer].quadrant_map.find(qk);
if (!Q) {
@@ -631,7 +631,7 @@ void TileMap::_recreate_internals() {
layers[layer].dirty_quadrant_list.add(&Q->get().dirty_list_element);
}
- Vector2i pk = E->key();
+ Vector2i pk = E.key;
Q->get().cells.insert(pk);
_make_quadrant_dirty(Q);
@@ -700,7 +700,7 @@ void TileMap::_recompute_rect_cache() {
Rect2 r_total;
for (unsigned int layer = 0; layer < layers.size(); layer++) {
- for (Map<Vector2i, TileMapQuadrant>::Element *E = layers[layer].quadrant_map.front(); E; E = E->next()) {
+ for (const Map<Vector2i, TileMapQuadrant>::Element *E = layers[layer].quadrant_map.front(); E; E = E->next()) {
Rect2 r;
r.position = map_to_world(E->key() * get_effective_quadrant_size(layer));
r.expand_to(map_to_world((E->key() + Vector2i(1, 0)) * get_effective_quadrant_size(layer)));
@@ -729,13 +729,13 @@ void TileMap::_rendering_notification(int p_what) {
case CanvasItem::NOTIFICATION_VISIBILITY_CHANGED: {
bool visible = is_visible_in_tree();
for (int layer = 0; layer < (int)layers.size(); layer++) {
- for (Map<Vector2i, TileMapQuadrant>::Element *E_quadrant = layers[layer].quadrant_map.front(); E_quadrant; E_quadrant = E_quadrant->next()) {
- TileMapQuadrant &q = E_quadrant->get();
+ for (KeyValue<Vector2i, TileMapQuadrant> &E_quadrant : layers[layer].quadrant_map) {
+ TileMapQuadrant &q = E_quadrant.value;
// Update occluders transform.
- for (Map<Vector2i, Vector2i, TileMapQuadrant::CoordsWorldComparator>::Element *E_cell = q.world_to_map.front(); E_cell; E_cell = E_cell->next()) {
+ for (const KeyValue<Vector2i, Vector2i> &E_cell : q.world_to_map) {
Transform2D xform;
- xform.set_origin(E_cell->key());
+ xform.set_origin(E_cell.key);
for (const RID &occluder : q.occluders) {
RS::get_singleton()->canvas_light_occluder_set_enabled(occluder, visible);
}
@@ -748,13 +748,13 @@ void TileMap::_rendering_notification(int p_what) {
return;
}
for (int layer = 0; layer < (int)layers.size(); layer++) {
- for (Map<Vector2i, TileMapQuadrant>::Element *E_quadrant = layers[layer].quadrant_map.front(); E_quadrant; E_quadrant = E_quadrant->next()) {
- TileMapQuadrant &q = E_quadrant->get();
+ for (KeyValue<Vector2i, TileMapQuadrant> &E_quadrant : layers[layer].quadrant_map) {
+ TileMapQuadrant &q = E_quadrant.value;
// Update occluders transform.
- for (Map<Vector2i, Vector2i, TileMapQuadrant::CoordsWorldComparator>::Element *E_cell = q.world_to_map.front(); E_cell; E_cell = E_cell->next()) {
+ for (const KeyValue<Vector2i, Vector2i> &E_cell : q.world_to_map) {
Transform2D xform;
- xform.set_origin(E_cell->key());
+ xform.set_origin(E_cell.key);
for (const RID &occluder : q.occluders) {
RS::get_singleton()->canvas_light_occluder_set_transform(occluder, get_global_transform() * xform);
}
@@ -833,8 +833,8 @@ void TileMap::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::List
RID prev_canvas_item;
// Iterate over the cells of the quadrant.
- for (Map<Vector2i, Vector2i, TileMapQuadrant::CoordsWorldComparator>::Element *E_cell = q.world_to_map.front(); E_cell; E_cell = E_cell->next()) {
- TileMapCell c = get_cell(q.layer, E_cell->value(), true);
+ for (const KeyValue<Vector2i, Vector2i> &E_cell : q.world_to_map) {
+ TileMapCell c = get_cell(q.layer, E_cell.value, true);
TileSetSource *source;
if (tile_set->has_source(c.source_id)) {
@@ -903,12 +903,12 @@ void TileMap::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::List
modulate.a *= 0.3;
}
}
- draw_tile(canvas_item, E_cell->key() - position, tile_set, c.source_id, c.get_atlas_coords(), c.alternative_tile, -1, modulate);
+ draw_tile(canvas_item, E_cell.key - position, tile_set, c.source_id, c.get_atlas_coords(), c.alternative_tile, -1, modulate);
// --- Occluders ---
for (int i = 0; i < tile_set->get_occlusion_layers_count(); i++) {
Transform2D xform;
- xform.set_origin(E_cell->key());
+ xform.set_origin(E_cell.key);
if (tile_data->get_occluder(i).is_valid()) {
RID occluder_id = rs->canvas_light_occluder_create();
rs->canvas_light_occluder_set_enabled(occluder_id, visible);
@@ -934,13 +934,13 @@ void TileMap::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::List
for (int layer = 0; layer < (int)layers.size(); layer++) {
// Sort the quadrants coords per world coordinates
Map<Vector2i, Vector2i, TileMapQuadrant::CoordsWorldComparator> world_to_map;
- for (Map<Vector2i, TileMapQuadrant>::Element *E = layers[layer].quadrant_map.front(); E; E = E->next()) {
- world_to_map[map_to_world(E->key())] = E->key();
+ for (const KeyValue<Vector2i, TileMapQuadrant> &E : layers[layer].quadrant_map) {
+ world_to_map[map_to_world(E.key)] = E.key;
}
// Sort the quadrants
- for (Map<Vector2i, Vector2i, TileMapQuadrant::CoordsWorldComparator>::Element *E = world_to_map.front(); E; E = E->next()) {
- TileMapQuadrant &q = layers[layer].quadrant_map[E->value()];
+ for (const KeyValue<Vector2i, Vector2i> &E : world_to_map) {
+ TileMapQuadrant &q = layers[layer].quadrant_map[E.value];
for (const RID &ci : q.canvas_items) {
RS::get_singleton()->canvas_item_set_draw_index(ci, index++);
}
@@ -1126,8 +1126,8 @@ void TileMap::_physics_notification(int p_what) {
// Update the new transform directly if we are not in animatable mode.
Transform2D global_transform = get_global_transform();
for (int layer = 0; layer < (int)layers.size(); layer++) {
- for (Map<Vector2i, TileMapQuadrant>::Element *E = layers[layer].quadrant_map.front(); E; E = E->next()) {
- TileMapQuadrant &q = E->get();
+ for (KeyValue<Vector2i, TileMapQuadrant> &E : layers[layer].quadrant_map) {
+ TileMapQuadrant &q = E.value;
for (RID body : q.bodies) {
Transform2D xform;
@@ -1148,8 +1148,8 @@ void TileMap::_physics_notification(int p_what) {
// Only active when animatable. Send the new transform to the physics...
new_transform = get_global_transform();
for (int layer = 0; layer < (int)layers.size(); layer++) {
- for (Map<Vector2i, TileMapQuadrant>::Element *E = layers[layer].quadrant_map.front(); E; E = E->next()) {
- TileMapQuadrant &q = E->get();
+ for (KeyValue<Vector2i, TileMapQuadrant> &E : layers[layer].quadrant_map) {
+ TileMapQuadrant &q = E.value;
for (RID body : q.bodies) {
Transform2D xform;
@@ -1335,16 +1335,16 @@ void TileMap::_navigation_notification(int p_what) {
if (is_inside_tree()) {
for (int layer = 0; layer < (int)layers.size(); layer++) {
Transform2D tilemap_xform = get_global_transform();
- for (Map<Vector2i, TileMapQuadrant>::Element *E_quadrant = layers[layer].quadrant_map.front(); E_quadrant; E_quadrant = E_quadrant->next()) {
- TileMapQuadrant &q = E_quadrant->get();
- for (Map<Vector2i, Vector<RID>>::Element *E_region = q.navigation_regions.front(); E_region; E_region = E_region->next()) {
- for (int layer_index = 0; layer_index < E_region->get().size(); layer_index++) {
- RID region = E_region->get()[layer_index];
+ for (KeyValue<Vector2i, TileMapQuadrant> &E_quadrant : layers[layer].quadrant_map) {
+ TileMapQuadrant &q = E_quadrant.value;
+ for (const KeyValue<Vector2i, Vector<RID>> &E_region : q.navigation_regions) {
+ for (int layer_index = 0; layer_index < E_region.value.size(); layer_index++) {
+ RID region = E_region.value[layer_index];
if (!region.is_valid()) {
continue;
}
Transform2D tile_transform;
- tile_transform.set_origin(map_to_world(E_region->key()));
+ tile_transform.set_origin(map_to_world(E_region.key));
NavigationServer2D::get_singleton()->region_set_transform(region, tilemap_xform * tile_transform);
}
}
@@ -1373,9 +1373,9 @@ void TileMap::_navigation_update_dirty_quadrants(SelfList<TileMapQuadrant>::List
TileMapQuadrant &q = *q_list_element->self();
// Clear navigation shapes in the quadrant.
- for (Map<Vector2i, Vector<RID>>::Element *E = q.navigation_regions.front(); E; E = E->next()) {
- for (int i = 0; i < E->get().size(); i++) {
- RID region = E->get()[i];
+ for (const KeyValue<Vector2i, Vector<RID>> &E : q.navigation_regions) {
+ for (int i = 0; i < E.value.size(); i++) {
+ RID region = E.value[i];
if (!region.is_valid()) {
continue;
}
@@ -1426,9 +1426,9 @@ void TileMap::_navigation_update_dirty_quadrants(SelfList<TileMapQuadrant>::List
void TileMap::_navigation_cleanup_quadrant(TileMapQuadrant *p_quadrant) {
// Clear navigation shapes in the quadrant.
- for (Map<Vector2i, Vector<RID>>::Element *E = p_quadrant->navigation_regions.front(); E; E = E->next()) {
- for (int i = 0; i < E->get().size(); i++) {
- RID region = E->get()[i];
+ for (const KeyValue<Vector2i, Vector<RID>> &E : p_quadrant->navigation_regions) {
+ for (int i = 0; i < E.value.size(); i++) {
+ RID region = E.value[i];
if (!region.is_valid()) {
continue;
}
@@ -1529,8 +1529,8 @@ void TileMap::_scenes_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r_
TileMapQuadrant &q = *q_list_element->self();
// Clear the scenes.
- for (Map<Vector2i, String>::Element *E = q.scenes.front(); E; E = E->next()) {
- Node *node = get_node(E->get());
+ for (const KeyValue<Vector2i, String> &E : q.scenes) {
+ Node *node = get_node(E.value);
if (node) {
node->queue_delete();
}
@@ -1577,8 +1577,8 @@ void TileMap::_scenes_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r_
void TileMap::_scenes_cleanup_quadrant(TileMapQuadrant *p_quadrant) {
// Clear the scenes.
- for (Map<Vector2i, String>::Element *E = p_quadrant->scenes.front(); E; E = E->next()) {
- Node *node = get_node(E->get());
+ for (const KeyValue<Vector2i, String> &E : p_quadrant->scenes) {
+ Node *node = get_node(E.value);
if (node) {
node->queue_delete();
}
@@ -1891,10 +1891,10 @@ void TileMap::fix_invalid_tiles() {
for (unsigned int i = 0; i < layers.size(); i++) {
const Map<Vector2i, TileMapCell> &tile_map = layers[i].tile_map;
Set<Vector2i> coords;
- for (Map<Vector2i, TileMapCell>::Element *E = tile_map.front(); E; E = E->next()) {
- TileSetSource *source = *tile_set->get_source(E->get().source_id);
- if (!source || !source->has_tile(E->get().get_atlas_coords()) || !source->has_alternative_tile(E->get().get_atlas_coords(), E->get().alternative_tile)) {
- coords.insert(E->key());
+ for (const KeyValue<Vector2i, TileMapCell> &E : tile_map) {
+ TileSetSource *source = *tile_set->get_source(E.value.source_id);
+ if (!source || !source->has_tile(E.value.get_atlas_coords()) || !source->has_alternative_tile(E.value.get_atlas_coords(), E.value.alternative_tile)) {
+ coords.insert(E.key);
}
}
for (Set<Vector2i>::Element *E = coords.front(); E; E = E->next()) {
@@ -2017,14 +2017,14 @@ Vector<int> TileMap::_get_tile_data(int p_layer) const {
// Save in highest format
int idx = 0;
- for (const Map<Vector2i, TileMapCell>::Element *E = tile_map.front(); E; E = E->next()) {
+ for (const KeyValue<Vector2i, TileMapCell> &E : tile_map) {
uint8_t *ptr = (uint8_t *)&w[idx];
- encode_uint16((int16_t)(E->key().x), &ptr[0]);
- encode_uint16((int16_t)(E->key().y), &ptr[2]);
- encode_uint16(E->get().source_id, &ptr[4]);
- encode_uint16(E->get().coord_x, &ptr[6]);
- encode_uint16(E->get().coord_y, &ptr[8]);
- encode_uint16(E->get().alternative_tile, &ptr[10]);
+ encode_uint16((int16_t)(E.key.x), &ptr[0]);
+ encode_uint16((int16_t)(E.key.y), &ptr[2]);
+ encode_uint16(E.value.source_id, &ptr[4]);
+ encode_uint16(E.value.coord_x, &ptr[6]);
+ encode_uint16(E.value.coord_y, &ptr[8]);
+ encode_uint16(E.value.alternative_tile, &ptr[10]);
idx += 3;
}
@@ -2778,8 +2778,8 @@ TypedArray<Vector2i> TileMap::get_used_cells(int p_layer) const {
TypedArray<Vector2i> a;
a.resize(layers[p_layer].tile_map.size());
int i = 0;
- for (Map<Vector2i, TileMapCell>::Element *E = layers[p_layer].tile_map.front(); E; E = E->next()) {
- Vector2i p(E->key().x, E->key().y);
+ for (const KeyValue<Vector2i, TileMapCell> &E : layers[p_layer].tile_map) {
+ Vector2i p(E.key.x, E.key.y);
a[i++] = p;
}
@@ -2800,8 +2800,8 @@ Rect2 TileMap::get_used_rect() { // Not const because of cache
first = false;
}
- for (Map<Vector2i, TileMapCell>::Element *E = tile_map.front(); E; E = E->next()) {
- used_rect_cache.expand_to(Vector2i(E->key().x, E->key().y));
+ for (const KeyValue<Vector2i, TileMapCell> &E : tile_map) {
+ used_rect_cache.expand_to(Vector2i(E.key.x, E.key.y));
}
}
}
@@ -2821,8 +2821,8 @@ void TileMap::set_light_mask(int p_light_mask) {
// Occlusion: set light mask.
CanvasItem::set_light_mask(p_light_mask);
for (unsigned int layer = 0; layer < layers.size(); layer++) {
- for (Map<Vector2i, TileMapQuadrant>::Element *E = layers[layer].quadrant_map.front(); E; E = E->next()) {
- for (const RID &ci : E->get().canvas_items) {
+ for (const KeyValue<Vector2i, TileMapQuadrant> &E : layers[layer].quadrant_map) {
+ for (const RID &ci : E.value.canvas_items) {
RenderingServer::get_singleton()->canvas_item_set_light_mask(ci, get_light_mask());
}
}
@@ -2836,8 +2836,8 @@ void TileMap::set_material(const Ref<Material> &p_material) {
// Update material for the whole tilemap.
for (unsigned int layer = 0; layer < layers.size(); layer++) {
- for (Map<Vector2i, TileMapQuadrant>::Element *E = layers[layer].quadrant_map.front(); E; E = E->next()) {
- TileMapQuadrant &q = E->get();
+ for (KeyValue<Vector2i, TileMapQuadrant> &E : layers[layer].quadrant_map) {
+ TileMapQuadrant &q = E.value;
for (const RID &ci : q.canvas_items) {
RS::get_singleton()->canvas_item_set_use_parent_material(ci, get_use_parent_material() || get_material().is_valid());
}
@@ -2852,8 +2852,8 @@ void TileMap::set_use_parent_material(bool p_use_parent_material) {
// Update use_parent_material for the whole tilemap.
for (unsigned int layer = 0; layer < layers.size(); layer++) {
- for (Map<Vector2i, TileMapQuadrant>::Element *E = layers[layer].quadrant_map.front(); E; E = E->next()) {
- TileMapQuadrant &q = E->get();
+ for (KeyValue<Vector2i, TileMapQuadrant> &E : layers[layer].quadrant_map) {
+ TileMapQuadrant &q = E.value;
for (const RID &ci : q.canvas_items) {
RS::get_singleton()->canvas_item_set_use_parent_material(ci, get_use_parent_material() || get_material().is_valid());
}
diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp
index 943586f43c..7e4c40ca0e 100644
--- a/scene/3d/area_3d.cpp
+++ b/scene/3d/area_3d.cpp
@@ -262,8 +262,8 @@ void Area3D::_clear_monitoring() {
body_map.clear();
//disconnect all monitored stuff
- for (Map<ObjectID, BodyState>::Element *E = bmcopy.front(); E; E = E->next()) {
- Object *obj = ObjectDB::get_instance(E->key());
+ for (const KeyValue<ObjectID, BodyState> &E : bmcopy) {
+ Object *obj = ObjectDB::get_instance(E.key);
Node *node = Object::cast_to<Node>(obj);
if (!node) { //node may have been deleted in previous frame or at other legitimate point
@@ -274,12 +274,12 @@ void Area3D::_clear_monitoring() {
node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_body_enter_tree));
node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_body_exit_tree));
- if (!E->get().in_tree) {
+ if (!E.value.in_tree) {
continue;
}
- for (int i = 0; i < E->get().shapes.size(); i++) {
- emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->get().rid, node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape);
+ for (int i = 0; i < E.value.shapes.size(); i++) {
+ emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E.value.rid, node, E.value.shapes[i].body_shape, E.value.shapes[i].area_shape);
}
emit_signal(SceneStringNames::get_singleton()->body_exited, node);
@@ -291,8 +291,8 @@ void Area3D::_clear_monitoring() {
area_map.clear();
//disconnect all monitored stuff
- for (Map<ObjectID, AreaState>::Element *E = bmcopy.front(); E; E = E->next()) {
- Object *obj = ObjectDB::get_instance(E->key());
+ for (const KeyValue<ObjectID, AreaState> &E : bmcopy) {
+ Object *obj = ObjectDB::get_instance(E.key);
Node *node = Object::cast_to<Node>(obj);
if (!node) { //node may have been deleted in previous frame or at other legitimate point
@@ -303,12 +303,12 @@ void Area3D::_clear_monitoring() {
node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_area_enter_tree));
node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_area_exit_tree));
- if (!E->get().in_tree) {
+ if (!E.value.in_tree) {
continue;
}
- for (int i = 0; i < E->get().shapes.size(); i++) {
- emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E->get().rid, node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape);
+ for (int i = 0; i < E.value.shapes.size(); i++) {
+ emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E.value.rid, node, E.value.shapes[i].area_shape, E.value.shapes[i].self_shape);
}
emit_signal(SceneStringNames::get_singleton()->area_exited, obj);
@@ -446,8 +446,8 @@ TypedArray<Node3D> Area3D::get_overlapping_bodies() const {
Array ret;
ret.resize(body_map.size());
int idx = 0;
- for (const Map<ObjectID, BodyState>::Element *E = body_map.front(); E; E = E->next()) {
- Object *obj = ObjectDB::get_instance(E->key());
+ for (const KeyValue<ObjectID, BodyState> &E : body_map) {
+ Object *obj = ObjectDB::get_instance(E.key);
if (!obj) {
ret.resize(ret.size() - 1); //ops
} else {
@@ -479,8 +479,8 @@ TypedArray<Area3D> Area3D::get_overlapping_areas() const {
Array ret;
ret.resize(area_map.size());
int idx = 0;
- for (const Map<ObjectID, AreaState>::Element *E = area_map.front(); E; E = E->next()) {
- Object *obj = ObjectDB::get_instance(E->key());
+ for (const KeyValue<ObjectID, AreaState> &E : area_map) {
+ Object *obj = ObjectDB::get_instance(E.key);
if (!obj) {
ret.resize(ret.size() - 1); //ops
} else {
diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp
index e2f953974a..814ed5c2a7 100644
--- a/scene/3d/collision_object_3d.cpp
+++ b/scene/3d/collision_object_3d.cpp
@@ -37,8 +37,8 @@ void CollisionObject3D::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
if (_are_collision_shapes_visible()) {
debug_shape_old_transform = get_global_transform();
- for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
- debug_shapes_to_update.insert(E->key());
+ for (const KeyValue<uint32_t, ShapeData> &E : shapes) {
+ debug_shapes_to_update.insert(E.key);
}
_update_debug_shapes();
}
@@ -324,8 +324,8 @@ void CollisionObject3D::_update_shape_data(uint32_t p_owner) {
}
void CollisionObject3D::_shape_changed(const Ref<Shape3D> &p_shape) {
- for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
- ShapeData &shapedata = E->get();
+ for (KeyValue<uint32_t, ShapeData> &E : shapes) {
+ ShapeData &shapedata = E.value;
ShapeData::ShapeBase *shapes = shapedata.shapes.ptrw();
for (int i = 0; i < shapedata.shapes.size(); i++) {
ShapeData::ShapeBase &s = shapes[i];
@@ -380,8 +380,8 @@ void CollisionObject3D::_update_debug_shapes() {
}
void CollisionObject3D::_clear_debug_shapes() {
- for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
- ShapeData &shapedata = E->get();
+ for (KeyValue<uint32_t, ShapeData> &E : shapes) {
+ ShapeData &shapedata = E.value;
ShapeData::ShapeBase *shapes = shapedata.shapes.ptrw();
for (int i = 0; i < shapedata.shapes.size(); i++) {
ShapeData::ShapeBase &s = shapes[i];
@@ -400,8 +400,8 @@ void CollisionObject3D::_clear_debug_shapes() {
void CollisionObject3D::_on_transform_changed() {
if (debug_shapes_count > 0 && !debug_shape_old_transform.is_equal_approx(get_global_transform())) {
debug_shape_old_transform = get_global_transform();
- for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
- ShapeData &shapedata = E->get();
+ for (KeyValue<uint32_t, ShapeData> &E : shapes) {
+ ShapeData &shapedata = E.value;
const ShapeData::ShapeBase *shapes = shapedata.shapes.ptr();
for (int i = 0; i < shapedata.shapes.size(); i++) {
RS::get_singleton()->instance_set_transform(shapes[i].debug_shape, debug_shape_old_transform * shapedata.xform);
@@ -523,15 +523,15 @@ bool CollisionObject3D::is_shape_owner_disabled(uint32_t p_owner) const {
}
void CollisionObject3D::get_shape_owners(List<uint32_t> *r_owners) {
- for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
- r_owners->push_back(E->key());
+ for (const KeyValue<uint32_t, ShapeData> &E : shapes) {
+ r_owners->push_back(E.key);
}
}
Array CollisionObject3D::_get_shape_owners() {
Array ret;
- for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
- ret.push_back(E->key());
+ for (const KeyValue<uint32_t, ShapeData> &E : shapes) {
+ ret.push_back(E.key);
}
return ret;
@@ -628,10 +628,10 @@ void CollisionObject3D::shape_owner_remove_shape(uint32_t p_owner, int p_shape)
shapes[p_owner].shapes.remove(p_shape);
- for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
- for (int i = 0; i < E->get().shapes.size(); i++) {
- if (E->get().shapes[i].index > index_to_remove) {
- E->get().shapes.write[i].index -= 1;
+ for (KeyValue<uint32_t, ShapeData> &E : shapes) {
+ for (int i = 0; i < E.value.shapes.size(); i++) {
+ if (E.value.shapes[i].index > index_to_remove) {
+ E.value.shapes.write[i].index -= 1;
}
}
}
@@ -650,10 +650,10 @@ void CollisionObject3D::shape_owner_clear_shapes(uint32_t p_owner) {
uint32_t CollisionObject3D::shape_find_owner(int p_shape_index) const {
ERR_FAIL_INDEX_V(p_shape_index, total_subshapes, 0);
- for (const Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
- for (int i = 0; i < E->get().shapes.size(); i++) {
- if (E->get().shapes[i].index == p_shape_index) {
- return E->key();
+ for (const KeyValue<uint32_t, ShapeData> &E : shapes) {
+ for (int i = 0; i < E.value.shapes.size(); i++) {
+ if (E.value.shapes[i].index == p_shape_index) {
+ return E.key;
}
}
}
diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp
index 7e7db57af3..4de67dd5dc 100644
--- a/scene/3d/mesh_instance_3d.cpp
+++ b/scene/3d/mesh_instance_3d.cpp
@@ -86,8 +86,8 @@ bool MeshInstance3D::_get(const StringName &p_name, Variant &r_ret) const {
void MeshInstance3D::_get_property_list(List<PropertyInfo> *p_list) const {
List<String> ls;
- for (const Map<StringName, BlendShapeTrack>::Element *E = blend_shape_tracks.front(); E; E = E->next()) {
- ls.push_back(E->key());
+ for (const KeyValue<StringName, BlendShapeTrack> &E : blend_shape_tracks) {
+ ls.push_back(E.key);
}
ls.sort();
diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp
index e6dc1ed3df..e6dbe115dd 100644
--- a/scene/3d/physics_body_3d.cpp
+++ b/scene/3d/physics_body_3d.cpp
@@ -516,9 +516,9 @@ void RigidDynamicBody3D::_body_state_changed(PhysicsDirectBodyState3D *p_state)
//untag all
int rc = 0;
- for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) {
- for (int i = 0; i < E->get().shapes.size(); i++) {
- E->get().shapes[i].tagged = false;
+ for (KeyValue<ObjectID, BodyState> &E : contact_monitor->body_map) {
+ for (int i = 0; i < E.value.shapes.size(); i++) {
+ E.value.shapes[i].tagged = false;
rc++;
}
}
@@ -564,12 +564,12 @@ void RigidDynamicBody3D::_body_state_changed(PhysicsDirectBodyState3D *p_state)
//put the ones to remove
- for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) {
- for (int i = 0; i < E->get().shapes.size(); i++) {
- if (!E->get().shapes[i].tagged) {
- toremove[toremove_count].rid = E->get().rid;
- toremove[toremove_count].body_id = E->key();
- toremove[toremove_count].pair = E->get().shapes[i];
+ for (const KeyValue<ObjectID, BodyState> &E : contact_monitor->body_map) {
+ for (int i = 0; i < E.value.shapes.size(); i++) {
+ if (!E.value.shapes[i].tagged) {
+ toremove[toremove_count].rid = E.value.rid;
+ toremove[toremove_count].body_id = E.key;
+ toremove[toremove_count].pair = E.value.shapes[i];
toremove_count++;
}
}
@@ -889,9 +889,9 @@ void RigidDynamicBody3D::set_contact_monitor(bool p_enabled) {
if (!p_enabled) {
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()) {
+ for (const KeyValue<ObjectID, BodyState> &E : contact_monitor->body_map) {
//clean up mess
- Object *obj = ObjectDB::get_instance(E->key());
+ Object *obj = ObjectDB::get_instance(E.key);
Node *node = Object::cast_to<Node>(obj);
if (node) {
@@ -918,8 +918,8 @@ Array RigidDynamicBody3D::get_colliding_bodies() const {
Array ret;
ret.resize(contact_monitor->body_map.size());
int idx = 0;
- for (const Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) {
- Object *obj = ObjectDB::get_instance(E->key());
+ for (const KeyValue<ObjectID, BodyState> &E : contact_monitor->body_map) {
+ Object *obj = ObjectDB::get_instance(E.key);
if (!obj) {
ret.resize(ret.size() - 1); //ops
} else {
@@ -1089,13 +1089,16 @@ void RigidDynamicBody3D::_reload_physics_characteristics() {
bool CharacterBody3D::move_and_slide() {
// Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky
double delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time();
- previous_position = get_global_transform().origin;
+
for (int i = 0; i < 3; i++) {
if (locked_axis & (1 << i)) {
- linear_velocity[i] = 0.0;
+ motion_velocity[i] = 0.0;
}
}
+ Transform3D gt = get_global_transform();
+ previous_position = gt.origin;
+
Vector3 current_platform_velocity = platform_velocity;
if ((collision_state.floor || collision_state.wall) && platform_rid.is_valid()) {
@@ -1109,7 +1112,6 @@ bool CharacterBody3D::move_and_slide() {
//this approach makes sure there is less delay between the actual body velocity and the one we saved
PhysicsDirectBodyState3D *bs = PhysicsServer3D::get_singleton()->body_get_direct_state(platform_rid);
if (bs) {
- Transform3D gt = get_global_transform();
Vector3 local_position = gt.origin - bs->get_transform().origin;
current_platform_velocity = bs->get_velocity_at_local_position(local_position);
}
@@ -1123,6 +1125,8 @@ bool CharacterBody3D::move_and_slide() {
bool was_on_floor = collision_state.floor;
collision_state.state = 0;
+ last_motion = Vector3();
+
if (!current_platform_velocity.is_equal_approx(Vector3())) {
PhysicsServer3D::MotionResult floor_result;
Set<RID> exclude;
@@ -1150,40 +1154,40 @@ bool CharacterBody3D::move_and_slide() {
if (moving_platform_apply_velocity_on_leave == PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY && current_platform_velocity.dot(up_direction) < 0) {
current_platform_velocity = current_platform_velocity.slide(up_direction);
}
- linear_velocity += current_platform_velocity;
+ motion_velocity += current_platform_velocity;
}
}
- // Reset the gravity accumulation when touching the ground.
- if (collision_state.floor && linear_velocity.dot(up_direction) <= 0) {
- linear_velocity = linear_velocity.slide(up_direction);
- }
-
return motion_results.size() > 0;
}
void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_floor) {
- Vector3 motion = linear_velocity * p_delta;
+ Vector3 motion = motion_velocity * p_delta;
Vector3 motion_slide_up = motion.slide(up_direction);
Vector3 prev_floor_normal = floor_normal;
platform_rid = RID();
platform_velocity = Vector3();
+ platform_ceiling_velocity = Vector3();
floor_normal = Vector3();
wall_normal = Vector3();
+ ceiling_normal = Vector3();
// No sliding on first attempt to keep floor motion stable when possible,
// When stop on slope is enabled or when there is no up direction.
bool sliding_enabled = !floor_stop_on_slope;
// Constant speed can be applied only the first time sliding is enabled.
bool can_apply_constant_speed = sliding_enabled;
+ // If the platform's ceiling push down the body.
+ bool apply_ceiling_velocity = false;
bool first_slide = true;
- bool vel_dir_facing_up = linear_velocity.dot(up_direction) > 0;
+ bool vel_dir_facing_up = motion_velocity.dot(up_direction) > 0;
Vector3 total_travel;
for (int iteration = 0; iteration < max_slides; ++iteration) {
PhysicsServer3D::MotionResult result;
bool collided = move_and_collide(motion, result, margin, false, 4, !sliding_enabled);
+ last_motion = result.travel;
if (collided) {
motion_results.push_back(result);
@@ -1193,20 +1197,33 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
CollisionState result_state;
_set_collision_direction(result, result_state);
- if (collision_state.floor && floor_stop_on_slope && (linear_velocity.normalized() + up_direction).length() < 0.01) {
+ // If we hit a ceiling platform, we set the vertical motion_velocity to at least the platform one.
+ if (collision_state.ceiling && platform_ceiling_velocity != Vector3() && platform_ceiling_velocity.dot(up_direction) < 0) {
+ // If ceiling sliding is on, only apply when the ceiling is flat or when the motion is upward.
+ if (!slide_on_ceiling || motion.dot(up_direction) < 0 || (ceiling_normal + up_direction).length() < 0.01) {
+ apply_ceiling_velocity = true;
+ Vector3 ceiling_vertical_velocity = up_direction * up_direction.dot(platform_ceiling_velocity);
+ Vector3 motion_vertical_velocity = up_direction * up_direction.dot(motion_velocity);
+ if (motion_vertical_velocity.dot(up_direction) > 0 || ceiling_vertical_velocity.length_squared() > motion_vertical_velocity.length_squared()) {
+ motion_velocity = ceiling_vertical_velocity + motion_velocity.slide(up_direction);
+ }
+ }
+ }
+
+ if (collision_state.floor && floor_stop_on_slope && (motion_velocity.normalized() + up_direction).length() < 0.01) {
Transform3D gt = get_global_transform();
if (result.travel.length() <= margin + CMP_EPSILON) {
gt.origin -= result.travel;
}
set_global_transform(gt);
- linear_velocity = Vector3();
+ motion_velocity = Vector3();
motion = Vector3();
+ last_motion = Vector3();
break;
}
if (result.remainder.is_equal_approx(Vector3())) {
motion = Vector3();
- last_motion = result.travel;
break;
}
@@ -1255,7 +1272,7 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
Vector3 forward = wall_normal.slide(up_direction).normalized();
motion = motion.slide(forward);
// Avoid accelerating when you jump on the wall and smooth falling.
- linear_velocity = linear_velocity.slide(forward);
+ motion_velocity = motion_velocity.slide(forward);
// Allow only lateral motion along previous floor when already on floor.
// Fixes slowing down when moving in diagonal against an inclined wall.
@@ -1284,7 +1301,7 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
if (stop_all_motion) {
motion = Vector3();
- linear_velocity = Vector3();
+ motion_velocity = Vector3();
}
}
}
@@ -1295,7 +1312,7 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
real_t motion_angle = Math::abs(Math::acos(-horizontal_normal.dot(motion_slide_up.normalized())));
if (motion_angle < wall_min_slide_angle) {
motion = up_direction * motion.dot(up_direction);
- linear_velocity = up_direction * linear_velocity.dot(up_direction);
+ motion_velocity = up_direction * motion_velocity.dot(up_direction);
apply_default_sliding = false;
}
@@ -1304,21 +1321,35 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
if (apply_default_sliding) {
// Regular sliding, the last part of the test handle the case when you don't want to slide on the ceiling.
- if ((sliding_enabled || !collision_state.floor) && (!collision_state.ceiling || slide_on_ceiling || !vel_dir_facing_up)) {
+ if ((sliding_enabled || !collision_state.floor) && (!collision_state.ceiling || slide_on_ceiling || !vel_dir_facing_up) && !apply_ceiling_velocity) {
const PhysicsServer3D::MotionCollision &collision = result.collisions[0];
+
Vector3 slide_motion = result.remainder.slide(collision.normal);
- if (slide_motion.dot(linear_velocity) > 0.0) {
+ if (collision_state.floor && !collision_state.wall) {
+ // Slide using the intersection between the motion plane and the floor plane,
+ // in order to keep the direction intact.
+ real_t motion_length = slide_motion.length();
+ slide_motion = up_direction.cross(result.remainder).cross(floor_normal);
+
+ // Keep the length from default slide to change speed in slopes by default,
+ // when constant speed is not enabled.
+ slide_motion.normalize();
+ slide_motion *= motion_length;
+ }
+
+ if (slide_motion.dot(motion_velocity) > 0.0) {
motion = slide_motion;
} else {
motion = Vector3();
}
+
if (slide_on_ceiling && result_state.ceiling) {
// Apply slide only in the direction of the input motion, otherwise just stop to avoid jittering when moving against a wall.
if (vel_dir_facing_up) {
- linear_velocity = linear_velocity.slide(collision.normal);
+ motion_velocity = motion_velocity.slide(collision.normal);
} else {
// Avoid acceleration in slope when falling.
- linear_velocity = up_direction * up_direction.dot(linear_velocity);
+ motion_velocity = up_direction * up_direction.dot(motion_velocity);
}
}
}
@@ -1326,18 +1357,19 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
else {
motion = result.remainder;
if (result_state.ceiling && !slide_on_ceiling && vel_dir_facing_up) {
- linear_velocity = linear_velocity.slide(up_direction);
+ motion_velocity = motion_velocity.slide(up_direction);
motion = motion.slide(up_direction);
}
}
}
+ total_travel += result.travel;
+
// Apply Constant Speed.
- if (p_was_on_floor && floor_constant_speed && collision_state.floor && !motion.is_equal_approx(Vector3())) {
- motion = motion.normalized() * MAX(0, (motion_slide_up.length() - result.travel.slide(up_direction).length() - total_travel.slide(up_direction).length()));
+ if (p_was_on_floor && floor_constant_speed && can_apply_constant_speed && collision_state.floor && !motion.is_equal_approx(Vector3())) {
+ Vector3 travel_slide_up = total_travel.slide(up_direction);
+ motion = motion.normalized() * MAX(0, (motion_slide_up.length() - travel_slide_up.length()));
}
-
- total_travel += result.travel;
}
// When you move forward in a downward slope you don’t collide because you will be in the air.
// This test ensures that constant speed is applied, only if the player is still on the ground after the snap is applied.
@@ -1348,34 +1380,34 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
gt.origin = gt.origin - result.travel;
set_global_transform(gt);
- Vector3 motion_slide_norm = motion.slide(prev_floor_normal).normalized();
+ // Slide using the intersection between the motion plane and the floor plane,
+ // in order to keep the direction intact.
+ Vector3 motion_slide_norm = up_direction.cross(motion).cross(prev_floor_normal);
+ motion_slide_norm.normalize();
+
motion = motion_slide_norm * (motion_slide_up.length());
collided = true;
}
- can_apply_constant_speed = !can_apply_constant_speed && !sliding_enabled;
- sliding_enabled = true;
- first_slide = false;
-
- if (!motion.is_equal_approx(Vector3())) {
- last_motion = motion;
- }
-
if (!collided || motion.is_equal_approx(Vector3())) {
break;
}
+
+ can_apply_constant_speed = !can_apply_constant_speed && !sliding_enabled;
+ sliding_enabled = true;
+ first_slide = false;
}
_snap_on_floor(p_was_on_floor, vel_dir_facing_up);
// Reset the gravity accumulation when touching the ground.
if (collision_state.floor && !vel_dir_facing_up) {
- linear_velocity = linear_velocity.slide(up_direction);
+ motion_velocity = motion_velocity.slide(up_direction);
}
}
void CharacterBody3D::_move_and_slide_free(double p_delta) {
- Vector3 motion = linear_velocity * p_delta;
+ Vector3 motion = motion_velocity * p_delta;
platform_rid = RID();
floor_normal = Vector3();
@@ -1386,6 +1418,7 @@ void CharacterBody3D::_move_and_slide_free(double p_delta) {
PhysicsServer3D::MotionResult result;
bool collided = move_and_collide(motion, result, margin, false, 1, false);
+ last_motion = result.travel;
if (collided) {
motion_results.push_back(result);
@@ -1393,7 +1426,12 @@ void CharacterBody3D::_move_and_slide_free(double p_delta) {
CollisionState result_state;
_set_collision_direction(result, result_state);
- if (wall_min_slide_angle != 0 && Math::acos(wall_normal.dot(-linear_velocity.normalized())) < wall_min_slide_angle + FLOOR_ANGLE_THRESHOLD) {
+ if (result.remainder.is_equal_approx(Vector3())) {
+ motion = Vector3();
+ break;
+ }
+
+ if (wall_min_slide_angle != 0 && Math::acos(wall_normal.dot(-motion_velocity.normalized())) < wall_min_slide_angle + FLOOR_ANGLE_THRESHOLD) {
motion = Vector3();
if (result.travel.length() < margin + CMP_EPSILON) {
Transform3D gt = get_global_transform();
@@ -1407,16 +1445,16 @@ void CharacterBody3D::_move_and_slide_free(double p_delta) {
motion = result.remainder.slide(wall_normal);
}
- if (motion.dot(linear_velocity) <= 0.0) {
+ if (motion.dot(motion_velocity) <= 0.0) {
motion = Vector3();
}
}
- first_slide = false;
-
if (!collided || motion.is_equal_approx(Vector3())) {
break;
}
+
+ first_slide = false;
}
}
@@ -1505,6 +1543,8 @@ void CharacterBody3D::_set_collision_direction(const PhysicsServer3D::MotionResu
if (ceiling_angle <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) {
r_state.ceiling = true;
if (p_apply_state.ceiling) {
+ platform_ceiling_velocity = collision.collider_velocity;
+ ceiling_normal = collision.normal;
collision_state.ceiling = true;
}
continue;
@@ -1568,12 +1608,12 @@ real_t CharacterBody3D::get_safe_margin() const {
return margin;
}
-Vector3 CharacterBody3D::get_linear_velocity() const {
- return linear_velocity;
+const Vector3 &CharacterBody3D::get_motion_velocity() const {
+ return motion_velocity;
}
-void CharacterBody3D::set_linear_velocity(const Vector3 &p_velocity) {
- linear_velocity = p_velocity;
+void CharacterBody3D::set_motion_velocity(const Vector3 &p_velocity) {
+ motion_velocity = p_velocity;
}
bool CharacterBody3D::is_on_floor() const {
@@ -1600,15 +1640,15 @@ bool CharacterBody3D::is_on_ceiling_only() const {
return collision_state.ceiling && !collision_state.floor && !collision_state.wall;
}
-Vector3 CharacterBody3D::get_floor_normal() const {
+const Vector3 &CharacterBody3D::get_floor_normal() const {
return floor_normal;
}
-Vector3 CharacterBody3D::get_wall_normal() const {
+const Vector3 &CharacterBody3D::get_wall_normal() const {
return wall_normal;
}
-Vector3 CharacterBody3D::get_last_motion() const {
+const Vector3 &CharacterBody3D::get_last_motion() const {
return last_motion;
}
@@ -1616,19 +1656,23 @@ Vector3 CharacterBody3D::get_position_delta() const {
return get_transform().origin - previous_position;
}
-Vector3 CharacterBody3D::get_real_velocity() const {
+const Vector3 &CharacterBody3D::get_real_velocity() const {
return real_velocity;
-};
+}
real_t CharacterBody3D::get_floor_angle(const Vector3 &p_up_direction) const {
ERR_FAIL_COND_V(p_up_direction == Vector3(), 0);
return Math::acos(floor_normal.dot(p_up_direction));
}
-Vector3 CharacterBody3D::get_platform_velocity() const {
+const Vector3 &CharacterBody3D::get_platform_velocity() const {
return platform_velocity;
}
+Vector3 CharacterBody3D::get_linear_velocity() const {
+ return get_real_velocity();
+}
+
int CharacterBody3D::get_slide_collision_count() const {
return motion_results.size();
}
@@ -1783,8 +1827,8 @@ void CharacterBody3D::_notification(int p_what) {
void CharacterBody3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("move_and_slide"), &CharacterBody3D::move_and_slide);
- ClassDB::bind_method(D_METHOD("set_linear_velocity", "linear_velocity"), &CharacterBody3D::set_linear_velocity);
- ClassDB::bind_method(D_METHOD("get_linear_velocity"), &CharacterBody3D::get_linear_velocity);
+ ClassDB::bind_method(D_METHOD("set_motion_velocity", "motion_velocity"), &CharacterBody3D::set_motion_velocity);
+ ClassDB::bind_method(D_METHOD("get_motion_velocity"), &CharacterBody3D::get_motion_velocity);
ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &CharacterBody3D::set_safe_margin);
ClassDB::bind_method(D_METHOD("get_safe_margin"), &CharacterBody3D::get_safe_margin);
@@ -1837,7 +1881,7 @@ void CharacterBody3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "motion_mode", PROPERTY_HINT_ENUM, "Grounded,Free", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_motion_mode", "get_motion_mode");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "up_direction"), "set_up_direction", "get_up_direction");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slide_on_ceiling"), "set_slide_on_ceiling_enabled", "is_slide_on_ceiling_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_linear_velocity", "get_linear_velocity");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "motion_velocity", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_motion_velocity", "get_motion_velocity");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_slides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_max_slides", "get_max_slides");
ADD_GROUP("Free Mode", "free_mode_");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "wall_min_slide_angle", PROPERTY_HINT_RANGE, "0,180,0.1,radians", PROPERTY_USAGE_DEFAULT), "set_wall_min_slide_angle", "get_wall_min_slide_angle");
@@ -1962,11 +2006,6 @@ Vector3 KinematicCollision3D::get_collider_velocity(int p_collision_index) const
return result.collisions[p_collision_index].collider_velocity;
}
-Variant KinematicCollision3D::get_collider_metadata(int p_collision_index) const {
- ERR_FAIL_INDEX_V(p_collision_index, result.collision_count, Variant());
- return Variant();
-}
-
Vector3 KinematicCollision3D::get_best_position() const {
return result.collision_count ? get_position() : Vector3();
}
@@ -2003,10 +2042,6 @@ Vector3 KinematicCollision3D::get_best_collider_velocity() const {
return result.collision_count ? get_collider_velocity() : Vector3();
}
-Variant KinematicCollision3D::get_best_collider_metadata() const {
- return result.collision_count ? get_collider_metadata() : Variant();
-}
-
void KinematicCollision3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_travel"), &KinematicCollision3D::get_travel);
ClassDB::bind_method(D_METHOD("get_remainder"), &KinematicCollision3D::get_remainder);
@@ -2021,7 +2056,6 @@ void KinematicCollision3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_collider_shape", "collision_index"), &KinematicCollision3D::get_collider_shape, DEFVAL(0));
ClassDB::bind_method(D_METHOD("get_collider_shape_index", "collision_index"), &KinematicCollision3D::get_collider_shape_index, DEFVAL(0));
ClassDB::bind_method(D_METHOD("get_collider_velocity", "collision_index"), &KinematicCollision3D::get_collider_velocity, DEFVAL(0));
- ClassDB::bind_method(D_METHOD("get_collider_metadata", "collision_index"), &KinematicCollision3D::get_collider_metadata, DEFVAL(0));
ClassDB::bind_method(D_METHOD("get_best_position"), &KinematicCollision3D::get_best_position);
ClassDB::bind_method(D_METHOD("get_best_normal"), &KinematicCollision3D::get_best_normal);
@@ -2032,7 +2066,6 @@ void KinematicCollision3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_best_collider_shape"), &KinematicCollision3D::get_best_collider_shape);
ClassDB::bind_method(D_METHOD("get_best_collider_shape_index"), &KinematicCollision3D::get_best_collider_shape_index);
ClassDB::bind_method(D_METHOD("get_best_collider_velocity"), &KinematicCollision3D::get_best_collider_velocity);
- ClassDB::bind_method(D_METHOD("get_best_collider_metadata"), &KinematicCollision3D::get_best_collider_metadata);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "travel"), "", "get_travel");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "remainder"), "", "get_remainder");
@@ -2046,7 +2079,6 @@ void KinematicCollision3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider_shape"), "", "get_best_collider_shape");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_shape_index"), "", "get_best_collider_shape_index");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "collider_velocity"), "", "get_best_collider_velocity");
- ADD_PROPERTY(PropertyInfo(Variant::NIL, "collider_metadata", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "", "get_best_collider_metadata");
}
///////////////////////////////////////
diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h
index a53147cb8f..2e96c4472e 100644
--- a/scene/3d/physics_body_3d.h
+++ b/scene/3d/physics_body_3d.h
@@ -328,8 +328,8 @@ public:
};
bool move_and_slide();
- virtual Vector3 get_linear_velocity() const override;
- void set_linear_velocity(const Vector3 &p_velocity);
+ const Vector3 &get_motion_velocity() const;
+ void set_motion_velocity(const Vector3 &p_velocity);
bool is_on_floor() const;
bool is_on_floor_only() const;
@@ -337,13 +337,15 @@ public:
bool is_on_wall_only() const;
bool is_on_ceiling() const;
bool is_on_ceiling_only() const;
- Vector3 get_last_motion() const;
+ const Vector3 &get_last_motion() const;
Vector3 get_position_delta() const;
- Vector3 get_floor_normal() const;
- Vector3 get_wall_normal() const;
- Vector3 get_real_velocity() const;
+ const Vector3 &get_floor_normal() const;
+ const Vector3 &get_wall_normal() const;
+ const Vector3 &get_real_velocity() const;
real_t get_floor_angle(const Vector3 &p_up_direction = Vector3(0.0, 1.0, 0.0)) const;
- Vector3 get_platform_velocity() const;
+ const Vector3 &get_platform_velocity() const;
+
+ virtual Vector3 get_linear_velocity() const override;
int get_slide_collision_count() const;
PhysicsServer3D::MotionResult get_slide_collision(int p_bounce) const;
@@ -379,7 +381,7 @@ private:
bool floor_block_on_wall = true;
bool slide_on_ceiling = true;
int max_slides = 6;
- int platform_layer;
+ int platform_layer = 0;
RID platform_rid;
uint32_t moving_platform_floor_layers = UINT32_MAX;
uint32_t moving_platform_wall_layers = 0;
@@ -387,11 +389,13 @@ private:
real_t floor_max_angle = Math::deg2rad((real_t)45.0);
real_t wall_min_slide_angle = Math::deg2rad((real_t)15.0);
Vector3 up_direction = Vector3(0.0, 1.0, 0.0);
- Vector3 linear_velocity;
+ Vector3 motion_velocity;
Vector3 floor_normal;
Vector3 wall_normal;
+ Vector3 ceiling_normal;
Vector3 last_motion;
Vector3 platform_velocity;
+ Vector3 platform_ceiling_velocity;
Vector3 previous_position;
Vector3 real_velocity;
@@ -483,7 +487,6 @@ public:
Object *get_collider_shape(int p_collision_index = 0) const;
int get_collider_shape_index(int p_collision_index = 0) const;
Vector3 get_collider_velocity(int p_collision_index = 0) const;
- Variant get_collider_metadata(int p_collision_index = 0) const;
Vector3 get_best_position() const;
Vector3 get_best_normal() const;
@@ -494,7 +497,6 @@ public:
Object *get_best_collider_shape() const;
int get_best_collider_shape_index() const;
Vector3 get_best_collider_velocity() const;
- Variant get_best_collider_metadata() const;
};
class PhysicalBone3D : public PhysicsBody3D {
diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp
index af186072ac..10a66386eb 100644
--- a/scene/animation/animation_blend_tree.cpp
+++ b/scene/animation/animation_blend_tree.cpp
@@ -828,9 +828,9 @@ Ref<AnimationNode> AnimationNodeBlendTree::get_node(const StringName &p_name) co
}
StringName AnimationNodeBlendTree::get_node_name(const Ref<AnimationNode> &p_node) const {
- for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
- if (E->get().node == p_node) {
- return E->key();
+ for (const KeyValue<StringName, Node> &E : nodes) {
+ if (E.value.node == p_node) {
+ return E.key;
}
}
@@ -850,8 +850,8 @@ Vector2 AnimationNodeBlendTree::get_node_position(const StringName &p_node) cons
void AnimationNodeBlendTree::get_child_nodes(List<ChildNode> *r_child_nodes) {
Vector<StringName> ns;
- for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
- ns.push_back(E->key());
+ for (const KeyValue<StringName, Node> &E : nodes) {
+ ns.push_back(E.key);
}
ns.sort_custom<StringName::AlphCompare>();
@@ -886,10 +886,10 @@ void AnimationNodeBlendTree::remove_node(const StringName &p_name) {
nodes.erase(p_name);
//erase connections to name
- for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
- for (int i = 0; i < E->get().connections.size(); i++) {
- if (E->get().connections[i] == p_name) {
- E->get().connections.write[i] = StringName();
+ for (KeyValue<StringName, Node> &E : nodes) {
+ for (int i = 0; i < E.value.connections.size(); i++) {
+ if (E.value.connections[i] == p_name) {
+ E.value.connections.write[i] = StringName();
}
}
}
@@ -910,10 +910,10 @@ void AnimationNodeBlendTree::rename_node(const StringName &p_name, const StringN
nodes.erase(p_name);
//rename connections
- for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
- for (int i = 0; i < E->get().connections.size(); i++) {
- if (E->get().connections[i] == p_name) {
- E->get().connections.write[i] = p_new_name;
+ for (KeyValue<StringName, Node> &E : nodes) {
+ for (int i = 0; i < E.value.connections.size(); i++) {
+ if (E.value.connections[i] == p_name) {
+ E.value.connections.write[i] = p_new_name;
}
}
}
@@ -932,9 +932,9 @@ void AnimationNodeBlendTree::connect_node(const StringName &p_input_node, int p_
Ref<AnimationNode> input = nodes[p_input_node].node;
ERR_FAIL_INDEX(p_input_index, nodes[p_input_node].connections.size());
- for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
- for (int i = 0; i < E->get().connections.size(); i++) {
- StringName output = E->get().connections[i];
+ for (KeyValue<StringName, Node> &E : nodes) {
+ for (int i = 0; i < E.value.connections.size(); i++) {
+ StringName output = E.value.connections[i];
ERR_FAIL_COND(output == p_output_node);
}
}
@@ -976,9 +976,9 @@ AnimationNodeBlendTree::ConnectionError AnimationNodeBlendTree::can_connect_node
return CONNECTION_ERROR_CONNECTION_EXISTS;
}
- for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
- for (int i = 0; i < E->get().connections.size(); i++) {
- StringName output = E->get().connections[i];
+ for (const KeyValue<StringName, Node> &E : nodes) {
+ for (int i = 0; i < E.value.connections.size(); i++) {
+ const StringName output = E.value.connections[i];
if (output == p_output_node) {
return CONNECTION_ERROR_CONNECTION_EXISTS;
}
@@ -988,12 +988,12 @@ AnimationNodeBlendTree::ConnectionError AnimationNodeBlendTree::can_connect_node
}
void AnimationNodeBlendTree::get_node_connections(List<NodeConnection> *r_connections) const {
- for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
- for (int i = 0; i < E->get().connections.size(); i++) {
- StringName output = E->get().connections[i];
+ for (const KeyValue<StringName, Node> &E : nodes) {
+ for (int i = 0; i < E.value.connections.size(); i++) {
+ const StringName output = E.value.connections[i];
if (output != StringName()) {
NodeConnection nc;
- nc.input_node = E->key();
+ nc.input_node = E.key;
nc.input_index = i;
nc.output_node = output;
r_connections->push_back(nc);
@@ -1012,8 +1012,8 @@ double AnimationNodeBlendTree::process(double p_time, bool p_seek) {
}
void AnimationNodeBlendTree::get_node_list(List<StringName> *r_list) {
- for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
- r_list->push_back(E->key());
+ for (const KeyValue<StringName, Node> &E : nodes) {
+ r_list->push_back(E.key);
}
}
@@ -1104,8 +1104,8 @@ bool AnimationNodeBlendTree::_get(const StringName &p_name, Variant &r_ret) cons
void AnimationNodeBlendTree::_get_property_list(List<PropertyInfo> *p_list) const {
List<StringName> names;
- for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
- names.push_back(E->key());
+ for (const KeyValue<StringName, Node> &E : nodes) {
+ names.push_back(E.key);
}
names.sort_custom<StringName::AlphCompare>();
diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp
index 9fc1dbd0c6..984be04285 100644
--- a/scene/animation/animation_node_state_machine.cpp
+++ b/scene/animation/animation_node_state_machine.cpp
@@ -571,9 +571,9 @@ Ref<AnimationNode> AnimationNodeStateMachine::get_node(const StringName &p_name)
}
StringName AnimationNodeStateMachine::get_node_name(const Ref<AnimationNode> &p_node) const {
- for (Map<StringName, State>::Element *E = states.front(); E; E = E->next()) {
- if (E->get().node == p_node) {
- return E->key();
+ for (const KeyValue<StringName, State> &E : states) {
+ if (E.value.node == p_node) {
+ return E.key;
}
}
@@ -583,8 +583,8 @@ StringName AnimationNodeStateMachine::get_node_name(const Ref<AnimationNode> &p_
void AnimationNodeStateMachine::get_child_nodes(List<ChildNode> *r_child_nodes) {
Vector<StringName> nodes;
- for (Map<StringName, State>::Element *E = states.front(); E; E = E->next()) {
- nodes.push_back(E->key());
+ for (const KeyValue<StringName, State> &E : states) {
+ nodes.push_back(E.key);
}
nodes.sort_custom<StringName::AlphCompare>();
@@ -674,8 +674,8 @@ void AnimationNodeStateMachine::rename_node(const StringName &p_name, const Stri
void AnimationNodeStateMachine::get_node_list(List<StringName> *r_nodes) const {
List<StringName> nodes;
- for (Map<StringName, State>::Element *E = states.front(); E; E = E->next()) {
- nodes.push_back(E->key());
+ for (const KeyValue<StringName, State> &E : states) {
+ nodes.push_back(E.key);
}
nodes.sort_custom<StringName::AlphCompare>();
@@ -897,8 +897,8 @@ bool AnimationNodeStateMachine::_get(const StringName &p_name, Variant &r_ret) c
void AnimationNodeStateMachine::_get_property_list(List<PropertyInfo> *p_list) const {
List<StringName> names;
- for (Map<StringName, State>::Element *E = states.front(); E; E = E->next()) {
- names.push_back(E->key());
+ for (const KeyValue<StringName, State> &E : states) {
+ names.push_back(E.key);
}
names.sort_custom<StringName::AlphCompare>();
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 5825a35030..a8d46eac6e 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -124,8 +124,8 @@ bool AnimationPlayer::_get(const StringName &p_name, Variant &r_ret) const {
} else if (name == "blend_times") {
Vector<BlendKey> keys;
- for (Map<BlendKey, float>::Element *E = blend_times.front(); E; E = E->next()) {
- keys.ordered_insert(E->key());
+ for (const KeyValue<BlendKey, float> &E : blend_times) {
+ keys.ordered_insert(E.key);
}
Array array;
@@ -147,8 +147,8 @@ void AnimationPlayer::_validate_property(PropertyInfo &property) const {
if (property.name == "current_animation") {
List<String> names;
- for (Map<StringName, AnimationData>::Element *E = animation_set.front(); E; E = E->next()) {
- names.push_back(E->key());
+ for (const KeyValue<StringName, AnimationData> &E : animation_set) {
+ names.push_back(E.key);
}
names.sort();
names.push_front("[stop]");
@@ -167,10 +167,10 @@ void AnimationPlayer::_validate_property(PropertyInfo &property) const {
void AnimationPlayer::_get_property_list(List<PropertyInfo> *p_list) const {
List<PropertyInfo> anim_names;
- for (Map<StringName, AnimationData>::Element *E = animation_set.front(); E; E = E->next()) {
- anim_names.push_back(PropertyInfo(Variant::OBJECT, "anims/" + String(E->key()), PROPERTY_HINT_RESOURCE_TYPE, "Animation", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE));
- if (E->get().next != StringName()) {
- anim_names.push_back(PropertyInfo(Variant::STRING, "next/" + String(E->key()), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
+ for (const KeyValue<StringName, AnimationData> &E : animation_set) {
+ anim_names.push_back(PropertyInfo(Variant::OBJECT, "anims/" + String(E.key), PROPERTY_HINT_RESOURCE_TYPE, "Animation", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE));
+ if (E.value.next != StringName()) {
+ anim_names.push_back(PropertyInfo(Variant::STRING, "next/" + String(E.key), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
}
}
@@ -1019,8 +1019,8 @@ void AnimationPlayer::rename_animation(const StringName &p_name, const StringNam
List<BlendKey> to_erase;
Map<BlendKey, float> to_insert;
- for (Map<BlendKey, float>::Element *E = blend_times.front(); E; E = E->next()) {
- BlendKey bk = E->key();
+ for (const KeyValue<BlendKey, float> &E : blend_times) {
+ BlendKey bk = E.key;
BlendKey new_bk = bk;
bool erase = false;
if (bk.from == p_name) {
@@ -1034,7 +1034,7 @@ void AnimationPlayer::rename_animation(const StringName &p_name, const StringNam
if (erase) {
to_erase.push_back(bk);
- to_insert[new_bk] = E->get();
+ to_insert[new_bk] = E.value;
}
}
@@ -1071,8 +1071,8 @@ Ref<Animation> AnimationPlayer::get_animation(const StringName &p_name) const {
void AnimationPlayer::get_animation_list(List<StringName> *p_animations) const {
List<String> anims;
- for (Map<StringName, AnimationData>::Element *E = animation_set.front(); E; E = E->next()) {
- anims.push_back(E->key());
+ for (const KeyValue<StringName, AnimationData> &E : animation_set) {
+ anims.push_back(E.key);
}
anims.sort();
@@ -1365,8 +1365,8 @@ void AnimationPlayer::clear_caches() {
node_cache_map.clear();
- for (Map<StringName, AnimationData>::Element *E = animation_set.front(); E; E = E->next()) {
- E->get().node_cache.clear();
+ for (KeyValue<StringName, AnimationData> &E : animation_set) {
+ E.value.node_cache.clear();
}
cache_update_size = 0;
@@ -1388,9 +1388,9 @@ bool AnimationPlayer::is_active() const {
}
StringName AnimationPlayer::find_animation(const Ref<Animation> &p_animation) const {
- for (Map<StringName, AnimationData>::Element *E = animation_set.front(); E; E = E->next()) {
- if (E->get().animation == p_animation) {
- return E->key();
+ for (const KeyValue<StringName, AnimationData> &E : animation_set) {
+ if (E.value.animation == p_animation) {
+ return E.key;
}
}
@@ -1545,12 +1545,12 @@ Ref<AnimatedValuesBackup> AnimationPlayer::backup_animated_values(Node *p_root_o
entry.bone_idx = -1;
backup->entries.push_back(entry);
} else {
- for (Map<StringName, TrackNodeCache::PropertyAnim>::Element *E = nc->property_anim.front(); E; E = E->next()) {
+ for (const KeyValue<StringName, TrackNodeCache::PropertyAnim> &E : nc->property_anim) {
AnimatedValuesBackup::Entry entry;
- entry.object = E->value().object;
- entry.subpath = E->value().subpath;
+ entry.object = E.value.object;
+ entry.subpath = E.value.subpath;
bool valid;
- entry.value = E->value().object->get_indexed(E->value().subpath, &valid);
+ entry.value = E.value.object->get_indexed(E.value.subpath, &valid);
entry.bone_idx = -1;
if (valid) {
backup->entries.push_back(entry);
diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp
index f4e477b613..3c8949ddfb 100644
--- a/scene/debugger/scene_debugger.cpp
+++ b/scene/debugger/scene_debugger.cpp
@@ -249,8 +249,8 @@ void SceneDebugger::remove_from_cache(const String &p_filename, Node *p_node) {
Map<Node *, Map<ObjectID, Node *>> &remove_list = debugger->live_edit_remove_list;
Map<Node *, Map<ObjectID, Node *>>::Element *F = remove_list.find(p_node);
if (F) {
- for (Map<ObjectID, Node *>::Element *G = F->get().front(); G; G = G->next()) {
- memdelete(G->get());
+ for (const KeyValue<ObjectID, Node *> &G : F->get()) {
+ memdelete(G.value);
}
remove_list.erase(F);
}
@@ -339,15 +339,15 @@ void SceneDebuggerObject::_parse_script_properties(Script *p_script, ScriptInsta
}
// Constants
for (ScriptConstantsMap::Element *sc = constants.front(); sc; sc = sc->next()) {
- for (Map<StringName, Variant>::Element *E = sc->get().front(); E; E = E->next()) {
+ for (const KeyValue<StringName, Variant> &E : sc->get()) {
String script_path = sc->key() == p_script ? "" : sc->key()->get_path().get_file() + "/";
- if (E->value().get_type() == Variant::OBJECT) {
- Variant id = ((Object *)E->value())->get_instance_id();
- PropertyInfo pi(id.get_type(), "Constants/" + E->key(), PROPERTY_HINT_OBJECT_ID, "Object");
+ if (E.value.get_type() == Variant::OBJECT) {
+ Variant id = ((Object *)E.value)->get_instance_id();
+ PropertyInfo pi(id.get_type(), "Constants/" + E.key, PROPERTY_HINT_OBJECT_ID, "Object");
properties.push_back(SceneDebuggerProperty(pi, id));
} else {
- PropertyInfo pi(E->value().get_type(), "Constants/" + script_path + E->key());
- properties.push_back(SceneDebuggerProperty(pi, E->value()));
+ PropertyInfo pi(E.value.get_type(), "Constants/" + script_path + E.key);
+ properties.push_back(SceneDebuggerProperty(pi, E.value));
}
}
}
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index 0476a764a5..28d1689ff8 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -1620,12 +1620,12 @@ Point2 CodeEdit::get_delimiter_start_position(int p_line, int p_column) const {
bool in_region = ((p_line <= 0 || delimiter_cache[p_line - 1].size() < 1) ? -1 : delimiter_cache[p_line - 1].back()->value()) != -1;
/* Check the keys for this line. */
- for (Map<int, int>::Element *E = delimiter_cache[p_line].front(); E; E = E->next()) {
- if (E->key() > p_column) {
+ for (const KeyValue<int, int> &E : delimiter_cache[p_line]) {
+ if (E.key > p_column) {
break;
}
- in_region = E->value() != -1;
- start_position.x = in_region ? E->key() : -1;
+ in_region = E.value != -1;
+ start_position.x = in_region ? E.key : -1;
}
/* Region was found on this line and is not a multiline continuation. */
@@ -1671,12 +1671,12 @@ Point2 CodeEdit::get_delimiter_end_position(int p_line, int p_column) const {
int region = (p_line <= 0 || delimiter_cache[p_line - 1].size() < 1) ? -1 : delimiter_cache[p_line - 1].back()->value();
/* Check the keys for this line. */
- for (Map<int, int>::Element *E = delimiter_cache[p_line].front(); E; E = E->next()) {
- end_position.x = (E->value() == -1) ? E->key() : -1;
- if (E->key() > p_column) {
+ for (const KeyValue<int, int> &E : delimiter_cache[p_line]) {
+ end_position.x = (E.value == -1) ? E.key : -1;
+ if (E.key > p_column) {
break;
}
- region = E->value();
+ region = E.value;
}
/* Region was found on this line and is not a multiline continuation. */
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index ecf735d7f5..8462fd259e 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -403,28 +403,28 @@ void GraphNode::_notification(int p_what) {
close_rect = Rect2();
}
- for (Map<int, Slot>::Element *E = slot_info.front(); E; E = E->next()) {
- if (E->key() < 0 || E->key() >= cache_y.size()) {
+ for (const KeyValue<int, Slot> &E : slot_info) {
+ if (E.key < 0 || E.key >= cache_y.size()) {
continue;
}
- if (!slot_info.has(E->key())) {
+ if (!slot_info.has(E.key)) {
continue;
}
- const Slot &s = slot_info[E->key()];
+ const Slot &s = slot_info[E.key];
//left
if (s.enable_left) {
Ref<Texture2D> p = port;
if (s.custom_slot_left.is_valid()) {
p = s.custom_slot_left;
}
- p->draw(get_canvas_item(), icofs + Point2(edgeofs, cache_y[E->key()]), s.color_left);
+ p->draw(get_canvas_item(), icofs + Point2(edgeofs, cache_y[E.key]), s.color_left);
}
if (s.enable_right) {
Ref<Texture2D> p = port;
if (s.custom_slot_right.is_valid()) {
p = s.custom_slot_right;
}
- p->draw(get_canvas_item(), icofs + Point2(get_size().x - edgeofs, cache_y[E->key()]), s.color_right);
+ p->draw(get_canvas_item(), icofs + Point2(get_size().x - edgeofs, cache_y[E.key]), s.color_right);
}
}
diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp
index 1107e3a4af..2beb2624d2 100644
--- a/scene/gui/grid_container.cpp
+++ b/scene/gui/grid_container.cpp
@@ -82,15 +82,15 @@ void GridContainer::_notification(int p_what) {
// Evaluate the remaining space for expanded columns/rows.
Size2 remaining_space = get_size();
- for (Map<int, int>::Element *E = col_minw.front(); E; E = E->next()) {
- if (!col_expanded.has(E->key())) {
- remaining_space.width -= E->get();
+ for (const KeyValue<int, int> &E : col_minw) {
+ if (!col_expanded.has(E.key)) {
+ remaining_space.width -= E.value;
}
}
- for (Map<int, int>::Element *E = row_minh.front(); E; E = E->next()) {
- if (!row_expanded.has(E->key())) {
- remaining_space.height -= E->get();
+ for (const KeyValue<int, int> &E : row_minh) {
+ if (!row_expanded.has(E.key)) {
+ remaining_space.height -= E.value;
}
}
remaining_space.height -= vsep * MAX(max_row - 1, 0);
@@ -247,12 +247,12 @@ Size2 GridContainer::get_minimum_size() const {
Size2 ms;
- for (Map<int, int>::Element *E = col_minw.front(); E; E = E->next()) {
- ms.width += E->get();
+ for (const KeyValue<int, int> &E : col_minw) {
+ ms.width += E.value;
}
- for (Map<int, int>::Element *E = row_minh.front(); E; E = E->next()) {
- ms.height += E->get();
+ for (const KeyValue<int, int> &E : row_minh) {
+ ms.height += E.value;
}
ms.height += vsep * max_row;
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index db5f714b99..b1ba9de85c 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -211,8 +211,8 @@ void Node::_propagate_enter_tree() {
data.inside_tree = true;
- for (Map<StringName, GroupData>::Element *E = data.grouped.front(); E; E = E->next()) {
- E->get().group = data.tree->add_to_group(E->key(), this);
+ for (KeyValue<StringName, GroupData> &E : data.grouped) {
+ E.value.group = data.tree->add_to_group(E.key, this);
}
notification(NOTIFICATION_ENTER_TREE);
@@ -274,9 +274,9 @@ void Node::_propagate_exit_tree() {
// exit groups
- for (Map<StringName, GroupData>::Element *E = data.grouped.front(); E; E = E->next()) {
- data.tree->remove_from_group(E->key(), this);
- E->get().group = nullptr;
+ for (KeyValue<StringName, GroupData> &E : data.grouped) {
+ data.tree->remove_from_group(E.key, this);
+ E.value.group = nullptr;
}
data.viewport = nullptr;
@@ -353,9 +353,9 @@ void Node::_move_child(Node *p_child, int p_pos, bool p_ignore_end) {
for (int i = motion_from; i <= motion_to; i++) {
data.children[i]->notification(NOTIFICATION_MOVED_IN_PARENT);
}
- for (const Map<StringName, GroupData>::Element *E = p_child->data.grouped.front(); E; E = E->next()) {
- if (E->get().group) {
- E->get().group->changed = true;
+ for (const KeyValue<StringName, GroupData> &E : p_child->data.grouped) {
+ if (E.value.group) {
+ E.value.group->changed = true;
}
}
@@ -1678,10 +1678,10 @@ Array Node::_get_groups() const {
}
void Node::get_groups(List<GroupInfo> *p_groups) const {
- for (const Map<StringName, GroupData>::Element *E = data.grouped.front(); E; E = E->next()) {
+ for (const KeyValue<StringName, GroupData> &E : data.grouped) {
GroupInfo gi;
- gi.name = E->key();
- gi.persistent = E->get().persistent;
+ gi.name = E.key;
+ gi.persistent = E.value.persistent;
p_groups->push_back(gi);
}
}
@@ -1689,8 +1689,8 @@ void Node::get_groups(List<GroupInfo> *p_groups) const {
int Node::get_persistent_group_count() const {
int count = 0;
- for (const Map<StringName, GroupData>::Element *E = data.grouped.front(); E; E = E->next()) {
- if (E->get().persistent) {
+ for (const KeyValue<StringName, GroupData> &E : data.grouped) {
+ if (E.value.persistent) {
count += 1;
}
}
diff --git a/scene/main/resource_preloader.cpp b/scene/main/resource_preloader.cpp
index cd9560db61..f4c90ee668 100644
--- a/scene/main/resource_preloader.cpp
+++ b/scene/main/resource_preloader.cpp
@@ -57,8 +57,8 @@ Array ResourcePreloader::_get_resources() const {
Set<String> sorted_names;
- for (Map<StringName, RES>::Element *E = resources.front(); E; E = E->next()) {
- sorted_names.insert(E->key());
+ for (const KeyValue<StringName, RES> &E : resources) {
+ sorted_names.insert(E.key);
}
int i = 0;
@@ -131,8 +131,8 @@ Vector<String> ResourcePreloader::_get_resource_list() const {
}
void ResourcePreloader::get_resource_list(List<StringName> *p_list) {
- for (Map<StringName, RES>::Element *E = resources.front(); E; E = E->next()) {
- p_list->push_back(E->key());
+ for (const KeyValue<StringName, RES> &E : resources) {
+ p_list->push_back(E.key);
}
}
diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp
index a364a27e80..9dc76dcf44 100644
--- a/scene/resources/curve.cpp
+++ b/scene/resources/curve.cpp
@@ -966,9 +966,9 @@ PackedVector2Array Curve2D::tessellate(int p_max_stages, float p_tolerance) cons
int pidx = 0;
for (int i = 0; i < points.size() - 1; i++) {
- for (Map<float, Vector2>::Element *E = midpoints[i].front(); E; E = E->next()) {
+ for (const KeyValue<float, Vector2> &E : midpoints[i]) {
pidx++;
- bpw[pidx] = E->get();
+ bpw[pidx] = E.value;
}
pidx++;
@@ -1652,9 +1652,9 @@ PackedVector3Array Curve3D::tessellate(int p_max_stages, float p_tolerance) cons
int pidx = 0;
for (int i = 0; i < points.size() - 1; i++) {
- for (Map<float, Vector3>::Element *E = midpoints[i].front(); E; E = E->next()) {
+ for (const KeyValue<float, Vector3> &E : midpoints[i]) {
pidx++;
- bpw[pidx] = E->get();
+ bpw[pidx] = E.value;
}
pidx++;
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index 67db8c1a10..18e6a51118 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -373,8 +373,8 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
//normalize
- for (Map<Vector3, Vector3>::Element *E = normal_accum.front(); E; E = E->next()) {
- E->get().normalize();
+ for (KeyValue<Vector3, Vector3> &E : normal_accum) {
+ E.value.normalize();
}
//displace normals
diff --git a/scene/resources/mesh_library.cpp b/scene/resources/mesh_library.cpp
index cfb7c3e037..309670e0b1 100644
--- a/scene/resources/mesh_library.cpp
+++ b/scene/resources/mesh_library.cpp
@@ -97,8 +97,8 @@ bool MeshLibrary::_get(const StringName &p_name, Variant &r_ret) const {
}
void MeshLibrary::_get_property_list(List<PropertyInfo> *p_list) const {
- for (Map<int, Item>::Element *E = item_map.front(); E; E = E->next()) {
- String name = "item/" + itos(E->key()) + "/";
+ for (const KeyValue<int, Item> &E : item_map) {
+ String name = "item/" + itos(E.key) + "/";
p_list->push_back(PropertyInfo(Variant::STRING, name + "name"));
p_list->push_back(PropertyInfo(Variant::OBJECT, name + "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"));
p_list->push_back(PropertyInfo(Variant::TRANSFORM3D, name + "mesh_transform"));
@@ -230,17 +230,17 @@ Vector<int> MeshLibrary::get_item_list() const {
Vector<int> ret;
ret.resize(item_map.size());
int idx = 0;
- for (Map<int, Item>::Element *E = item_map.front(); E; E = E->next()) {
- ret.write[idx++] = E->key();
+ for (const KeyValue<int, Item> &E : item_map) {
+ ret.write[idx++] = E.key;
}
return ret;
}
int MeshLibrary::find_item_by_name(const String &p_name) const {
- for (Map<int, Item>::Element *E = item_map.front(); E; E = E->next()) {
- if (E->get().name == p_name) {
- return E->key();
+ for (const KeyValue<int, Item> &E : item_map) {
+ if (E.value.name == p_name) {
+ return E.key;
}
}
return -1;
diff --git a/scene/resources/navigation_mesh.cpp b/scene/resources/navigation_mesh.cpp
index 00cee9269b..d0e0f15ef6 100644
--- a/scene/resources/navigation_mesh.cpp
+++ b/scene/resources/navigation_mesh.cpp
@@ -367,10 +367,10 @@ Ref<Mesh> NavigationMesh::get_debug_mesh() {
}
List<Vector3> lines;
- for (Map<_EdgeKey, bool>::Element *E = edge_map.front(); E; E = E->next()) {
- if (E->get()) {
- lines.push_back(E->key().from);
- lines.push_back(E->key().to);
+ for (const KeyValue<_EdgeKey, bool> &E : edge_map) {
+ if (E.value) {
+ lines.push_back(E.key.from);
+ lines.push_back(E.key.to);
}
}
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 9722570060..c8d3ea5e37 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -299,8 +299,8 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
}
}
- for (Map<Ref<Resource>, Ref<Resource>>::Element *E = resources_local_to_scene.front(); E; E = E->next()) {
- E->get()->setup_local_to_scene();
+ for (KeyValue<Ref<Resource>, Ref<Resource>> &E : resources_local_to_scene) {
+ E.value->setup_local_to_scene();
}
//do connections
@@ -887,8 +887,8 @@ Error SceneState::pack(Node *p_scene) {
names.resize(name_map.size());
- for (Map<StringName, int>::Element *E = name_map.front(); E; E = E->next()) {
- names.write[E->get()] = E->key();
+ for (const KeyValue<StringName, int> &E : name_map) {
+ names.write[E.value] = E.key;
}
variants.resize(variant_map.size());
@@ -899,14 +899,14 @@ Error SceneState::pack(Node *p_scene) {
}
node_paths.resize(nodepath_map.size());
- for (Map<Node *, int>::Element *E = nodepath_map.front(); E; E = E->next()) {
- node_paths.write[E->get()] = scene->get_path_to(E->key());
+ for (const KeyValue<Node *, int> &E : nodepath_map) {
+ node_paths.write[E.value] = scene->get_path_to(E.key);
}
if (Engine::get_singleton()->is_editor_hint()) {
// Build node path cache
- for (Map<Node *, int>::Element *E = node_map.front(); E; E = E->next()) {
- node_path_cache[scene->get_path_to(E->key())] = E->get();
+ for (const KeyValue<Node *, int> &E : node_map) {
+ node_path_cache[scene->get_path_to(E.key)] = E.value;
}
}
@@ -977,9 +977,9 @@ int SceneState::find_node_by_path(const NodePath &p_node) const {
}
int SceneState::_find_base_scene_node_remap_key(int p_idx) const {
- for (Map<int, int>::Element *E = base_scene_node_remap.front(); E; E = E->next()) {
- if (E->value() == p_idx) {
- return E->key();
+ for (const KeyValue<int, int> &E : base_scene_node_remap) {
+ if (E.value == p_idx) {
+ return E.key;
}
}
return -1;
diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp
index 341ce22185..77d915aef9 100644
--- a/scene/resources/resource_format_text.cpp
+++ b/scene/resources/resource_format_text.cpp
@@ -1653,55 +1653,55 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
#ifdef TOOLS_ENABLED
// Keep order from cached ids.
Set<String> cached_ids_found;
- for (Map<RES, String>::Element *E = external_resources.front(); E; E = E->next()) {
- String cached_id = E->key()->get_id_for_path(local_path);
+ for (KeyValue<RES, String> &E : external_resources) {
+ String cached_id = E.key->get_id_for_path(local_path);
if (cached_id == "" || cached_ids_found.has(cached_id)) {
- int sep_pos = E->get().find("_");
+ int sep_pos = E.value.find("_");
if (sep_pos != -1) {
- E->get() = E->get().substr(0, sep_pos + 1); // Keep the order found, for improved thread loading performance.
+ E.value = E.value.substr(0, sep_pos + 1); // Keep the order found, for improved thread loading performance.
} else {
- E->get() = "";
+ E.value = "";
}
} else {
- E->get() = cached_id;
+ E.value = cached_id;
cached_ids_found.insert(cached_id);
}
}
// Create IDs for non cached resources.
- for (Map<RES, String>::Element *E = external_resources.front(); E; E = E->next()) {
- if (cached_ids_found.has(E->get())) { // Already cached, go on.
+ for (KeyValue<RES, String> &E : external_resources) {
+ if (cached_ids_found.has(E.value)) { // Already cached, go on.
continue;
}
String attempt;
while (true) {
- attempt = E->get() + Resource::generate_scene_unique_id();
+ attempt = E.value + Resource::generate_scene_unique_id();
if (!cached_ids_found.has(attempt)) {
break;
}
}
cached_ids_found.insert(attempt);
- E->get() = attempt;
+ E.value = attempt;
// Update also in resource.
- Ref<Resource> res = E->key();
+ Ref<Resource> res = E.key;
res->set_id_for_path(local_path, attempt);
}
#else
// Make sure to start from one, as it makes format more readable.
int counter = 1;
- for (Map<RES, String>::Element *E = external_resources.front(); E; E = E->next()) {
- E->get() = itos(counter++);
+ for (KeyValue<RES, String> &E : external_resources) {
+ E.value = itos(counter++);
}
#endif
Vector<ResourceSort> sorted_er;
- for (Map<RES, String>::Element *E = external_resources.front(); E; E = E->next()) {
+ for (const KeyValue<RES, String> &E : external_resources) {
ResourceSort rs;
- rs.resource = E->key();
- rs.id = E->get();
+ rs.resource = E.key;
+ rs.id = E.value;
sorted_er.push_back(rs);
}
diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp
index 44d524f142..242e20f3b0 100644
--- a/scene/resources/shader.cpp
+++ b/scene/resources/shader.cpp
@@ -116,8 +116,8 @@ Ref<Texture2D> Shader::get_default_texture_param(const StringName &p_param) cons
}
void Shader::get_default_texture_param_list(List<StringName> *r_textures) const {
- for (const Map<StringName, Ref<Texture2D>>::Element *E = default_textures.front(); E; E = E->next()) {
- r_textures->push_back(E->key());
+ for (const KeyValue<StringName, Ref<Texture2D>> &E : default_textures) {
+ r_textures->push_back(E.key);
}
}
diff --git a/scene/resources/sprite_frames.cpp b/scene/resources/sprite_frames.cpp
index 140c6f821f..01afb00283 100644
--- a/scene/resources/sprite_frames.cpp
+++ b/scene/resources/sprite_frames.cpp
@@ -108,15 +108,15 @@ Vector<String> SpriteFrames::_get_animation_list() const {
}
void SpriteFrames::get_animation_list(List<StringName> *r_animations) const {
- for (const Map<StringName, Anim>::Element *E = animations.front(); E; E = E->next()) {
- r_animations->push_back(E->key());
+ for (const KeyValue<StringName, Anim> &E : animations) {
+ r_animations->push_back(E.key);
}
}
Vector<String> SpriteFrames::get_animation_names() const {
Vector<String> names;
- for (const Map<StringName, Anim>::Element *E = animations.front(); E; E = E->next()) {
- names.push_back(E->key());
+ for (const KeyValue<StringName, Anim> &E : animations) {
+ names.push_back(E.key);
}
names.sort();
return names;
@@ -164,14 +164,14 @@ Array SpriteFrames::_get_frames() const {
Array SpriteFrames::_get_animations() const {
Array anims;
- for (Map<StringName, Anim>::Element *E = animations.front(); E; E = E->next()) {
+ for (const KeyValue<StringName, Anim> &E : animations) {
Dictionary d;
- d["name"] = E->key();
- d["speed"] = E->get().speed;
- d["loop"] = E->get().loop;
+ d["name"] = E.key;
+ d["speed"] = E.value.speed;
+ d["loop"] = E.value.loop;
Array frames;
- for (int i = 0; i < E->get().frames.size(); i++) {
- frames.push_back(E->get().frames[i]);
+ for (int i = 0; i < E.value.frames.size(); i++) {
+ frames.push_back(E.value.frames[i]);
}
d["frames"] = frames;
anims.push_back(d);
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 80cab99373..1b3a7a5f2a 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -1249,7 +1249,7 @@ bool AtlasTexture::is_pixel_opaque(int p_x, int p_y) const {
}
Ref<Image> AtlasTexture::get_image() const {
- if (!atlas.is_valid()) {
+ if (!atlas.is_valid() || !atlas->get_image().is_valid()) {
return Ref<Image>();
}
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 15e622c9d6..40eedb63c1 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -66,8 +66,8 @@ const char *TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[] = {
void TileSet::set_tile_shape(TileSet::TileShape p_shape) {
tile_shape = p_shape;
- for (Map<int, Ref<TileSetSource>>::Element *E_source = sources.front(); E_source; E_source = E_source->next()) {
- E_source->get()->notify_tile_data_properties_should_change();
+ for (KeyValue<int, Ref<TileSetSource>> &E_source : sources) {
+ E_source.value->notify_tile_data_properties_should_change();
}
terrain_bits_meshes_dirty = true;
@@ -89,8 +89,8 @@ TileSet::TileLayout TileSet::get_tile_layout() const {
void TileSet::set_tile_offset_axis(TileSet::TileOffsetAxis p_alignment) {
tile_offset_axis = p_alignment;
- for (Map<int, Ref<TileSetSource>>::Element *E_source = sources.front(); E_source; E_source = E_source->next()) {
- E_source->get()->notify_tile_data_properties_should_change();
+ for (KeyValue<int, Ref<TileSetSource>> &E_source : sources) {
+ E_source.value->notify_tile_data_properties_should_change();
}
terrain_bits_meshes_dirty = true;
@@ -386,8 +386,8 @@ void TileSet::remove_terrain_set(int p_index) {
void TileSet::set_terrain_set_mode(int p_terrain_set, TerrainMode p_terrain_mode) {
ERR_FAIL_INDEX(p_terrain_set, terrain_sets.size());
terrain_sets.write[p_terrain_set].mode = p_terrain_mode;
- for (Map<int, Ref<TileSetSource>>::Element *E_source = sources.front(); E_source; E_source = E_source->next()) {
- E_source->get()->notify_tile_data_properties_should_change();
+ for (KeyValue<int, Ref<TileSetSource>> &E_source : sources) {
+ E_source.value->notify_tile_data_properties_should_change();
}
notify_property_list_changed();
@@ -719,8 +719,8 @@ void TileSet::set_custom_data_type(int p_layer_id, Variant::Type p_value) {
ERR_FAIL_INDEX(p_layer_id, custom_data_layers.size());
custom_data_layers.write[p_layer_id].type = p_value;
- for (Map<int, Ref<TileSetSource>>::Element *E_source = sources.front(); E_source; E_source = E_source->next()) {
- E_source->get()->notify_tile_data_properties_should_change();
+ for (KeyValue<int, Ref<TileSetSource>> &E_source : sources) {
+ E_source.value->notify_tile_data_properties_should_change();
}
emit_changed();
@@ -858,10 +858,10 @@ void TileSet::remove_alternative_level_tile_proxy(int p_source_from, Vector2i p_
Array TileSet::get_source_level_tile_proxies() const {
Array output;
- for (Map<int, int>::Element *E = source_level_proxies.front(); E; E = E->next()) {
+ for (const KeyValue<int, int> &E : source_level_proxies) {
Array proxy;
- proxy.push_back(E->key());
- proxy.push_back(E->get());
+ proxy.push_back(E.key);
+ proxy.push_back(E.value);
output.push_back(proxy);
}
return output;
@@ -869,10 +869,10 @@ Array TileSet::get_source_level_tile_proxies() const {
Array TileSet::get_coords_level_tile_proxies() const {
Array output;
- for (Map<Array, Array>::Element *E = coords_level_proxies.front(); E; E = E->next()) {
+ for (const KeyValue<Array, Array> &E : coords_level_proxies) {
Array proxy;
- proxy.append_array(E->key());
- proxy.append_array(E->get());
+ proxy.append_array(E.key);
+ proxy.append_array(E.value);
output.push_back(proxy);
}
return output;
@@ -880,10 +880,10 @@ Array TileSet::get_coords_level_tile_proxies() const {
Array TileSet::get_alternative_level_tile_proxies() const {
Array output;
- for (Map<Array, Array>::Element *E = alternative_level_proxies.front(); E; E = E->next()) {
+ for (const KeyValue<Array, Array> &E : alternative_level_proxies) {
Array proxy;
- proxy.append_array(E->key());
- proxy.append_array(E->get());
+ proxy.append_array(E.key);
+ proxy.append_array(E.value);
output.push_back(proxy);
}
return output;
@@ -935,9 +935,9 @@ Array TileSet::map_tile_proxy(int p_source_from, Vector2i p_coords_from, int p_a
void TileSet::cleanup_invalid_tile_proxies() {
// Source level.
Vector<int> source_to_remove;
- for (Map<int, int>::Element *E = source_level_proxies.front(); E; E = E->next()) {
- if (has_source(E->key())) {
- source_to_remove.append(E->key());
+ for (const KeyValue<int, int> &E : source_level_proxies) {
+ if (has_source(E.key)) {
+ source_to_remove.append(E.key);
}
}
for (int i = 0; i < source_to_remove.size(); i++) {
@@ -946,8 +946,8 @@ void TileSet::cleanup_invalid_tile_proxies() {
// Coords level.
Vector<Array> coords_to_remove;
- for (Map<Array, Array>::Element *E = coords_level_proxies.front(); E; E = E->next()) {
- Array a = E->key();
+ for (const KeyValue<Array, Array> &E : coords_level_proxies) {
+ Array a = E.key;
if (has_source(a[0]) && get_source(a[0])->has_tile(a[1])) {
coords_to_remove.append(a);
}
@@ -959,8 +959,8 @@ void TileSet::cleanup_invalid_tile_proxies() {
// Alternative level.
Vector<Array> alternative_to_remove;
- for (Map<Array, Array>::Element *E = alternative_level_proxies.front(); E; E = E->next()) {
- Array a = E->key();
+ for (const KeyValue<Array, Array> &E : alternative_level_proxies) {
+ Array a = E.key;
if (has_source(a[0]) && get_source(a[0])->has_tile(a[1]) && get_source(a[0])->has_alternative_tile(a[1], a[2])) {
alternative_to_remove.append(a);
}
@@ -1911,8 +1911,8 @@ const int TileSetSource::INVALID_TILE_ALTERNATIVE = -1;
#ifndef DISABLE_DEPRECATED
void TileSet::_compatibility_conversion() {
- for (Map<int, CompatibilityTileData *>::Element *E = compatibility_data.front(); E; E = E->next()) {
- CompatibilityTileData *ctd = E->value();
+ for (KeyValue<int, CompatibilityTileData *> &E : compatibility_data) {
+ CompatibilityTileData *ctd = E.value;
// Add the texture
TileSetAtlasSource *atlas_source = memnew(TileSetAtlasSource);
@@ -1950,11 +1950,11 @@ void TileSet::_compatibility_conversion() {
value_array.push_back(coords);
value_array.push_back(alternative_tile);
- if (!compatibility_tilemap_mapping.has(E->key())) {
- compatibility_tilemap_mapping[E->key()] = Map<Array, Array>();
+ if (!compatibility_tilemap_mapping.has(E.key)) {
+ compatibility_tilemap_mapping[E.key] = Map<Array, Array>();
}
- compatibility_tilemap_mapping[E->key()][key_array] = value_array;
- compatibility_tilemap_mapping_tile_modes[E->key()] = COMPATIBILITY_TILE_MODE_SINGLE_TILE;
+ compatibility_tilemap_mapping[E.key][key_array] = value_array;
+ compatibility_tilemap_mapping_tile_modes[E.key] = COMPATIBILITY_TILE_MODE_SINGLE_TILE;
TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(coords, alternative_tile));
@@ -2042,11 +2042,11 @@ void TileSet::_compatibility_conversion() {
value_array.push_back(coords);
value_array.push_back(alternative_tile);
- if (!compatibility_tilemap_mapping.has(E->key())) {
- compatibility_tilemap_mapping[E->key()] = Map<Array, Array>();
+ if (!compatibility_tilemap_mapping.has(E.key)) {
+ compatibility_tilemap_mapping[E.key] = Map<Array, Array>();
}
- compatibility_tilemap_mapping[E->key()][key_array] = value_array;
- compatibility_tilemap_mapping_tile_modes[E->key()] = COMPATIBILITY_TILE_MODE_ATLAS_TILE;
+ compatibility_tilemap_mapping[E.key][key_array] = value_array;
+ compatibility_tilemap_mapping_tile_modes[E.key] = COMPATIBILITY_TILE_MODE_ATLAS_TILE;
TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(coords, alternative_tile));
@@ -2128,8 +2128,8 @@ void TileSet::_compatibility_conversion() {
}
// Reset compatibility data
- for (Map<int, CompatibilityTileData *>::Element *E = compatibility_data.front(); E; E = E->next()) {
- memdelete(E->get());
+ for (const KeyValue<int, CompatibilityTileData *> &E : compatibility_data) {
+ memdelete(E.value);
}
compatibility_data = Map<int, CompatibilityTileData *>();
}
@@ -2579,25 +2579,25 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const {
} else if (components.size() == 2 && components[0] == "tile_proxies") {
if (components[1] == "source_level") {
Array a;
- for (Map<int, int>::Element *E = source_level_proxies.front(); E; E = E->next()) {
- a.push_back(E->key());
- a.push_back(E->get());
+ for (const KeyValue<int, int> &E : source_level_proxies) {
+ a.push_back(E.key);
+ a.push_back(E.value);
}
r_ret = a;
return true;
} else if (components[1] == "coords_level") {
Array a;
- for (Map<Array, Array>::Element *E = coords_level_proxies.front(); E; E = E->next()) {
- a.push_back(E->key());
- a.push_back(E->get());
+ for (const KeyValue<Array, Array> &E : coords_level_proxies) {
+ a.push_back(E.key);
+ a.push_back(E.value);
}
r_ret = a;
return true;
} else if (components[1] == "alternative_level") {
Array a;
- for (Map<Array, Array>::Element *E = alternative_level_proxies.front(); E; E = E->next()) {
- a.push_back(E->key());
- a.push_back(E->get());
+ for (const KeyValue<Array, Array> &E : alternative_level_proxies) {
+ a.push_back(E.key);
+ a.push_back(E.value);
}
r_ret = a;
return true;
@@ -2673,8 +2673,8 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
// Sources.
// Note: sources have to be listed in at the end as some TileData rely on the TileSet properties being initialized first.
- for (Map<int, Ref<TileSetSource>>::Element *E_source = sources.front(); E_source; E_source = E_source->next()) {
- p_list->push_back(PropertyInfo(Variant::INT, vformat("sources/%d", E_source->key()), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ for (const KeyValue<int, Ref<TileSetSource>> &E_source : sources) {
+ p_list->push_back(PropertyInfo(Variant::INT, vformat("sources/%d", E_source.key), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
}
// Tile Proxies.
@@ -2850,8 +2850,8 @@ TileSet::TileSet() {
TileSet::~TileSet() {
#ifndef DISABLE_DEPRECATED
- for (Map<int, CompatibilityTileData *>::Element *E = compatibility_data.front(); E; E = E->next()) {
- memdelete(E->get());
+ for (const KeyValue<int, CompatibilityTileData *> &E : compatibility_data) {
+ memdelete(E.value);
}
#endif // DISABLE_DEPRECATED
while (!source_ids.is_empty()) {
@@ -2883,18 +2883,18 @@ void TileSetAtlasSource::set_tile_set(const TileSet *p_tile_set) {
tile_set = p_tile_set;
// Set the TileSet on all TileData.
- for (Map<Vector2i, TileAlternativesData>::Element *E_tile = tiles.front(); E_tile; E_tile = E_tile->next()) {
- for (Map<int, TileData *>::Element *E_alternative = E_tile->get().alternatives.front(); E_alternative; E_alternative = E_alternative->next()) {
- E_alternative->get()->set_tile_set(tile_set);
+ for (KeyValue<Vector2i, TileAlternativesData> &E_tile : tiles) {
+ for (KeyValue<int, TileData *> &E_alternative : E_tile.value.alternatives) {
+ E_alternative.value->set_tile_set(tile_set);
}
}
}
void TileSetAtlasSource::notify_tile_data_properties_should_change() {
// Set the TileSet on all TileData.
- for (Map<Vector2i, TileAlternativesData>::Element *E_tile = tiles.front(); E_tile; E_tile = E_tile->next()) {
- for (Map<int, TileData *>::Element *E_alternative = E_tile->get().alternatives.front(); E_alternative; E_alternative = E_alternative->next()) {
- E_alternative->get()->notify_tile_data_properties_should_change();
+ for (KeyValue<Vector2i, TileAlternativesData> &E_tile : tiles) {
+ for (KeyValue<int, TileData *> &E_alternative : E_tile.value.alternatives) {
+ E_alternative.value->notify_tile_data_properties_should_change();
}
}
}
@@ -3045,9 +3045,9 @@ void TileSetAtlasSource::remove_custom_data_layer(int p_index) {
void TileSetAtlasSource::reset_state() {
// Reset all TileData.
- for (Map<Vector2i, TileAlternativesData>::Element *E_tile = tiles.front(); E_tile; E_tile = E_tile->next()) {
- for (Map<int, TileData *>::Element *E_alternative = E_tile->get().alternatives.front(); E_alternative; E_alternative = E_alternative->next()) {
- E_alternative->get()->reset_state();
+ for (KeyValue<Vector2i, TileAlternativesData> &E_tile : tiles) {
+ for (KeyValue<int, TileData *> &E_alternative : E_tile.value.alternatives) {
+ E_alternative.value->reset_state();
}
}
}
@@ -3260,40 +3260,40 @@ bool TileSetAtlasSource::_get(const StringName &p_name, Variant &r_ret) const {
void TileSetAtlasSource::_get_property_list(List<PropertyInfo> *p_list) const {
// Atlases data.
PropertyInfo property_info;
- for (Map<Vector2i, TileAlternativesData>::Element *E_tile = tiles.front(); E_tile; E_tile = E_tile->next()) {
+ for (const KeyValue<Vector2i, TileAlternativesData> &E_tile : tiles) {
List<PropertyInfo> tile_property_list;
// size_in_atlas
property_info = PropertyInfo(Variant::VECTOR2I, "size_in_atlas", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR);
- if (E_tile->get().size_in_atlas == Vector2i(1, 1)) {
+ if (E_tile.value.size_in_atlas == Vector2i(1, 1)) {
property_info.usage ^= PROPERTY_USAGE_STORAGE;
}
tile_property_list.push_back(property_info);
// next_alternative_id
property_info = PropertyInfo(Variant::INT, "next_alternative_id", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR);
- if (E_tile->get().next_alternative_id == 1) {
+ if (E_tile.value.next_alternative_id == 1) {
property_info.usage ^= PROPERTY_USAGE_STORAGE;
}
tile_property_list.push_back(property_info);
// animation_columns.
property_info = PropertyInfo(Variant::INT, "animation_columns", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR);
- if (E_tile->get().animation_columns == 0) {
+ if (E_tile.value.animation_columns == 0) {
property_info.usage ^= PROPERTY_USAGE_STORAGE;
}
tile_property_list.push_back(property_info);
// animation_separation.
property_info = PropertyInfo(Variant::INT, "animation_separation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR);
- if (E_tile->get().animation_separation == Vector2i()) {
+ if (E_tile.value.animation_separation == Vector2i()) {
property_info.usage ^= PROPERTY_USAGE_STORAGE;
}
tile_property_list.push_back(property_info);
// animation_speed.
property_info = PropertyInfo(Variant::FLOAT, "animation_speed", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR);
- if (E_tile->get().animation_speed == 1.0) {
+ if (E_tile.value.animation_speed == 1.0) {
property_info.usage ^= PROPERTY_USAGE_STORAGE;
}
tile_property_list.push_back(property_info);
@@ -3302,8 +3302,8 @@ void TileSetAtlasSource::_get_property_list(List<PropertyInfo> *p_list) const {
tile_property_list.push_back(PropertyInfo(Variant::INT, "animation_frames_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NETWORK));
// animation_frame_*.
- bool store_durations = tiles[E_tile->key()].animation_frames_durations.size() >= 2;
- for (int i = 0; i < (int)tiles[E_tile->key()].animation_frames_durations.size(); i++) {
+ bool store_durations = tiles[E_tile.key].animation_frames_durations.size() >= 2;
+ for (int i = 0; i < (int)tiles[E_tile.key].animation_frames_durations.size(); i++) {
property_info = PropertyInfo(Variant::FLOAT, vformat("animation_frame_%d/duration", i), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR);
if (!store_durations) {
property_info.usage ^= PROPERTY_USAGE_STORAGE;
@@ -3311,27 +3311,27 @@ void TileSetAtlasSource::_get_property_list(List<PropertyInfo> *p_list) const {
tile_property_list.push_back(property_info);
}
- for (Map<int, TileData *>::Element *E_alternative = E_tile->get().alternatives.front(); E_alternative; E_alternative = E_alternative->next()) {
+ for (const KeyValue<int, TileData *> &E_alternative : E_tile.value.alternatives) {
// Add a dummy property to show the alternative exists.
- tile_property_list.push_back(PropertyInfo(Variant::INT, vformat("%d", E_alternative->key()), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ tile_property_list.push_back(PropertyInfo(Variant::INT, vformat("%d", E_alternative.key), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
// Get the alternative tile's properties and append them to the list of properties.
List<PropertyInfo> alternative_property_list;
- E_alternative->get()->get_property_list(&alternative_property_list);
+ E_alternative.value->get_property_list(&alternative_property_list);
for (PropertyInfo &alternative_property_info : alternative_property_list) {
Variant default_value = ClassDB::class_get_default_property_value("TileData", alternative_property_info.name);
- Variant value = E_alternative->get()->get(alternative_property_info.name);
+ Variant value = E_alternative.value->get(alternative_property_info.name);
if (default_value.get_type() != Variant::NIL && bool(Variant::evaluate(Variant::OP_EQUAL, value, default_value))) {
alternative_property_info.usage ^= PROPERTY_USAGE_STORAGE;
}
- alternative_property_info.name = vformat("%s/%s", vformat("%d", E_alternative->key()), alternative_property_info.name);
+ alternative_property_info.name = vformat("%s/%s", vformat("%d", E_alternative.key), alternative_property_info.name);
tile_property_list.push_back(alternative_property_info);
}
}
// Add all alternative.
for (PropertyInfo &tile_property_info : tile_property_list) {
- tile_property_info.name = vformat("%s/%s", vformat("%d:%d", E_tile->key().x, E_tile->key().y), tile_property_info.name);
+ tile_property_info.name = vformat("%s/%s", vformat("%d:%d", E_tile.key.x, E_tile.key.y), tile_property_info.name);
p_list->push_back(tile_property_info);
}
}
@@ -3373,8 +3373,8 @@ void TileSetAtlasSource::remove_tile(Vector2i p_atlas_coords) {
_clear_coords_mapping_cache(p_atlas_coords);
// Free tile data.
- for (Map<int, TileData *>::Element *E_tile_data = tiles[p_atlas_coords].alternatives.front(); E_tile_data; E_tile_data = E_tile_data->next()) {
- memdelete(E_tile_data->get());
+ for (const KeyValue<int, TileData *> &E_tile_data : tiles[p_atlas_coords].alternatives) {
+ memdelete(E_tile_data.value);
}
// Delete the tile
@@ -3619,8 +3619,8 @@ bool TileSetAtlasSource::has_tiles_outside_texture() {
Vector2i grid_size = get_atlas_grid_size();
Vector<Vector2i> to_remove;
- for (Map<Vector2i, TileSetAtlasSource::TileAlternativesData>::Element *E = tiles.front(); E; E = E->next()) {
- if (E->key().x >= grid_size.x || E->key().y >= grid_size.y) {
+ for (const KeyValue<Vector2i, TileSetAtlasSource::TileAlternativesData> &E : tiles) {
+ if (E.key.x >= grid_size.x || E.key.y >= grid_size.y) {
return true;
}
}
@@ -3632,9 +3632,9 @@ void TileSetAtlasSource::clear_tiles_outside_texture() {
Vector2i grid_size = get_atlas_grid_size();
Vector<Vector2i> to_remove;
- for (Map<Vector2i, TileSetAtlasSource::TileAlternativesData>::Element *E = tiles.front(); E; E = E->next()) {
- if (E->key().x >= grid_size.x || E->key().y >= grid_size.y) {
- to_remove.append(E->key());
+ for (const KeyValue<Vector2i, TileSetAtlasSource::TileAlternativesData> &E : tiles) {
+ if (E.key.x >= grid_size.x || E.key.y >= grid_size.y) {
+ to_remove.append(E.key);
}
}
@@ -3775,9 +3775,9 @@ void TileSetAtlasSource::_bind_methods() {
TileSetAtlasSource::~TileSetAtlasSource() {
// Free everything needed.
- for (Map<Vector2i, TileAlternativesData>::Element *E_alternatives = tiles.front(); E_alternatives; E_alternatives = E_alternatives->next()) {
- for (Map<int, TileData *>::Element *E_tile_data = E_alternatives->get().alternatives.front(); E_tile_data; E_tile_data = E_tile_data->next()) {
- memdelete(E_tile_data->get());
+ for (KeyValue<Vector2i, TileAlternativesData> &E_alternatives : tiles) {
+ for (KeyValue<int, TileData *> &E_tile_data : E_alternatives.value.alternatives) {
+ memdelete(E_tile_data.value);
}
}
}
diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h
index 42b82957fb..2b4929b3df 100644
--- a/scene/resources/tile_set.h
+++ b/scene/resources/tile_set.h
@@ -646,7 +646,7 @@ private:
};
Vector2 linear_velocity;
- float angular_velocity;
+ float angular_velocity = 0.0;
Vector<PolygonShapeTileData> polygons;
};
Vector<PhysicsLayerTileData> physics;
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index e8fe3ff3cd..934d16bd7e 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -197,9 +197,9 @@ Vector<StringName> VisualShaderNode::get_editable_properties() const {
Array VisualShaderNode::get_default_input_values() const {
Array ret;
- for (Map<int, Variant>::Element *E = default_input_values.front(); E; E = E->next()) {
- ret.push_back(E->key());
- ret.push_back(E->get());
+ for (const KeyValue<int, Variant> &E : default_input_values) {
+ ret.push_back(E.key);
+ ret.push_back(E.value);
}
return ret;
}
@@ -460,14 +460,14 @@ Dictionary VisualShader::get_engine_version() const {
void VisualShader::update_engine_version(const Dictionary &p_new_version) {
if (engine_version.is_empty()) { // before 4.0
for (int i = 0; i < TYPE_MAX; i++) {
- for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) {
- Ref<VisualShaderNodeInput> input = Object::cast_to<VisualShaderNodeInput>(E->get().node.ptr());
+ for (KeyValue<int, Node> &E : graph[i].nodes) {
+ Ref<VisualShaderNodeInput> input = Object::cast_to<VisualShaderNodeInput>(E.value.node.ptr());
if (input.is_valid()) {
if (input->get_input_name() == "side") {
input->set_input_name("front_facing");
}
}
- Ref<VisualShaderNodeExpression> expression = Object::cast_to<VisualShaderNodeExpression>(E->get().node.ptr());
+ Ref<VisualShaderNodeExpression> expression = Object::cast_to<VisualShaderNodeExpression>(E.value.node.ptr());
if (expression.is_valid()) {
for (int j = 0; j < expression->get_input_port_count(); j++) {
int type = expression->get_input_port_type(j);
@@ -484,7 +484,7 @@ void VisualShader::update_engine_version(const Dictionary &p_new_version) {
expression->set_output_port_type(j, type);
}
}
- Ref<VisualShaderNodeCompare> compare = Object::cast_to<VisualShaderNodeCompare>(E->get().node.ptr());
+ Ref<VisualShaderNodeCompare> compare = Object::cast_to<VisualShaderNodeCompare>(E.value.node.ptr());
if (compare.is_valid()) {
int ctype = int(compare->get_comparison_type());
if (int(ctype) > 0) { // + PORT_TYPE_SCALAR_INT
@@ -561,8 +561,8 @@ Vector<int> VisualShader::get_node_list(Type p_type) const {
const Graph *g = &graph[p_type];
Vector<int> ret;
- for (Map<int, Node>::Element *E = g->nodes.front(); E; E = E->next()) {
- ret.push_back(E->key());
+ for (const KeyValue<int, Node> &E : g->nodes) {
+ ret.push_back(E.key);
}
return ret;
@@ -575,9 +575,9 @@ int VisualShader::get_valid_node_id(Type p_type) const {
}
int VisualShader::find_node_id(Type p_type, const Ref<VisualShaderNode> &p_node) const {
- for (const Map<int, Node>::Element *E = graph[p_type].nodes.front(); E; E = E->next()) {
- if (E->get().node == p_node) {
- return E->key();
+ for (const KeyValue<int, Node> &E : graph[p_type].nodes) {
+ if (E.value.node == p_node) {
+ return E.key;
}
}
@@ -819,8 +819,8 @@ void VisualShader::set_mode(Mode p_mode) {
flags.clear();
shader_mode = p_mode;
for (int i = 0; i < TYPE_MAX; i++) {
- for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) {
- Ref<VisualShaderNodeInput> input = E->get().node;
+ for (KeyValue<int, Node> &E : graph[i].nodes) {
+ Ref<VisualShaderNodeInput> input = E.value.node;
if (input.is_valid()) {
input->shader_mode = shader_mode;
//input->input_index = 0;
@@ -1041,8 +1041,8 @@ String VisualShader::validate_uniform_name(const String &p_name, const Ref<Visua
while (true) {
bool exists = false;
for (int i = 0; i < TYPE_MAX; i++) {
- for (const Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) {
- Ref<VisualShaderNodeUniform> node = E->get().node;
+ for (const KeyValue<int, Node> &E : graph[i].nodes) {
+ Ref<VisualShaderNodeUniform> node = E.value.node;
if (node == p_uniform) { //do not test on self
continue;
}
@@ -1271,8 +1271,8 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const {
}
}
- for (Map<String, String>::Element *E = blend_mode_enums.front(); E; E = E->next()) {
- p_list->push_back(PropertyInfo(Variant::INT, "modes/" + E->key(), PROPERTY_HINT_ENUM, E->get()));
+ for (const KeyValue<String, String> &E : blend_mode_enums) {
+ p_list->push_back(PropertyInfo(Variant::INT, "modes/" + E.key, PROPERTY_HINT_ENUM, E.value));
}
for (Set<String>::Element *E = toggles.front(); E; E = E->next()) {
@@ -1280,22 +1280,22 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const {
}
for (int i = 0; i < TYPE_MAX; i++) {
- for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) {
+ for (const KeyValue<int, Node> &E : graph[i].nodes) {
String prop_name = "nodes/";
prop_name += type_string[i];
- prop_name += "/" + itos(E->key());
+ prop_name += "/" + itos(E.key);
- if (E->key() != NODE_ID_OUTPUT) {
+ if (E.key != NODE_ID_OUTPUT) {
p_list->push_back(PropertyInfo(Variant::OBJECT, prop_name + "/node", PROPERTY_HINT_RESOURCE_TYPE, "VisualShaderNode", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE));
}
p_list->push_back(PropertyInfo(Variant::VECTOR2, prop_name + "/position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
- if (Object::cast_to<VisualShaderNodeGroupBase>(E->get().node.ptr()) != nullptr) {
+ if (Object::cast_to<VisualShaderNodeGroupBase>(E.value.node.ptr()) != nullptr) {
p_list->push_back(PropertyInfo(Variant::VECTOR2, prop_name + "/size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
p_list->push_back(PropertyInfo(Variant::STRING, prop_name + "/input_ports", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
p_list->push_back(PropertyInfo(Variant::STRING, prop_name + "/output_ports", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
}
- if (Object::cast_to<VisualShaderNodeExpression>(E->get().node.ptr()) != nullptr) {
+ if (Object::cast_to<VisualShaderNodeExpression>(E.value.node.ptr()) != nullptr) {
p_list->push_back(PropertyInfo(Variant::STRING, prop_name + "/expression", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
}
}
@@ -1716,9 +1716,9 @@ void VisualShader::_update_shader() const {
emitters.insert(i, List<int>());
}
- for (Map<int, Node>::Element *M = graph[i].nodes.front(); M; M = M->next()) {
- if (M->get().node == emit_particle.ptr()) {
- emitters[i].push_back(M->key());
+ for (const KeyValue<int, Node> &M : graph[i].nodes) {
+ if (M.value.node == emit_particle.ptr()) {
+ emitters[i].push_back(M.key);
break;
}
}