summaryrefslogtreecommitdiff
path: root/scene/2d/tile_map.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/2d/tile_map.cpp')
-rw-r--r--scene/2d/tile_map.cpp95
1 files changed, 87 insertions, 8 deletions
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 361d765c97..c126dd8f6b 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -142,16 +142,20 @@ void TileMap::_update_quadrant_transform() {
void TileMap::set_tileset(const Ref<TileSet> &p_tileset) {
- if (tile_set.is_valid())
+ if (tile_set.is_valid()) {
tile_set->disconnect("changed", this, "_recreate_quadrants");
+ tile_set->remove_change_receptor(this);
+ }
_clear_quadrants();
tile_set = p_tileset;
- if (tile_set.is_valid())
+ if (tile_set.is_valid()) {
tile_set->connect("changed", this, "_recreate_quadrants");
- else
+ tile_set->add_change_receptor(this);
+ } else {
clear();
+ }
_recreate_quadrants();
emit_signal("settings_changed");
@@ -261,12 +265,18 @@ void TileMap::_update_dirty_quadrants() {
SceneTree *st = SceneTree::get_singleton();
Color debug_collision_color;
+ Color debug_navigation_color;
bool debug_shapes = st && st->is_debugging_collisions_hint();
if (debug_shapes) {
debug_collision_color = st->get_debug_collisions_color();
}
+ bool debug_navigation = st && st->is_debugging_navigation_hint();
+ if (debug_navigation) {
+ debug_navigation_color = st->get_debug_navigation_color();
+ }
+
while (dirty_quadrant_list.first()) {
Quadrant &q = *dirty_quadrant_list.first()->self();
@@ -353,7 +363,7 @@ void TileMap::_update_dirty_quadrants() {
}
Rect2 r = tile_set->tile_get_region(c.id);
- if (tile_set->tile_get_is_autotile(c.id)) {
+ if (tile_set->tile_get_tile_mode(c.id) == TileSet::AUTO_TILE) {
int spacing = tile_set->autotile_get_spacing(c.id);
r.size = tile_set->autotile_get_size(c.id);
r.position += (r.size + Vector2(spacing, spacing)) * Vector2(c.autotile_coord_x, c.autotile_coord_y);
@@ -447,7 +457,7 @@ void TileMap::_update_dirty_quadrants() {
for (int i = 0; i < shapes.size(); i++) {
Ref<Shape2D> shape = shapes[i].shape;
if (shape.is_valid()) {
- if (!tile_set->tile_get_is_autotile(c.id) || (shapes[i].autotile_coord.x == c.autotile_coord_x && shapes[i].autotile_coord.y == c.autotile_coord_y)) {
+ if (tile_set->tile_get_tile_mode(c.id) == TileSet::SINGLE_TILE || (shapes[i].autotile_coord.x == c.autotile_coord_x && shapes[i].autotile_coord.y == c.autotile_coord_y)) {
Transform2D xform;
xform.set_origin(offset.floor());
@@ -474,7 +484,7 @@ void TileMap::_update_dirty_quadrants() {
if (navigation) {
Ref<NavigationPolygon> navpoly;
Vector2 npoly_ofs;
- if (tile_set->tile_get_is_autotile(c.id)) {
+ if (tile_set->tile_get_tile_mode(c.id) == TileSet::AUTO_TILE) {
navpoly = tile_set->autotile_get_navigation_polygon(c.id, Vector2(c.autotile_coord_x, c.autotile_coord_y));
npoly_ofs = Vector2();
} else {
@@ -493,11 +503,60 @@ void TileMap::_update_dirty_quadrants() {
np.id = pid;
np.xform = xform;
q.navpoly_ids[E->key()] = np;
+
+ if (debug_navigation) {
+ RID debug_navigation_item = vs->canvas_item_create();
+ vs->canvas_item_set_parent(debug_navigation_item, canvas_item);
+ vs->canvas_item_set_z_as_relative_to_parent(debug_navigation_item, false);
+ vs->canvas_item_set_z_index(debug_navigation_item, VS::CANVAS_ITEM_Z_MAX - 2); // Display one below collision debug
+
+ if (debug_navigation_item.is_valid()) {
+ PoolVector<Vector2> navigation_polygon_vertices = navpoly->get_vertices();
+ int vsize = navigation_polygon_vertices.size();
+
+ if (vsize > 2) {
+ Vector<Color> colors;
+ Vector<Vector2> vertices;
+ vertices.resize(vsize);
+ colors.resize(vsize);
+ {
+ PoolVector<Vector2>::Read vr = navigation_polygon_vertices.read();
+ for (int i = 0; i < vsize; i++) {
+ vertices[i] = vr[i];
+ colors[i] = debug_navigation_color;
+ }
+ }
+
+ Vector<int> indices;
+
+ for (int i = 0; i < navpoly->get_polygon_count(); i++) {
+ Vector<int> polygon = navpoly->get_polygon(i);
+
+ for (int j = 2; j < polygon.size(); j++) {
+
+ int kofs[3] = { 0, j - 1, j };
+ for (int k = 0; k < 3; k++) {
+
+ int idx = polygon[kofs[k]];
+ ERR_FAIL_INDEX(idx, vsize);
+ indices.push_back(idx);
+ }
+ }
+ }
+ Transform2D navxform;
+ navxform.set_origin(offset.floor());
+ _fix_cell_transform(navxform, c, npoly_ofs + center_ofs, s);
+
+ vs->canvas_item_set_transform(debug_navigation_item, navxform);
+ vs->canvas_item_add_triangle_array(debug_navigation_item, indices, vertices, colors);
+ }
+ }
+ }
}
}
Ref<OccluderPolygon2D> occluder;
- if (tile_set->tile_get_is_autotile(c.id)) {
+ if (tile_set->tile_get_tile_mode(c.id) == TileSet::AUTO_TILE) {
occluder = tile_set->autotile_get_light_occluder(c.id, Vector2(c.autotile_coord_x, c.autotile_coord_y));
} else {
occluder = tile_set->tile_get_light_occluder(c.id);
@@ -766,7 +825,7 @@ void TileMap::update_cell_bitmask(int p_x, int p_y) {
Map<PosKey, Cell>::Element *E = tile_map.find(p);
if (E != NULL) {
int id = get_cell(p_x, p_y);
- if (tile_set->tile_get_is_autotile(id)) {
+ if (tile_set->tile_get_tile_mode(id) == TileSet::AUTO_TILE) {
uint16_t mask = 0;
if (tile_set->autotile_get_bitmask_mode(id) == TileSet::BITMASK_2X2) {
if (tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y - 1)) && tile_set->is_tile_bound(id, get_cell(p_x, p_y - 1)) && tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y))) {
@@ -830,6 +889,16 @@ void TileMap::update_dirty_bitmask() {
}
}
+void TileMap::fix_invalid_tiles() {
+
+ 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);
+ }
+ }
+}
+
int TileMap::get_cell(int p_x, int p_y) const {
PosKey pk(p_x, p_y);
@@ -1515,6 +1584,7 @@ void TileMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_cell_y_flipped", "x", "y"), &TileMap::is_cell_y_flipped);
ClassDB::bind_method(D_METHOD("is_cell_transposed", "x", "y"), &TileMap::is_cell_transposed);
+ ClassDB::bind_method(D_METHOD("fix_invalid_tiles"), &TileMap::fix_invalid_tiles);
ClassDB::bind_method(D_METHOD("clear"), &TileMap::clear);
ClassDB::bind_method(D_METHOD("get_used_cells"), &TileMap::get_used_cells);
@@ -1573,6 +1643,12 @@ void TileMap::_bind_methods() {
BIND_ENUM_CONSTANT(TILE_ORIGIN_BOTTOM_LEFT);
}
+void TileMap::_changed_callback(Object *p_changed, const char *p_prop) {
+ if (tile_set.is_valid() && tile_set.ptr() == p_changed) {
+ emit_signal("settings_changed");
+ }
+}
+
TileMap::TileMap() {
rect_cache_dirty = true;
@@ -1601,5 +1677,8 @@ TileMap::TileMap() {
TileMap::~TileMap() {
+ if (tile_set.is_valid())
+ tile_set->remove_change_receptor(this);
+
clear();
}