diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index c9367edec67..8f7d6a98752 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -303,6 +303,12 @@ void TileMapEditor::_set_cell(const Point2i &p_pos, Vector p_values, bool p if (manual_autotile || (p_value != -1 && node->get_tileset()->tile_get_tile_mode(p_value) == TileSet::ATLAS_TILE)) { if (current != -1) { node->set_cell_autotile_coord(p_pos.x, p_pos.y, position); + + } else if (tool != TOOL_PASTING && node->get_tileset()->tile_get_tile_mode(p_value) == TileSet::ATLAS_TILE && priority_atlastile) { + + // BIND_CENTER is used to indicate that bitmask should not update for this tile cell + node->get_tileset()->autotile_set_bitmask(p_value, Vector2(p_pos.x, p_pos.y), TileSet::BIND_CENTER); + node->update_cell_bitmask(p_pos.x, p_pos.y); } } else { // manually placing tiles should not update bitmasks @@ -317,6 +323,11 @@ void TileMapEditor::_manual_toggled(bool p_enabled) { _update_palette(); } +void TileMapEditor::_priority_toggled(bool p_enabled) { + priority_atlastile = p_enabled; + _update_palette(); +} + void TileMapEditor::_text_entered(const String &p_text) { canvas_item_editor_viewport->grab_focus(); @@ -475,7 +486,8 @@ void TileMapEditor::_update_palette() { } if (sel_tile != TileMap::INVALID_CELL) { - if ((manual_autotile && tileset->tile_get_tile_mode(sel_tile) == TileSet::AUTO_TILE) || tileset->tile_get_tile_mode(sel_tile) == TileSet::ATLAS_TILE) { + if ((manual_autotile && tileset->tile_get_tile_mode(sel_tile) == TileSet::AUTO_TILE) || + (!priority_atlastile && tileset->tile_get_tile_mode(sel_tile) == TileSet::ATLAS_TILE)) { const Map &tiles = tileset->autotile_get_bitmask_map(sel_tile); @@ -519,8 +531,10 @@ void TileMapEditor::_update_palette() { if (tileset->tile_get_tile_mode(sel_tile) == TileSet::AUTO_TILE) { manual_button->show(); + priority_button->hide(); } else { manual_button->hide(); + priority_button->show(); } } @@ -664,7 +678,8 @@ void TileMapEditor::_fill_points(const PoolVector p_points, const Dicti _set_cell(pr[i], ids, xf, yf, tr); node->make_bitmask_area_dirty(pr[i]); } - node->update_dirty_bitmask(); + if (!manual_autotile) + node->update_dirty_bitmask(); } void TileMapEditor::_erase_points(const PoolVector p_points) { @@ -723,7 +738,7 @@ void TileMapEditor::_draw_cell(Control *p_viewport, int p_cell, const Point2i &p if (node->get_tileset()->tile_get_tile_mode(p_cell) == TileSet::AUTO_TILE || node->get_tileset()->tile_get_tile_mode(p_cell) == TileSet::ATLAS_TILE) { Vector2 offset; int selected = manual_palette->get_current(); - if ((manual_autotile || node->get_tileset()->tile_get_tile_mode(p_cell) == TileSet::ATLAS_TILE) && selected != -1) { + if ((manual_autotile || (node->get_tileset()->tile_get_tile_mode(p_cell) == TileSet::ATLAS_TILE && !priority_atlastile)) && selected != -1) { offset = manual_palette->get_item_metadata(selected); } else { if (tool != TOOL_PASTING) { @@ -1683,6 +1698,7 @@ void TileMapEditor::_icon_size_changed(float p_value) { void TileMapEditor::_bind_methods() { ClassDB::bind_method(D_METHOD("_manual_toggled"), &TileMapEditor::_manual_toggled); + ClassDB::bind_method(D_METHOD("_priority_toggled"), &TileMapEditor::_priority_toggled); ClassDB::bind_method(D_METHOD("_text_entered"), &TileMapEditor::_text_entered); ClassDB::bind_method(D_METHOD("_text_changed"), &TileMapEditor::_text_changed); ClassDB::bind_method(D_METHOD("_sbox_input"), &TileMapEditor::_sbox_input); @@ -1785,6 +1801,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { node = NULL; manual_autotile = false; + priority_atlastile = false; manual_position = Vector2(0, 0); canvas_item_editor_viewport = NULL; editor = p_editor; @@ -1815,10 +1832,15 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { add_child(tool_hb); manual_button = memnew(CheckBox); - manual_button->set_text("Disable Autotile"); + manual_button->set_text(TTR("Disable Autotile")); manual_button->connect("toggled", this, "_manual_toggled"); add_child(manual_button); + priority_button = memnew(CheckBox); + priority_button->set_text(TTR("Enable Priority")); + priority_button->connect("toggled", this, "_priority_toggled"); + add_child(priority_button); + search_box = memnew(LineEdit); search_box->set_h_size_flags(SIZE_EXPAND_FILL); search_box->connect("text_entered", this, "_text_entered"); diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h index 8356d3af101..ca3b6ef5673 100644 --- a/editor/plugins/tile_map_editor_plugin.h +++ b/editor/plugins/tile_map_editor_plugin.h @@ -78,6 +78,7 @@ class TileMapEditor : public VBoxContainer { TileMap *node; bool manual_autotile; + bool priority_atlastile; Vector2 manual_position; EditorNode *editor; @@ -101,6 +102,7 @@ class TileMapEditor : public VBoxContainer { ToolButton *clear_transform_button; CheckBox *manual_button; + CheckBox *priority_button; Tool tool; @@ -180,6 +182,7 @@ class TileMapEditor : public VBoxContainer { void set_selected_tiles(Vector p_tile); void _manual_toggled(bool p_enabled); + void _priority_toggled(bool p_enabled); void _text_entered(const String &p_text); void _text_changed(const String &p_text); void _sbox_input(const Ref &p_ie); diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp index e5551d385b7..8cb19d73be2 100644 --- a/editor/plugins/tile_set_editor_plugin.cpp +++ b/editor/plugins/tile_set_editor_plugin.cpp @@ -2279,7 +2279,6 @@ void TileSetEditor::update_workspace_tile_mode() { select_coord(edited_shape_coord); tool_editmode[EDITMODE_BITMASK]->hide(); - tool_editmode[EDITMODE_PRIORITY]->hide(); } _on_edit_mode_changed(edit_mode); } diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 37886861e0c..8c92a08224c 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -906,8 +906,17 @@ 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)); + + E->get().autotile_coord_x = (int)coord.x; + E->get().autotile_coord_y = (int)coord.y; + } } } } diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index 8a24d4bab14..8922dc89397 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -314,6 +314,7 @@ void TileSet::_get_property_list(List *p_list) const { p_list->push_back(PropertyInfo(Variant::INT, pre + "autotile/spacing", PROPERTY_HINT_RANGE, "0,256,1", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/occluder_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/navpoly_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); + p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/priority_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/z_index_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); } p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "occluder_offset")); @@ -606,6 +607,36 @@ Vector2 TileSet::autotile_get_subtile_for_bitmask(int p_id, uint16_t p_bitmask, } } +Vector2 TileSet::atlastile_get_subtile_by_priority(int p_id, const Node *p_tilemap_node, const Vector2 &p_tile_location) { + + ERR_FAIL_COND_V(!tile_map.has(p_id), Vector2()); + //First try to forward selection to script + if (get_script_instance() != NULL) { + if (get_script_instance()->has_method("_forward_atlas_subtile_selection")) { + Variant ret = get_script_instance()->call("_forward_atlas_subtile_selection", p_id, p_tilemap_node, p_tile_location); + if (ret.get_type() == Variant::VECTOR2) { + return ret; + } + } + } + + Vector2 coord = tile_get_region(p_id).size / autotile_get_size(p_id); + + List coords; + for (int x = 0; x < coord.x; x++) { + for (int y = 0; y < coord.y; y++) { + for (int i = 0; i < autotile_get_subtile_priority(p_id, Vector2(x, y)); i++) { + coords.push_back(Vector2(x, y)); + } + } + } + if (coords.size() == 0) { + return autotile_get_icon_coordinate(p_id); + } else { + return coords[Math::random(0, (int)coords.size())]; + } +} + void TileSet::tile_set_name(int p_id, const String &p_name) { ERR_FAIL_COND(!tile_map.has(p_id)); @@ -1037,6 +1068,7 @@ void TileSet::_bind_methods() { BIND_VMETHOD(MethodInfo(Variant::BOOL, "_is_tile_bound", PropertyInfo(Variant::INT, "drawn_id"), PropertyInfo(Variant::INT, "neighbor_id"))); BIND_VMETHOD(MethodInfo(Variant::VECTOR2, "_forward_subtile_selection", PropertyInfo(Variant::INT, "autotile_id"), PropertyInfo(Variant::INT, "bitmask"), PropertyInfo(Variant::OBJECT, "tilemap", PROPERTY_HINT_NONE, "TileMap"), PropertyInfo(Variant::VECTOR2, "tile_location"))); + BIND_VMETHOD(MethodInfo(Variant::VECTOR2, "_forward_atlas_subtile_selection", PropertyInfo(Variant::INT, "atlastile_id"), PropertyInfo(Variant::OBJECT, "tilemap", PROPERTY_HINT_NONE, "TileMap"), PropertyInfo(Variant::VECTOR2, "tile_location"))); BIND_ENUM_CONSTANT(BITMASK_2X2); BIND_ENUM_CONSTANT(BITMASK_3X3_MINIMAL); diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h index 2ab771b1b0a..fb1cac3c816 100644 --- a/scene/resources/tile_set.h +++ b/scene/resources/tile_set.h @@ -180,6 +180,7 @@ public: uint16_t autotile_get_bitmask(int p_id, Vector2 p_coord); const Map &autotile_get_bitmask_map(int p_id); Vector2 autotile_get_subtile_for_bitmask(int p_id, uint16_t p_bitmask, const Node *p_tilemap_node = NULL, const Vector2 &p_tile_location = Vector2()); + Vector2 atlastile_get_subtile_by_priority(int p_id, const Node *p_tilemap_node = NULL, const Vector2 &p_tile_location = Vector2()); void tile_set_shape(int p_id, int p_shape_id, const Ref &p_shape); Ref tile_get_shape(int p_id, int p_shape_id) const;