Correct overflowing rivers in Valleys mapgen.
[oweals/minetest.git] / src / mapgen_valleys.cpp
1 /*
2 Minetest Valleys C
3 Copyright (C) 2010-2015 kwolekr, Ryan Kwolek <kwolekr@minetest.net>
4 Copyright (C) 2010-2015 paramat, Matt Gregory
5 Copyright (C) 2016 Duane Robertson <duane@duanerobertson.com>
6
7 Based on Valleys Mapgen by Gael de Sailly
8  (https://forum.minetest.net/viewtopic.php?f=9&t=11430)
9 and mapgen_v7 by kwolekr and paramat.
10
11 Licensing changed by permission of Gael de Sailly.
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU Lesser General Public License as published by
15 the Free Software Foundation; either version 2.1 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 GNU Lesser General Public License for more details.
22
23 You should have received a copy of the GNU Lesser General Public License along
24 with this program; if not, write to the Free Software Foundation, Inc.,
25 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 */
27
28
29 #include "mapgen.h"
30 #include "voxel.h"
31 #include "noise.h"
32 #include "mapblock.h"
33 #include "mapnode.h"
34 #include "map.h"
35 #include "content_sao.h"
36 #include "nodedef.h"
37 #include "voxelalgorithms.h"
38 #include "settings.h" // For g_settings
39 #include "emerge.h"
40 #include "dungeongen.h"
41 #include "treegen.h"
42 #include "mg_biome.h"
43 #include "mg_ore.h"
44 #include "mg_decoration.h"
45 #include "mapgen_valleys.h"
46
47 //#undef NDEBUG
48 //#include "assert.h"
49
50 //#include "util/timetaker.h"
51 //#include "profiler.h"
52
53
54 //static Profiler mapgen_prof;
55 //Profiler *mapgen_profiler = &mapgen_prof;
56
57 static FlagDesc flagdesc_mapgen_valleys[] = {
58         {"altitude_chill",  MG_VALLEYS_ALT_CHILL},
59         {"cliffs",          MG_VALLEYS_CLIFFS},
60         {"fast",            MG_VALLEYS_FAST},
61         {"humid_rivers",    MG_VALLEYS_HUMID_RIVERS},
62         {"rugged",          MG_VALLEYS_RUGGED},
63         {NULL,              0}
64 };
65
66 ///////////////////////////////////////////////////////////////////////////////
67
68
69 MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager *emerge)
70         : Mapgen(mapgenid, params, emerge)
71 {
72         this->m_emerge = emerge;
73         this->bmgr = emerge->biomemgr;
74
75         //// amount of elements to skip for the next index
76         //// for noise/height/biome maps (not vmanip)
77         this->ystride = csize.X;
78         this->zstride = csize.X * (csize.Y + 2);
79
80         this->biomemap  = new u8[csize.X * csize.Z];
81         this->heightmap = new s16[csize.X * csize.Z];
82         this->heatmap   = NULL;
83         this->humidmap  = NULL;
84
85         MapgenValleysParams *sp = (MapgenValleysParams *)params->sparams;
86         this->spflags = sp->spflags;
87
88         this->cliff_terrain      = (spflags & MG_VALLEYS_CLIFFS);
89         this->fast_terrain       = (spflags & MG_VALLEYS_FAST);
90         this->humid_rivers       = (spflags & MG_VALLEYS_HUMID_RIVERS);
91         this->rugged_terrain     = (spflags & MG_VALLEYS_RUGGED);
92         this->use_altitude_chill = (spflags & MG_VALLEYS_ALT_CHILL);
93
94         this->altitude_chill        = sp->altitude_chill;
95         this->cave_water_max_height = sp->cave_water_max_height;
96         this->humidity_adjust       = sp->humidity - 50.f;
97         this->humidity_break_point  = sp->humidity_break_point;
98         this->lava_max_height       = sp->lava_max_height;
99         this->river_depth           = sp->river_depth + 1.f;
100         this->river_size            = sp->river_size / 100.f;
101         this->temperature_adjust    = sp->temperature - 50.f;
102         this->water_features        = MYMAX(1, MYMIN(11, 11 - sp->water_features));
103
104         //// 2D Terrain noise
105         noise_cliffs             = new Noise(&sp->np_cliffs,             seed, csize.X, csize.Z);
106         noise_corr               = new Noise(&sp->np_corr,               seed, csize.X, csize.Z);
107         noise_filler_depth       = new Noise(&sp->np_filler_depth,       seed, csize.X, csize.Z);
108         noise_inter_valley_slope = new Noise(&sp->np_inter_valley_slope, seed, csize.X, csize.Z);
109         noise_rivers             = new Noise(&sp->np_rivers,             seed, csize.X, csize.Z);
110         noise_terrain_height     = new Noise(&sp->np_terrain_height,     seed, csize.X, csize.Z);
111         noise_valley_depth       = new Noise(&sp->np_valley_depth,       seed, csize.X, csize.Z);
112         noise_valley_profile     = new Noise(&sp->np_valley_profile,     seed, csize.X, csize.Z);
113
114         if (this->fast_terrain)
115                 noise_inter_valley_fill = new Noise(&sp->np_inter_valley_fill, seed, csize.X, csize.Z);
116
117         //// 3D Terrain noise
118         noise_simple_caves_1 = new Noise(&sp->np_simple_caves_1, seed, csize.X, csize.Y + 2, csize.Z);
119         noise_simple_caves_2 = new Noise(&sp->np_simple_caves_2, seed, csize.X, csize.Y + 2, csize.Z);
120
121         if (!this->fast_terrain)
122                 noise_inter_valley_fill = new Noise(&sp->np_inter_valley_fill, seed, csize.X, csize.Y + 2, csize.Z);
123
124         //// Biome noise
125         noise_heat_blend     = new Noise(&params->np_biome_heat_blend,     seed, csize.X, csize.Z);
126         noise_heat           = new Noise(&params->np_biome_heat,           seed, csize.X, csize.Z);
127         noise_humidity_blend = new Noise(&params->np_biome_humidity_blend, seed, csize.X, csize.Z);
128         noise_humidity       = new Noise(&params->np_biome_humidity,       seed, csize.X, csize.Z);
129
130         //// Resolve nodes to be used
131         INodeDefManager *ndef = emerge->ndef;
132
133         c_cobble               = ndef->getId("mapgen_cobble");
134         c_desert_stone         = ndef->getId("mapgen_desert_stone");
135         c_dirt                 = ndef->getId("mapgen_dirt");
136         c_lava_source          = ndef->getId("mapgen_lava_source");
137         c_mossycobble          = ndef->getId("mapgen_mossycobble");
138         c_river_water_source   = ndef->getId("mapgen_river_water_source");
139         c_sand                 = ndef->getId("mapgen_sand");
140         c_sandstonebrick       = ndef->getId("mapgen_sandstonebrick");
141         c_sandstone            = ndef->getId("mapgen_sandstone");
142         c_stair_cobble         = ndef->getId("mapgen_stair_cobble");
143         c_stair_sandstonebrick = ndef->getId("mapgen_stair_sandstonebrick");
144         c_stone                = ndef->getId("mapgen_stone");
145         c_water_source         = ndef->getId("mapgen_water_source");
146
147         if (c_mossycobble == CONTENT_IGNORE)
148                 c_mossycobble = c_cobble;
149         if (c_river_water_source == CONTENT_IGNORE)
150                 c_river_water_source = c_water_source;
151         if (c_sand == CONTENT_IGNORE)
152                 c_sand = c_stone;
153         if (c_sandstonebrick == CONTENT_IGNORE)
154                 c_sandstonebrick = c_sandstone;
155         if (c_stair_cobble == CONTENT_IGNORE)
156                 c_stair_cobble = c_cobble;
157         if (c_stair_sandstonebrick == CONTENT_IGNORE)
158                 c_stair_sandstonebrick = c_sandstone;
159 }
160
161
162 MapgenValleys::~MapgenValleys()
163 {
164         delete noise_cliffs;
165         delete noise_corr;
166         delete noise_filler_depth;
167         delete noise_heat;
168         delete noise_heat_blend;
169         delete noise_humidity;
170         delete noise_humidity_blend;
171         delete noise_inter_valley_fill;
172         delete noise_inter_valley_slope;
173         delete noise_rivers;
174         delete noise_simple_caves_1;
175         delete noise_simple_caves_2;
176         delete noise_terrain_height;
177         delete noise_valley_depth;
178         delete noise_valley_profile;
179
180         delete[] heightmap;
181         delete[] biomemap;
182 }
183
184
185 MapgenValleysParams::MapgenValleysParams()
186 {
187         spflags = MG_VALLEYS_CLIFFS | MG_VALLEYS_RUGGED
188                 | MG_VALLEYS_HUMID_RIVERS | MG_VALLEYS_ALT_CHILL;
189
190         altitude_chill         = 90; // The altitude at which temperature drops by 20C.
191         // Water in caves will never be higher than this.
192         cave_water_max_height  = MAX_MAP_GENERATION_LIMIT;
193         humidity               = 50;
194         // the maximum humidity around rivers in otherwise dry areas
195         humidity_break_point   = 65;
196         lava_max_height        = 0;  // Lava will never be higher than this.
197         river_depth            = 4;  // How deep to carve river channels.
198         river_size             = 5;  // How wide to make rivers.
199         temperature            = 50;
200         water_features         = 3;  // How often water will occur in caves.
201
202         np_cliffs             = NoiseParams(0.f,   1.f,  v3f(750,  750,  750),  8445,  5, 1.f,  2.f);
203         np_corr               = NoiseParams(0.f,   1.f,  v3f(40,   40,   40),   -3536, 4, 1.f,  2.f);
204         np_filler_depth       = NoiseParams(0.f,   1.2f, v3f(256,  256,  256),  1605,  3, 0.5f, 2.f);
205         np_inter_valley_fill  = NoiseParams(0.f,   1.f,  v3f(256,  512,  256),  1993,  6, 0.8f, 2.f);
206         np_inter_valley_slope = NoiseParams(0.5f,  0.5f, v3f(128,  128,  128),  746,   1, 1.f,  2.f);
207         np_rivers             = NoiseParams(0.f,   1.f,  v3f(256,  256,  256),  -6050, 5, 0.6f, 2.f);
208         np_simple_caves_1     = NoiseParams(0.f,   1.f,  v3f(64,   64,   64),   -8402, 3, 0.5f, 2.f);
209         np_simple_caves_2     = NoiseParams(0.f,   1.f,  v3f(64,   64,   64),   3944,  3, 0.5f, 2.f);
210         np_terrain_height     = NoiseParams(-10.f, 50.f, v3f(1024, 1024, 1024), 5202,  6, 0.4f, 2.f);
211         np_valley_depth       = NoiseParams(5.f,   4.f,  v3f(512,  512,  512),  -1914, 1, 1.f,  2.f);
212         np_valley_profile     = NoiseParams(0.6f,  0.5f, v3f(512,  512,  512),  777,   1, 1.f,  2.f);
213         }
214
215
216 void MapgenValleysParams::readParams(const Settings *settings)
217 {
218         settings->getFlagStrNoEx("mg_valleys_spflags", spflags, flagdesc_mapgen_valleys);
219
220         settings->getU16NoEx("mg_valleys_altitude_chill",        altitude_chill);
221         settings->getS16NoEx("mg_valleys_cave_water_max_height", cave_water_max_height);
222         settings->getS16NoEx("mg_valleys_humidity",              humidity);
223         settings->getS16NoEx("mg_valleys_humidity_break_point",  humidity_break_point);
224         settings->getS16NoEx("mg_valleys_lava_max_height",       lava_max_height);
225         settings->getU16NoEx("mg_valleys_river_depth",           river_depth);
226         settings->getU16NoEx("mg_valleys_river_size",            river_size);
227         settings->getS16NoEx("mg_valleys_temperature",           temperature);
228         settings->getU16NoEx("mg_valleys_water_features",        water_features);
229
230         settings->getNoiseParams("mg_valleys_np_cliffs",             np_cliffs);
231         settings->getNoiseParams("mg_valleys_np_corr",               np_corr);
232         settings->getNoiseParams("mg_valleys_np_filler_depth",       np_filler_depth);
233         settings->getNoiseParams("mg_valleys_np_inter_valley_fill",  np_inter_valley_fill);
234         settings->getNoiseParams("mg_valleys_np_inter_valley_slope", np_inter_valley_slope);
235         settings->getNoiseParams("mg_valleys_np_rivers",             np_rivers);
236         settings->getNoiseParams("mg_valleys_np_simple_caves_1",     np_simple_caves_1);
237         settings->getNoiseParams("mg_valleys_np_simple_caves_2",     np_simple_caves_2);
238         settings->getNoiseParams("mg_valleys_np_terrain_height",     np_terrain_height);
239         settings->getNoiseParams("mg_valleys_np_valley_depth",       np_valley_depth);
240         settings->getNoiseParams("mg_valleys_np_valley_profile",     np_valley_profile);
241 }
242
243
244 void MapgenValleysParams::writeParams(Settings *settings) const
245 {
246         settings->setFlagStr("mg_valleys_spflags", spflags, flagdesc_mapgen_valleys, U32_MAX);
247
248         settings->setU16("mg_valleys_altitude_chill",        altitude_chill);
249         settings->setS16("mg_valleys_cave_water_max_height", cave_water_max_height);
250         settings->setS16("mg_valleys_humidity",              humidity);
251         settings->setS16("mg_valleys_humidity_break_point",  humidity_break_point);
252         settings->setS16("mg_valleys_lava_max_height",       lava_max_height);
253         settings->setU16("mg_valleys_river_depth",           river_depth);
254         settings->setU16("mg_valleys_river_size",            river_size);
255         settings->setS16("mg_valleys_temperature",           temperature);
256         settings->setU16("mg_valleys_water_features",        water_features);
257
258         settings->setNoiseParams("mg_valleys_np_cliffs",             np_cliffs);
259         settings->setNoiseParams("mg_valleys_np_corr",               np_corr);
260         settings->setNoiseParams("mg_valleys_np_filler_depth",       np_filler_depth);
261         settings->setNoiseParams("mg_valleys_np_inter_valley_fill",  np_inter_valley_fill);
262         settings->setNoiseParams("mg_valleys_np_inter_valley_slope", np_inter_valley_slope);
263         settings->setNoiseParams("mg_valleys_np_rivers",             np_rivers);
264         settings->setNoiseParams("mg_valleys_np_simple_caves_1",     np_simple_caves_1);
265         settings->setNoiseParams("mg_valleys_np_simple_caves_2",     np_simple_caves_2);
266         settings->setNoiseParams("mg_valleys_np_terrain_height",     np_terrain_height);
267         settings->setNoiseParams("mg_valleys_np_valley_depth",       np_valley_depth);
268         settings->setNoiseParams("mg_valleys_np_valley_profile",     np_valley_profile);
269 }
270
271
272 ///////////////////////////////////////
273
274
275 void MapgenValleys::makeChunk(BlockMakeData *data)
276 {
277         // Pre-conditions
278         assert(data->vmanip);
279         assert(data->nodedef);
280         assert(data->blockpos_requested.X >= data->blockpos_min.X &&
281                 data->blockpos_requested.Y >= data->blockpos_min.Y &&
282                 data->blockpos_requested.Z >= data->blockpos_min.Z);
283         assert(data->blockpos_requested.X <= data->blockpos_max.X &&
284                 data->blockpos_requested.Y <= data->blockpos_max.Y &&
285                 data->blockpos_requested.Z <= data->blockpos_max.Z);
286
287         this->generating = true;
288         this->vm = data->vmanip;
289         this->ndef = data->nodedef;
290
291         //TimeTaker t("makeChunk");
292
293         v3s16 blockpos_min = data->blockpos_min;
294         v3s16 blockpos_max = data->blockpos_max;
295         node_min = blockpos_min * MAP_BLOCKSIZE;
296         node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
297         full_node_min = (blockpos_min - 1) * MAP_BLOCKSIZE;
298         full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
299
300         blockseed = getBlockSeed2(full_node_min, seed);
301
302         // Generate noise maps and base terrain height.
303         calculateNoise();
304
305         // Generate base terrain with initial heightmaps
306         s16 stone_surface_max_y = generateTerrain();
307
308         // Create biomemap at heightmap surface
309         bmgr->calcBiomes(csize.X, csize.Z, heatmap, humidmap, heightmap, biomemap);
310
311         // Actually place the biome-specific nodes
312         MgStoneType stone_type = generateBiomes(heatmap, humidmap);
313
314         // Cave creation.
315         if (flags & MG_CAVES)
316                 generateSimpleCaves(stone_surface_max_y);
317
318         // Dungeon creation
319         if ((flags & MG_DUNGEONS) && node_max.Y < 50 && (stone_surface_max_y >= node_min.Y)) {
320                 DungeonParams dp;
321
322                 dp.np_rarity  = nparams_dungeon_rarity;
323                 dp.np_density = nparams_dungeon_density;
324                 dp.np_wetness = nparams_dungeon_wetness;
325                 dp.c_water    = c_water_source;
326                 if (stone_type == STONE) {
327                         dp.c_cobble = c_cobble;
328                         dp.c_moss   = c_mossycobble;
329                         dp.c_stair  = c_stair_cobble;
330
331                         dp.diagonal_dirs = false;
332                         dp.mossratio     = 3.f;
333                         dp.holesize      = v3s16(1, 2, 1);
334                         dp.roomsize      = v3s16(0, 0, 0);
335                         dp.notifytype    = GENNOTIFY_DUNGEON;
336                 } else if (stone_type == DESERT_STONE) {
337                         dp.c_cobble = c_desert_stone;
338                         dp.c_moss   = c_desert_stone;
339                         dp.c_stair  = c_desert_stone;
340
341                         dp.diagonal_dirs = true;
342                         dp.mossratio     = 0.f;
343                         dp.holesize      = v3s16(2, 3, 2);
344                         dp.roomsize      = v3s16(2, 5, 2);
345                         dp.notifytype    = GENNOTIFY_TEMPLE;
346                 } else if (stone_type == SANDSTONE) {
347                         dp.c_cobble = c_sandstonebrick;
348                         dp.c_moss   = c_sandstonebrick;
349                         dp.c_stair  = c_sandstonebrick;
350
351                         dp.diagonal_dirs = false;
352                         dp.mossratio     = 0.f;
353                         dp.holesize      = v3s16(2, 2, 2);
354                         dp.roomsize      = v3s16(2, 0, 2);
355                         dp.notifytype    = GENNOTIFY_DUNGEON;
356                 }
357
358                 DungeonGen dgen(this, &dp);
359                 dgen.generate(blockseed, full_node_min, full_node_max);
360         }
361
362         // Generate the registered decorations
363         if (flags & MG_DECORATIONS)
364                 m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
365
366         // Generate the registered ores
367         m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max);
368
369         // Sprinkle some dust on top after everything else was generated
370         dustTopNodes();
371
372         //TimeTaker tll("liquid_lighting");
373
374         updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
375
376         if (flags & MG_LIGHT)
377                 calcLighting(
378                                 node_min - v3s16(0, 1, 0),
379                                 node_max + v3s16(0, 1, 0),
380                                 full_node_min,
381                                 full_node_max);
382
383         //mapgen_profiler->avg("liquid_lighting", tll.stop() / 1000.f);
384         //mapgen_profiler->avg("makeChunk", t.stop() / 1000.f);
385
386         this->generating = false;
387 }
388
389
390 // Populate the noise tables and do most of the
391 // calculation necessary to determine terrain height.
392 void MapgenValleys::calculateNoise()
393 {
394         //TimeTaker t("calculateNoise", NULL, PRECISION_MICRO);
395
396         int x = node_min.X;
397         int y = node_min.Y - 1;
398         int z = node_min.Z;
399
400         //TimeTaker tcn("actualNoise");
401
402         noise_filler_depth->perlinMap2D(x, z);
403         noise_heat_blend->perlinMap2D(x, z);
404         noise_heat->perlinMap2D(x, z);
405         noise_humidity_blend->perlinMap2D(x, z);
406         noise_humidity->perlinMap2D(x, z);
407         noise_inter_valley_slope->perlinMap2D(x, z);
408         noise_rivers->perlinMap2D(x, z);
409         noise_terrain_height->perlinMap2D(x, z);
410         noise_valley_depth->perlinMap2D(x, z);
411         noise_valley_profile->perlinMap2D(x, z);
412
413         if (fast_terrain) {
414                 // Make this 2D for speed, if requested.
415                 noise_inter_valley_fill->perlinMap2D(x, z);
416
417                 if (cliff_terrain)
418                         noise_cliffs->perlinMap2D(x, z);
419                 if (rugged_terrain)
420                         noise_corr->perlinMap2D(x, z);
421         } else {
422                 noise_inter_valley_fill->perlinMap3D(x, y, z);
423         }
424
425         if (flags & MG_CAVES) {
426                 noise_simple_caves_1->perlinMap3D(x, y, z);
427                 noise_simple_caves_2->perlinMap3D(x, y, z);
428         }
429
430         //mapgen_profiler->avg("noisemaps", tcn.stop() / 1000.f);
431
432         for (s32 index = 0; index < csize.X * csize.Z; index++) {
433                 noise_heat->result[index] += noise_heat_blend->result[index];
434                 noise_heat->result[index] += temperature_adjust;
435                 noise_humidity->result[index] += noise_humidity_blend->result[index];
436         }
437
438         TerrainNoise tn;
439
440         u32 index = 0;
441         for (tn.z = node_min.Z; tn.z <= node_max.Z; tn.z++)
442         for (tn.x = node_min.X; tn.x <= node_max.X; tn.x++, index++) {
443                 // The parameters that we actually need to generate terrain
444                 //  are passed by address (and the return value).
445                 tn.terrain_height = noise_terrain_height->result[index];
446                 // River noise is replaced with base terrain, which
447                 // is basically the height of the water table.
448                 tn.rivers = &noise_rivers->result[index];
449                 // Valley depth noise is replaced with the valley
450                 // number that represents the height of terrain
451                 // over rivers and is used to determine about
452                 // how close a river is for humidity calculation.
453                 tn.valley = &noise_valley_depth->result[index];
454                 tn.valley_profile = noise_valley_profile->result[index];
455                 // Slope noise is replaced by the calculated slope
456                 // which is used to get terrain height in the slow
457                 // method, to create sharper mountains.
458                 tn.slope = &noise_inter_valley_slope->result[index];
459                 tn.inter_valley_fill = noise_inter_valley_fill->result[index];
460                 tn.cliffs = noise_cliffs->result[index];
461                 tn.corr = noise_corr->result[index];
462
463                 // This is the actual terrain height.
464                 float mount = terrainLevelFromNoise(&tn);
465                 noise_terrain_height->result[index] = mount;
466
467                 if (fast_terrain) {
468                         // Assign humidity adjusted by water proximity.
469                         // I can't think of a reason why a mod would expect base humidity
470                         //  from noise or at any altitude other than ground level.
471                         noise_humidity->result[index] = humidityByTerrain(
472                                         noise_humidity->result[index],
473                                         mount,
474                                         noise_rivers->result[index],
475                                         noise_valley_depth->result[index]);
476
477                         // Assign heat adjusted by altitude. See humidity, above.
478                         if (use_altitude_chill && mount > 0.f)
479                                 noise_heat->result[index] *= pow(0.5f, (mount - altitude_chill / 3.f) / altitude_chill);
480                 }
481         }
482
483         heatmap = noise_heat->result;
484         humidmap = noise_humidity->result;
485 }
486
487
488 // This keeps us from having to maintain two similar sets of
489 //  complicated code to determine ground level.
490 float MapgenValleys::terrainLevelFromNoise(TerrainNoise *tn)
491 {
492         float inter_valley_slope = *tn->slope;
493
494         // The square function changes the behaviour of this noise:
495         //  very often small, and sometimes very high.
496         float valley_d = pow(*tn->valley, 2);
497
498         // valley_d is here because terrain is generally higher where valleys
499         //  are deep (mountains). base represents the height of the
500         //  rivers, most of the surface is above.
501         float base = tn->terrain_height + valley_d;
502
503         // "river" represents the distance from the river, in arbitrary units.
504         float river = fabs(*tn->rivers) - river_size;
505
506         // Use the curve of the function 1−exp(−(x/a)²) to model valleys.
507         //  Making "a" vary (0 < a â‰¤ 1) changes the shape of the valleys.
508         //  Try it with a geometry software !
509         //   (here x = "river" and a = valley_profile).
510         //  "valley" represents the height of the terrain, from the rivers.
511         *tn->valley = valley_d * (1.f - exp(- pow(river / tn->valley_profile, 2)));
512
513         // approximate height of the terrain at this point
514         float mount = base + *tn->valley;
515
516         *tn->slope *= *tn->valley;
517
518         // Rivers are placed where "river" is negative, so where the original
519         //  noise value is close to zero.
520         // Base ground is returned as rivers since it's basically the water table.
521         *tn->rivers = base;
522         if (river < 0.f) {
523                 // Use the the function âˆ’sqrt(1−x²) which models a circle.
524                 float depth = (river_depth * sqrt(1.f - pow((river / river_size + 1), 2)));
525
526                 // base - depth : height of the bottom of the river
527                 // water_level - 2 : don't make rivers below 2 nodes under the surface
528                 u16 min_bottom = 2;
529                 if (!fast_terrain)
530                         min_bottom = 6;
531                 mount = fmin(fmax(base - depth, (float) (water_level - min_bottom)), mount);
532
533                 // Slope has no influence on rivers.
534                 *tn->slope = 0.f;
535         }
536
537         if (fast_terrain) {
538                 // The penultimate step builds up the heights, but we reduce it
539                 //  occasionally to create cliffs.
540                 float delta = sin(tn->inter_valley_fill) * *tn->slope;
541                 if (cliff_terrain && tn->cliffs >= 0.2f)
542                         mount += delta * 0.66f;
543                 else
544                         mount += delta;
545
546                 // Use yet another noise to make the heights look more rugged.
547                 if (rugged_terrain
548                                 && mount > water_level
549                                 && fabs(inter_valley_slope * tn->inter_valley_fill) < 0.3f)
550                         mount += ((delta < 0.f) ? -1.f : 1.f) * pow(fabs(delta), 0.5f) * fabs(sin(tn->corr));
551         }
552
553         return mount;
554 }
555
556
557 // This avoids duplicating the code in terrainLevelFromNoise, adding
558 // only the final step of terrain generation without a noise map.
559 float MapgenValleys::adjustedTerrainLevelFromNoise(TerrainNoise *tn)
560 {
561         float mount = terrainLevelFromNoise(tn);
562
563         if (!fast_terrain) {
564                 for (s16 y = round(mount); y <= round(mount) + 1000; y++) {
565                         float fill = NoisePerlin3D(&noise_inter_valley_fill->np, tn->x, y, tn->z, seed);
566
567                         if (fill * *tn->slope <= y - mount) {
568                                 mount = fmax(y - 1, mount);
569                                 break;
570                         }
571                 }
572         }
573
574         return mount;
575 }
576
577
578 float MapgenValleys::humidityByTerrain(
579                 float humidity_base,
580                 float mount,
581                 float rivers,
582                 float valley)
583 {
584         // Although the original valleys adjusts humidity by distance
585         // from seawater, this causes problems with the default biomes.
586         // Adjust only by freshwater proximity.
587         float humidity = humidity_base + humidity_adjust;
588
589         if (humid_rivers && mount > water_level) {
590                 // Offset to make everything average the same.
591                 humidity -= (humidity_break_point - humidity_adjust) / 3.f;
592
593                 // This method is from the original lua.
594                 float water_table = pow(0.5f, fmax(rivers / 3.f, 0.f));
595                 // This adds humidity next to rivers and lakes.
596                 float river_water = pow(0.5f, fmax(valley / 12.f, 0.f));
597                 // Combine the two.
598                 float water = water_table + (1.f - water_table) * river_water;
599                 humidity = fmax(humidity, (humidity_break_point * water));
600         }
601
602         return humidity;
603 }
604
605
606 int MapgenValleys::getGroundLevelAtPoint(v2s16 p)
607 {
608         // ***********************************************
609         // This method (deliberately) does not return correct 
610         // terrain values. This may be a problem in the future.
611         // ***********************************************
612
613         // Since MT doesn't normally deal with rivers, check
614         // to make sure this isn't a request for a location
615         // in a river.
616         float rivers = NoisePerlin2D(&noise_rivers->np, p.X, p.Y, seed);
617
618         // If it's wet, return an unusable number.
619         if (fabs(rivers) < river_size)
620                 return MAX_MAP_GENERATION_LIMIT;
621
622         // Otherwise, return the real result.
623         return terrainLevelAtPoint(p.X, p.Y);
624 }
625
626
627 float MapgenValleys::terrainLevelAtPoint(s16 x, s16 z)
628 {
629         TerrainNoise tn;
630
631         float rivers = NoisePerlin2D(&noise_rivers->np, x, z, seed);
632         float valley = NoisePerlin2D(&noise_valley_depth->np, x, z, seed);
633         float inter_valley_slope = NoisePerlin2D(&noise_inter_valley_slope->np, x, z, seed);
634
635         tn.x = x;
636         tn.z = z;
637         tn.terrain_height = NoisePerlin2D(&noise_terrain_height->np, x, z, seed);
638         tn.rivers = &rivers;
639         tn.valley = &valley;
640         tn.valley_profile = NoisePerlin2D(&noise_valley_profile->np, x, z, seed);
641         tn.slope = &inter_valley_slope;
642         tn.inter_valley_fill = 0.f;
643         tn.cliffs = 0.f;
644         tn.corr = 0.f;
645
646         if (fast_terrain) {
647                 tn.inter_valley_fill = NoisePerlin2D(&noise_inter_valley_fill->np, x, z, seed);
648
649                 if (cliff_terrain)
650                         tn.cliffs = NoisePerlin2D(&noise_cliffs->np, x, z, seed);
651                 if (rugged_terrain)
652                         tn.corr = NoisePerlin2D(&noise_corr->np, x, z, seed);
653         }
654
655         return adjustedTerrainLevelFromNoise(&tn);
656 }
657
658
659 int MapgenValleys::generateTerrain()
660 {
661         MapNode n_air(CONTENT_AIR);
662         MapNode n_river_water(c_river_water_source);
663         MapNode n_sand(c_sand);
664         MapNode n_stone(c_stone);
665         MapNode n_water(c_water_source);
666
667         v3s16 em = vm->m_area.getExtent();
668         s16 surface_max_y = -MAX_MAP_GENERATION_LIMIT;
669         u32 index_2d = 0;
670
671         for (s16 z = node_min.Z; z <= node_max.Z; z++)
672         for (s16 x = node_min.X; x <= node_max.X; x++, index_2d++) {
673                 s16 river_y = floor(noise_rivers->result[index_2d]);
674                 s16 surface_y = floor(noise_terrain_height->result[index_2d]);
675                 float slope = noise_inter_valley_slope->result[index_2d];
676
677                 heightmap[index_2d] = surface_y;
678
679                 if (surface_y > surface_max_y)
680                         surface_max_y = surface_y;
681
682                 u32 index_3d = 0;
683                 if (!fast_terrain)
684                         index_3d = (z - node_min.Z) * zstride + (x - node_min.X);
685
686                 u32 index_data = vm->m_area.index(x, node_min.Y - 1, z);
687
688                 // Mapgens concern themselves with stone and water.
689                 for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) {
690                         float fill = 0.f;
691                         if (!fast_terrain)
692                                 fill = noise_inter_valley_fill->result[index_3d];
693
694                         if (vm->m_data[index_data].getContent() == CONTENT_IGNORE) {
695                                 bool river = (river_y > surface_y);
696
697                                 if (river && y == surface_y) {
698                                         // river bottom
699                                         vm->m_data[index_data] = n_sand;
700                                 } else if ((fast_terrain || river) && y <= surface_y) {
701                                         // ground
702                                         vm->m_data[index_data] = n_stone;
703                                 } else if (river && y < river_y) {
704                                         // river
705                                         vm->m_data[index_data] = n_river_water;
706                                 } else if ((!fast_terrain) && (!river) && round(fill * slope) >= y - surface_y) {
707                                         // ground (slow method)
708                                         vm->m_data[index_data] = n_stone;
709                                         heightmap[index_2d] = surface_max_y = y;
710                                 } else if (y <= water_level) {
711                                         // sea
712                                         vm->m_data[index_data] = n_water;
713                                 } else {
714                                         vm->m_data[index_data] = n_air;
715                                 }
716                         }
717
718                         vm->m_area.add_y(em, index_data, 1);
719                         if (!fast_terrain)
720                                 index_3d += ystride;
721                 }
722
723                 if (!fast_terrain) {
724                         // Assign the humidity adjusted by water proximity.
725                         noise_humidity->result[index_2d] = humidityByTerrain(
726                                         noise_humidity->result[index_2d],
727                                         surface_max_y,
728                                         noise_rivers->result[index_2d],
729                                         noise_valley_depth->result[index_2d]);
730
731                         // Assign the heat adjusted by altitude. See humidity, above.
732                         if (use_altitude_chill && surface_max_y > 0)
733                                 noise_heat->result[index_2d]
734                                         *= pow(0.5f, (surface_max_y - altitude_chill / 3.f) / altitude_chill);
735                 }
736         }
737
738         return surface_max_y;
739 }
740
741
742 MgStoneType MapgenValleys::generateBiomes(float *heat_map, float *humidity_map)
743 {
744         v3s16 em = vm->m_area.getExtent();
745         u32 index = 0;
746         MgStoneType stone_type = STONE;
747
748         for (s16 z = node_min.Z; z <= node_max.Z; z++)
749         for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
750                 Biome *biome = NULL;
751                 u16 depth_top = 0;
752                 u16 base_filler = 0;
753                 u16 depth_water_top = 0;
754                 u32 vi = vm->m_area.index(x, node_max.Y, z);
755
756                 // Check node at base of mapchunk above, either a node of a previously
757                 // generated mapchunk or if not, a node of overgenerated base terrain.
758                 content_t c_above = vm->m_data[vi + em.X].getContent();
759                 bool air_above = c_above == CONTENT_AIR;
760                 bool water_above = (c_above == c_water_source);
761
762                 // If there is air or water above enable top/filler placement, otherwise force
763                 // nplaced to stone level by setting a number exceeding any possible filler depth.
764                 u16 nplaced = (air_above || water_above) ? 0 : U16_MAX;
765
766                 for (s16 y = node_max.Y; y >= node_min.Y; y--) {
767                         content_t c = vm->m_data[vi].getContent();
768
769                         // Biome is recalculated each time an upper surface is detected while
770                         // working down a column. The selected biome then remains in effect for
771                         // all nodes below until the next surface and biome recalculation.
772                         // Biome is recalculated:
773                         // 1. At the surface of stone below air or water.
774                         // 2. At the surface of water below air.
775                         // 3. When stone or water is detected but biome has not yet been calculated.
776                         if ((c == c_stone && (air_above || water_above || !biome))
777                                         || ((c == c_water_source || c == c_river_water_source)
778                                                         && (air_above || !biome))) {
779                                 // Both heat and humidity have already been adjusted for altitude.
780                                 biome = bmgr->getBiome(heat_map[index], humidity_map[index], y);
781
782                                 depth_top = biome->depth_top;
783                                 base_filler = MYMAX(depth_top
784                                                 + biome->depth_filler
785                                                 + noise_filler_depth->result[index], 0.f);
786                                 depth_water_top = biome->depth_water_top;
787
788                                 // Detect stone type for dungeons during every biome calculation.
789                                 // This is more efficient than detecting per-node and will not
790                                 // miss any desert stone or sandstone biomes.
791                                 if (biome->c_stone == c_desert_stone)
792                                         stone_type = DESERT_STONE;
793                                 else if (biome->c_stone == c_sandstone)
794                                         stone_type = SANDSTONE;
795                         }
796
797                         if (c == c_stone) {
798                                 content_t c_below = vm->m_data[vi - em.X].getContent();
799
800                                 // If the node below isn't solid, make this node stone, so that
801                                 // any top/filler nodes above are structurally supported.
802                                 // This is done by aborting the cycle of top/filler placement
803                                 // immediately by forcing nplaced to stone level.
804                                 if (c_below == CONTENT_AIR
805                                                 || c_below == c_water_source
806                                                 || c_below == c_river_water_source)
807                                         nplaced = U16_MAX;
808
809                                 if (nplaced < depth_top) {
810                                         vm->m_data[vi] = MapNode(biome->c_top);
811                                         nplaced++;
812                                 } else if (nplaced < base_filler) {
813                                         vm->m_data[vi] = MapNode(biome->c_filler);
814                                         nplaced++;
815                                 } else {
816                                         vm->m_data[vi] = MapNode(biome->c_stone);
817                                 }
818
819                                 air_above = false;
820                                 water_above = false;
821                         } else if (c == c_water_source) {
822                                 vm->m_data[vi] = MapNode((y > (s32)(water_level - depth_water_top))
823                                                 ? biome->c_water_top : biome->c_water);
824                                 nplaced = 0;  // Enable top/filler placement for next surface
825                                 air_above = false;
826                                 water_above = true;
827                         } else if (c == c_river_water_source) {
828                                 vm->m_data[vi] = MapNode(biome->c_river_water);
829                                 nplaced = U16_MAX;  // Sand was already placed under rivers.
830                                 air_above = false;
831                                 water_above = true;
832                         } else if (c == CONTENT_AIR) {
833                                 nplaced = 0;  // Enable top/filler placement for next surface
834                                 air_above = true;
835                                 water_above = false;
836                         } else {  // Possible various nodes overgenerated from neighbouring mapchunks
837                                 nplaced = U16_MAX;  // Disable top/filler placement
838                                 air_above = false;
839                                 water_above = false;
840                         }
841
842                         vm->m_area.add_y(em, vi, -1);
843                 }
844         }
845
846         return stone_type;
847 }
848
849
850 void MapgenValleys::dustTopNodes()
851 {
852         if (node_max.Y < water_level)
853                 return;
854
855         v3s16 em = vm->m_area.getExtent();
856         u32 index = 0;
857
858         for (s16 z = node_min.Z; z <= node_max.Z; z++)
859         for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
860                 Biome *biome = (Biome *)bmgr->getRaw(biomemap[index]);
861
862                 if (biome->c_dust == CONTENT_IGNORE)
863                         continue;
864
865                 u32 vi = vm->m_area.index(x, full_node_max.Y, z);
866                 content_t c_full_max = vm->m_data[vi].getContent();
867                 s16 y_start;
868
869                 if (c_full_max == CONTENT_AIR) {
870                         y_start = full_node_max.Y - 1;
871                 } else if (c_full_max == CONTENT_IGNORE) {
872                         vi = vm->m_area.index(x, node_max.Y + 1, z);
873                         content_t c_max = vm->m_data[vi].getContent();
874
875                         if (c_max == CONTENT_AIR)
876                                 y_start = node_max.Y;
877                         else
878                                 continue;
879                 } else {
880                         continue;
881                 }
882
883                 vi = vm->m_area.index(x, y_start, z);
884                 for (s16 y = y_start; y >= node_min.Y - 1; y--) {
885                         if (vm->m_data[vi].getContent() != CONTENT_AIR)
886                                 break;
887
888                         vm->m_area.add_y(em, vi, -1);
889                 }
890
891                 content_t c = vm->m_data[vi].getContent();
892                 if (!ndef->get(c).buildable_to && c != CONTENT_IGNORE && c != biome->c_dust) {
893                         vm->m_area.add_y(em, vi, 1);
894                         vm->m_data[vi] = MapNode(biome->c_dust);
895                 }
896         }
897 }
898
899
900 void MapgenValleys::generateSimpleCaves(s16 max_stone_y)
901 {
902         PseudoRandom ps(blockseed + 72202);
903
904         MapNode n_air(CONTENT_AIR);
905         MapNode n_dirt(c_dirt);
906         MapNode n_lava(c_lava_source);
907         MapNode n_water(c_river_water_source);
908
909         v3s16 em = vm->m_area.getExtent();
910
911         s16 base_water_chance = 0;
912         if (water_features < 11)
913                 base_water_chance = ceil(MAX_MAP_GENERATION_LIMIT / (water_features * 1000));
914
915         if (max_stone_y >= node_min.Y) {
916                 u32 index_2d = 0;
917                 u32 index_3d = 0;
918                 for (s16 z = node_min.Z; z <= node_max.Z; z++)
919                 for (s16 x = node_min.X; x <= node_max.X; x++, index_2d++) {
920                         bool air_above = false;
921                         //bool underground = false;
922                         u32 index_data = vm->m_area.index(x, node_max.Y + 1, z);
923
924                         index_3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride + (x - node_min.X);
925
926                         // Dig caves on down loop to check for air above.
927                         for (s16 y = node_max.Y + 1;
928                                         y >= node_min.Y - 1;
929                                         y--, index_3d -= ystride, vm->m_area.add_y(em, index_data, -1)) {
930                                 float terrain = noise_terrain_height->result[index_2d];
931
932                                 // Saves some time and prevents removing above ground nodes.
933                                 if (y > terrain + 1) {
934                                         air_above = true;
935                                         continue;
936                                 }
937
938                                 content_t c = vm->m_data[index_data].getContent();
939                                 bool n1 = (fabs(noise_simple_caves_1->result[index_3d]) < 0.07f);
940                                 bool n2 = (fabs(noise_simple_caves_2->result[index_3d]) < 0.07f);
941
942                                 // River water is (foolishly) not set as ground content
943                                 // in the default game. This can produce strange results
944                                 // when a cave undercuts a river. However, that's not for
945                                 // the mapgen to correct. Fix it in lua.
946
947                                 if (c == CONTENT_AIR) {
948                                         air_above = true;
949                                 } else if (n1 && n2 && ndef->get(c).is_ground_content) {
950                                         // When both n's are true, we're in a cave.
951                                         vm->m_data[index_data] = n_air;
952                                         air_above = true;
953                                 } else if (air_above
954                                                 && (c == c_stone || c == c_sandstone || c == c_desert_stone)) {
955                                         // At the cave floor
956                                         s16 sr = ps.next() & 1023;
957                                         u32 j = index_data;
958                                         vm->m_area.add_y(em, j, 1);
959
960                                         if (sr > (terrain - y) * 25) {
961                                                 // Put dirt in caves near the surface.
962                                                 Biome *biome = (Biome *)bmgr->getRaw(biomemap[index_2d]);
963                                                 vm->m_data[index_data] = MapNode(biome->c_filler);
964                                         } else {
965                                                 s16 lava_chance = 0;
966
967                                                 if (y <= lava_max_height && c == c_stone) {
968                                                         // Lava spawns increase with depth.
969                                                         lava_chance = ceil((lava_max_height - y + 1) / 10000);
970
971                                                         if (sr < lava_chance)
972                                                                 vm->m_data[j] = n_lava;
973                                                 }
974
975                                                 if (base_water_chance > 0 && y <= cave_water_max_height) {
976                                                         s16 water_chance = base_water_chance
977                                                                 - (abs(y - water_level) / (water_features * 1000));
978
979                                                         // Waterfalls may get out of control above ground.
980                                                         sr -= lava_chance;
981                                                         // If sr < 0 then we should have already placed lava --
982                                                         // don't immediately dump water on it.
983                                                         if (sr >= 0 && sr < water_chance)
984                                                                 vm->m_data[j] = n_water;
985                                                 }
986                                         }
987
988                                         air_above = false;
989                                 }
990
991                                 // If we're not in a cave, there's no open space.
992                                 if (!(n1 && n2))
993                                         air_above = false;
994                         }
995                 }
996         }
997 }