diff options
Diffstat (limited to 'scene/2d/tile_map.cpp')
-rw-r--r-- | scene/2d/tile_map.cpp | 317 |
1 files changed, 21 insertions, 296 deletions
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index f40ee1f506..4cbcfa6dc2 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -49,131 +49,8 @@ ERR_FAIL_INDEX_V(layer, (int)layers.size(), err_value); \ return layers[layer]->function(__VA_ARGS__); -Vector2i TileMap::transform_coords_layout(const Vector2i &p_coords, TileSet::TileOffsetAxis p_offset_axis, TileSet::TileLayout p_from_layout, TileSet::TileLayout p_to_layout) { - // Transform to stacked layout. - Vector2i output = p_coords; - if (p_offset_axis == TileSet::TILE_OFFSET_AXIS_VERTICAL) { - SWAP(output.x, output.y); - } - switch (p_from_layout) { - case TileSet::TILE_LAYOUT_STACKED: - break; - case TileSet::TILE_LAYOUT_STACKED_OFFSET: - if (output.y % 2) { - output.x -= 1; - } - break; - case TileSet::TILE_LAYOUT_STAIRS_RIGHT: - case TileSet::TILE_LAYOUT_STAIRS_DOWN: - if ((p_from_layout == TileSet::TILE_LAYOUT_STAIRS_RIGHT) ^ (p_offset_axis == TileSet::TILE_OFFSET_AXIS_VERTICAL)) { - if (output.y < 0 && bool(output.y % 2)) { - output = Vector2i(output.x + output.y / 2 - 1, output.y); - } else { - output = Vector2i(output.x + output.y / 2, output.y); - } - } else { - if (output.x < 0 && bool(output.x % 2)) { - output = Vector2i(output.x / 2 - 1, output.x + output.y * 2); - } else { - output = Vector2i(output.x / 2, output.x + output.y * 2); - } - } - break; - case TileSet::TILE_LAYOUT_DIAMOND_RIGHT: - case TileSet::TILE_LAYOUT_DIAMOND_DOWN: - if ((p_from_layout == TileSet::TILE_LAYOUT_DIAMOND_RIGHT) ^ (p_offset_axis == TileSet::TILE_OFFSET_AXIS_VERTICAL)) { - if ((output.x + output.y) < 0 && (output.x - output.y) % 2) { - output = Vector2i((output.x + output.y) / 2 - 1, output.y - output.x); - } else { - output = Vector2i((output.x + output.y) / 2, -output.x + output.y); - } - } else { - if ((output.x - output.y) < 0 && (output.x + output.y) % 2) { - output = Vector2i((output.x - output.y) / 2 - 1, output.x + output.y); - } else { - output = Vector2i((output.x - output.y) / 2, output.x + output.y); - } - } - break; - } - - switch (p_to_layout) { - case TileSet::TILE_LAYOUT_STACKED: - break; - case TileSet::TILE_LAYOUT_STACKED_OFFSET: - if (output.y % 2) { - output.x += 1; - } - break; - case TileSet::TILE_LAYOUT_STAIRS_RIGHT: - case TileSet::TILE_LAYOUT_STAIRS_DOWN: - if ((p_to_layout == TileSet::TILE_LAYOUT_STAIRS_RIGHT) ^ (p_offset_axis == TileSet::TILE_OFFSET_AXIS_VERTICAL)) { - if (output.y < 0 && (output.y % 2)) { - output = Vector2i(output.x - output.y / 2 + 1, output.y); - } else { - output = Vector2i(output.x - output.y / 2, output.y); - } - } else { - if (output.y % 2) { - if (output.y < 0) { - output = Vector2i(2 * output.x + 1, -output.x + output.y / 2 - 1); - } else { - output = Vector2i(2 * output.x + 1, -output.x + output.y / 2); - } - } else { - output = Vector2i(2 * output.x, -output.x + output.y / 2); - } - } - break; - case TileSet::TILE_LAYOUT_DIAMOND_RIGHT: - case TileSet::TILE_LAYOUT_DIAMOND_DOWN: - if ((p_to_layout == TileSet::TILE_LAYOUT_DIAMOND_RIGHT) ^ (p_offset_axis == TileSet::TILE_OFFSET_AXIS_VERTICAL)) { - if (output.y % 2) { - if (output.y > 0) { - output = Vector2i(output.x - output.y / 2, output.x + output.y / 2 + 1); - } else { - output = Vector2i(output.x - output.y / 2 + 1, output.x + output.y / 2); - } - } else { - output = Vector2i(output.x - output.y / 2, output.x + output.y / 2); - } - } else { - if (output.y % 2) { - if (output.y < 0) { - output = Vector2i(output.x + output.y / 2, -output.x + output.y / 2 - 1); - } else { - output = Vector2i(output.x + output.y / 2 + 1, -output.x + output.y / 2); - } - } else { - output = Vector2i(output.x + output.y / 2, -output.x + output.y / 2); - } - } - break; - } - - if (p_offset_axis == TileSet::TILE_OFFSET_AXIS_VERTICAL) { - SWAP(output.x, output.y); - } - - return output; -} - -void TileMap::set_selected_layer(int p_layer_id) { - ERR_FAIL_COND(p_layer_id < -1 || p_layer_id >= (int)layers.size()); - if (selected_layer == p_layer_id) { - return; - } - selected_layer = p_layer_id; +void TileMap::_emit_changed() { emit_signal(CoreStringNames::get_singleton()->changed); - - // Update the layers modulation. - for (TileMapLayer *layer : layers) { - layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_SELECTED_LAYER); - } -} - -int TileMap::get_selected_layer() const { - return selected_layer; } void TileMap::_notification(int p_what) { @@ -188,7 +65,6 @@ void TileMap::_notification(int p_what) { if (is_inside_tree() && collision_animatable && !in_editor) { // Update transform on the physics tick when in animatable mode. last_valid_transform = new_transform; - print_line("Physics: ", new_transform); set_notify_local_transform(false); set_global_transform(new_transform); set_notify_local_transform(true); @@ -207,7 +83,6 @@ void TileMap::_notification(int p_what) { // Store last valid transform. new_transform = get_global_transform(); - print_line("local XFORM: ", last_valid_transform); // ... but then revert changes. set_notify_local_transform(false); set_global_transform(last_valid_transform); @@ -225,55 +100,6 @@ void TileMap::force_update(int p_layer) { } #endif -void TileMap::queue_internal_update() { - if (pending_update) { - return; - } - pending_update = true; - callable_mp(this, &TileMap::_internal_update).call_deferred(); -} - -void TileMap::_internal_update() { - // Other updates. - if (!pending_update) { - return; - } - - // Update dirty quadrants on layers. - for (TileMapLayer *layer : layers) { - layer->internal_update(); - } - - pending_update = false; -} - -void TileMap::set_tileset(const Ref<TileSet> &p_tileset) { - if (p_tileset == tile_set) { - return; - } - - // Set the tileset, registering to its changes. - if (tile_set.is_valid()) { - tile_set->disconnect_changed(callable_mp(this, &TileMap::_tile_set_changed)); - } - - tile_set = p_tileset; - - if (tile_set.is_valid()) { - tile_set->connect_changed(callable_mp(this, &TileMap::_tile_set_changed)); - } - - for (TileMapLayer *layer : layers) { - layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_TILE_SET); - } - - emit_signal(CoreStringNames::get_singleton()->changed); -} - -Ref<TileSet> TileMap::get_tileset() const { - return tile_set; -} - void TileMap::set_rendering_quadrant_size(int p_size) { ERR_FAIL_COND_MSG(p_size < 1, "TileMapQuadrant size cannot be smaller than 1."); @@ -281,7 +107,7 @@ void TileMap::set_rendering_quadrant_size(int p_size) { for (TileMapLayer *layer : layers) { layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_QUADRANT_SIZE); } - emit_signal(CoreStringNames::get_singleton()->changed); + _emit_changed(); } int TileMap::get_rendering_quadrant_size() const { @@ -392,10 +218,11 @@ void TileMap::add_layer(int p_to_pos) { for (uint32_t i = 0; i < layers.size(); i++) { layers[i]->set_layer_index_in_tile_map_node(i); } - queue_internal_update(); + new_layer->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TileMap::_emit_changed)); + notify_property_list_changed(); - emit_signal(CoreStringNames::get_singleton()->changed); + _emit_changed(); update_configuration_warnings(); } @@ -412,14 +239,9 @@ void TileMap::move_layer(int p_layer, int p_to_pos) { move_child(layer, i); layers[i]->set_layer_index_in_tile_map_node(i); } - queue_internal_update(); notify_property_list_changed(); - if (selected_layer == p_layer) { - selected_layer = p_to_pos < p_layer ? p_to_pos - 1 : p_to_pos; - } - - emit_signal(CoreStringNames::get_singleton()->changed); + _emit_changed(); update_configuration_warnings(); } @@ -433,14 +255,9 @@ void TileMap::remove_layer(int p_layer) { for (uint32_t i = 0; i < layers.size(); i++) { layers[i]->set_layer_index_in_tile_map_node(i); } - queue_internal_update(); notify_property_list_changed(); - if (selected_layer >= p_layer) { - selected_layer -= 1; - } - - emit_signal(CoreStringNames::get_singleton()->changed); + _emit_changed(); update_configuration_warnings(); } @@ -533,7 +350,7 @@ void TileMap::set_collision_visibility_mode(TileMap::VisibilityMode p_show_colli for (TileMapLayer *layer : layers) { layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_COLLISION_VISIBILITY_MODE); } - emit_signal(CoreStringNames::get_singleton()->changed); + _emit_changed(); } TileMap::VisibilityMode TileMap::get_collision_visibility_mode() const { @@ -548,7 +365,7 @@ void TileMap::set_navigation_visibility_mode(TileMap::VisibilityMode p_show_navi for (TileMapLayer *layer : layers) { layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_NAVIGATION_VISIBILITY_MODE); } - emit_signal(CoreStringNames::get_singleton()->changed); + _emit_changed(); } TileMap::VisibilityMode TileMap::get_navigation_visibility_mode() const { @@ -563,7 +380,7 @@ void TileMap::set_y_sort_enabled(bool p_enable) { for (TileMapLayer *layer : layers) { layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_Y_SORT_ENABLED); } - emit_signal(CoreStringNames::get_singleton()->changed); + _emit_changed(); update_configuration_warnings(); } @@ -671,8 +488,9 @@ void TileMap::clear() { } void TileMap::update_internals() { - pending_update = true; - _internal_update(); + for (TileMapLayer *layer : layers) { + layer->update_internals(); + } } void TileMap::notify_runtime_tile_data_update(int p_layer) { @@ -721,10 +539,11 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) { add_child(new_layer); new_layer->set_name("Layer0"); new_layer->set_layer_index_in_tile_map_node(0); + new_layer->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TileMap::_emit_changed)); layers.push_back(new_layer); } layers[0]->set_tile_data(format, p_value); - emit_signal(CoreStringNames::get_singleton()->changed); + _emit_changed(); return true; } return false; @@ -745,11 +564,12 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) { add_child(new_layer); new_layer->set_name(vformat("Layer%d", index)); new_layer->set_layer_index_in_tile_map_node(index); + new_layer->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TileMap::_emit_changed)); layers.push_back(new_layer); } notify_property_list_changed(); - emit_signal(CoreStringNames::get_singleton()->changed); + _emit_changed(); update_configuration_warnings(); } @@ -776,7 +596,7 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) { return true; } else if (components[1] == "tile_data") { layers[index]->set_tile_data(format, p_value); - emit_signal(CoreStringNames::get_singleton()->changed); + _emit_changed(); return true; } else { return false; @@ -1014,93 +834,12 @@ void TileMap::set_texture_repeat(CanvasItem::TextureRepeat p_texture_repeat) { } } -TypedArray<Vector2i> TileMap::get_surrounding_cells(const Vector2i &coords) { +TypedArray<Vector2i> TileMap::get_surrounding_cells(const Vector2i &p_coords) { if (!tile_set.is_valid()) { return TypedArray<Vector2i>(); } - TypedArray<Vector2i> around; - TileSet::TileShape shape = tile_set->get_tile_shape(); - if (shape == TileSet::TILE_SHAPE_SQUARE) { - around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_RIGHT_SIDE)); - around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_BOTTOM_SIDE)); - around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_LEFT_SIDE)); - around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_TOP_SIDE)); - } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC) { - around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE)); - around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE)); - around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE)); - around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE)); - } else { - if (tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) { - around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_RIGHT_SIDE)); - around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE)); - around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE)); - around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_LEFT_SIDE)); - around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE)); - around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE)); - } else { - around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE)); - around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_BOTTOM_SIDE)); - around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE)); - around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE)); - around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_TOP_SIDE)); - around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE)); - } - } - - return around; -} - -void TileMap::draw_cells_outline(Control *p_control, const RBSet<Vector2i> &p_cells, Color p_color, Transform2D p_transform) { - if (!tile_set.is_valid()) { - return; - } - - // Create a set. - Vector2i tile_size = tile_set->get_tile_size(); - Vector<Vector2> polygon = tile_set->get_tile_shape_polygon(); - TileSet::TileShape shape = tile_set->get_tile_shape(); - - for (const Vector2i &E : p_cells) { - Vector2 center = map_to_local(E); - -#define DRAW_SIDE_IF_NEEDED(side, polygon_index_from, polygon_index_to) \ - if (!p_cells.has(get_neighbor_cell(E, side))) { \ - Vector2 from = p_transform.xform(center + polygon[polygon_index_from] * tile_size); \ - Vector2 to = p_transform.xform(center + polygon[polygon_index_to] * tile_size); \ - p_control->draw_line(from, to, p_color); \ - } - - if (shape == TileSet::TILE_SHAPE_SQUARE) { - DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_RIGHT_SIDE, 1, 2); - DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_BOTTOM_SIDE, 2, 3); - DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_LEFT_SIDE, 3, 0); - DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_TOP_SIDE, 0, 1); - } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC) { - DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE, 2, 3); - DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE, 1, 2); - DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE, 0, 1); - DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE, 3, 0); - } else { - if (tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) { - DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE, 3, 4); - DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE, 2, 3); - DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_LEFT_SIDE, 1, 2); - DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE, 0, 1); - DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE, 5, 0); - DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_RIGHT_SIDE, 4, 5); - } else { - DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE, 3, 4); - DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_BOTTOM_SIDE, 4, 5); - DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE, 5, 0); - DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE, 0, 1); - DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_TOP_SIDE, 1, 2); - DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE, 2, 3); - } - } - } -#undef DRAW_SIDE_IF_NEEDED + return tile_set->get_surrounding_cells(p_coords); } Array TileMap::get_configuration_warnings() const { @@ -1171,9 +910,6 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("force_update", "layer"), &TileMap::force_update, DEFVAL(-1)); #endif // DISABLE_DEPRECATED - ClassDB::bind_method(D_METHOD("set_tileset", "tileset"), &TileMap::set_tileset); - ClassDB::bind_method(D_METHOD("get_tileset"), &TileMap::get_tileset); - ClassDB::bind_method(D_METHOD("set_rendering_quadrant_size", "size"), &TileMap::set_rendering_quadrant_size); ClassDB::bind_method(D_METHOD("get_rendering_quadrant_size"), &TileMap::get_rendering_quadrant_size); @@ -1244,7 +980,6 @@ void TileMap::_bind_methods() { GDVIRTUAL_BIND(_use_tile_data_runtime_update, "layer", "coords"); GDVIRTUAL_BIND(_tile_data_runtime_update, "layer", "coords", "tile_data"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tile_set", PROPERTY_HINT_RESOURCE_TYPE, "TileSet"), "set_tileset", "get_tileset"); ADD_PROPERTY(PropertyInfo(Variant::INT, "rendering_quadrant_size", PROPERTY_HINT_RANGE, "1,128,1"), "set_rendering_quadrant_size", "get_rendering_quadrant_size"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision_animatable"), "set_collision_animatable", "is_collision_animatable"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_visibility_mode", PROPERTY_HINT_ENUM, "Default,Force Show,Force Hide"), "set_collision_visibility_mode", "get_collision_visibility_mode"); @@ -1261,28 +996,18 @@ void TileMap::_bind_methods() { BIND_ENUM_CONSTANT(VISIBILITY_MODE_FORCE_SHOW); } -void TileMap::_tile_set_changed() { - emit_signal(CoreStringNames::get_singleton()->changed); - for (TileMapLayer *layer : layers) { - layer->notify_tile_map_change(TileMapLayer::DIRTY_FLAGS_TILE_MAP_TILE_SET); - } - update_configuration_warnings(); -} - TileMap::TileMap() { TileMapLayer *new_layer = memnew(TileMapLayer); add_child(new_layer); new_layer->set_name("Layer0"); new_layer->set_layer_index_in_tile_map_node(0); + new_layer->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TileMap::_emit_changed)); layers.push_back(new_layer); default_layer = memnew(TileMapLayer); } TileMap::~TileMap() { - if (tile_set.is_valid()) { - tile_set->disconnect_changed(callable_mp(this, &TileMap::_tile_set_changed)); - } memdelete(default_layer); } |