Skip to content

Commit

Permalink
Fix tileset being completely cleared when resizing a project
Browse files Browse the repository at this point in the history
Now only remove the tiles that are used so they can be remade as resized tiles. Unused tiles remain in the tileset as is.
  • Loading branch information
OverloadedOrama committed Dec 27, 2024
1 parent 616bd91 commit c60c62f
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 12 deletions.
9 changes: 6 additions & 3 deletions src/Autoload/OpenSave.gd
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,10 @@ func open_pxo_file(path: String, is_backup := false, replace_empty := true) -> v
var image := Image.create_from_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()
new_project.export_directory_path = path.get_base_dir()

Expand Down Expand Up @@ -878,7 +881,7 @@ func open_image_as_tileset(
Rect2i(frame_width * xx, frame_height * yy, frame_width, frame_height)
)
@warning_ignore("int_as_enum_without_cast")
tileset.add_tile(cropped_image, null)
tileset.add_tile(cropped_image, null, 0)
project.tilesets.append(tileset)


Expand All @@ -901,7 +904,7 @@ func open_image_as_tileset_smart(
)
cropped_image.blit_rect(image, rect, offset)
@warning_ignore("int_as_enum_without_cast")
tileset.add_tile(cropped_image, null)
tileset.add_tile(cropped_image, null, 0)
project.tilesets.append(tileset)


Expand Down
9 changes: 8 additions & 1 deletion src/Classes/Cels/CelTileMap.gd
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ func serialize_undo_data_source_image(
if source_image.get_size() != image.get_size():
undo_data[self]["resize"] = true
_resize_cells(source_image.get_size())
tileset.clear_tileset(self)
tileset.handle_project_resize(self)
var tile_editing_mode := TileSetPanel.tile_editing_mode
if tile_editing_mode == TileSetPanel.TileEditingMode.MANUAL:
tile_editing_mode = TileSetPanel.TileEditingMode.AUTO
Expand All @@ -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))


## 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],
## 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
Expand Down
18 changes: 10 additions & 8 deletions src/Classes/TileSetCustom.gd
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ var name := ""
var tile_size: Vector2i
## The collection of tiles in the form of an [Array] of type [TileSetCustom.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.
## 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].
var _tileset_has_been_cleared := false

Expand Down Expand Up @@ -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.
## 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.
func add_tile(image: Image, cel: CelTileMap) -> void:
func add_tile(image: Image, cel: CelTileMap, times_used := 1) -> void:
var tile := Tile.new(image)
tile.times_used = times_used
tiles.append(tile)
updated.emit(cel, -1)

Expand Down Expand Up @@ -115,14 +116,15 @@ func remove_unused_tiles(cel: CelTileMap) -> bool:
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.
func clear_tileset(cel: CelTileMap) -> void:
func handle_project_resize(cel: CelTileMap) -> void:
if _tileset_has_been_cleared:
return
tiles.clear()
var empty_image := Image.create_empty(tile_size.x, tile_size.y, false, Image.FORMAT_RGBA8)
tiles.append(Tile.new(empty_image))
for i in range(tiles.size() - 1, 0, -1):
var tile := tiles[i]
if tile.times_used > 0:
tiles.erase(tile)
updated.emit(cel, -1)
_tileset_has_been_cleared = true
set_deferred("_tileset_has_been_cleared", false)
Expand Down

0 comments on commit c60c62f

Please sign in to comment.