2
0
Эх сурвалжийг харах

Merge pull request #65903 from groud/improve_terrain_painting

Right-click to erase TileSet terrains and bugfixes
Rémi Verschelde 2 жил өмнө
parent
commit
e69b7083d4

+ 122 - 82
editor/plugins/tiles/tile_data_editors.cpp

@@ -1977,6 +1977,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t
 				}
 			}
 			drag_last_pos = mm->get_position();
+			accept_event();
 		} else if (drag_type == DRAG_TYPE_PAINT_TERRAIN_BITS) {
 			int terrain_set = Dictionary(drag_painted_value)["terrain_set"];
 			int terrain = Dictionary(drag_painted_value)["terrain"];
@@ -2026,14 +2027,15 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t
 				}
 			}
 			drag_last_pos = mm->get_position();
+			accept_event();
 		}
 	}
 
 	Ref<InputEventMouseButton> mb = p_event;
 	if (mb.is_valid()) {
-		if (mb->get_button_index() == MouseButton::LEFT) {
+		if (mb->get_button_index() == MouseButton::LEFT || mb->get_button_index() == MouseButton::RIGHT) {
 			if (mb->is_pressed()) {
-				if (picker_button->is_pressed()) {
+				if (mb->get_button_index() == MouseButton::LEFT && picker_button->is_pressed()) {
 					Vector2i coords = p_tile_atlas_view->get_atlas_tile_coords_at_pos(mb->get_position());
 					coords = p_tile_set_atlas_source->get_tile_at_coords(coords);
 					if (coords != TileSetSource::INVALID_ATLAS_COORDS) {
@@ -2060,6 +2062,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t
 						terrain_set_property_editor->update_property();
 						_update_terrain_selector();
 						picker_button->set_pressed(false);
+						accept_event();
 					}
 				} else {
 					Vector2i coords = p_tile_atlas_view->get_atlas_tile_coords_at_pos(mb->get_position());
@@ -2071,6 +2074,10 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t
 					int terrain_set = int(dummy_object->get("terrain_set"));
 					int terrain = int(dummy_object->get("terrain"));
 					if (terrain_set == -1 || !tile_data || tile_data->get_terrain_set() != terrain_set) {
+						// Paint terrain sets.
+						if (mb->get_button_index() == MouseButton::RIGHT) {
+							terrain_set = -1;
+						}
 						if (mb->is_ctrl_pressed()) {
 							// Paint terrain set with rect.
 							drag_type = DRAG_TYPE_PAINT_TERRAIN_SET_RECT;
@@ -2106,9 +2113,14 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t
 							}
 							drag_last_pos = mb->get_position();
 						}
+						accept_event();
 					} else if (tile_data->get_terrain_set() == terrain_set) {
+						// Paint terrain bits.
+						if (mb->get_button_index() == MouseButton::RIGHT) {
+							terrain = -1;
+						}
 						if (mb->is_ctrl_pressed()) {
-							// Paint terrain set with rect.
+							// Paint terrain bits with rect.
 							drag_type = DRAG_TYPE_PAINT_TERRAIN_BITS_RECT;
 							drag_modified.clear();
 							Dictionary painted_dict;
@@ -2163,6 +2175,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t
 							}
 							drag_last_pos = mb->get_position();
 						}
+						accept_event();
 					}
 				}
 			} else {
@@ -2190,18 +2203,21 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t
 					for (const TileMapCell &E : edited) {
 						Vector2i coords = E.get_atlas_coords();
 						TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, 0);
-						undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E.alternative_tile), tile_data->get_terrain_set());
 						undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E.alternative_tile), drag_painted_value);
-						undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain", coords.x, coords.y, E.alternative_tile), tile_data->get_terrain());
-						for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) {
-							TileSet::CellNeighbor bit = TileSet::CellNeighbor(i);
-							if (tile_data->is_valid_terrain_peering_bit(bit)) {
-								undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]), coords.x, coords.y, E.alternative_tile), tile_data->get_terrain_peering_bit(bit));
+						undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E.alternative_tile), tile_data->get_terrain_set());
+						if (tile_data->get_terrain_set() >= 0) {
+							undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain", coords.x, coords.y, E.alternative_tile), tile_data->get_terrain());
+							for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) {
+								TileSet::CellNeighbor bit = TileSet::CellNeighbor(i);
+								if (tile_data->is_valid_terrain_peering_bit(bit)) {
+									undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]), coords.x, coords.y, E.alternative_tile), tile_data->get_terrain_peering_bit(bit));
+								}
 							}
 						}
 					}
 					undo_redo->commit_action(true);
 					drag_type = DRAG_TYPE_NONE;
+					accept_event();
 				} else if (drag_type == DRAG_TYPE_PAINT_TERRAIN_SET) {
 					undo_redo->create_action(TTR("Painting Terrain Set"));
 					for (KeyValue<TileMapCell, Variant> &E : drag_modified) {
@@ -2209,17 +2225,20 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t
 						Vector2i coords = E.key.get_atlas_coords();
 						undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E.key.alternative_tile), drag_painted_value);
 						undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E.key.alternative_tile), dict["terrain_set"]);
-						undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain", coords.x, coords.y, E.key.alternative_tile), dict["terrain"]);
-						Array array = dict["terrain_peering_bits"];
-						for (int i = 0; i < array.size(); i++) {
-							TileSet::CellNeighbor bit = TileSet::CellNeighbor(i);
-							if (tile_set->is_valid_terrain_peering_bit(dict["terrain_set"], bit)) {
-								undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]), coords.x, coords.y, E.key.alternative_tile), array[i]);
+						if (int(dict["terrain_set"]) >= 0) {
+							undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain", coords.x, coords.y, E.key.alternative_tile), dict["terrain"]);
+							Array array = dict["terrain_peering_bits"];
+							for (int i = 0; i < array.size(); i++) {
+								TileSet::CellNeighbor bit = TileSet::CellNeighbor(i);
+								if (tile_set->is_valid_terrain_peering_bit(dict["terrain_set"], bit)) {
+									undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]), coords.x, coords.y, E.key.alternative_tile), array[i]);
+								}
 							}
 						}
 					}
 					undo_redo->commit_action(false);
 					drag_type = DRAG_TYPE_NONE;
+					accept_event();
 				} else if (drag_type == DRAG_TYPE_PAINT_TERRAIN_BITS) {
 					Dictionary painted = Dictionary(drag_painted_value);
 					int terrain_set = int(painted["terrain_set"]);
@@ -2243,6 +2262,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t
 					}
 					undo_redo->commit_action(false);
 					drag_type = DRAG_TYPE_NONE;
+					accept_event();
 				} else if (drag_type == DRAG_TYPE_PAINT_TERRAIN_BITS_RECT) {
 					Dictionary painted = Dictionary(drag_painted_value);
 					int terrain_set = int(painted["terrain_set"]);
@@ -2312,6 +2332,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t
 					}
 					undo_redo->commit_action(true);
 					drag_type = DRAG_TYPE_NONE;
+					accept_event();
 				}
 			}
 		}
@@ -2348,6 +2369,7 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi
 			}
 
 			drag_last_pos = mm->get_position();
+			accept_event();
 		} else if (drag_type == DRAG_TYPE_PAINT_TERRAIN_BITS) {
 			Dictionary painted = Dictionary(drag_painted_value);
 			int terrain_set = int(painted["terrain_set"]);
@@ -2400,14 +2422,15 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi
 				}
 			}
 			drag_last_pos = mm->get_position();
+			accept_event();
 		}
 	}
 
 	Ref<InputEventMouseButton> mb = p_event;
 	if (mb.is_valid()) {
-		if (mb->get_button_index() == MouseButton::LEFT) {
+		if (mb->get_button_index() == MouseButton::LEFT || mb->get_button_index() == MouseButton::RIGHT) {
 			if (mb->is_pressed()) {
-				if (picker_button->is_pressed()) {
+				if (mb->get_button_index() == MouseButton::LEFT && picker_button->is_pressed()) {
 					Vector3i tile = p_tile_atlas_view->get_alternative_tile_at_pos(mb->get_position());
 					Vector2i coords = Vector2i(tile.x, tile.y);
 					int alternative_tile = tile.z;
@@ -2437,6 +2460,7 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi
 						terrain_set_property_editor->update_property();
 						_update_terrain_selector();
 						picker_button->set_pressed(false);
+						accept_event();
 					}
 				} else {
 					int terrain_set = int(dummy_object->get("terrain_set"));
@@ -2446,75 +2470,87 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi
 					Vector2i coords = Vector2i(tile.x, tile.y);
 					int alternative_tile = tile.z;
 
-					TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, alternative_tile);
+					if (coords != TileSetSource::INVALID_ATLAS_COORDS) {
+						TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, alternative_tile);
 
-					if (terrain_set == -1 || !tile_data || tile_data->get_terrain_set() != terrain_set) {
-						drag_type = DRAG_TYPE_PAINT_TERRAIN_SET;
-						drag_modified.clear();
-						drag_painted_value = int(dummy_object->get("terrain_set"));
-						if (coords != TileSetSource::INVALID_ATLAS_COORDS) {
-							TileMapCell cell;
-							cell.source_id = 0;
-							cell.set_atlas_coords(coords);
-							cell.alternative_tile = alternative_tile;
-							Dictionary dict;
-							dict["terrain_set"] = tile_data->get_terrain_set();
-							Array array;
-							for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) {
-								TileSet::CellNeighbor bit = TileSet::CellNeighbor(i);
-								array.push_back(tile_data->is_valid_terrain_peering_bit(bit) ? tile_data->get_terrain_peering_bit(bit) : -1);
+						if (terrain_set == -1 || !tile_data || tile_data->get_terrain_set() != terrain_set) {
+							// Paint terrain sets.
+							if (mb->get_button_index() == MouseButton::RIGHT) {
+								terrain_set = -1;
 							}
-							dict["terrain_peering_bits"] = array;
-							drag_modified[cell] = dict;
-							tile_data->set_terrain_set(drag_painted_value);
-						}
-						drag_last_pos = mb->get_position();
-					} else if (tile_data->get_terrain_set() == terrain_set) {
-						// Paint terrain bits.
-						drag_type = DRAG_TYPE_PAINT_TERRAIN_BITS;
-						drag_modified.clear();
-						Dictionary painted_dict;
-						painted_dict["terrain_set"] = terrain_set;
-						painted_dict["terrain"] = terrain;
-						drag_painted_value = painted_dict;
-
-						if (coords != TileSetSource::INVALID_ATLAS_COORDS) {
-							TileMapCell cell;
-							cell.source_id = 0;
-							cell.set_atlas_coords(coords);
-							cell.alternative_tile = alternative_tile;
-
-							// Save the old terrain_set and terrains bits.
-							Dictionary dict;
-							dict["terrain_set"] = tile_data->get_terrain_set();
-							dict["terrain"] = tile_data->get_terrain();
-							Array array;
-							for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) {
-								TileSet::CellNeighbor bit = TileSet::CellNeighbor(i);
-								array.push_back(tile_data->is_valid_terrain_peering_bit(bit) ? tile_data->get_terrain_peering_bit(bit) : -1);
+							drag_type = DRAG_TYPE_PAINT_TERRAIN_SET;
+							drag_modified.clear();
+							drag_painted_value = int(dummy_object->get("terrain_set"));
+							if (coords != TileSetSource::INVALID_ATLAS_COORDS) {
+								TileMapCell cell;
+								cell.source_id = 0;
+								cell.set_atlas_coords(coords);
+								cell.alternative_tile = alternative_tile;
+								Dictionary dict;
+								dict["terrain_set"] = tile_data->get_terrain_set();
+								Array array;
+								for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) {
+									TileSet::CellNeighbor bit = TileSet::CellNeighbor(i);
+									array.push_back(tile_data->is_valid_terrain_peering_bit(bit) ? tile_data->get_terrain_peering_bit(bit) : -1);
+								}
+								dict["terrain_peering_bits"] = array;
+								drag_modified[cell] = dict;
+								tile_data->set_terrain_set(drag_painted_value);
 							}
-							dict["terrain_peering_bits"] = array;
-							drag_modified[cell] = dict;
+							drag_last_pos = mb->get_position();
+							accept_event();
+						} else if (tile_data->get_terrain_set() == terrain_set) {
+							// Paint terrain bits.
+							if (mb->get_button_index() == MouseButton::RIGHT) {
+								terrain = -1;
+							}
+							// Paint terrain bits.
+							drag_type = DRAG_TYPE_PAINT_TERRAIN_BITS;
+							drag_modified.clear();
+							Dictionary painted_dict;
+							painted_dict["terrain_set"] = terrain_set;
+							painted_dict["terrain"] = terrain;
+							drag_painted_value = painted_dict;
 
-							// Set the terrain bit.
-							Rect2i texture_region = p_tile_atlas_view->get_alternative_tile_rect(coords, alternative_tile);
-							Vector2i position = texture_region.get_center() + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, alternative_tile);
+							if (coords != TileSetSource::INVALID_ATLAS_COORDS) {
+								TileMapCell cell;
+								cell.source_id = 0;
+								cell.set_atlas_coords(coords);
+								cell.alternative_tile = alternative_tile;
 
-							Vector<Vector2> polygon = tile_set->get_terrain_polygon(terrain_set);
-							if (Geometry2D::is_point_in_polygon(mb->get_position() - position, polygon)) {
-								tile_data->set_terrain(terrain);
-							}
-							for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) {
-								TileSet::CellNeighbor bit = TileSet::CellNeighbor(i);
-								if (tile_set->is_valid_terrain_peering_bit(terrain_set, bit)) {
-									polygon = tile_set->get_terrain_peering_bit_polygon(terrain_set, bit);
-									if (Geometry2D::is_point_in_polygon(mb->get_position() - position, polygon)) {
-										tile_data->set_terrain_peering_bit(bit, terrain);
+								// Save the old terrain_set and terrains bits.
+								Dictionary dict;
+								dict["terrain_set"] = tile_data->get_terrain_set();
+								dict["terrain"] = tile_data->get_terrain();
+								Array array;
+								for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) {
+									TileSet::CellNeighbor bit = TileSet::CellNeighbor(i);
+									array.push_back(tile_data->is_valid_terrain_peering_bit(bit) ? tile_data->get_terrain_peering_bit(bit) : -1);
+								}
+								dict["terrain_peering_bits"] = array;
+								drag_modified[cell] = dict;
+
+								// Set the terrain bit.
+								Rect2i texture_region = p_tile_atlas_view->get_alternative_tile_rect(coords, alternative_tile);
+								Vector2i position = texture_region.get_center() + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, alternative_tile);
+
+								Vector<Vector2> polygon = tile_set->get_terrain_polygon(terrain_set);
+								if (Geometry2D::is_point_in_polygon(mb->get_position() - position, polygon)) {
+									tile_data->set_terrain(terrain);
+								}
+								for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) {
+									TileSet::CellNeighbor bit = TileSet::CellNeighbor(i);
+									if (tile_set->is_valid_terrain_peering_bit(terrain_set, bit)) {
+										polygon = tile_set->get_terrain_peering_bit_polygon(terrain_set, bit);
+										if (Geometry2D::is_point_in_polygon(mb->get_position() - position, polygon)) {
+											tile_data->set_terrain_peering_bit(bit, terrain);
+										}
 									}
 								}
 							}
+							drag_last_pos = mb->get_position();
+							accept_event();
 						}
-						drag_last_pos = mb->get_position();
 					}
 				}
 			} else {
@@ -2523,16 +2559,19 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi
 					for (KeyValue<TileMapCell, Variant> &E : drag_modified) {
 						Dictionary dict = E.value;
 						Vector2i coords = E.key.get_atlas_coords();
-						undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E.key.alternative_tile), dict["terrain_set"]);
 						undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E.key.alternative_tile), drag_painted_value);
-						undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain", coords.x, coords.y, E.key.alternative_tile), dict["terrain"]);
-						Array array = dict["terrain_peering_bits"];
-						for (int i = 0; i < array.size(); i++) {
-							undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]), coords.x, coords.y, E.key.alternative_tile), array[i]);
+						undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E.key.alternative_tile), dict["terrain_set"]);
+						if (int(dict["terrain_set"]) >= 0) {
+							undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain", coords.x, coords.y, E.key.alternative_tile), dict["terrain"]);
+							Array array = dict["terrain_peering_bits"];
+							for (int i = 0; i < array.size(); i++) {
+								undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]), coords.x, coords.y, E.key.alternative_tile), array[i]);
+							}
 						}
 					}
 					undo_redo->commit_action(false);
 					drag_type = DRAG_TYPE_NONE;
+					accept_event();
 				} else if (drag_type == DRAG_TYPE_PAINT_TERRAIN_BITS) {
 					Dictionary painted = Dictionary(drag_painted_value);
 					int terrain_set = int(painted["terrain_set"]);
@@ -2556,6 +2595,7 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi
 					}
 					undo_redo->commit_action(false);
 					drag_type = DRAG_TYPE_NONE;
+					accept_event();
 				}
 			}
 		}

+ 1 - 0
scene/resources/tile_set.cpp

@@ -5275,6 +5275,7 @@ void TileData::set_terrain_set(int p_terrain_set) {
 	}
 	if (tile_set) {
 		ERR_FAIL_COND(p_terrain_set >= tile_set->get_terrain_sets_count());
+		terrain = -1;
 		for (int i = 0; i < 16; i++) {
 			terrain_peering_bits[i] = -1;
 		}