From 2301ba9fcc6f89d1f97328fd07d4b0bdb3b37552 Mon Sep 17 00:00:00 2001 From: Emmanouil Papadeas <35376950+OverloadedOrama@users.noreply.github.com> Date: Mon, 25 Nov 2024 19:02:05 +0200 Subject: [PATCH] Make manual tile editing mode automatically update all other image portions that have the same tile index --- src/Autoload/Global.gd | 4 +-- src/Classes/Cels/BaseCel.gd | 2 +- src/Classes/Cels/CelTileMap.gd | 53 ++++++++++++++++++++++++---------- src/Classes/Cels/PixelCel.gd | 4 +-- src/UI/Canvas/Canvas.gd | 6 ++-- 5 files changed, 46 insertions(+), 23 deletions(-) diff --git a/src/Autoload/Global.gd b/src/Autoload/Global.gd index 4b1d1690d..4b373734f 100644 --- a/src/Autoload/Global.gd +++ b/src/Autoload/Global.gd @@ -983,7 +983,7 @@ func undo_or_redo( var cel := project.frames[frame_index].cels[layer_index] if action_name == "Scale": cel.size_changed(project.size) - canvas.update_texture(layer_index, frame_index, project) + canvas.update_texture(layer_index, frame_index, project, undo) cel.on_undo_redo(undo) else: for i in project.frames.size(): @@ -991,7 +991,7 @@ func undo_or_redo( var cel := project.frames[i].cels[j] if action_name == "Scale": cel.size_changed(project.size) - canvas.update_texture(j, i, project) + canvas.update_texture(j, i, project, undo) cel.on_undo_redo(undo) canvas.selection.queue_redraw() diff --git a/src/Classes/Cels/BaseCel.gd b/src/Classes/Cels/BaseCel.gd index 2ac64dcab..ec9b9089c 100644 --- a/src/Classes/Cels/BaseCel.gd +++ b/src/Classes/Cels/BaseCel.gd @@ -67,7 +67,7 @@ func get_image() -> Image: ## Used to update the texture of the cel. -func update_texture() -> void: +func update_texture(_undo := false) -> void: texture_changed.emit() if link_set != null: var frame := Global.current_project.current_frame diff --git a/src/Classes/Cels/CelTileMap.gd b/src/Classes/Cels/CelTileMap.gd index 339945671..fef8ff6b2 100644 --- a/src/Classes/Cels/CelTileMap.gd +++ b/src/Classes/Cels/CelTileMap.gd @@ -14,6 +14,12 @@ var indices_y: int ## Dictionary of [int] and an [Array] of [bool] ([member TileSetPanel.placing_tiles]) ## and [enum TileSetPanel.TileEditingMode]. var undo_redo_modes := {} +## Dictionary of [int] and [Array]. +## The key is the index of the tile in the tileset, +## and the value is the index of the tilemap tile that changed first, along with +## its image that is being changed when manual mode is enabled. +## Gets reset on [method update_tileset]. +var editing_images := {} func _init(_tileset: TileSetCustom, _image: ImageExtended, _opacity := 1.0) -> void: @@ -30,6 +36,7 @@ func set_index(tile_position: int, index: int) -> void: func update_tileset(undo: bool) -> void: + editing_images.clear() var undos := tileset.project.undos if not undo and not _is_redo(): undo_redo_modes[undos] = [TileSetPanel.placing_tiles, TileSetPanel.tile_editing_mode] @@ -42,7 +49,7 @@ func update_tileset(undo: bool) -> void: var image_portion := image.get_region(rect) var index := indices[i] if index >= tileset.tiles.size(): - print(i, " is out of bounds") + printerr("Tile at position ", i, ", mapped to ", index, " is out of bounds!") index = 0 indices[i] = 0 var current_tile := tileset.tiles[index] @@ -57,7 +64,6 @@ func update_tileset(undo: bool) -> void: continue if image_portion.get_data() != current_tile.image.get_data(): tileset.replace_tile_at(image_portion, index) - update_cel_portions() elif tile_editing_mode == TileSetPanel.TileEditingMode.AUTO: handle_auto_editing_mode(i, image_portion) else: # Stack @@ -195,6 +201,7 @@ func update_cel_portion(tile_position: int) -> void: image.blit_rect(current_tile.image, Rect2i(Vector2i.ZERO, tile_size), coords) +## Unused, should delete. func update_cel_portions() -> void: for i in indices.size(): update_cel_portion(i) @@ -247,21 +254,35 @@ func _get_tile_editing_mode(undos: int) -> TileSetPanel.TileEditingMode: # Overridden Methods: -func update_texture() -> void: - 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] +func update_texture(undo := false) -> void: + var tile_editing_mode := TileSetPanel.tile_editing_mode + if undo or _is_redo() or tile_editing_mode != TileSetPanel.TileEditingMode.MANUAL: + super.update_texture(undo) + return + + for i in indices.size(): + var index := indices[i] + var coords := get_tile_coords(i) + var rect := Rect2i(coords, tileset.tile_size) + var image_portion := image.get_region(rect) + var current_tile := tileset.tiles[index] + if index == 0 and tileset.tiles.size() > 1: # Prevent from drawing on empty image portions. - if index == 0 and tileset.tiles.size() > 1: - var coords := get_tile_coords(i) - var current_tile := tileset.tiles[index] - var tile_size := current_tile.image.get_size() - image.blit_rect(current_tile.image, Rect2i(Vector2i.ZERO, tile_size), coords) - super.update_texture() + var tile_size := current_tile.image.get_size() + image.blit_rect(current_tile.image, Rect2i(Vector2i.ZERO, tile_size), coords) + continue + if editing_images.has(index): + var editing_portion := editing_images[index][0] as int + if i == editing_portion: + editing_images[index] = [i, image_portion] + var editing_image := editing_images[index][1] as Image + if editing_image.get_data() != image_portion.get_data(): + var tile_size := image_portion.get_size() + image.blit_rect(editing_image, Rect2i(Vector2i.ZERO, tile_size), coords) + else: + if image_portion.get_data() != current_tile.image.get_data(): + editing_images[index] = [i, image_portion] + super.update_texture(undo) func size_changed(new_size: Vector2i) -> void: diff --git a/src/Classes/Cels/PixelCel.gd b/src/Classes/Cels/PixelCel.gd index dc2bb3aa7..82c09bf61 100644 --- a/src/Classes/Cels/PixelCel.gd +++ b/src/Classes/Cels/PixelCel.gd @@ -54,9 +54,9 @@ func get_image() -> ImageExtended: return image -func update_texture() -> void: +func update_texture(undo := false) -> void: image_texture.set_image(image) - super.update_texture() + super.update_texture(undo) func get_class_name() -> String: diff --git a/src/UI/Canvas/Canvas.gd b/src/UI/Canvas/Canvas.gd index 62518ffd5..bf0aadc99 100644 --- a/src/UI/Canvas/Canvas.gd +++ b/src/UI/Canvas/Canvas.gd @@ -110,13 +110,15 @@ func camera_zoom() -> void: Global.transparent_checker.update_rect() -func update_texture(layer_i: int, frame_i := -1, project := Global.current_project) -> void: +func update_texture( + layer_i: int, frame_i := -1, project := Global.current_project, undo := false +) -> void: if frame_i == -1: frame_i = project.current_frame if frame_i < project.frames.size() and layer_i < project.layers.size(): var current_cel := project.frames[frame_i].cels[layer_i] - current_cel.update_texture() + current_cel.update_texture(undo) # Needed so that changes happening to the non-selected layer(s) are also visible # e.g. when undoing/redoing, when applying image effects to the entire frame, etc if frame_i != project.current_frame: