diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp index a875cd9edfc9..68a027f6a4d6 100644 --- a/editor/plugins/tile_set_editor_plugin.cpp +++ b/editor/plugins/tile_set_editor_plugin.cpp @@ -274,6 +274,8 @@ void TileSetEditor::_bind_methods() { ClassDB::bind_method("_on_tool_clicked", &TileSetEditor::_on_tool_clicked); ClassDB::bind_method("_on_priority_changed", &TileSetEditor::_on_priority_changed); ClassDB::bind_method("_on_z_index_changed", &TileSetEditor::_on_z_index_changed); + ClassDB::bind_method("_on_horizontal_leap_toggled", &TileSetEditor::_on_horizontal_leap_toggled); + ClassDB::bind_method("_on_vertical_leap_toggled", &TileSetEditor::_on_vertical_leap_toggled); ClassDB::bind_method("_on_grid_snap_toggled", &TileSetEditor::_on_grid_snap_toggled); ClassDB::bind_method("_set_snap_step", &TileSetEditor::_set_snap_step); ClassDB::bind_method("_set_snap_off", &TileSetEditor::_set_snap_off); @@ -340,6 +342,7 @@ void TileSetEditor::_notification(int p_what) { tool_editmode[EDITMODE_PRIORITY]->set_icon(get_icon("MaterialPreviewLight1", "EditorIcons")); tool_editmode[EDITMODE_ICON]->set_icon(get_icon("LargeTexture", "EditorIcons")); tool_editmode[EDITMODE_Z_INDEX]->set_icon(get_icon("Sort", "EditorIcons")); + tool_editmode[EDITMODE_META]->set_icon(get_icon("LargeTexture", "EditorIcons")); scroll->add_style_override("bg", get_stylebox("bg", "Tree")); } break; @@ -481,6 +484,8 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) { tool_editmode[EDITMODE_PRIORITY]->set_shortcut(ED_SHORTCUT("tileset_editor/editmode_priority", TTR("Priority Mode"), KEY_6)); tool_editmode[EDITMODE_ICON]->set_shortcut(ED_SHORTCUT("tileset_editor/editmode_icon", TTR("Icon Mode"), KEY_7)); tool_editmode[EDITMODE_Z_INDEX]->set_shortcut(ED_SHORTCUT("tileset_editor/editmode_z_index", TTR("Z Index Mode"), KEY_8)); + tool_editmode[EDITMODE_META]->set_shortcut(ED_SHORTCUT("tileset_editor/editmode_meta", TTR("LTTP Tile Metadata"), KEY_9)); + main_vb->add_child(tool_hb); separator_editmode = memnew(HSeparator); @@ -558,6 +563,20 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) { spin_z_index->hide(); toolbar->add_child(spin_z_index); + check_vertical_leap = memnew(CheckButton); + check_vertical_leap->set_toggle_mode(true); + check_vertical_leap->set_text("Leap V"); + check_vertical_leap->connect("toggled", this, "_on_vertical_leap_toggled"); + check_vertical_leap->hide(); + toolbar->add_child(check_vertical_leap); + + check_horizontal_leap = memnew(CheckButton); + check_horizontal_leap->set_toggle_mode(true); + check_horizontal_leap->set_text("Leap H"); + check_horizontal_leap->connect("toggled", this, "_on_horizontal_leap_toggled"); + check_horizontal_leap->hide(); + toolbar->add_child(check_horizontal_leap); + separator_grid = memnew(VSeparator); toolbar->add_child(separator_grid); tools[SHAPE_KEEP_INSIDE_TILE] = memnew(ToolButton); @@ -815,6 +834,8 @@ void TileSetEditor::_on_edit_mode_changed(int p_edit_mode) { tools[SHAPE_DELETE]->set_tooltip(TTR("Delete selected Rect.")); spin_priority->hide(); spin_z_index->hide(); + check_horizontal_leap->hide(); + check_vertical_leap->hide(); } break; case EDITMODE_COLLISION: case EDITMODE_OCCLUSION: @@ -839,6 +860,8 @@ void TileSetEditor::_on_edit_mode_changed(int p_edit_mode) { tools[SHAPE_DELETE]->set_tooltip(TTR("Delete polygon.")); spin_priority->hide(); spin_z_index->hide(); + check_horizontal_leap->hide(); + check_vertical_leap->hide(); _select_edited_shape_coord(); } break; @@ -860,10 +883,13 @@ void TileSetEditor::_on_edit_mode_changed(int p_edit_mode) { tools[TOOL_SELECT]->set_pressed(true); tools[TOOL_SELECT]->set_tooltip(TTR("LMB: Set bit on.\nRMB: Set bit off.\nShift+LMB: Set wildcard bit.\nClick on another Tile to edit it.")); spin_priority->hide(); + check_horizontal_leap->hide(); + check_vertical_leap->hide(); } break; case EDITMODE_Z_INDEX: case EDITMODE_PRIORITY: - case EDITMODE_ICON: { + case EDITMODE_ICON: + case EDITMODE_META: { tools[TOOL_SELECT]->show(); separator_bitmask->hide(); @@ -880,17 +906,21 @@ void TileSetEditor::_on_edit_mode_changed(int p_edit_mode) { tools[SHAPE_KEEP_INSIDE_TILE]->hide(); tools[TOOL_GRID_SNAP]->show(); + spin_priority->hide(); + spin_z_index->hide(); + check_horizontal_leap->hide(); + check_vertical_leap->hide(); if (edit_mode == EDITMODE_ICON) { tools[TOOL_SELECT]->set_tooltip(TTR("Select sub-tile to use as icon, this will be also used on invalid autotile bindings.\nClick on another Tile to edit it.")); - spin_priority->hide(); - spin_z_index->hide(); } else if (edit_mode == EDITMODE_PRIORITY) { tools[TOOL_SELECT]->set_tooltip(TTR("Select sub-tile to change its priority.\nClick on another Tile to edit it.")); spin_priority->show(); - spin_z_index->hide(); + } else if (edit_mode == EDITMODE_META) { + tools[TOOL_SELECT]->set_tooltip(TTR("Select subtile to change its game-related metadata. \nClick on another Tile to edit it")); + check_horizontal_leap->show(); + check_vertical_leap->show(); } else { tools[TOOL_SELECT]->set_tooltip(TTR("Select sub-tile to change its z index.\nClick on another Tile to edit it.")); - spin_priority->hide(); spin_z_index->show(); } } break; @@ -1064,6 +1094,18 @@ void TileSetEditor::_on_workspace_draw() { spin_z_index->set_value(tileset->autotile_get_z_index(get_current_tile(), edited_shape_coord)); draw_highlight_subtile(edited_shape_coord); } break; + case EDITMODE_META: { + + if (tileset->tile_get_leap_horiz(get_current_tile()) != check_horizontal_leap->is_pressed()) { + check_horizontal_leap->set_pressed( tileset->tile_get_leap_horiz(get_current_tile()) ); + } + + if (tileset->tile_get_leap_vert(get_current_tile()) != check_vertical_leap->is_pressed()) { + check_vertical_leap->set_pressed(tileset->tile_get_leap_vert(get_current_tile())); + } + + draw_highlight_subtile(edited_shape_coord); + } break; default: { } } @@ -1581,7 +1623,8 @@ void TileSetEditor::_on_workspace_input(const Ref &p_ie) { case EDITMODE_OCCLUSION: case EDITMODE_NAVIGATION: case EDITMODE_PRIORITY: - case EDITMODE_Z_INDEX: { + case EDITMODE_Z_INDEX: + case EDITMODE_META: { Vector2 shape_anchor = Vector2(0, 0); if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) { shape_anchor = edited_shape_coord; @@ -1969,6 +2012,34 @@ void TileSetEditor::_on_z_index_changed(float val) { undo_redo->commit_action(); } +void TileSetEditor::_on_horizontal_leap_toggled(bool value) { + if (value == tileset->tile_get_leap_horiz(get_current_tile())) + return; + + undo_redo->create_action(TTR("Toggle Horizontal Leap")); + undo_redo->add_do_method(tileset.ptr(), "tile_set_leap_horiz", get_current_tile(), value); + undo_redo->add_undo_method(tileset.ptr(), "tile_set_leap_horiz", get_current_tile(), tileset->tile_get_leap_horiz(get_current_tile())); + undo_redo->add_do_method(workspace, "update"); + undo_redo->add_undo_method(workspace, "update"); + undo_redo->commit_action(); + + workspace->update(); +} + +void TileSetEditor::_on_vertical_leap_toggled(bool value) { + if (value == tileset->tile_get_leap_vert(get_current_tile())) + return; + + undo_redo->create_action(TTR("Toggle Vertical Leap")); + undo_redo->add_do_method(tileset.ptr(), "tile_set_leap_vert", get_current_tile(), value); + undo_redo->add_undo_method(tileset.ptr(), "tile_set_leap_vert", get_current_tile(), tileset->tile_get_leap_vert(get_current_tile())); + undo_redo->add_do_method(workspace, "update"); + undo_redo->add_undo_method(workspace, "update"); + undo_redo->commit_action(); + + workspace->update(); +} + void TileSetEditor::_on_grid_snap_toggled(bool p_val) { helper->set_snap_options_visible(p_val); workspace->update(); @@ -2095,7 +2166,8 @@ void TileSetEditor::_select_next_tile() { case EDITMODE_OCCLUSION: case EDITMODE_NAVIGATION: case EDITMODE_PRIORITY: - case EDITMODE_Z_INDEX: { + case EDITMODE_Z_INDEX: + case EDITMODE_META: { edited_shape_coord = Vector2(); _select_edited_shape_coord(); } break; @@ -2129,7 +2201,8 @@ void TileSetEditor::_select_previous_tile() { case EDITMODE_OCCLUSION: case EDITMODE_NAVIGATION: case EDITMODE_PRIORITY: - case EDITMODE_Z_INDEX: { + case EDITMODE_Z_INDEX: + case EDITMODE_META: { int spacing = tileset->autotile_get_spacing(get_current_tile()); Vector2 size = tileset->tile_get_region(get_current_tile()).size; Vector2 cell_count = (size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing))).floor(); @@ -3645,3 +3718,4 @@ TileSetEditorPlugin::TileSetEditorPlugin(EditorNode *p_node) { tileset_editor_button = p_node->add_bottom_panel_item(TTR("TileSet"), tileset_editor); tileset_editor_button->hide(); } + diff --git a/editor/plugins/tile_set_editor_plugin.h b/editor/plugins/tile_set_editor_plugin.h index 41a62fa99d06..8c8e0f96aa12 100644 --- a/editor/plugins/tile_set_editor_plugin.h +++ b/editor/plugins/tile_set_editor_plugin.h @@ -72,6 +72,7 @@ class TileSetEditor : public HSplitContainer { EDITMODE_PRIORITY, EDITMODE_ICON, EDITMODE_Z_INDEX, + EDITMODE_META, EDITMODE_MAX }; @@ -154,6 +155,9 @@ class TileSetEditor : public HSplitContainer { VSeparator *separator_grid; SpinBox *spin_priority; SpinBox *spin_z_index; + CheckButton *check_vertical_leap; + CheckButton *check_horizontal_leap; + WorkspaceMode workspace_mode; EditMode edit_mode; int current_tile; @@ -206,6 +210,8 @@ class TileSetEditor : public HSplitContainer { void _on_tool_clicked(int p_tool); void _on_priority_changed(float val); void _on_z_index_changed(float val); + void _on_horizontal_leap_toggled(bool value); + void _on_vertical_leap_toggled(bool value); void _on_grid_snap_toggled(bool p_val); Vector _get_collision_shape_points(const Ref &p_shape); Vector _get_edited_shape_points(); diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index b33edc0129ef..674fe46d60d2 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -199,6 +199,10 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) { tile_set_navigation_polygon_offset(id, p_value); else if (what == "z_index") tile_set_z_index(id, p_value); + else if (what == "leap_vert") + tile_set_leap_vert(id, p_value); + else if (what == "leap_horiz") + tile_set_leap_horiz(id, p_value); else return false; @@ -313,6 +317,10 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const { r_ret = tile_get_navigation_polygon_offset(id); else if (what == "z_index") r_ret = tile_get_z_index(id); + else if (what == "leap_vert") + r_ret = tile_get_leap_vert(id); + else if (what == "leap_horiz") + r_ret = tile_get_leap_horiz(id); else return false; @@ -363,6 +371,8 @@ void TileSet::_get_property_list(List *p_list) const { p_list->push_back(PropertyInfo(Variant::REAL, pre + "shape_one_way_margin", PROPERTY_HINT_RANGE, "0,128,0.01", PROPERTY_USAGE_NOEDITOR)); p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "shapes", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); p_list->push_back(PropertyInfo(Variant::INT, pre + "z_index", PROPERTY_HINT_RANGE, itos(VS::CANVAS_ITEM_Z_MIN) + "," + itos(VS::CANVAS_ITEM_Z_MAX) + ",1", PROPERTY_USAGE_NOEDITOR)); + p_list->push_back(PropertyInfo(Variant::BOOL, pre + "leap_vert", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); + p_list->push_back(PropertyInfo(Variant::BOOL, pre + "leap_horiz", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); } } @@ -1041,6 +1051,32 @@ void TileSet::_tile_set_shapes(int p_id, const Array &p_shapes) { emit_changed(); } +void TileSet::tile_set_leap_vert(int p_id, bool value){ + ERR_FAIL_COND(!tile_map.has(p_id)); + + tile_map[p_id].vertical_leap = value; + emit_changed(); +} + +bool TileSet::tile_get_leap_vert(int p_id) const{ + ERR_FAIL_COND_V(!tile_map.has(p_id), 0); + + return tile_map[p_id].vertical_leap; +} + +void TileSet::tile_set_leap_horiz(int p_id, bool value) { + ERR_FAIL_COND(!tile_map.has(p_id)); + + tile_map[p_id].horizontal_leap = value; + emit_changed(); +} + +bool TileSet::tile_get_leap_horiz(int p_id) const { + ERR_FAIL_COND_V(!tile_map.has(p_id), 0); + + return tile_map[p_id].horizontal_leap; +} + Array TileSet::_tile_get_shapes(int p_id) const { ERR_FAIL_COND_V(!tile_map.has(p_id), Array()); @@ -1215,6 +1251,11 @@ void TileSet::_bind_methods() { ClassDB::bind_method(D_METHOD("tile_set_z_index", "id", "z_index"), &TileSet::tile_set_z_index); ClassDB::bind_method(D_METHOD("tile_get_z_index", "id"), &TileSet::tile_get_z_index); + ClassDB::bind_method(D_METHOD("tile_set_leap_vert", "id", "value"), &TileSet::tile_set_leap_vert); + ClassDB::bind_method(D_METHOD("tile_get_leap_vert", "id"), &TileSet::tile_get_leap_vert); + ClassDB::bind_method(D_METHOD("tile_set_leap_horiz", "id", "value"), &TileSet::tile_set_leap_horiz); + ClassDB::bind_method(D_METHOD("tile_get_leap_horiz", "id"), &TileSet::tile_get_leap_horiz); + ClassDB::bind_method(D_METHOD("remove_tile", "id"), &TileSet::remove_tile); ClassDB::bind_method(D_METHOD("clear"), &TileSet::clear); ClassDB::bind_method(D_METHOD("get_last_unused_tile_id"), &TileSet::get_last_unused_tile_id); diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h index 7edd3c408163..b3d5a4e3f5d3 100644 --- a/scene/resources/tile_set.h +++ b/scene/resources/tile_set.h @@ -128,12 +128,16 @@ class TileSet : public Resource { Color modulate; AutotileData autotile_data; int z_index; + bool horizontal_leap; + bool vertical_leap; // Default modulate for back-compat explicit TileData() : tile_mode(SINGLE_TILE), modulate(1, 1, 1), - z_index(0) {} + z_index(0), + horizontal_leap(false), + vertical_leap(false) {} }; Map tile_map; @@ -191,6 +195,8 @@ class TileSet : public Resource { int autotile_get_z_index(int p_id, const Vector2 &p_coord); const Map &autotile_get_z_index_map(int p_id) const; + + void autotile_set_bitmask(int p_id, Vector2 p_coord, uint32_t p_flag); uint32_t autotile_get_bitmask(int p_id, Vector2 p_coord); const Map &autotile_get_bitmask_map(int p_id); @@ -248,6 +254,12 @@ class TileSet : public Resource { void tile_set_z_index(int p_id, int p_z_index); int tile_get_z_index(int p_id) const; + void tile_set_leap_vert(int p_id, bool value); + bool tile_get_leap_vert(int p_id) const; + + void tile_set_leap_horiz(int p_id, bool value); + bool tile_get_leap_horiz(int p_id) const; + void remove_tile(int p_id); bool has_tile(int p_id) const;