diff options
Diffstat (limited to 'scene/2d/tile_map.cpp')
-rw-r--r-- | scene/2d/tile_map.cpp | 350 |
1 files changed, 126 insertions, 224 deletions
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index c468389040..c7a809f6d8 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -39,22 +39,18 @@ #include "servers/physics_server_2d.h" int TileMap::_get_quadrant_size() const { - - if (y_sort_mode) + if (use_y_sort) { return 1; - else + } else { return quadrant_size; + } } void TileMap::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_ENTER_TREE: { - Node2D *c = this; while (c) { - navigation = Object::cast_to<Navigation2D>(c); if (navigation) { break; @@ -79,14 +75,11 @@ void TileMap::_notification(int p_what) { } break; case NOTIFICATION_EXIT_TREE: { - _update_quadrant_space(RID()); for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Quadrant &q = E->get(); if (navigation) { for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) { - NavigationServer2D::get_singleton()->region_set_map(F->get().region, RID()); } q.navpoly_ids.clear(); @@ -103,19 +96,17 @@ void TileMap::_notification(int p_what) { q.occluder_instances.clear(); } - collision_parent = NULL; - navigation = NULL; + collision_parent = nullptr; + navigation = nullptr; } break; case NOTIFICATION_TRANSFORM_CHANGED: { - //move stuff _update_quadrant_transform(); } break; case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: { - if (use_parent) { _recreate_quadrants(); } @@ -125,10 +116,8 @@ void TileMap::_notification(int p_what) { } void TileMap::_update_quadrant_space(const RID &p_space) { - if (!use_parent) { for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Quadrant &q = E->get(); PhysicsServer2D::get_singleton()->body_set_space(q.body, p_space); } @@ -136,22 +125,23 @@ void TileMap::_update_quadrant_space(const RID &p_space) { } void TileMap::_update_quadrant_transform() { - - if (!is_inside_tree()) + if (!is_inside_tree()) { return; + } Transform2D global_transform = get_global_transform(); Transform2D local_transform; - if (collision_parent) + if (collision_parent) { local_transform = get_transform(); + } Transform2D nav_rel; - if (navigation) + if (navigation) { nav_rel = get_relative_transform_to_parent(navigation); + } for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Quadrant &q = E->get(); Transform2D xform; xform.set_origin(q.pos); @@ -163,7 +153,6 @@ void TileMap::_update_quadrant_transform() { if (navigation) { for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) { - NavigationServer2D::get_singleton()->region_set_transform(F->get().region, nav_rel * F->get().xform); } } @@ -175,7 +164,6 @@ void TileMap::_update_quadrant_transform() { } void TileMap::set_tileset(const Ref<TileSet> &p_tileset) { - if (tile_set.is_valid()) { tile_set->disconnect("changed", callable_mp(this, &TileMap::_recreate_quadrants)); tile_set->remove_change_receptor(this); @@ -196,12 +184,10 @@ void TileMap::set_tileset(const Ref<TileSet> &p_tileset) { } Ref<TileSet> TileMap::get_tileset() const { - return tile_set; } void TileMap::set_cell_size(Size2 p_size) { - ERR_FAIL_COND(p_size.x < 1 || p_size.y < 1); _clear_quadrants(); @@ -211,12 +197,10 @@ void TileMap::set_cell_size(Size2 p_size) { } Size2 TileMap::get_cell_size() const { - return cell_size; } void TileMap::set_quadrant_size(int p_size) { - ERR_FAIL_COND_MSG(p_size < 1, "Quadrant size cannot be smaller than 1."); _clear_quadrants(); @@ -226,17 +210,14 @@ void TileMap::set_quadrant_size(int p_size) { } int TileMap::get_quadrant_size() const { - return quadrant_size; } void TileMap::_fix_cell_transform(Transform2D &xform, const Cell &p_cell, const Vector2 &p_offset, const Size2 &p_sc) { - Size2 s = p_sc; Vector2 offset = p_offset; if (compatibility_mode && !centered_textures) { - if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) { offset.y += cell_size.y; } else if (tile_origin == TILE_ORIGIN_CENTER) { @@ -314,7 +295,7 @@ void TileMap::_add_shape(int &shape_idx, const Quadrant &p_q, const Ref<Shape2D> int real_index = collision_parent->shape_owner_get_shape_index(p_q.shape_owner_id, shape_idx); RID rid = collision_parent->get_rid(); - if (Object::cast_to<Area2D>(collision_parent) != NULL) { + if (Object::cast_to<Area2D>(collision_parent) != nullptr) { ps->area_set_shape_transform(rid, real_index, get_transform() * xform); } else { ps->body_set_shape_transform(rid, real_index, get_transform() * xform); @@ -326,9 +307,9 @@ void TileMap::_add_shape(int &shape_idx, const Quadrant &p_q, const Ref<Shape2D> } void TileMap::update_dirty_quadrants() { - - if (!pending_update) + if (!pending_update) { return; + } if (!is_inside_tree() || !tile_set.is_valid()) { pending_update = false; return; @@ -338,8 +319,9 @@ void TileMap::update_dirty_quadrants() { PhysicsServer2D *ps = PhysicsServer2D::get_singleton(); Vector2 tofs = get_cell_draw_offset(); Transform2D nav_rel; - if (navigation) + if (navigation) { nav_rel = get_relative_transform_to_parent(navigation); + } Vector2 qofs; @@ -358,11 +340,9 @@ void TileMap::update_dirty_quadrants() { } while (dirty_quadrant_list.first()) { - Quadrant &q = *dirty_quadrant_list.first()->self(); for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) { - vs->free(E->get()); } @@ -377,7 +357,6 @@ void TileMap::update_dirty_quadrants() { if (navigation) { for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) { - NavigationServer2D::get_singleton()->region_set_map(E->get().region, RID()); } q.navpoly_ids.clear(); @@ -393,20 +372,21 @@ void TileMap::update_dirty_quadrants() { RID prev_debug_canvas_item; for (int i = 0; i < q.cells.size(); i++) { - Map<PosKey, Cell>::Element *E = tile_map.find(q.cells[i]); Cell &c = E->get(); //moment of truth - if (!tile_set->has_tile(c.id)) + if (!tile_set->has_tile(c.id)) { continue; + } Ref<Texture2D> tex = tile_set->tile_get_texture(c.id); Vector2 tile_ofs = tile_set->tile_get_texture_offset(c.id); Vector2 wofs = _map_to_world(E->key().x, E->key().y); Vector2 offset = wofs - q.pos + tofs; - if (!tex.is_valid()) + if (!tex.is_valid()) { continue; + } Ref<ShaderMaterial> mat = tile_set->tile_get_material(c.id); int z_index = tile_set->tile_get_z_index(c.id); @@ -420,10 +400,10 @@ void TileMap::update_dirty_quadrants() { RID debug_canvas_item; if (prev_canvas_item == RID() || prev_material != mat || prev_z_index != z_index) { - canvas_item = vs->canvas_item_create(); - if (mat.is_valid()) + if (mat.is_valid()) { vs->canvas_item_set_material(canvas_item, mat->get_rid()); + } vs->canvas_item_set_parent(canvas_item, get_canvas_item()); _update_item_material_state(canvas_item); Transform2D xform; @@ -435,7 +415,6 @@ void TileMap::update_dirty_quadrants() { q.canvas_items.push_back(canvas_item); if (debug_shapes) { - debug_canvas_item = vs->canvas_item_create(); vs->canvas_item_set_parent(debug_canvas_item, canvas_item); vs->canvas_item_set_z_as_relative_to_parent(debug_canvas_item, false); @@ -463,10 +442,11 @@ void TileMap::update_dirty_quadrants() { } Size2 s; - if (r == Rect2()) + if (r == Rect2()) { s = tex->get_size(); - else + } else { s = r.size; + } Rect2 rect; rect.position = offset.floor(); @@ -476,11 +456,13 @@ void TileMap::update_dirty_quadrants() { if (compatibility_mode && !centered_textures) { if (rect.size.y > rect.size.x) { - if ((c.flip_h && (c.flip_v || c.transpose)) || (c.flip_v && !c.transpose)) + if ((c.flip_h && (c.flip_v || c.transpose)) || (c.flip_v && !c.transpose)) { tile_ofs.y += rect.size.y - rect.size.x; + } } else if (rect.size.y < rect.size.x) { - if ((c.flip_v && (c.flip_h || c.transpose)) || (c.flip_h && !c.transpose)) + if ((c.flip_v && (c.flip_h || c.transpose)) || (c.flip_h && !c.transpose)) { tile_ofs.x += rect.size.x - rect.size.y; + } } } @@ -509,34 +491,36 @@ void TileMap::update_dirty_quadrants() { rect.position += tile_ofs; } else if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) { - rect.position += tile_ofs; if (c.transpose) { - if (c.flip_h) + if (c.flip_h) { rect.position.x -= cell_size.x; - else + } else { rect.position.x += cell_size.x; + } } else { - if (c.flip_v) + if (c.flip_v) { rect.position.y -= cell_size.y; - else + } else { rect.position.y += cell_size.y; + } } } else if (tile_origin == TILE_ORIGIN_CENTER) { - rect.position += tile_ofs; - if (c.flip_h) + if (c.flip_h) { rect.position.x -= cell_size.x / 2; - else + } else { rect.position.x += cell_size.x / 2; + } - if (c.flip_v) + if (c.flip_v) { rect.position.y -= cell_size.y / 2; - else + } else { rect.position.y += cell_size.y / 2; + } } } else { rect.position += tile_ofs; @@ -651,10 +635,8 @@ void TileMap::update_dirty_quadrants() { Vector<int> polygon = navpoly->get_polygon(j); for (int k = 2; k < polygon.size(); k++) { - int kofs[3] = { 0, k - 1, k }; for (int l = 0; l < 3; l++) { - int idx = polygon[kofs[l]]; ERR_FAIL_INDEX(idx, vsize); indices.push_back(idx); @@ -704,13 +686,10 @@ void TileMap::update_dirty_quadrants() { pending_update = false; if (quadrant_order_dirty) { - int index = -(int64_t)0x80000000; //always must be drawn below children for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Quadrant &q = E->get(); for (List<RID>::Element *F = q.canvas_items.front(); F; F = F->next()) { - RS::get_singleton()->canvas_item_set_draw_index(F->get(), index++); } } @@ -722,24 +701,24 @@ void TileMap::update_dirty_quadrants() { } void TileMap::_recompute_rect_cache() { - #ifdef DEBUG_ENABLED - if (!rect_cache_dirty) + if (!rect_cache_dirty) { return; + } Rect2 r_total; for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Rect2 r; r.position = _map_to_world(E->key().x * _get_quadrant_size(), E->key().y * _get_quadrant_size()); r.expand_to(_map_to_world(E->key().x * _get_quadrant_size() + _get_quadrant_size(), E->key().y * _get_quadrant_size())); r.expand_to(_map_to_world(E->key().x * _get_quadrant_size() + _get_quadrant_size(), E->key().y * _get_quadrant_size() + _get_quadrant_size())); r.expand_to(_map_to_world(E->key().x * _get_quadrant_size(), E->key().y * _get_quadrant_size() + _get_quadrant_size())); - if (E == quadrant_map.front()) + if (E == quadrant_map.front()) { r_total = r; - else + } else { r_total = r_total.merge(r); + } } rect_cache = r_total; @@ -751,16 +730,16 @@ void TileMap::_recompute_rect_cache() { } Map<TileMap::PosKey, TileMap::Quadrant>::Element *TileMap::_create_quadrant(const PosKey &p_qk) { - Transform2D xform; //xform.set_origin(Point2(p_qk.x,p_qk.y)*cell_size*quadrant_size); Quadrant q; q.pos = _map_to_world(p_qk.x * _get_quadrant_size(), p_qk.y * _get_quadrant_size()); q.pos += get_cell_draw_offset(); - if (tile_origin == TILE_ORIGIN_CENTER) + if (tile_origin == TILE_ORIGIN_CENTER) { q.pos += cell_size / 2; - else if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) + } else if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) { q.pos.y += cell_size.y; + } xform.set_origin(q.pos); //q.canvas_item = RenderingServer::get_singleton()->canvas_item_create(); @@ -794,7 +773,6 @@ Map<TileMap::PosKey, TileMap::Quadrant>::Element *TileMap::_create_quadrant(cons } void TileMap::_erase_quadrant(Map<PosKey, Quadrant>::Element *Q) { - Quadrant &q = Q->get(); if (!use_parent) { PhysicsServer2D::get_singleton()->free(q.body); @@ -803,16 +781,15 @@ void TileMap::_erase_quadrant(Map<PosKey, Quadrant>::Element *Q) { } for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) { - RenderingServer::get_singleton()->free(E->get()); } q.canvas_items.clear(); - if (q.dirty_list.in_list()) + if (q.dirty_list.in_list()) { dirty_quadrant_list.remove(&q.dirty_list); + } if (navigation) { for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) { - NavigationServer2D::get_singleton()->region_set_map(E->get().region, RID()); } q.navpoly_ids.clear(); @@ -828,16 +805,18 @@ void TileMap::_erase_quadrant(Map<PosKey, Quadrant>::Element *Q) { } void TileMap::_make_quadrant_dirty(Map<PosKey, Quadrant>::Element *Q, bool update) { - Quadrant &q = Q->get(); - if (!q.dirty_list.in_list()) + if (!q.dirty_list.in_list()) { dirty_quadrant_list.add(&q.dirty_list); + } - if (pending_update) + if (pending_update) { return; + } pending_update = true; - if (!is_inside_tree()) + if (!is_inside_tree()) { return; + } if (update) { call_deferred("update_dirty_quadrants"); @@ -845,12 +824,10 @@ void TileMap::_make_quadrant_dirty(Map<PosKey, Quadrant>::Element *Q, bool updat } void TileMap::set_cellv(const Vector2 &p_pos, int p_tile, bool p_flip_x, bool p_flip_y, bool p_transpose) { - set_cell(p_pos.x, p_pos.y, p_tile, p_flip_x, p_flip_y, p_transpose); } void TileMap::_set_celld(const Vector2 &p_pos, const Dictionary &p_data) { - Variant v_pos_x = p_pos.x, v_pos_y = p_pos.y, v_tile = p_data["id"], v_flip_h = p_data["flip_h"], v_flip_v = p_data["flip_y"], v_transpose = p_data["transpose"], v_autotile_coord = p_data["auto_coord"]; const Variant *args[7] = { &v_pos_x, &v_pos_y, &v_tile, &v_flip_h, &v_flip_v, &v_transpose, &v_autotile_coord }; Callable::CallError ce; @@ -858,12 +835,12 @@ void TileMap::_set_celld(const Vector2 &p_pos, const Dictionary &p_data) { } void TileMap::set_cell(int p_x, int p_y, int p_tile, bool p_flip_x, bool p_flip_y, bool p_transpose, Vector2 p_autotile_coord) { - PosKey pk(p_x, p_y); Map<PosKey, Cell>::Element *E = tile_map.find(pk); - if (!E && p_tile == INVALID_CELL) + if (!E && p_tile == INVALID_CELL) { return; //nothing to do + } PosKey qk = pk.to_quadrant(_get_quadrant_size()); if (p_tile == INVALID_CELL) { @@ -873,10 +850,11 @@ void TileMap::set_cell(int p_x, int p_y, int p_tile, bool p_flip_x, bool p_flip_ ERR_FAIL_COND(!Q); Quadrant &q = Q->get(); q.cells.erase(pk); - if (q.cells.size() == 0) + if (q.cells.size() == 0) { _erase_quadrant(Q); - else + } else { _make_quadrant_dirty(Q); + } used_size_cache_dirty = true; return; @@ -894,8 +872,9 @@ void TileMap::set_cell(int p_x, int p_y, int p_tile, bool p_flip_x, bool p_flip_ } else { ERR_FAIL_COND(!Q); // quadrant should exist... - if (E->get().id == p_tile && E->get().flip_h == p_flip_x && E->get().flip_v == p_flip_y && E->get().transpose == p_transpose && E->get().autotile_coord_x == (uint16_t)p_autotile_coord.x && E->get().autotile_coord_y == (uint16_t)p_autotile_coord.y) + if (E->get().id == p_tile && E->get().flip_h == p_flip_x && E->get().flip_v == p_flip_y && E->get().transpose == p_transpose && E->get().autotile_coord_x == (uint16_t)p_autotile_coord.x && E->get().autotile_coord_y == (uint16_t)p_autotile_coord.y) { return; //nothing changed + } } Cell &c = E->get(); @@ -912,16 +891,14 @@ void TileMap::set_cell(int p_x, int p_y, int p_tile, bool p_flip_x, bool p_flip_ } int TileMap::get_cellv(const Vector2 &p_pos) const { - return get_cell(p_pos.x, p_pos.y); } void TileMap::make_bitmask_area_dirty(const Vector2 &p_pos) { - for (int x = p_pos.x - 1; x <= p_pos.x + 1; x++) { for (int y = p_pos.y - 1; y <= p_pos.y + 1; y++) { PosKey p(x, y); - if (dirty_bitmask.find(p) == NULL) { + if (dirty_bitmask.find(p) == nullptr) { dirty_bitmask.push_back(p); } } @@ -929,7 +906,6 @@ void TileMap::make_bitmask_area_dirty(const Vector2 &p_pos) { } void TileMap::update_bitmask_area(const Vector2 &p_pos) { - for (int x = p_pos.x - 1; x <= p_pos.x + 1; x++) { for (int y = p_pos.y - 1; y <= p_pos.y + 1; y++) { update_cell_bitmask(x, y); @@ -938,15 +914,11 @@ void TileMap::update_bitmask_area(const Vector2 &p_pos) { } void TileMap::update_bitmask_region(const Vector2 &p_start, const Vector2 &p_end) { - if ((p_end.x < p_start.x || p_end.y < p_start.y) || (p_end.x == p_start.x && p_end.y == p_start.y)) { - int i; Array a = get_used_cells(); - for (i = 0; i < a.size(); i++) { - // update_bitmask_area() in order to update cells adjacent to the - // current cell, since ordering in array may not be reliable + for (int i = 0; i < a.size(); i++) { Vector2 vector = (Vector2)a[i]; - update_bitmask_area(Vector2(vector.x, vector.y)); + update_cell_bitmask(vector.x, vector.y); } return; } @@ -958,11 +930,10 @@ void TileMap::update_bitmask_region(const Vector2 &p_start, const Vector2 &p_end } void TileMap::update_cell_bitmask(int p_x, int p_y) { - ERR_FAIL_COND_MSG(tile_set.is_null(), "Cannot update cell bitmask if Tileset is not open."); PosKey p(p_x, p_y); Map<PosKey, Cell>::Element *E = tile_map.find(p); - if (E != NULL) { + if (E != nullptr) { int id = get_cell(p_x, p_y); if (tile_set->tile_get_tile_mode(id) == TileSet::AUTO_TILE) { uint16_t mask = 0; @@ -1030,11 +1001,9 @@ void TileMap::update_cell_bitmask(int p_x, int p_y) { _make_quadrant_dirty(Q); } else if (tile_set->tile_get_tile_mode(id) == TileSet::SINGLE_TILE) { - E->get().autotile_coord_x = 0; E->get().autotile_coord_y = 0; } else if (tile_set->tile_get_tile_mode(id) == TileSet::ATLAS_TILE) { - if (tile_set->autotile_get_bitmask(id, Vector2(p_x, p_y)) == TileSet::BIND_CENTER) { Vector2 coord = tile_set->atlastile_get_subtile_by_priority(id, this, Vector2(p_x, p_y)); @@ -1046,7 +1015,6 @@ void TileMap::update_cell_bitmask(int p_x, int p_y) { } void TileMap::update_dirty_bitmask() { - while (dirty_bitmask.size() > 0) { update_cell_bitmask(dirty_bitmask[0].x, dirty_bitmask[0].y); dirty_bitmask.pop_front(); @@ -1054,10 +1022,8 @@ void TileMap::update_dirty_bitmask() { } void TileMap::fix_invalid_tiles() { - ERR_FAIL_COND_MSG(tile_set.is_null(), "Cannot fix invalid tiles if Tileset is not open."); for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) { - if (!tile_set->has_tile(get_cell(E->key().x, E->key().y))) { set_cell(E->key().x, E->key().y, INVALID_CELL); } @@ -1065,58 +1031,61 @@ void TileMap::fix_invalid_tiles() { } int TileMap::get_cell(int p_x, int p_y) const { - PosKey pk(p_x, p_y); const Map<PosKey, Cell>::Element *E = tile_map.find(pk); - if (!E) + if (!E) { return INVALID_CELL; + } return E->get().id; } -bool TileMap::is_cell_x_flipped(int p_x, int p_y) const { +bool TileMap::is_cell_x_flipped(int p_x, int p_y) const { PosKey pk(p_x, p_y); const Map<PosKey, Cell>::Element *E = tile_map.find(pk); - if (!E) + if (!E) { return false; + } return E->get().flip_h; } -bool TileMap::is_cell_y_flipped(int p_x, int p_y) const { +bool TileMap::is_cell_y_flipped(int p_x, int p_y) const { PosKey pk(p_x, p_y); const Map<PosKey, Cell>::Element *E = tile_map.find(pk); - if (!E) + if (!E) { return false; + } return E->get().flip_v; } -bool TileMap::is_cell_transposed(int p_x, int p_y) const { +bool TileMap::is_cell_transposed(int p_x, int p_y) const { PosKey pk(p_x, p_y); const Map<PosKey, Cell>::Element *E = tile_map.find(pk); - if (!E) + if (!E) { return false; + } return E->get().transpose; } void TileMap::set_cell_autotile_coord(int p_x, int p_y, const Vector2 &p_coord) { - PosKey pk(p_x, p_y); const Map<PosKey, Cell>::Element *E = tile_map.find(pk); - if (!E) + if (!E) { return; + } Cell c = E->get(); c.autotile_coord_x = p_coord.x; @@ -1126,30 +1095,29 @@ void TileMap::set_cell_autotile_coord(int p_x, int p_y, const Vector2 &p_coord) PosKey qk = pk.to_quadrant(_get_quadrant_size()); Map<PosKey, Quadrant>::Element *Q = quadrant_map.find(qk); - if (!Q) + if (!Q) { return; + } _make_quadrant_dirty(Q); } Vector2 TileMap::get_cell_autotile_coord(int p_x, int p_y) const { - PosKey pk(p_x, p_y); const Map<PosKey, Cell>::Element *E = tile_map.find(pk); - if (!E) + if (!E) { return Vector2(); + } return Vector2(E->get().autotile_coord_x, E->get().autotile_coord_y); } void TileMap::_recreate_quadrants() { - _clear_quadrants(); for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) { - PosKey qk = PosKey(E->key().x, E->key().y).to_quadrant(_get_quadrant_size()); Map<PosKey, Quadrant>::Element *Q = quadrant_map.find(qk); @@ -1165,50 +1133,41 @@ void TileMap::_recreate_quadrants() { } void TileMap::_clear_quadrants() { - while (quadrant_map.size()) { _erase_quadrant(quadrant_map.front()); } } void TileMap::set_material(const Ref<Material> &p_material) { - CanvasItem::set_material(p_material); _update_all_items_material_state(); } void TileMap::set_use_parent_material(bool p_use_parent_material) { - CanvasItem::set_use_parent_material(p_use_parent_material); _update_all_items_material_state(); } void TileMap::_update_all_items_material_state() { - for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Quadrant &q = E->get(); for (List<RID>::Element *F = q.canvas_items.front(); F; F = F->next()) { - _update_item_material_state(F->get()); } } } void TileMap::_update_item_material_state(const RID &p_canvas_item) { - RS::get_singleton()->canvas_item_set_use_parent_material(p_canvas_item, get_use_parent_material() || get_material().is_valid()); } void TileMap::clear() { - _clear_quadrants(); tile_map.clear(); used_size_cache_dirty = true; } void TileMap::_set_tile_data(const Vector<int> &p_data) { - ERR_FAIL_COND(format > FORMAT_2); int c = p_data.size(); @@ -1218,11 +1177,11 @@ void TileMap::_set_tile_data(const Vector<int> &p_data) { clear(); for (int i = 0; i < c; i += offset) { - const uint8_t *ptr = (const uint8_t *)&r[i]; uint8_t local[12]; - for (int j = 0; j < ((format == FORMAT_2) ? 12 : 8); j++) + for (int j = 0; j < ((format == FORMAT_2) ? 12 : 8); j++) { local[j] = ptr[j]; + } #ifdef BIG_ENDIAN_ENABLED @@ -1256,7 +1215,6 @@ void TileMap::_set_tile_data(const Vector<int> &p_data) { } Vector<int> TileMap::_get_tile_data() const { - Vector<int> data; data.resize(tile_map.size() * 3); int *w = data.ptrw(); @@ -1269,12 +1227,15 @@ Vector<int> TileMap::_get_tile_data() const { encode_uint16(E->key().x, &ptr[0]); encode_uint16(E->key().y, &ptr[2]); uint32_t val = E->get().id; - if (E->get().flip_h) + if (E->get().flip_h) { val |= (1 << 29); - if (E->get().flip_v) + } + if (E->get().flip_v) { val |= (1 << 30); - if (E->get().transpose) + } + if (E->get().transpose) { val |= (1 << 31); + } encode_uint32(val, &ptr[4]); encode_uint16(E->get().autotile_coord_x, &ptr[8]); encode_uint16(E->get().autotile_coord_y, &ptr[10]); @@ -1296,11 +1257,9 @@ Rect2 TileMap::_edit_get_rect() const { #endif void TileMap::set_collision_layer(uint32_t p_layer) { - collision_layer = p_layer; if (!use_parent) { for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Quadrant &q = E->get(); PhysicsServer2D::get_singleton()->body_set_collision_layer(q.body, collision_layer); } @@ -1308,11 +1267,9 @@ void TileMap::set_collision_layer(uint32_t p_layer) { } void TileMap::set_collision_mask(uint32_t p_mask) { - collision_mask = p_mask; if (!use_parent) { for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Quadrant &q = E->get(); PhysicsServer2D::get_singleton()->body_set_collision_mask(q.body, collision_mask); } @@ -1320,45 +1277,43 @@ void TileMap::set_collision_mask(uint32_t p_mask) { } void TileMap::set_collision_layer_bit(int p_bit, bool p_value) { - uint32_t layer = get_collision_layer(); - if (p_value) + if (p_value) { layer |= 1 << p_bit; - else + } else { layer &= ~(1 << p_bit); + } set_collision_layer(layer); } void TileMap::set_collision_mask_bit(int p_bit, bool p_value) { - uint32_t mask = get_collision_mask(); - if (p_value) + if (p_value) { mask |= 1 << p_bit; - else + } else { mask &= ~(1 << p_bit); + } set_collision_mask(mask); } bool TileMap::get_collision_use_kinematic() const { - return use_kinematic; } void TileMap::set_collision_use_kinematic(bool p_use_kinematic) { - _clear_quadrants(); use_kinematic = p_use_kinematic; _recreate_quadrants(); } bool TileMap::get_collision_use_parent() const { - return use_parent; } void TileMap::set_collision_use_parent(bool p_use_parent) { - - if (use_parent == p_use_parent) return; + if (use_parent == p_use_parent) { + return; + } _clear_quadrants(); @@ -1368,7 +1323,7 @@ void TileMap::set_collision_use_parent(bool p_use_parent) { if (use_parent && is_inside_tree()) { collision_parent = Object::cast_to<CollisionObject2D>(get_parent()); } else { - collision_parent = NULL; + collision_parent = nullptr; } _recreate_quadrants(); @@ -1377,11 +1332,9 @@ void TileMap::set_collision_use_parent(bool p_use_parent) { } void TileMap::set_collision_friction(float p_friction) { - friction = p_friction; if (!use_parent) { for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Quadrant &q = E->get(); PhysicsServer2D::get_singleton()->body_set_param(q.body, PhysicsServer2D::BODY_PARAM_FRICTION, p_friction); } @@ -1389,48 +1342,40 @@ void TileMap::set_collision_friction(float p_friction) { } float TileMap::get_collision_friction() const { - return friction; } void TileMap::set_collision_bounce(float p_bounce) { - bounce = p_bounce; if (!use_parent) { for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - Quadrant &q = E->get(); PhysicsServer2D::get_singleton()->body_set_param(q.body, PhysicsServer2D::BODY_PARAM_BOUNCE, p_bounce); } } } -float TileMap::get_collision_bounce() const { +float TileMap::get_collision_bounce() const { return bounce; } uint32_t TileMap::get_collision_layer() const { - return collision_layer; } uint32_t TileMap::get_collision_mask() const { - return collision_mask; } bool TileMap::get_collision_layer_bit(int p_bit) const { - return get_collision_layer() & (1 << p_bit); } bool TileMap::get_collision_mask_bit(int p_bit) const { - return get_collision_mask() & (1 << p_bit); } void TileMap::set_mode(Mode p_mode) { - _clear_quadrants(); mode = p_mode; _recreate_quadrants(); @@ -1442,7 +1387,6 @@ TileMap::Mode TileMap::get_mode() const { } void TileMap::set_half_offset(HalfOffset p_half_offset) { - _clear_quadrants(); half_offset = p_half_offset; _recreate_quadrants(); @@ -1450,7 +1394,6 @@ void TileMap::set_half_offset(HalfOffset p_half_offset) { } void TileMap::set_tile_origin(TileOrigin p_tile_origin) { - _clear_quadrants(); tile_origin = p_tile_origin; _recreate_quadrants(); @@ -1458,25 +1401,19 @@ void TileMap::set_tile_origin(TileOrigin p_tile_origin) { } TileMap::TileOrigin TileMap::get_tile_origin() const { - return tile_origin; } Vector2 TileMap::get_cell_draw_offset() const { - switch (mode) { - case MODE_SQUARE: { - return Vector2(); } break; case MODE_ISOMETRIC: { - return Vector2(-cell_size.x * 0.5, 0); } break; case MODE_CUSTOM: { - Vector2 min; min.x = MIN(custom_transform[0].x, min.x); min.y = MIN(custom_transform[0].y, min.y); @@ -1494,18 +1431,14 @@ TileMap::HalfOffset TileMap::get_half_offset() const { } Transform2D TileMap::get_cell_transform() const { - switch (mode) { - case MODE_SQUARE: { - Transform2D m; m[0] *= cell_size.x; m[1] *= cell_size.y; return m; } break; case MODE_ISOMETRIC: { - //isometric only makes sense when y is positive in both x and y vectors, otherwise //the drawing of tiles will overlap Transform2D m; @@ -1515,7 +1448,6 @@ Transform2D TileMap::get_cell_transform() const { } break; case MODE_CUSTOM: { - return custom_transform; } break; } @@ -1524,7 +1456,6 @@ Transform2D TileMap::get_cell_transform() const { } void TileMap::set_custom_transform(const Transform2D &p_xform) { - _clear_quadrants(); custom_transform = p_xform; _recreate_quadrants(); @@ -1532,20 +1463,16 @@ void TileMap::set_custom_transform(const Transform2D &p_xform) { } Transform2D TileMap::get_custom_transform() const { - return custom_transform; } Vector2 TileMap::_map_to_world(int p_x, int p_y, bool p_ignore_ofs) const { - Vector2 ret = get_cell_transform().xform(Vector2(p_x, p_y)); if (!p_ignore_ofs) { switch (half_offset) { - case HALF_OFFSET_X: case HALF_OFFSET_NEGATIVE_X: { if (ABS(p_y) & 1) { - ret += get_cell_transform()[0] * (half_offset == HALF_OFFSET_X ? 0.5 : -0.5); } } break; @@ -1564,7 +1491,6 @@ Vector2 TileMap::_map_to_world(int p_x, int p_y, bool p_ignore_ofs) const { } bool TileMap::_set(const StringName &p_name, const Variant &p_value) { - if (p_name == "format") { if (p_value.get_type() == Variant::INT) { format = (DataFormat)(p_value.operator int64_t()); // Set format used for loading @@ -1581,7 +1507,6 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) { } bool TileMap::_get(const StringName &p_name, Variant &r_ret) const { - if (p_name == "format") { r_ret = FORMAT_2; // When saving, always save highest format return true; @@ -1593,7 +1518,6 @@ bool TileMap::_get(const StringName &p_name, Variant &r_ret) const { } void TileMap::_get_property_list(List<PropertyInfo> *p_list) const { - PropertyInfo p(Variant::INT, "format", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL); p_list->push_back(p); @@ -1608,16 +1532,13 @@ void TileMap::_validate_property(PropertyInfo &property) const { } Vector2 TileMap::map_to_world(const Vector2 &p_pos, bool p_ignore_ofs) const { - return _map_to_world(p_pos.x, p_pos.y, p_ignore_ofs); } Vector2 TileMap::world_to_map(const Vector2 &p_pos) const { - Vector2 ret = get_cell_transform().affine_inverse().xform(p_pos); switch (half_offset) { - case HALF_OFFSET_X: { if (int(floor(ret.y)) & 1) { ret.x -= 0.5; @@ -1651,22 +1572,19 @@ Vector2 TileMap::world_to_map(const Vector2 &p_pos) const { return ret.floor(); } -void TileMap::set_y_sort_mode(bool p_enable) { - +void TileMap::set_y_sort_enabled(bool p_enable) { _clear_quadrants(); - y_sort_mode = p_enable; - RS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), y_sort_mode); + use_y_sort = p_enable; + RS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), use_y_sort); _recreate_quadrants(); emit_signal("settings_changed"); } -bool TileMap::is_y_sort_mode_enabled() const { - - return y_sort_mode; +bool TileMap::is_y_sort_enabled() const { + return use_y_sort; } void TileMap::set_compatibility_mode(bool p_enable) { - _clear_quadrants(); compatibility_mode = p_enable; _recreate_quadrants(); @@ -1674,12 +1592,10 @@ void TileMap::set_compatibility_mode(bool p_enable) { } bool TileMap::is_compatibility_mode_enabled() const { - return compatibility_mode; } void TileMap::set_centered_textures(bool p_enable) { - _clear_quadrants(); centered_textures = p_enable; _recreate_quadrants(); @@ -1687,31 +1603,26 @@ void TileMap::set_centered_textures(bool p_enable) { } bool TileMap::is_centered_textures_enabled() const { - return centered_textures; } -Array TileMap::get_used_cells() const { - - Array a; +TypedArray<Vector2i> TileMap::get_used_cells() const { + TypedArray<Vector2i> a; a.resize(tile_map.size()); int i = 0; for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) { - - Vector2 p(E->key().x, E->key().y); + Vector2i p(E->key().x, E->key().y); a[i++] = p; } return a; } -Array TileMap::get_used_cells_by_id(int p_id) const { - - Array a; +TypedArray<Vector2i> TileMap::get_used_cells_by_index(int p_id) const { + TypedArray<Vector2i> a; for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) { - if (E->value().id == p_id) { - Vector2 p(E->key().x, E->key().y); + Vector2i p(E->key().x, E->key().y); a.push_back(p); } } @@ -1741,10 +1652,8 @@ Rect2 TileMap::get_used_rect() { // Not const because of cache } void TileMap::set_occluder_light_mask(int p_mask) { - occluder_light_mask = p_mask; for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - for (Map<PosKey, Quadrant::Occluder>::Element *F = E->get().occluder_instances.front(); F; F = F->next()) { RenderingServer::get_singleton()->canvas_light_occluder_set_light_mask(F->get().id, occluder_light_mask); } @@ -1752,15 +1661,12 @@ void TileMap::set_occluder_light_mask(int p_mask) { } int TileMap::get_occluder_light_mask() const { - return occluder_light_mask; } void TileMap::set_light_mask(int p_light_mask) { - CanvasItem::set_light_mask(p_light_mask); for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { - for (List<RID>::Element *F = E->get().canvas_items.front(); F; F = F->next()) { RenderingServer::get_singleton()->canvas_item_set_light_mask(F->get(), get_light_mask()); } @@ -1768,9 +1674,9 @@ void TileMap::set_light_mask(int p_light_mask) { } void TileMap::set_clip_uv(bool p_enable) { - - if (clip_uv == p_enable) + if (clip_uv == p_enable) { return; + } _clear_quadrants(); clip_uv = p_enable; @@ -1778,12 +1684,10 @@ void TileMap::set_clip_uv(bool p_enable) { } bool TileMap::get_clip_uv() const { - return clip_uv; } String TileMap::get_configuration_warning() const { - String warning = Node2D::get_configuration_warning(); if (use_parent && !collision_parent) { @@ -1797,7 +1701,6 @@ String TileMap::get_configuration_warning() const { } void TileMap::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_tileset", "tileset"), &TileMap::set_tileset); ClassDB::bind_method(D_METHOD("get_tileset"), &TileMap::get_tileset); @@ -1825,8 +1728,8 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("set_clip_uv", "enable"), &TileMap::set_clip_uv); ClassDB::bind_method(D_METHOD("get_clip_uv"), &TileMap::get_clip_uv); - ClassDB::bind_method(D_METHOD("set_y_sort_mode", "enable"), &TileMap::set_y_sort_mode); - ClassDB::bind_method(D_METHOD("is_y_sort_mode_enabled"), &TileMap::is_y_sort_mode_enabled); + ClassDB::bind_method(D_METHOD("set_y_sort_enabled", "enable"), &TileMap::set_y_sort_enabled); + ClassDB::bind_method(D_METHOD("is_y_sort_enabled"), &TileMap::is_y_sort_enabled); ClassDB::bind_method(D_METHOD("set_compatibility_mode", "enable"), &TileMap::set_compatibility_mode); ClassDB::bind_method(D_METHOD("is_compatibility_mode_enabled"), &TileMap::is_compatibility_mode_enabled); @@ -1876,7 +1779,7 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("clear"), &TileMap::clear); ClassDB::bind_method(D_METHOD("get_used_cells"), &TileMap::get_used_cells); - ClassDB::bind_method(D_METHOD("get_used_cells_by_id", "id"), &TileMap::get_used_cells_by_id); + ClassDB::bind_method(D_METHOD("get_used_cells_by_index", "index"), &TileMap::get_used_cells_by_index); ClassDB::bind_method(D_METHOD("get_used_rect"), &TileMap::get_used_rect); ClassDB::bind_method(D_METHOD("map_to_world", "map_position", "ignore_half_ofs"), &TileMap::map_to_world, DEFVAL(false)); @@ -1900,7 +1803,7 @@ void TileMap::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "cell_custom_transform"), "set_custom_transform", "get_custom_transform"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_half_offset", PROPERTY_HINT_ENUM, "Offset X,Offset Y,Disabled,Offset Negative X,Offset Negative Y"), "set_half_offset", "get_half_offset"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_tile_origin", PROPERTY_HINT_ENUM, "Top Left,Center,Bottom Left"), "set_tile_origin", "get_tile_origin"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cell_y_sort"), "set_y_sort_mode", "is_y_sort_mode_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cell_y_sort"), "set_y_sort_enabled", "is_y_sort_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "compatibility_mode"), "set_compatibility_mode", "is_compatibility_mode_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "centered_textures"), "set_centered_textures", "is_centered_textures_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cell_clip_uv"), "set_clip_uv", "get_clip_uv"); @@ -1944,7 +1847,6 @@ void TileMap::_changed_callback(Object *p_changed, const char *p_prop) { } TileMap::TileMap() { - rect_cache_dirty = true; used_size_cache_dirty = true; pending_update = false; @@ -1959,10 +1861,10 @@ TileMap::TileMap() { mode = MODE_SQUARE; half_offset = HALF_OFFSET_DISABLED; use_parent = false; - collision_parent = NULL; + collision_parent = nullptr; use_kinematic = false; - navigation = NULL; - y_sort_mode = false; + navigation = nullptr; + use_y_sort = false; compatibility_mode = false; centered_textures = false; occluder_light_mask = 1; @@ -1976,9 +1878,9 @@ TileMap::TileMap() { } TileMap::~TileMap() { - - if (tile_set.is_valid()) + if (tile_set.is_valid()) { tile_set->remove_change_receptor(this); + } clear(); } |