summaryrefslogtreecommitdiff
path: root/scripts/lake_generator.gd
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/lake_generator.gd')
-rw-r--r--scripts/lake_generator.gd141
1 files changed, 141 insertions, 0 deletions
diff --git a/scripts/lake_generator.gd b/scripts/lake_generator.gd
new file mode 100644
index 0000000..6c5050d
--- /dev/null
+++ b/scripts/lake_generator.gd
@@ -0,0 +1,141 @@
+extends Object
+
+class_name LakeGenerator
+
+var map_config : MapGeneratorResource = preload("res://resources/map_generator_resource.tres")
+var _tile_map : TileMapLayer
+var _lake : Array[Vector2i]
+var _lake_queue : Array[Vector2i]
+var _path : Array[Vector2i]
+
+enum TileTransform {
+ ROTATE_0 = 0,
+ ROTATE_90 = TileSetAtlasSource.TRANSFORM_TRANSPOSE | TileSetAtlasSource.TRANSFORM_FLIP_H,
+ ROTATE_180 = TileSetAtlasSource.TRANSFORM_FLIP_H | TileSetAtlasSource.TRANSFORM_FLIP_V,
+ ROTATE_270 = TileSetAtlasSource.TRANSFORM_TRANSPOSE | TileSetAtlasSource.TRANSFORM_FLIP_V,
+}
+
+func _init(tile_map_layer: TileMapLayer, path : Array[Vector2i]):
+ _tile_map = tile_map_layer
+ _path = path
+
+func generate_lake():
+ var tile : Vector2i
+
+ while 1:
+ tile.x = randi_range(0, map_config.grid_width - 1)
+ tile.y = randi_range(0, map_config.grid_height - 1)
+
+ if _is_expansion_valid(tile):
+ break
+
+ _visit_tile(tile)
+ print(map_config.max_lake_size)
+ while _lake.size() < map_config.max_lake_size:
+ tile = _pop_tile()
+ # no room to grow
+ if tile == Vector2i(-1, -1):
+ break
+
+ var adj_tiles : Array[Vector2i] = _get_adjacent_tiles(tile)
+ for i in adj_tiles:
+ _try_expand(i)
+
+ draw_lake()
+
+func draw_lake():
+ for i in _lake:
+ var score : int = _get_tile_score(i)
+
+ var atlas_coords : Vector2i = map_config.atlas_coords["WATER_MIDDLE"]
+ var rot : TileTransform = TileTransform.ROTATE_0
+
+ match score:
+ 1, 3, 129, 131:
+ atlas_coords = map_config.atlas_coords["WATER_END"]
+ rot = TileTransform.ROTATE_180
+ 4, 6, 12, 14:
+ atlas_coords = map_config.atlas_coords["WATER_END"]
+ rot = TileTransform.ROTATE_270
+ 16, 24, 48, 56:
+ atlas_coords = map_config.atlas_coords["WATER_END"]
+ 64, 96, 192, 224:
+ atlas_coords = map_config.atlas_coords["WATER_END"]
+ rot = TileTransform.ROTATE_90
+ 7, 135, 15, 143:
+ atlas_coords = map_config.atlas_coords["WATER_BEND_OUTER"]
+ rot = TileTransform.ROTATE_270
+ 28, 30, 60, 62:
+ atlas_coords = map_config.atlas_coords["WATER_BEND_OUTER"]
+ 112, 120, 240, 248:
+ atlas_coords = map_config.atlas_coords["WATER_BEND_OUTER"]
+ rot = TileTransform.ROTATE_90
+ 193, 195, 225, 227:
+ atlas_coords = map_config.atlas_coords["WATER_BEND_OUTER"]
+ rot = TileTransform.ROTATE_180
+ 199, 207, 231, 239:
+ atlas_coords = map_config.atlas_coords["WATER_SHORE"]
+ rot = TileTransform.ROTATE_270
+ 31, 63, 159, 191:
+ atlas_coords = map_config.atlas_coords["WATER_SHORE"]
+ 124, 126, 252, 254:
+ atlas_coords = map_config.atlas_coords["WATER_SHORE"]
+ rot = TileTransform.ROTATE_90
+ 241, 243, 249, 251:
+ atlas_coords = map_config.atlas_coords["WATER_SHORE"]
+ rot = TileTransform.ROTATE_180
+ 68, 100, 196:
+ atlas_coords = map_config.atlas_coords["WATER_STRAIGHT"]
+ rot = TileTransform.ROTATE_90
+ 17:
+ atlas_coords = map_config.atlas_coords["WATER_STRAIGHT"]
+
+ _display_tile(atlas_coords, rot, i)
+
+func _try_expand(tile : Vector2i):
+ if _is_expansion_valid(tile):
+ _visit_tile(tile)
+
+func _is_expansion_valid(tile : Vector2i) -> bool:
+ return !(_is_tile_oob(tile) || _lake.has(tile) || _path.has(tile))
+
+func _is_tile_oob(tile : Vector2i):
+ return tile.y < 0 || tile.y > map_config.grid_height - 1 || tile.x < 0 || tile.x > map_config.grid_width - 1
+
+func _visit_tile(tile: Vector2i):
+ _lake_queue.append(tile)
+ _lake.append(tile)
+
+func _pop_tile() -> Vector2i:
+ if _lake_queue.size() > 0:
+ return _lake_queue.pop_front()
+ return Vector2i(-1, -1)
+
+func _get_adjacent_tiles(tile: Vector2i) -> Array[Vector2i]:
+ var adj: Array[Vector2i] = []
+ var dirs: Array = [Vector2i(0, -1), Vector2i(0, 1), Vector2i(-1, 0), Vector2i(1, 0)]
+
+ for dir in dirs:
+ var n = tile + dir
+ adj.append(n)
+
+ return adj
+
+func _display_tile(coords : Vector2i, rot : TileTransform, pos : Vector2i):
+ _tile_map.set_cell(pos, 0, coords, rot)
+
+func _get_tile_score(tile : Vector2i) -> int:
+ var score : int = 0
+ var x : int = tile.x
+ var y : int = tile.y
+
+ score += 1 if _lake.has(Vector2i(x, y - 1)) else 0
+ score += 2 if _lake.has(Vector2i(x + 1, y - 1)) else 0
+ score += 4 if _lake.has(Vector2i(x + 1, y)) else 0
+ score += 8 if _lake.has(Vector2i(x + 1, y + 1)) else 0
+ score += 16 if _lake.has(Vector2i(x, y + 1)) else 0
+ score += 32 if _lake.has(Vector2i(x - 1, y + 1)) else 0
+ score += 64 if _lake.has(Vector2i(x - 1, y)) else 0
+ score += 128 if _lake.has(Vector2i(x - 1, y - 1)) else 0
+
+ return score