From 04ab9faa876fcea4a892b1af52904b1471e8cbd2 Mon Sep 17 00:00:00 2001 From: Emmanouil Papadeas <35376950+OverloadedOrama@users.noreply.github.com> Date: Mon, 25 Nov 2024 14:17:01 +0200 Subject: [PATCH] Fix out of bounds issues when undoing/redoing when the place tiles mode is enabled --- src/Classes/Cels/CelTileMap.gd | 48 +++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/src/Classes/Cels/CelTileMap.gd b/src/Classes/Cels/CelTileMap.gd index ef65f0109..339945671 100644 --- a/src/Classes/Cels/CelTileMap.gd +++ b/src/Classes/Cels/CelTileMap.gd @@ -11,6 +11,9 @@ var tileset: TileSetCustom: var indices := PackedInt32Array() var indices_x: int var indices_y: int +## Dictionary of [int] and an [Array] of [bool] ([member TileSetPanel.placing_tiles]) +## and [enum TileSetPanel.TileEditingMode]. +var undo_redo_modes := {} func _init(_tileset: TileSetCustom, _image: ImageExtended, _opacity := 1.0) -> void: @@ -27,6 +30,12 @@ func set_index(tile_position: int, index: int) -> void: func update_tileset(undo: bool) -> void: + var undos := tileset.project.undos + if not undo and not _is_redo(): + undo_redo_modes[undos] = [TileSetPanel.placing_tiles, TileSetPanel.tile_editing_mode] + if undo: + undos += 1 + var tile_editing_mode := _get_tile_editing_mode(undos) for i in indices.size(): var coords := get_tile_coords(i) var rect := Rect2i(coords, tileset.tile_size) @@ -37,19 +46,19 @@ func update_tileset(undo: bool) -> void: index = 0 indices[i] = 0 var current_tile := tileset.tiles[index] - if TileSetPanel.tile_editing_mode == TileSetPanel.TileEditingMode.MANUAL: + if tile_editing_mode == TileSetPanel.TileEditingMode.MANUAL: if image_portion.is_invisible(): continue if index == 0: # If the tileset is empty, only then add a new tile. if tileset.tiles.size() <= 1: - tileset.add_tile(image_portion, TileSetPanel.tile_editing_mode) + tileset.add_tile(image_portion, tile_editing_mode) indices[i] = tileset.tiles.size() - 1 continue if image_portion.get_data() != current_tile.image.get_data(): tileset.replace_tile_at(image_portion, index) update_cel_portions() - elif TileSetPanel.tile_editing_mode == TileSetPanel.TileEditingMode.AUTO: + elif tile_editing_mode == TileSetPanel.TileEditingMode.AUTO: handle_auto_editing_mode(i, image_portion) else: # Stack if image_portion.is_invisible(): @@ -62,7 +71,7 @@ func update_tileset(undo: bool) -> void: found_tile = true break if not found_tile: - tileset.add_tile(image_portion, TileSetPanel.tile_editing_mode) + tileset.add_tile(image_portion, tile_editing_mode) indices[i] = tileset.tiles.size() - 1 if undo: var tile_removed := tileset.remove_unused_tiles() @@ -129,7 +138,7 @@ func handle_auto_editing_mode(i: int, image_portion: Image) -> void: else: # Case 2: The portion is not mapped already, # and it does not exist in the tileset. - tileset.add_tile(image_portion, TileSetPanel.tile_editing_mode) + tileset.add_tile(image_portion, TileSetPanel.TileEditingMode.AUTO) indices[i] = tileset.tiles.size() - 1 else: # If the portion is already mapped. if image_portion.get_data() == current_tile.image.get_data(): @@ -157,7 +166,7 @@ func handle_auto_editing_mode(i: int, image_portion: Image) -> void: # exist in the tileset as a tile, # and the currently mapped tile still exists in the tileset. tileset.unuse_tile_at_index(index) - tileset.add_tile(image_portion, TileSetPanel.tile_editing_mode) + tileset.add_tile(image_portion, TileSetPanel.TileEditingMode.AUTO) indices[i] = tileset.tiles.size() - 1 else: # Case 7: The portion is mapped and it does not @@ -224,9 +233,26 @@ func re_index_all_tiles() -> void: break +func _is_redo() -> bool: + return Global.control.redone + + +func _get_tile_editing_mode(undos: int) -> TileSetPanel.TileEditingMode: + var tile_editing_mode: TileSetPanel.TileEditingMode + if undo_redo_modes.has(undos): + tile_editing_mode = undo_redo_modes[undos][1] + else: + tile_editing_mode = TileSetPanel.tile_editing_mode + return tile_editing_mode + + # Overridden Methods: func update_texture() -> void: - if TileSetPanel.tile_editing_mode == TileSetPanel.TileEditingMode.MANUAL: + var undos := tileset.project.undos + #if undo: + #undos += 1 + var tile_editing_mode := _get_tile_editing_mode(undos) + if tile_editing_mode == TileSetPanel.TileEditingMode.MANUAL: for i in indices.size(): var index := indices[i] # Prevent from drawing on empty image portions. @@ -246,6 +272,14 @@ func size_changed(new_size: Vector2i) -> void: func on_undo_redo(undo: bool) -> void: + var undos := tileset.project.undos + if undo: + undos += 1 + if (undo or _is_redo()) and undo_redo_modes.has(undos): + var placing_tiles: bool = undo_redo_modes[undos][0] + if placing_tiles: + re_index_all_tiles() + return update_tileset(undo)