75 lines
2.4 KiB
GDScript
75 lines
2.4 KiB
GDScript
## Caches the sprite location and terrains of each tile in the TileMapDual world grid.
|
|
class_name TileCache
|
|
extends Resource
|
|
|
|
|
|
##[br] Maps a cell coordinate to the stored tile data.
|
|
##[codeblock]
|
|
## Dictionary{
|
|
## key: Vector2i = # The coordinates of this tile in the world grid.
|
|
## value: Dictionary{
|
|
## 'sid': int = # The Source ID of this tile.
|
|
## 'tile': Vector2i = # The coordinates of this tile in its Atlas.
|
|
## 'terrain': int = # The terrain assigned to this tile.
|
|
## } = # The data stored at this tile.
|
|
## }
|
|
##[/codeblock]
|
|
var cells := {}
|
|
func _init() -> void:
|
|
pass
|
|
|
|
##[br] Updates specific cells of the TileCache based on the current layer data at those points.
|
|
##[br] Makes corrections in case the user accidentally places invalid tiles.
|
|
func update(world: TileMapLayer, edited: Array = cells.keys()) -> void:
|
|
var tile_set := world.tile_set
|
|
if tile_set == null:
|
|
push_error('Attempted to update TileCache while tile set was null')
|
|
return
|
|
for cell in edited:
|
|
# Invalid cells will be treated as empty and ignored
|
|
var sid := world.get_cell_source_id(cell)
|
|
if sid == -1:
|
|
cells.erase(cell)
|
|
continue
|
|
if not tile_set.has_source(sid):
|
|
continue
|
|
var src = tile_set.get_source(sid)
|
|
var tile := world.get_cell_atlas_coords(cell)
|
|
if not src.has_tile(tile):
|
|
continue
|
|
var data := world.get_cell_tile_data(cell)
|
|
if data == null:
|
|
continue
|
|
# Accidental cells should be reset to their previous value
|
|
# They will be treated as unchanged
|
|
if data.terrain == -1 or data.terrain_set != 0:
|
|
if cell not in cells:
|
|
world.erase_cell(cell)
|
|
continue
|
|
var cached: Dictionary = cells[cell]
|
|
sid = cached.sid
|
|
tile = cached.tile
|
|
world.set_cell(cell, sid, tile)
|
|
data = world.get_cell_tile_data(cell)
|
|
cells[cell] = {'sid': sid, 'tile': tile, 'terrain': data.terrain}
|
|
|
|
|
|
## Returns the symmetric difference (xor) of two tile caches.
|
|
func xor(other: TileCache) -> Array[Vector2i]:
|
|
var out: Array[Vector2i] = []
|
|
for key in cells:
|
|
if key not in other.cells or cells[key].terrain != other.cells[key].terrain:
|
|
out.push_back(key)
|
|
for key in other.cells:
|
|
if key not in cells:
|
|
out.push_back(key)
|
|
return out
|
|
|
|
|
|
##[br] Returns the terrain value of the tile at the given cell coordinates.
|
|
##[br] Empty cells have a terrain of -1.
|
|
func get_terrain_at(cell: Vector2i) -> int:
|
|
if cell not in cells:
|
|
return -1
|
|
return cells[cell].terrain
|