1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
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)
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
|