@@ -29,7 +29,9 @@ void TerrainGen::generate(GridMap *myGridMap, int height, int width, int depth,
2929 vector<vector<vector<int >>> gridMap (
3030 depth, vector<vector<int >>(width, vector<int >(height, 0 )));
3131
32+ vector<vector<float >> rawNoise (width, vector<float >(height, 0 ));
3233 vector<vector<int >> elevationMap (width, vector<int >(height, 0 ));
34+ vector<vector<TileType>> tileMap (width, vector<TileType>(height, GROUND));
3335
3436 int blockSize = 4 ;
3537 int reducedX = floor (width / blockSize);
@@ -50,6 +52,7 @@ void TerrainGen::generate(GridMap *myGridMap, int height, int width, int depth,
5052 for (int y = 0 ; y < height; y++) {
5153 float currentNoise = noise->get_noise_2d ((float )x, (float )y);
5254
55+ rawNoise[x][y] = currentNoise;
5356 // Normalize and scale noise to [0, depth]
5457 float normalizedNoise = (currentNoise + 1 .0f ) / 2 .0f ;
5558 elevationMap[x][y] = round (normalizedNoise * depth);
@@ -90,20 +93,50 @@ void TerrainGen::generate(GridMap *myGridMap, int height, int width, int depth,
9093 }
9194 }
9295 }
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+
93124 /* ****************************************************
94125
95126 Tile Placement
96127
97128 *****************************************************/
98129
99- bool forceCliff = false ; // Track cliff sections
100-
130+ // Loop over all the grid cells
101131 for (int x = 0 ; x < width; ++x) {
102132 for (int y = 0 ; y < height; ++y) {
133+ // Get the elevation for the current grid cell
103134 int elevation = elevationMap[x][y];
104135
105- TileType tileType = GROUND;
136+ // Init the current grid cell to ground
137+ tileMap[x][y] = GROUND;
106138
139+ // Setup booleans & Ints
107140 bool needsRamp = false , needsCliff = false , adjacentToWater = false ;
108141
109142 int rotationOrientation = 0 ;
@@ -113,88 +146,76 @@ void TerrainGen::generate(GridMap *myGridMap, int height, int width, int depth,
113146 int waterEdgeNeighbors = 0 ;
114147 int waterNeighbors[4 ] = { 0 , 0 , 0 , 0 };
115148
149+ // If Elevation is 0, we get water tiles
116150 if (elevation == 0 ) {
117151 myGridMap->set_cell_item (Vector3i (x, elevation, y), WATER, 0 );
118152 continue ;
119153 }
120154
155+ // Get the cardinal neighbors
121156 int neighborElevations[4 ] = { elevation, elevation, elevation, elevation };
122157
158+ // Loop through and assign value to the cardinal neighbors
123159 for (int d = 0 ; d < 4 ; ++d) {
124160 int nx = x + dx[d];
125161 int ny = y + dy[d];
126162
127163 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
132165 neighborElevations[d] = elevationMap[nx][ny];
133166 if (neighborElevations[d] == 0 ) {
167+ // If neighbor is water, store that info
134168 adjacentToWater = true ;
135169 waterNeighbors[d] = 1 ;
136170 }
137171 }
138172 }
139173
174+ // Loop through the grid cells cardinal neighbors again
140175 for (int d = 0 ; d < 4 ; ++d) {
176+ // Find the Elevation diff between neighbors
141177 int diff = neighborElevations[d] - elevation;
142178
179+ // If not 0, then there is a change
143180 if (diff != 0 )
144181 numDirectionChanges++;
145182
183+ // If an elevation diff of 1
146184 if (diff == 1 || diff == -1 ) {
185+ // We have elevation change
186+
147187 numElevationChanges++;
148188 maxElevationChange = max (maxElevationChange, abs (diff));
149189
150190 float randomFactor = (float )rand () / RAND_MAX;
151191
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 ;
155195 } else {
156- tileType = RAMP;
157- forceCliff = false ;
196+ tileMap[x][y] = RAMP;
158197 }
159198 }
160199 }
161200
201+ // If grid cell is adjacent to water
162202 if (adjacentToWater) {
203+ // Get the cardinal neighbors
163204 waterEdgeNeighbors = waterNeighbors[0 ] + waterNeighbors[1 ] + waterNeighbors[2 ] + waterNeighbors[3 ];
164205
206+ // Decide if it needs to be a water edge or a water corner
165207 if (waterEdgeNeighbors == 1 ) {
166- tileType = WATER_EDGE;
208+ tileMap[x][y] = WATER_EDGE;
167209 } else if (
168210 (waterNeighbors[0 ] && waterNeighbors[1 ]) ||
169211 (waterNeighbors[1 ] && waterNeighbors[2 ]) ||
170212 (waterNeighbors[2 ] && waterNeighbors[3 ]) ||
171213 (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
173215 }
174216 }
175217
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) {
198219 int highestNeighborIndex = -1 ;
199220 int secondaryNeighborIndex = -1 ;
200221 int highestNeighborElevation = elevation;
@@ -260,11 +281,36 @@ void TerrainGen::generate(GridMap *myGridMap, int height, int width, int depth,
260281
261282 *****************************************************/
262283
263- myGridMap->set_cell_item (Vector3i (x, elevation, y), tileType , rotationOrientation);
284+ myGridMap->set_cell_item (Vector3i (x, elevation, y), tileMap[x][y] , rotationOrientation);
264285 }
265286 }
266287}
267288
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+
268314void TerrainGen::_bind_methods () {
269315 ClassDB::bind_method (D_METHOD (" generate" , " GridMap" , " height" , " width" , " depth" , " seed" , " noiseType" , " waterRemoval" , " noiseFreq" ), &TerrainGen::generate);
270316}
0 commit comments