152 lines
4.1 KiB
GDScript
152 lines
4.1 KiB
GDScript
##[br] A Node designed to hold and manage up to 2 DisplayLayer children.
|
|
##[br] See DisplayLayer.gd for details.
|
|
class_name Display
|
|
extends Node2D
|
|
|
|
|
|
## See TerrainDual.gd
|
|
var terrain: TerrainDual
|
|
## See TileSetWatcher.gd
|
|
var _tileset_watcher: TileSetWatcher
|
|
## The parent TileMapDual to base the terrains off of.
|
|
@export var world: TileMapDual
|
|
## Creates a new Display that updates when the TileSet updates.
|
|
func _init(world: TileMapDual, tileset_watcher: TileSetWatcher) -> void:
|
|
#print('initializing Display...')
|
|
self.world = world
|
|
_tileset_watcher = tileset_watcher
|
|
terrain = TerrainDual.new(tileset_watcher)
|
|
terrain.changed.connect(_terrain_changed, 1)
|
|
world_tiles_changed.connect(_world_tiles_changed, 1)
|
|
# let parent materal through to the displaylayers
|
|
use_parent_material = true
|
|
|
|
|
|
## Activates when the TerrainDual changes.
|
|
func _terrain_changed() -> void:
|
|
cached_cells.update(world)
|
|
_delete_layers()
|
|
if _tileset_watcher.tile_set != null:
|
|
_create_layers()
|
|
|
|
|
|
## Emitted when the tiles in the map have been edited.
|
|
signal world_tiles_changed(changed: Array)
|
|
func _world_tiles_changed(changed: Array) -> void:
|
|
#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() -> void:
|
|
#print('GRID SHAPE: %s' % _tileset_watcher.grid_shape)
|
|
var grid: Array = GRIDS[_tileset_watcher.grid_shape]
|
|
for i in grid.size():
|
|
var layer_config: Dictionary = grid[i]
|
|
#print('layer_config: %s' % layer_config)
|
|
var layer := DisplayLayer.new(world, _tileset_watcher, layer_config, terrain.layers[i])
|
|
add_child(layer)
|
|
layer.update_tiles_all(cached_cells)
|
|
|
|
|
|
## Deletes all of the DisplayLayers.
|
|
func _delete_layers() -> void:
|
|
for child in get_children(true):
|
|
child.queue_free()
|
|
|
|
|
|
## 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 world TileMapDual.
|
|
func update(updated: Array) -> void:
|
|
if _tileset_watcher.tile_set == null:
|
|
return
|
|
_update_properties()
|
|
if not updated.is_empty():
|
|
cached_cells.update(world, updated)
|
|
world_tiles_changed.emit(updated)
|
|
|
|
|
|
## Activates when the properties of the parent TileMapDual have been edited.
|
|
func _update_properties() -> void:
|
|
for child in get_children(true):
|
|
child.update_properties(world)
|
|
|
|
|
|
# TODO: phase out GridShape and simply transpose everything when the offset axis is vertical
|
|
##[br] Returns what kind of grid a TileSet is.
|
|
##[br] 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:
|
|
TileSet.TileShape.TILE_SHAPE_SQUARE:
|
|
return GridShape.SQUARE
|
|
TileSet.TileShape.TILE_SHAPE_ISOMETRIC:
|
|
return GridShape.ISO
|
|
TileSet.TileShape.TILE_SHAPE_HALF_OFFSET_SQUARE:
|
|
return GridShape.HALF_OFF_HORI if hori else GridShape.HALF_OFF_VERT
|
|
TileSet.TileShape.TILE_SHAPE_HEXAGON:
|
|
return GridShape.HEX_HORI if hori else GridShape.HEX_VERT
|
|
_:
|
|
return GridShape.SQUARE
|
|
|
|
|
|
## Every meaningfully different TileSet.tile_shape * TileSet.tile_offset_axis combination.
|
|
enum GridShape {
|
|
SQUARE,
|
|
ISO,
|
|
HALF_OFF_HORI,
|
|
HALF_OFF_VERT,
|
|
HEX_HORI,
|
|
HEX_VERT,
|
|
}
|
|
|
|
|
|
##[br] How to deal with every available GridShape.
|
|
##[br] See DisplayLayer.gd for more information about these fields.
|
|
const GRIDS: Dictionary = {
|
|
GridShape.SQUARE: [
|
|
{ # []
|
|
'offset': Vector2(-0.5, -0.5),
|
|
}
|
|
],
|
|
GridShape.ISO: [
|
|
{ # <>
|
|
'offset': Vector2(0, -0.5),
|
|
}
|
|
],
|
|
GridShape.HALF_OFF_HORI: [
|
|
{ # v
|
|
'offset': Vector2(0.0, -0.5),
|
|
},
|
|
{ # ^
|
|
'offset': Vector2(-0.5, -0.5),
|
|
},
|
|
],
|
|
GridShape.HALF_OFF_VERT: [
|
|
{ # >
|
|
'offset': Vector2(-0.5, 0.0),
|
|
},
|
|
{ # <
|
|
'offset': Vector2(-0.5, -0.5),
|
|
},
|
|
],
|
|
GridShape.HEX_HORI: [
|
|
{ # v
|
|
'offset': Vector2(0.0, -3.0 / 8.0),
|
|
},
|
|
{ # ^
|
|
'offset': Vector2(-0.5, -3.0 / 8.0),
|
|
},
|
|
],
|
|
GridShape.HEX_VERT: [
|
|
{ # >
|
|
'offset': Vector2(-3.0 / 8.0, 0.0),
|
|
},
|
|
{ # <
|
|
'offset': Vector2(-3.0 / 8.0, -0.5),
|
|
},
|
|
],
|
|
}
|