1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-01-18 09:09:47 +00:00

Fix tileset being completely cleared when resizing a project

Now only remove the tiles that are used so they can be remade as resized tiles. Unused tiles remain in the tileset as is.
This commit is contained in:
Emmanouil Papadeas 2024-12-27 03:30:56 +02:00
parent 616bd91c49
commit c60c62f476
3 changed files with 24 additions and 12 deletions

View file

@ -287,7 +287,10 @@ func open_pxo_file(path: String, is_backup := false, replace_empty := true) -> v
var image := Image.create_from_data( var image := Image.create_from_data(
tile_size.x, tile_size.y, false, new_project.get_image_format(), image_data tile_size.x, tile_size.y, false, new_project.get_image_format(), image_data
) )
tileset.add_tile(image, null) tileset.add_tile(image, null, 0)
for cel in new_project.get_all_pixel_cels():
if cel is CelTileMap:
cel.find_times_used_of_tiles()
zip_reader.close() zip_reader.close()
new_project.export_directory_path = path.get_base_dir() new_project.export_directory_path = path.get_base_dir()
@ -878,7 +881,7 @@ func open_image_as_tileset(
Rect2i(frame_width * xx, frame_height * yy, frame_width, frame_height) Rect2i(frame_width * xx, frame_height * yy, frame_width, frame_height)
) )
@warning_ignore("int_as_enum_without_cast") @warning_ignore("int_as_enum_without_cast")
tileset.add_tile(cropped_image, null) tileset.add_tile(cropped_image, null, 0)
project.tilesets.append(tileset) project.tilesets.append(tileset)
@ -901,7 +904,7 @@ func open_image_as_tileset_smart(
) )
cropped_image.blit_rect(image, rect, offset) cropped_image.blit_rect(image, rect, offset)
@warning_ignore("int_as_enum_without_cast") @warning_ignore("int_as_enum_without_cast")
tileset.add_tile(cropped_image, null) tileset.add_tile(cropped_image, null, 0)
project.tilesets.append(tileset) project.tilesets.append(tileset)

View file

@ -330,7 +330,7 @@ func serialize_undo_data_source_image(
if source_image.get_size() != image.get_size(): if source_image.get_size() != image.get_size():
undo_data[self]["resize"] = true undo_data[self]["resize"] = true
_resize_cells(source_image.get_size()) _resize_cells(source_image.get_size())
tileset.clear_tileset(self) tileset.handle_project_resize(self)
var tile_editing_mode := TileSetPanel.tile_editing_mode var tile_editing_mode := TileSetPanel.tile_editing_mode
if tile_editing_mode == TileSetPanel.TileEditingMode.MANUAL: if tile_editing_mode == TileSetPanel.TileEditingMode.MANUAL:
tile_editing_mode = TileSetPanel.TileEditingMode.AUTO tile_editing_mode = TileSetPanel.TileEditingMode.AUTO
@ -352,6 +352,13 @@ func deserialize_undo_data(dict: Dictionary, undo_redo: UndoRedo, undo: bool) ->
undo_redo.add_do_method(tileset.deserialize_undo_data.bind(dict.tileset, self)) undo_redo.add_do_method(tileset.deserialize_undo_data.bind(dict.tileset, self))
## Called when loading a new project. Loops through all [member cells]
## and finds the amount of times each tile from the [member tileset] is being used.
func find_times_used_of_tiles() -> void:
for cell in cells:
tileset.tiles[cell.index].times_used += 1
## Gets called every time a change is being applied to the [param image], ## Gets called every time a change is being applied to the [param image],
## such as when finishing drawing with a draw tool, or when applying an image effect. ## such as when finishing drawing with a draw tool, or when applying an image effect.
## This method responsible for updating the indices of the [member cells], as well as ## This method responsible for updating the indices of the [member cells], as well as

View file

@ -16,9 +16,9 @@ var name := ""
var tile_size: Vector2i var tile_size: Vector2i
## The collection of tiles in the form of an [Array] of type [TileSetCustom.Tile]. ## The collection of tiles in the form of an [Array] of type [TileSetCustom.Tile].
var tiles: Array[Tile] = [] var tiles: Array[Tile] = []
## If [code]true[/code], the code in [method clear_tileset] does not execute. ## If [code]true[/code], the code in [method handle_project_resize] does not execute.
## This variable is used to prevent multiple cels from clearing the tileset at the same time. ## This variable is used to prevent multiple cels from clearing the tileset at the same time.
## In [method clear_tileset], the variable is set to [code]true[/code], and then ## In [method handle_project_resize], the variable is set to [code]true[/code], and then
## immediately set to [code]false[/code] in the next frame using [method Object.set_deferred]. ## immediately set to [code]false[/code] in the next frame using [method Object.set_deferred].
var _tileset_has_been_cleared := false var _tileset_has_been_cleared := false
@ -50,8 +50,9 @@ func _init(_tile_size: Vector2i, _name := "", add_empty_tile := true) -> void:
## Adds a new [param image] as a tile to the tileset. ## Adds a new [param image] as a tile to the tileset.
## The [param cel] parameter references the [CelTileMap] that this change is coming from, ## The [param cel] parameter references the [CelTileMap] that this change is coming from,
## and the [param edit_mode] parameter contains the tile editing mode at the time of this change. ## and the [param edit_mode] parameter contains the tile editing mode at the time of this change.
func add_tile(image: Image, cel: CelTileMap) -> void: func add_tile(image: Image, cel: CelTileMap, times_used := 1) -> void:
var tile := Tile.new(image) var tile := Tile.new(image)
tile.times_used = times_used
tiles.append(tile) tiles.append(tile)
updated.emit(cel, -1) updated.emit(cel, -1)
@ -115,14 +116,15 @@ func remove_unused_tiles(cel: CelTileMap) -> bool:
return tile_removed return tile_removed
## Clears the tileset. Usually called when the project gets resized, ## Clears the used tiles of tileset. Called when the project gets resized,
## and tilemap cels are updating their size and clearing the tileset to re-create it. ## and tilemap cels are updating their size and clearing the tileset to re-create it.
func clear_tileset(cel: CelTileMap) -> void: func handle_project_resize(cel: CelTileMap) -> void:
if _tileset_has_been_cleared: if _tileset_has_been_cleared:
return return
tiles.clear() for i in range(tiles.size() - 1, 0, -1):
var empty_image := Image.create_empty(tile_size.x, tile_size.y, false, Image.FORMAT_RGBA8) var tile := tiles[i]
tiles.append(Tile.new(empty_image)) if tile.times_used > 0:
tiles.erase(tile)
updated.emit(cel, -1) updated.emit(cel, -1)
_tileset_has_been_cleared = true _tileset_has_been_cleared = true
set_deferred("_tileset_has_been_cleared", false) set_deferred("_tileset_has_been_cleared", false)