1
1
/*
2
2
Minetest
3
- Copyright (C) 2015-2018 paramat
4
- Copyright (C) 2015-2018 kwolekr, Ryan Kwolek <kwolekr@minetest.net>
3
+ Copyright (C) 2015-2019 paramat
4
+ Copyright (C) 2015-2016 kwolekr, Ryan Kwolek
5
5
6
6
This program is free software; you can redistribute it and/or modify
7
7
it under the terms of the GNU Lesser General Public License as published by
@@ -41,7 +41,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
41
41
42
42
43
43
FlagDesc flagdesc_mapgen_fractal[] = {
44
- {NULL , 0 }
44
+ {" terrain" , MGFRACTAL_TERRAIN},
45
+ {NULL , 0 }
45
46
};
46
47
47
48
// /////////////////////////////////////////////////////////////////////////////////////
@@ -66,13 +67,17 @@ MapgenFractal::MapgenFractal(MapgenFractalParams *params, EmergeManager *emerge)
66
67
julia_z = params->julia_z ;
67
68
julia_w = params->julia_w ;
68
69
69
- // // 2D terrain noise
70
- noise_seabed = new Noise (¶ms->np_seabed , seed, csize.X , csize.Z );
70
+ // // 2D noise
71
+ if (spflags & MGFRACTAL_TERRAIN)
72
+ noise_seabed = new Noise (¶ms->np_seabed , seed, csize.X , csize.Z );
73
+
71
74
noise_filler_depth = new Noise (¶ms->np_filler_depth , seed, csize.X , csize.Z );
72
75
76
+ // // 3D noise
77
+ MapgenBasic::np_dungeons = params->np_dungeons ;
78
+ // Overgeneration to node_min.Y - 1
73
79
MapgenBasic::np_cave1 = params->np_cave1 ;
74
80
MapgenBasic::np_cave2 = params->np_cave2 ;
75
- MapgenBasic::np_dungeons = params->np_dungeons ;
76
81
77
82
formula = fractal / 2 + fractal % 2 ;
78
83
julia = fractal % 2 == 0 ;
@@ -81,7 +86,9 @@ MapgenFractal::MapgenFractal(MapgenFractalParams *params, EmergeManager *emerge)
81
86
82
87
MapgenFractal::~MapgenFractal ()
83
88
{
84
- delete noise_seabed;
89
+ if (noise_seabed)
90
+ delete noise_seabed;
91
+
85
92
delete noise_filler_depth;
86
93
}
87
94
@@ -153,21 +160,25 @@ void MapgenFractalParams::writeParams(Settings *settings) const
153
160
154
161
int MapgenFractal::getSpawnLevelAtPoint (v2s16 p)
155
162
{
156
- bool solid_below = false ; // Dry solid node is present below to spawn on
157
- u8 air_count = 0 ; // Consecutive air nodes above the dry solid node
158
- s16 seabed_level = NoisePerlin2D (&noise_seabed->np , p.X , p.Y , seed);
159
- // Seabed can rise above water_level or might be raised to create dry land
160
- s16 search_start = MYMAX (seabed_level, water_level + 1 );
161
- if (seabed_level > water_level)
162
- solid_below = true ;
163
-
164
- for (s16 y = search_start; y <= search_start + 128 ; y++) {
165
- if (getFractalAtPoint (p.X , y, p.Y )) { // Fractal node
163
+ bool solid_below = false ; // Fractal node is present below to spawn on
164
+ u8 air_count = 0 ; // Consecutive air nodes above a fractal node
165
+ s16 search_start = 0 ; // No terrain search start
166
+
167
+ // If terrain present, don't start search below terrain or water level
168
+ if (noise_seabed) {
169
+ s16 seabed_level = NoisePerlin2D (&noise_seabed->np , p.X , p.Y , seed);
170
+ search_start = MYMAX (search_start, MYMAX (seabed_level, water_level));
171
+ }
172
+
173
+ for (s16 y = search_start; y <= search_start + 4096 ; y++) {
174
+ if (getFractalAtPoint (p.X , y, p.Y )) {
175
+ // Fractal node
166
176
solid_below = true ;
167
177
air_count = 0 ;
168
- } else if (solid_below) { // Air above solid node
178
+ } else if (solid_below) {
179
+ // Air above fractal node
169
180
air_count++;
170
- // 3 to account for snowblock dust
181
+ // 3 and -2 to account for biome dust nodes
171
182
if (air_count == 3 )
172
183
return y - 2 ;
173
184
}
@@ -189,10 +200,11 @@ void MapgenFractal::makeChunk(BlockMakeData *data)
189
200
data->blockpos_requested .Y <= data->blockpos_max .Y &&
190
201
data->blockpos_requested .Z <= data->blockpos_max .Z );
191
202
203
+ // TimeTaker t("makeChunk");
204
+
192
205
this ->generating = true ;
193
- this ->vm = data->vmanip ;
206
+ this ->vm = data->vmanip ;
194
207
this ->ndef = data->nodedef ;
195
- // TimeTaker t("makeChunk");
196
208
197
209
v3s16 blockpos_min = data->blockpos_min ;
198
210
v3s16 blockpos_max = data->blockpos_max ;
@@ -203,7 +215,7 @@ void MapgenFractal::makeChunk(BlockMakeData *data)
203
215
204
216
blockseed = getBlockSeed2 (full_node_min, seed);
205
217
206
- // Generate base terrain, mountains, and ridges with initial heightmaps
218
+ // Generate fractal and optional terrain
207
219
s16 stone_surface_max_y = generateTerrain ();
208
220
209
221
// Create heightmap
@@ -215,16 +227,16 @@ void MapgenFractal::makeChunk(BlockMakeData *data)
215
227
generateBiomes ();
216
228
}
217
229
230
+ // Generate tunnels and randomwalk caves
218
231
if (flags & MG_CAVES) {
219
- // Generate tunnels
220
232
generateCavesNoiseIntersection (stone_surface_max_y);
221
- // Generate large randomwalk caves
222
233
generateCavesRandomWalk (stone_surface_max_y, large_cave_depth);
223
234
}
224
235
225
236
// Generate the registered ores
226
237
m_emerge->oremgr ->placeAllOres (this , blockseed, node_min, node_max);
227
238
239
+ // Generate dungeons
228
240
if ((flags & MG_DUNGEONS) && full_node_min.Y >= dungeon_ymin &&
229
241
full_node_max.Y <= dungeon_ymax)
230
242
generateDungeons (stone_surface_max_y);
@@ -237,18 +249,18 @@ void MapgenFractal::makeChunk(BlockMakeData *data)
237
249
if (flags & MG_BIOMES)
238
250
dustTopNodes ();
239
251
240
- // printf("makeChunk: %dms\n", t.stop());
241
-
242
- updateLiquid (&data->transforming_liquid , full_node_min, full_node_max);
252
+ // Update liquids
253
+ if (spflags & MGFRACTAL_TERRAIN)
254
+ updateLiquid (&data->transforming_liquid , full_node_min, full_node_max);
243
255
256
+ // Calculate lighting
244
257
if (flags & MG_LIGHT)
245
258
calcLighting (node_min - v3s16 (0 , 1 , 0 ), node_max + v3s16 (0 , 1 , 0 ),
246
259
full_node_min, full_node_max);
247
260
248
- // setLighting(node_min - v3s16(1, 0, 1) * MAP_BLOCKSIZE,
249
- // node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE, 0xFF);
250
-
251
261
this ->generating = false ;
262
+
263
+ // printf("makeChunk: %lums\n", t.stop());
252
264
}
253
265
254
266
@@ -391,24 +403,29 @@ s16 MapgenFractal::generateTerrain()
391
403
s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT;
392
404
u32 index2d = 0 ;
393
405
394
- noise_seabed->perlinMap2D (node_min.X , node_min.Z );
406
+ if (noise_seabed)
407
+ noise_seabed->perlinMap2D (node_min.X , node_min.Z );
395
408
396
409
for (s16 z = node_min.Z ; z <= node_max.Z ; z++) {
397
410
for (s16 y = node_min.Y - 1 ; y <= node_max.Y + 1 ; y++) {
398
411
u32 vi = vm->m_area .index (node_min.X , y, z);
399
412
for (s16 x = node_min.X ; x <= node_max.X ; x++, vi++, index2d++) {
400
- if (vm->m_data [vi].getContent () == CONTENT_IGNORE) {
401
- s16 seabed_height = noise_seabed->result [index2d];
402
-
403
- if (y <= seabed_height || getFractalAtPoint (x, y, z)) {
404
- vm->m_data [vi] = n_stone;
405
- if (y > stone_surface_max_y)
406
- stone_surface_max_y = y;
407
- } else if (y <= water_level) {
408
- vm->m_data [vi] = n_water;
409
- } else {
410
- vm->m_data [vi] = n_air;
411
- }
413
+ if (vm->m_data [vi].getContent () != CONTENT_IGNORE)
414
+ continue ;
415
+
416
+ s16 seabed_height;
417
+ if (noise_seabed)
418
+ seabed_height = noise_seabed->result [index2d];
419
+
420
+ if (((spflags & MGFRACTAL_TERRAIN) && y <= seabed_height) ||
421
+ getFractalAtPoint (x, y, z)) {
422
+ vm->m_data [vi] = n_stone;
423
+ if (y > stone_surface_max_y)
424
+ stone_surface_max_y = y;
425
+ } else if ((spflags & MGFRACTAL_TERRAIN) && y <= water_level) {
426
+ vm->m_data [vi] = n_water;
427
+ } else {
428
+ vm->m_data [vi] = n_air;
412
429
}
413
430
}
414
431
index2d -= ystride;
0 commit comments