Skip to content

Commit

Permalink
Merge pull request #19 from raffimolero/10-add-comments
Browse files Browse the repository at this point in the history
10 add comments
  • Loading branch information
raffimolero authored Dec 28, 2024
2 parents b67f955 + 931ef02 commit 3dd2712
Show file tree
Hide file tree
Showing 8 changed files with 313 additions and 156 deletions.
8 changes: 3 additions & 5 deletions addons/TileMapDual/CursorDual.gd
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,12 @@ func _process(_delta: float) -> void:
if Input.is_action_pressed("quick_action_2"):
terrain_offset = 2
# Clicking the 0 key activates tile removal.
# It does remove tiles for both right and left clicks, since atlas_id = -1.
# The same can be achieved with:
# tilemap_dual.remove_tile(cell)
# It does remove tiles for both right and left clicks, since the terrain is -1.
if Input.is_action_pressed("quick_action_0"):
terrain_offset = -1

cell = tilemap_dual.local_to_map(global_position)
if Input.is_action_pressed("left_click"):
tilemap_dual.draw(cell, terrain_offset + 1)
tilemap_dual.draw_cell(cell, terrain_offset + 1)
elif Input.is_action_pressed("right_click"):
tilemap_dual.draw(cell, terrain_offset)
tilemap_dual.draw_cell(cell, terrain_offset)
149 changes: 55 additions & 94 deletions addons/TileMapDual/Display.gd
Original file line number Diff line number Diff line change
@@ -1,27 +1,37 @@
## Manages up to 2 DisplayLayer children.
## A Node designed to hold and manage up to 2 DisplayLayer children.
## See DisplayLayer.gd for details.
class_name Display
extends Node


const TODO = null


## See TerrainDual.gd
var terrain: TerrainDual
## See TileSetWatcher.gd
var _tileset_watcher: TileSetWatcher
## Creates a new Display that updates when the TileSet updates.
func _init(tileset_watcher: TileSetWatcher) -> void:
#print('initializing Display...')
_tileset_watcher = tileset_watcher
terrain = TerrainDual.new(tileset_watcher)
terrain.changed.connect(_tileset_reshaped, 1)
terrain.changed.connect(_terrain_changed, 1)
world_tiles_changed.connect(_world_tiles_changed, 1)


## Activates when the TerrainDual changes.
func _terrain_changed():
_delete_layers()
_create_layers()


## Emitted when the tiles in the map have been edited.
signal world_tiles_changed(changed: Array)
func _world_tiles_changed(changed: Array):
#print('SIGNAL EMITTED: world_tiles_changed(%s)' % {'changed': changed})
for child in get_children(true):
child.update_tiles(cached_cells, changed)


## Initializes and configures new DisplayLayers according to the grid shape.
func _create_layers():
#print('GRID SHAPE: %s' % _tileset_watcher.grid_shape)
var grid: Array = GRIDS[_tileset_watcher.grid_shape]
Expand All @@ -32,71 +42,20 @@ func _create_layers():
add_child(layer)
layer.update_tiles_all(cached_cells)


## Deletes all of the DisplayLayers.
func _delete_layers():
for child in get_children(true):
child.queue_free()

func _tileset_reshaped():
_delete_layers()
_create_layers()


class CellCache:
extends Resource

var cells := {}
func _init() -> void:
pass

## Computes a new CellCache based on the current layer data.
## Needs the old CellCache in case corrections need to made due to accidents.
func compute(tile_set: TileSet, layer: TileMapLayer, cache: CellCache) -> void:
if tile_set == null:
push_error('Attempted to construct CellCache while tile set was null')
return
for cell in layer.get_used_cells():
# Invalid cells will be treated as empty and ignored
var sid := layer.get_cell_source_id(cell)
if not tile_set.has_source(sid):
continue
var src = tile_set.get_source(sid)
var tile := layer.get_cell_atlas_coords(cell)
if not src.has_tile(tile):
continue
var data := layer.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 cache.cells:
layer.erase_cell(cell)
continue
var cached: Dictionary = cache.cells[cell]
sid = cached.sid
tile = cached.tile
layer.set_cell(cell, cached.sid, cached.tile)
cells[cell] = {'sid': sid, 'tile': tile, 'terrain': data.terrain}

## Returns the difference between two tile caches
func diff(other: CellCache) -> 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


## {Vector2i: {'sid': int, 'tile': Vector2i}}
var cached_cells := CellCache.new()
## Updates the display based on the cells found in the TileMapLayer.
## The TileCache computed from the last time update() was called.
var cached_cells := TileCache.new()
## Updates the display based on the cells changed in the TileMapLayer.
func update(layer: TileMapLayer):
if _tileset_watcher.tile_set == null:
return
var current := CellCache.new()
var current := TileCache.new()
current.compute(_tileset_watcher.tile_set, layer, cached_cells)
var updated := current.diff(cached_cells)
cached_cells = current
Expand All @@ -105,8 +64,9 @@ func update(layer: TileMapLayer):
world_tiles_changed.emit(updated)


# TODO: phase out GridShape and simply transpose everything when the offset axis is vertical
## Returns what kind of grid a TileSet is.
## Defaults to SQUARE.
## Will default to SQUARE if Godot decides to add a new TileShape.
static func tileset_gridshape(tile_set: TileSet) -> GridShape:
var hori: bool = tile_set.tile_offset_axis == TileSet.TILE_OFFSET_AXIS_HORIZONTAL
match tile_set.tile_shape:
Expand All @@ -122,7 +82,7 @@ static func tileset_gridshape(tile_set: TileSet) -> GridShape:
return GridShape.SQUARE


## Every meningfully different TileSet.tile_shape * TileSet.tile_offset_axis combination.
## Every meaningfully different TileSet.tile_shape * TileSet.tile_offset_axis combination.
enum GridShape {
SQUARE,
ISO,
Expand All @@ -134,34 +94,35 @@ enum GridShape {


## How to deal with every available GridShape.
## See DisplayLayer.gd for more information about these fields.
const GRIDS: Dictionary = {
GridShape.SQUARE: [
{ # []
'offset': Vector2(-0.5, -0.5),
'dual_to_display': [
[],
[TileSet.CELL_NEIGHBOR_RIGHT_SIDE],
[TileSet.CELL_NEIGHBOR_BOTTOM_SIDE],
[TileSet.CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER],
],
'display_to_dual': [
[TileSet.CELL_NEIGHBOR_TOP_LEFT_CORNER],
[TileSet.CELL_NEIGHBOR_TOP_SIDE],
[TileSet.CELL_NEIGHBOR_LEFT_SIDE],
[],
'world_to_affected_display_neighbors': [
[], # NW
[TileSet.CELL_NEIGHBOR_RIGHT_SIDE], # NE
[TileSet.CELL_NEIGHBOR_BOTTOM_SIDE], # SW
[TileSet.CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER], # SE
],
'display_to_world_neighbors': [
[TileSet.CELL_NEIGHBOR_TOP_LEFT_CORNER], # NW
[TileSet.CELL_NEIGHBOR_TOP_SIDE], # NE
[TileSet.CELL_NEIGHBOR_LEFT_SIDE], # SW
[], # SE
],
}
],
GridShape.ISO: [
{ # <>
'offset': Vector2(0, -0.5),
'dual_to_display': [
'world_to_affected_display_neighbors': [
[], # TOP
[TileSet.CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE], # RIGHT
[TileSet.CELL_NEIGHBOR_BOTTOM_LEFT_SIDE], # LEFT
[TileSet.CELL_NEIGHBOR_BOTTOM_CORNER], # BOTTOM
],
'display_to_dual': [
'display_to_world_neighbors': [
[TileSet.CELL_NEIGHBOR_TOP_CORNER], # TOP
[TileSet.CELL_NEIGHBOR_TOP_RIGHT_SIDE], # RIGHT
[TileSet.CELL_NEIGHBOR_TOP_LEFT_SIDE], # LEFT
Expand All @@ -172,24 +133,24 @@ const GRIDS: Dictionary = {
GridShape.HALF_OFF_HORI: [
{
'offset': Vector2(0.0, -0.5),
'dual_to_display': [
'world_to_affected_display_neighbors': [
[],
[TileSet.CELL_NEIGHBOR_BOTTOM_LEFT_SIDE],
[TileSet.CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE],
],
'display_to_dual': [
'display_to_world_neighbors': [
[],
[TileSet.CELL_NEIGHBOR_TOP_LEFT_SIDE],
[TileSet.CELL_NEIGHBOR_TOP_RIGHT_SIDE],
],
}, {
'offset': Vector2(-0.5, -0.5),
'dual_to_display': [
'world_to_affected_display_neighbors': [
[],
[TileSet.CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE],
[TileSet.CELL_NEIGHBOR_RIGHT_SIDE],
],
'display_to_dual': [
'display_to_world_neighbors': [
[TileSet.CELL_NEIGHBOR_TOP_LEFT_SIDE],
[TileSet.CELL_NEIGHBOR_LEFT_SIDE],
[],
Expand All @@ -199,24 +160,24 @@ const GRIDS: Dictionary = {
GridShape.HALF_OFF_VERT: [
{
'offset': Vector2(-0.5, 0.0),
'dual_to_display': [
'world_to_affected_display_neighbors': [
[],
[TileSet.CELL_NEIGHBOR_TOP_RIGHT_SIDE],
[TileSet.CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE],
],
'display_to_dual': [
'display_to_world_neighbors': [
[],
[TileSet.CELL_NEIGHBOR_TOP_LEFT_SIDE],
[TileSet.CELL_NEIGHBOR_BOTTOM_LEFT_SIDE],
],
}, {
'offset': Vector2(-0.5, -0.5),
'dual_to_display': [
'world_to_affected_display_neighbors': [
[],
[TileSet.CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE],
[TileSet.CELL_NEIGHBOR_BOTTOM_SIDE],
],
'display_to_dual': [
'display_to_world_neighbors': [
[TileSet.CELL_NEIGHBOR_TOP_LEFT_SIDE],
[TileSet.CELL_NEIGHBOR_TOP_SIDE],
[],
Expand All @@ -226,51 +187,51 @@ const GRIDS: Dictionary = {
GridShape.HEX_HORI: [
{
'offset': Vector2(0.0, -3.0 / 8.0),
'dual_to_display': [
'world_to_affected_display_neighbors': [
[],
[TileSet.CELL_NEIGHBOR_BOTTOM_LEFT_SIDE],
[TileSet.CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE],
],
'display_to_dual': [
'display_to_world_neighbors': [
[],
[TileSet.CELL_NEIGHBOR_TOP_LEFT_SIDE],
[TileSet.CELL_NEIGHBOR_TOP_RIGHT_SIDE],
],
}, {
'offset': Vector2(-0.5, -3.0 / 8.0),
'dual_to_display': [
'world_to_affected_display_neighbors': [
[],
[TileSet.CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE],
[TileSet.CELL_NEIGHBOR_RIGHT_SIDE],
],
'display_to_dual': [
'display_to_world_neighbors': [
[TileSet.CELL_NEIGHBOR_TOP_LEFT_SIDE],
[TileSet.CELL_NEIGHBOR_LEFT_SIDE],
[],
],
},
],
GridShape.HEX_VERT: [
{
{ # >
'offset': Vector2(-3.0 / 8.0, 0.0),
'dual_to_display': [
'world_to_affected_display_neighbors': [
[],
[TileSet.CELL_NEIGHBOR_TOP_RIGHT_SIDE],
[TileSet.CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE],
],
'display_to_dual': [
'display_to_world_neighbors': [
[],
[TileSet.CELL_NEIGHBOR_TOP_LEFT_SIDE],
[TileSet.CELL_NEIGHBOR_BOTTOM_LEFT_SIDE],
],
}, {
'offset': Vector2(-3.0 / 8.0, -0.5),
'dual_to_display': [
'world_to_affected_display_neighbors': [
[],
[TileSet.CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE],
[TileSet.CELL_NEIGHBOR_BOTTOM_SIDE],
],
'display_to_dual': [
'display_to_world_neighbors': [
[TileSet.CELL_NEIGHBOR_TOP_LEFT_SIDE],
[TileSet.CELL_NEIGHBOR_TOP_SIDE],
[],
Expand Down
Loading

0 comments on commit 3dd2712

Please sign in to comment.