@@ -29,7 +29,9 @@ void TerrainGen::generate(GridMap *myGridMap, int height, int width, int depth,
29
29
vector<vector<vector<int >>> gridMap (
30
30
depth, vector<vector<int >>(width, vector<int >(height, 0 )));
31
31
32
+ vector<vector<float >> rawNoise (width, vector<float >(height, 0 ));
32
33
vector<vector<int >> elevationMap (width, vector<int >(height, 0 ));
34
+ vector<vector<TileType>> tileMap (width, vector<TileType>(height, GROUND));
33
35
34
36
int blockSize = 4 ;
35
37
int reducedX = floor (width / blockSize);
@@ -50,6 +52,7 @@ void TerrainGen::generate(GridMap *myGridMap, int height, int width, int depth,
50
52
for (int y = 0 ; y < height; y++) {
51
53
float currentNoise = noise->get_noise_2d ((float )x, (float )y);
52
54
55
+ rawNoise[x][y] = currentNoise;
53
56
// Normalize and scale noise to [0, depth]
54
57
float normalizedNoise = (currentNoise + 1 .0f ) / 2 .0f ;
55
58
elevationMap[x][y] = round (normalizedNoise * depth);
@@ -90,20 +93,50 @@ void TerrainGen::generate(GridMap *myGridMap, int height, int width, int depth,
90
93
}
91
94
}
92
95
}
96
+
97
+ // Smoothing
98
+ // Ensure elevation change's aren't in succession
99
+ // TODO...
100
+
101
+ // Water Clean Up
102
+ for (int x = 1 ; x < width - 1 ; x++) {
103
+ for (int y = 1 ; y < height - 1 ; y++) {
104
+ if (elevationMap[x][y] > 0 ) { // Check if it's an elevated tile
105
+ int waterCount = 0 ;
106
+
107
+ // Check surrounding 3x3 neighbors
108
+ for (int dx = -1 ; dx <= 1 ; dx++) {
109
+ for (int dy = -1 ; dy <= 1 ; dy++) {
110
+ if (elevationMap[x + dx][y + dy] == 0 ) {
111
+ waterCount++;
112
+ }
113
+ }
114
+ }
115
+
116
+ // If it's surrounded by water, set elevation to 0
117
+ if (waterCount >= 5 ) {
118
+ elevationMap[x][y] = 0 ;
119
+ }
120
+ }
121
+ }
122
+ }
123
+
93
124
/* ****************************************************
94
125
95
126
Tile Placement
96
127
97
128
*****************************************************/
98
129
99
- bool forceCliff = false ; // Track cliff sections
100
-
130
+ // Loop over all the grid cells
101
131
for (int x = 0 ; x < width; ++x) {
102
132
for (int y = 0 ; y < height; ++y) {
133
+ // Get the elevation for the current grid cell
103
134
int elevation = elevationMap[x][y];
104
135
105
- TileType tileType = GROUND;
136
+ // Init the current grid cell to ground
137
+ tileMap[x][y] = GROUND;
106
138
139
+ // Setup booleans & Ints
107
140
bool needsRamp = false , needsCliff = false , adjacentToWater = false ;
108
141
109
142
int rotationOrientation = 0 ;
@@ -113,88 +146,76 @@ void TerrainGen::generate(GridMap *myGridMap, int height, int width, int depth,
113
146
int waterEdgeNeighbors = 0 ;
114
147
int waterNeighbors[4 ] = { 0 , 0 , 0 , 0 };
115
148
149
+ // If Elevation is 0, we get water tiles
116
150
if (elevation == 0 ) {
117
151
myGridMap->set_cell_item (Vector3i (x, elevation, y), WATER, 0 );
118
152
continue ;
119
153
}
120
154
155
+ // Get the cardinal neighbors
121
156
int neighborElevations[4 ] = { elevation, elevation, elevation, elevation };
122
157
158
+ // Loop through and assign value to the cardinal neighbors
123
159
for (int d = 0 ; d < 4 ; ++d) {
124
160
int nx = x + dx[d];
125
161
int ny = y + dy[d];
126
162
127
163
if (nx >= 0 && ny >= 0 && nx < width && ny < height) {
128
- neighborElevations[d] = elevationMap[nx][ny];
129
- }
130
-
131
- if (nx >= 0 && ny >= 0 && nx < width && ny < height) {
164
+ // Get Neighbors Elevation
132
165
neighborElevations[d] = elevationMap[nx][ny];
133
166
if (neighborElevations[d] == 0 ) {
167
+ // If neighbor is water, store that info
134
168
adjacentToWater = true ;
135
169
waterNeighbors[d] = 1 ;
136
170
}
137
171
}
138
172
}
139
173
174
+ // Loop through the grid cells cardinal neighbors again
140
175
for (int d = 0 ; d < 4 ; ++d) {
176
+ // Find the Elevation diff between neighbors
141
177
int diff = neighborElevations[d] - elevation;
142
178
179
+ // If not 0, then there is a change
143
180
if (diff != 0 )
144
181
numDirectionChanges++;
145
182
183
+ // If an elevation diff of 1
146
184
if (diff == 1 || diff == -1 ) {
185
+ // We have elevation change
186
+
147
187
numElevationChanges++;
148
188
maxElevationChange = max (maxElevationChange, abs (diff));
149
189
150
190
float randomFactor = (float )rand () / RAND_MAX;
151
191
152
- if (forceCliff || randomFactor < 0.2 ) {
153
- tileType = CLIFF;
154
- forceCliff = true ;
192
+ // Set Cliffs or Ramps since Elevation has changed
193
+ if (rawNoise[x][y] < 0.4 ) {
194
+ tileMap[x][y] = CLIFF ;
155
195
} else {
156
- tileType = RAMP;
157
- forceCliff = false ;
196
+ tileMap[x][y] = RAMP;
158
197
}
159
198
}
160
199
}
161
200
201
+ // If grid cell is adjacent to water
162
202
if (adjacentToWater) {
203
+ // Get the cardinal neighbors
163
204
waterEdgeNeighbors = waterNeighbors[0 ] + waterNeighbors[1 ] + waterNeighbors[2 ] + waterNeighbors[3 ];
164
205
206
+ // Decide if it needs to be a water edge or a water corner
165
207
if (waterEdgeNeighbors == 1 ) {
166
- tileType = WATER_EDGE;
208
+ tileMap[x][y] = WATER_EDGE;
167
209
} else if (
168
210
(waterNeighbors[0 ] && waterNeighbors[1 ]) ||
169
211
(waterNeighbors[1 ] && waterNeighbors[2 ]) ||
170
212
(waterNeighbors[2 ] && waterNeighbors[3 ]) ||
171
213
(waterNeighbors[3 ] && waterNeighbors[0 ])) {
172
- tileType = WATER_CORNER; // Two adjacent water edges form a corner
214
+ tileMap[x][y] = WATER_CORNER; // Two adjacent water edges form a corner
173
215
}
174
216
}
175
217
176
- if (tileType == CLIFF && forceCliff) {
177
- forceCliff = true ;
178
- } else if (tileType == RAMP) {
179
- forceCliff = false ;
180
- }
181
-
182
- if (numElevationChanges >= 2 ) {
183
- if (tileType == RAMP)
184
- tileType = RAMP_CORNER;
185
- if (tileType == CLIFF)
186
- tileType = CLIFF_CORNER;
187
- }
188
-
189
- if (tileType == WATER) {
190
- if (numDirectionChanges == 1 ) {
191
- tileType = WATER_EDGE;
192
- } else if (numDirectionChanges >= 2 ) {
193
- tileType = WATER_CORNER;
194
- }
195
- }
196
-
197
- if (tileType == RAMP || tileType == CLIFF || tileType == RAMP_CORNER || tileType == CLIFF_CORNER) {
218
+ if (tileMap[x][y] == RAMP || tileMap[x][y] == CLIFF || tileMap[x][y] == RAMP_CORNER || tileMap[x][y] == CLIFF_CORNER) {
198
219
int highestNeighborIndex = -1 ;
199
220
int secondaryNeighborIndex = -1 ;
200
221
int highestNeighborElevation = elevation;
@@ -260,11 +281,36 @@ void TerrainGen::generate(GridMap *myGridMap, int height, int width, int depth,
260
281
261
282
*****************************************************/
262
283
263
- myGridMap->set_cell_item (Vector3i (x, elevation, y), tileType , rotationOrientation);
284
+ myGridMap->set_cell_item (Vector3i (x, elevation, y), tileMap[x][y] , rotationOrientation);
264
285
}
265
286
}
266
287
}
267
288
289
+ TerrainGen::TileType TerrainGen::isCornerTile (int x, int y, vector<vector<TileType>> &tileMap) {
290
+ if (x < 1 || y < 1 || x >= tileMap.size () - 1 || y >= tileMap[0 ].size () - 1 )
291
+ return GROUND; // Bounds check
292
+
293
+ TileType TL = tileMap[x - 1 ][y - 1 ];
294
+ TileType TR = tileMap[x + 1 ][y - 1 ];
295
+ TileType BL = tileMap[x - 1 ][y + 1 ];
296
+ TileType BR = tileMap[x + 1 ][y + 1 ];
297
+
298
+ // Check diagonal patterns for L-shapes
299
+ if ((TL == WATER && BR == WATER) || (TR == WATER && BL == WATER)) {
300
+ return WATER_CORNER; // Water Corner
301
+ }
302
+
303
+ if ((TL == CLIFF && BR == CLIFF) || (TR == CLIFF && BL == CLIFF)) {
304
+ return CLIFF_CORNER; // Cliff Corner
305
+ }
306
+
307
+ if ((TL == RAMP && BR == RAMP) || (TR == RAMP && BL == RAMP)) {
308
+ return RAMP_CORNER; // Ramp Corner
309
+ }
310
+
311
+ return GROUND;
312
+ }
313
+
268
314
void TerrainGen::_bind_methods () {
269
315
ClassDB::bind_method (D_METHOD (" generate" , " GridMap" , " height" , " width" , " depth" , " seed" , " noiseType" , " waterRemoval" , " noiseFreq" ), &TerrainGen::generate);
270
316
}
0 commit comments