Move biome calculation to BiomeGen
[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, mapgen_flat 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 #include "mapgen.h"
29 #include "voxel.h"
30 #include "noise.h"
31 #include "mapblock.h"
32 #include "mapnode.h"
33 #include "map.h"
34 #include "content_sao.h"
35 #include "nodedef.h"
36 #include "voxelalgorithms.h"
37 #include "settings.h" // For g_settings
38 #include "emerge.h"
39 #include "dungeongen.h"
40 #include "treegen.h"
41 #include "mg_biome.h"
42 #include "mg_ore.h"
43 #include "mg_decoration.h"
44 #include "mapgen_valleys.h"
45 #include "cavegen.h"
46
47
48 //#undef NDEBUG
49 //#include "assert.h"
50
51 //#include "util/timetaker.h"
52 //#include "profiler.h"
53
54
55 //static Profiler mapgen_prof;
56 //Profiler *mapgen_profiler = &mapgen_prof;
57
58 static FlagDesc flagdesc_mapgen_valleys[] = {
59         {"altitude_chill", MGVALLEYS_ALT_CHILL},
60         {"humid_rivers",   MGVALLEYS_HUMID_RIVERS},
61         {NULL,             0}
62 };
63
64 ///////////////////////////////////////////////////////////////////////////////
65
66
67 MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager *emerge)
68         : Mapgen(mapgenid, params, emerge)
69 {
70         this->m_emerge = emerge;
71         this->bmgr     = emerge->biomemgr;
72
73         //// amount of elements to skip for the next index
74         //// for noise/height/biome maps (not vmanip)
75         this->ystride = csize.X;
76         this->zstride = csize.X * (csize.Y + 2);
77         // 1-down overgeneration
78         this->zstride_1d = csize.X * (csize.Y + 1);
79
80         this->heightmap = new s16[csize.X * csize.Z];
81
82         this->map_gen_limit = MYMIN(MAX_MAP_GENERATION_LIMIT,
83                         g_settings->getU16("map_generation_limit"));
84
85         MapgenValleysParams *sp = (MapgenValleysParams *)params->sparams;
86         BiomeParamsOriginal *bp = (BiomeParamsOriginal *)params->bparams;
87
88         this->spflags            = sp->spflags;
89         this->altitude_chill     = sp->altitude_chill;
90         this->large_cave_depth   = sp->large_cave_depth;
91         this->lava_features_lim  = rangelim(sp->lava_features, 0, 10);
92         this->massive_cave_depth = sp->massive_cave_depth;
93         this->river_depth_bed    = sp->river_depth + 1.f;
94         this->river_size_factor  = sp->river_size / 100.f;
95         this->water_features_lim = rangelim(sp->water_features, 0, 10);
96         this->cave_width         = sp->cave_width;
97
98         //// 2D Terrain noise
99         noise_filler_depth       = new Noise(&sp->np_filler_depth,       seed, csize.X, csize.Z);
100         noise_inter_valley_slope = new Noise(&sp->np_inter_valley_slope, seed, csize.X, csize.Z);
101         noise_rivers             = new Noise(&sp->np_rivers,             seed, csize.X, csize.Z);
102         noise_terrain_height     = new Noise(&sp->np_terrain_height,     seed, csize.X, csize.Z);
103         noise_valley_depth       = new Noise(&sp->np_valley_depth,       seed, csize.X, csize.Z);
104         noise_valley_profile     = new Noise(&sp->np_valley_profile,     seed, csize.X, csize.Z);
105
106         //// 3D Terrain noise
107         // 1-up 1-down overgeneration
108         noise_inter_valley_fill = new Noise(&sp->np_inter_valley_fill, seed, csize.X, csize.Y + 2, csize.Z);
109         // 1-down overgeneraion
110         noise_cave1             = new Noise(&sp->np_cave1,             seed, csize.X, csize.Y + 1, csize.Z);
111         noise_cave2             = new Noise(&sp->np_cave2,             seed, csize.X, csize.Y + 1, csize.Z);
112         noise_massive_caves     = new Noise(&sp->np_massive_caves,     seed, csize.X, csize.Y + 1, csize.Z);
113
114         //// Initialize biome generator
115         // NOTE: valleys mapgen can only use BiomeGenOriginal
116         biomegen = emerge->biomemgr->createBiomeGen(
117                 BIOMEGEN_ORIGINAL, params->bparams, csize);
118         biomemap = biomegen->biomemap;
119         m_bgen = (BiomeGenOriginal *)biomegen;
120
121         this->humid_rivers       = (spflags & MGVALLEYS_HUMID_RIVERS);
122         this->use_altitude_chill = (spflags & MGVALLEYS_ALT_CHILL);
123         this->humidity_adjust    = bp->np_humidity.offset - 50.f;
124
125         // a small chance of overflows if the settings are very high
126         this->cave_water_max_height = water_level + MYMAX(0, water_features_lim - 4) * 50;
127         this->lava_max_height       = water_level + MYMAX(0, lava_features_lim - 4) * 50;
128
129         tcave_cache = new float[csize.Y + 2];
130
131         //// Resolve nodes to be used
132         c_cobble               = ndef->getId("mapgen_cobble");
133         c_desert_stone         = ndef->getId("mapgen_desert_stone");
134         c_dirt                 = ndef->getId("mapgen_dirt");
135         c_lava_source          = ndef->getId("mapgen_lava_source");
136         c_mossycobble          = ndef->getId("mapgen_mossycobble");
137         c_river_water_source   = ndef->getId("mapgen_river_water_source");
138         c_sand                 = ndef->getId("mapgen_sand");
139         c_sandstonebrick       = ndef->getId("mapgen_sandstonebrick");
140         c_sandstone            = ndef->getId("mapgen_sandstone");
141         c_stair_cobble         = ndef->getId("mapgen_stair_cobble");
142         c_stair_sandstonebrick = ndef->getId("mapgen_stair_sandstonebrick");
143         c_stone                = ndef->getId("mapgen_stone");
144         c_water_source         = ndef->getId("mapgen_water_source");
145
146         if (c_mossycobble == CONTENT_IGNORE)
147                 c_mossycobble = c_cobble;
148         if (c_river_water_source == CONTENT_IGNORE)
149                 c_river_water_source = c_water_source;
150         if (c_sand == CONTENT_IGNORE)
151                 c_sand = c_stone;
152         if (c_sandstonebrick == CONTENT_IGNORE)
153                 c_sandstonebrick = c_sandstone;
154         if (c_stair_cobble == CONTENT_IGNORE)
155                 c_stair_cobble = c_cobble;
156         if (c_stair_sandstonebrick == CONTENT_IGNORE)
157                 c_stair_sandstonebrick = c_sandstone;
158 }
159
160
161 MapgenValleys::~MapgenValleys()
162 {
163         delete noise_cave1;
164         delete noise_cave2;
165         delete noise_filler_depth;
166         delete noise_inter_valley_fill;
167         delete noise_inter_valley_slope;
168         delete noise_rivers;
169         delete noise_massive_caves;
170         delete noise_terrain_height;
171         delete noise_valley_depth;
172         delete noise_valley_profile;
173
174         delete biomegen;
175
176         delete[] heightmap;
177         delete[] tcave_cache;
178 }
179
180
181 MapgenValleysParams::MapgenValleysParams()
182 {
183         spflags            = MGVALLEYS_HUMID_RIVERS | MGVALLEYS_ALT_CHILL;
184         altitude_chill     = 90; // The altitude at which temperature drops by 20C.
185         large_cave_depth   = -33;
186         lava_features      = 0;  // How often water will occur in caves.
187         massive_cave_depth = -256;  // highest altitude of massive caves
188         river_depth        = 4;  // How deep to carve river channels.
189         river_size         = 5;  // How wide to make rivers.
190         water_features     = 0;  // How often water will occur in caves.
191         cave_width         = 0.3;
192
193         np_cave1              = NoiseParams(0,     12,   v3f(96,   96,   96),   52534, 4, 0.5,   2.0);
194         np_cave2              = NoiseParams(0,     12,   v3f(96,   96,   96),   10325, 4, 0.5,   2.0);
195         np_filler_depth       = NoiseParams(0.f,   1.2f, v3f(256,  256,  256),  1605,  3, 0.5f,  2.f);
196         np_inter_valley_fill  = NoiseParams(0.f,   1.f,  v3f(256,  512,  256),  1993,  6, 0.8f,  2.f);
197         np_inter_valley_slope = NoiseParams(0.5f,  0.5f, v3f(128,  128,  128),  746,   1, 1.f,   2.f);
198         np_rivers             = NoiseParams(0.f,   1.f,  v3f(256,  256,  256),  -6050, 5, 0.6f,  2.f);
199         np_massive_caves      = NoiseParams(0.f,   1.f,  v3f(768,  256,  768),  59033, 6, 0.63f, 2.f);
200         np_terrain_height     = NoiseParams(-10.f, 50.f, v3f(1024, 1024, 1024), 5202,  6, 0.4f,  2.f);
201         np_valley_depth       = NoiseParams(5.f,   4.f,  v3f(512,  512,  512),  -1914, 1, 1.f,   2.f);
202         np_valley_profile     = NoiseParams(0.6f,  0.5f, v3f(512,  512,  512),  777,   1, 1.f,   2.f);
203 }
204
205
206 void MapgenValleysParams::readParams(const Settings *settings)
207 {
208         settings->getFlagStrNoEx("mgvalleys_spflags",        spflags, flagdesc_mapgen_valleys);
209         settings->getU16NoEx("mgvalleys_altitude_chill",     altitude_chill);
210         settings->getS16NoEx("mgvalleys_large_cave_depth",   large_cave_depth);
211         settings->getU16NoEx("mgvalleys_lava_features",      lava_features);
212         settings->getS16NoEx("mgvalleys_massive_cave_depth", massive_cave_depth);
213         settings->getU16NoEx("mgvalleys_river_depth",        river_depth);
214         settings->getU16NoEx("mgvalleys_river_size",         river_size);
215         settings->getU16NoEx("mgvalleys_water_features",     water_features);
216         settings->getFloatNoEx("mgvalleys_cave_width",       cave_width);
217
218         settings->getNoiseParams("mgvalleys_np_cave1",              np_cave1);
219         settings->getNoiseParams("mgvalleys_np_cave2",              np_cave2);
220         settings->getNoiseParams("mgvalleys_np_filler_depth",       np_filler_depth);
221         settings->getNoiseParams("mgvalleys_np_inter_valley_fill",  np_inter_valley_fill);
222         settings->getNoiseParams("mgvalleys_np_inter_valley_slope", np_inter_valley_slope);
223         settings->getNoiseParams("mgvalleys_np_rivers",             np_rivers);
224         settings->getNoiseParams("mgvalleys_np_massive_caves",      np_massive_caves);
225         settings->getNoiseParams("mgvalleys_np_terrain_height",     np_terrain_height);
226         settings->getNoiseParams("mgvalleys_np_valley_depth",       np_valley_depth);
227         settings->getNoiseParams("mgvalleys_np_valley_profile",     np_valley_profile);
228 }
229
230
231 void MapgenValleysParams::writeParams(Settings *settings) const
232 {
233         settings->setFlagStr("mgvalleys_spflags",        spflags, flagdesc_mapgen_valleys, U32_MAX);
234         settings->setU16("mgvalleys_altitude_chill",     altitude_chill);
235         settings->setS16("mgvalleys_large_cave_depth",   large_cave_depth);
236         settings->setU16("mgvalleys_lava_features",      lava_features);
237         settings->setS16("mgvalleys_massive_cave_depth", massive_cave_depth);
238         settings->setU16("mgvalleys_river_depth",        river_depth);
239         settings->setU16("mgvalleys_river_size",         river_size);
240         settings->setU16("mgvalleys_water_features",     water_features);
241         settings->setFloat("mgvalleys_cave_width",       cave_width);
242
243         settings->setNoiseParams("mgvalleys_np_cave1",              np_cave1);
244         settings->setNoiseParams("mgvalleys_np_cave2",              np_cave2);
245         settings->setNoiseParams("mgvalleys_np_filler_depth",       np_filler_depth);
246         settings->setNoiseParams("mgvalleys_np_inter_valley_fill",  np_inter_valley_fill);
247         settings->setNoiseParams("mgvalleys_np_inter_valley_slope", np_inter_valley_slope);
248         settings->setNoiseParams("mgvalleys_np_rivers",             np_rivers);
249         settings->setNoiseParams("mgvalleys_np_massive_caves",      np_massive_caves);
250         settings->setNoiseParams("mgvalleys_np_terrain_height",     np_terrain_height);
251         settings->setNoiseParams("mgvalleys_np_valley_depth",       np_valley_depth);
252         settings->setNoiseParams("mgvalleys_np_valley_profile",     np_valley_profile);
253 }
254
255
256 ///////////////////////////////////////
257
258
259 void MapgenValleys::makeChunk(BlockMakeData *data)
260 {
261         // Pre-conditions
262         assert(data->vmanip);
263         assert(data->nodedef);
264         assert(data->blockpos_requested.X >= data->blockpos_min.X &&
265                 data->blockpos_requested.Y >= data->blockpos_min.Y &&
266                 data->blockpos_requested.Z >= data->blockpos_min.Z);
267         assert(data->blockpos_requested.X <= data->blockpos_max.X &&
268                 data->blockpos_requested.Y <= data->blockpos_max.Y &&
269                 data->blockpos_requested.Z <= data->blockpos_max.Z);
270
271         this->generating = true;
272         this->vm = data->vmanip;
273         this->ndef = data->nodedef;
274
275         //TimeTaker t("makeChunk");
276
277         v3s16 blockpos_min = data->blockpos_min;
278         v3s16 blockpos_max = data->blockpos_max;
279         node_min = blockpos_min * MAP_BLOCKSIZE;
280         node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
281         full_node_min = (blockpos_min - 1) * MAP_BLOCKSIZE;
282         full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
283
284         blockseed = getBlockSeed2(full_node_min, seed);
285
286         // Generate noise maps and base terrain height.
287         calculateNoise();
288
289         // Generate biome noises.  Note this must be executed strictly before
290         // generateTerrain, because generateTerrain depends on intermediate
291         // biome-related noises.
292         biomegen->calcBiomeNoise(node_min);
293
294         // Generate base terrain with initial heightmaps
295         s16 stone_surface_max_y = generateTerrain();
296
297         // Build biomemap
298         biomegen->getBiomes(heightmap);
299
300         // Place biome-specific nodes
301         MgStoneType stone_type = generateBiomes();
302
303         // Cave creation.
304         if (flags & MG_CAVES)
305                 generateCaves(stone_surface_max_y);
306
307         // Dungeon creation
308         if ((flags & MG_DUNGEONS) && node_max.Y < 50 && (stone_surface_max_y >= node_min.Y)) {
309                 DungeonParams dp;
310
311                 dp.np_rarity  = nparams_dungeon_rarity;
312                 dp.np_density = nparams_dungeon_density;
313                 dp.np_wetness = nparams_dungeon_wetness;
314                 dp.c_water    = c_water_source;
315                 if (stone_type == STONE) {
316                         dp.c_cobble = c_cobble;
317                         dp.c_moss   = c_mossycobble;
318                         dp.c_stair  = c_stair_cobble;
319
320                         dp.diagonal_dirs = false;
321                         dp.mossratio     = 3.f;
322                         dp.holesize      = v3s16(1, 2, 1);
323                         dp.roomsize      = v3s16(0, 0, 0);
324                         dp.notifytype    = GENNOTIFY_DUNGEON;
325                 } else if (stone_type == DESERT_STONE) {
326                         dp.c_cobble = c_desert_stone;
327                         dp.c_moss   = c_desert_stone;
328                         dp.c_stair  = c_desert_stone;
329
330                         dp.diagonal_dirs = true;
331                         dp.mossratio     = 0.f;
332                         dp.holesize      = v3s16(2, 3, 2);
333                         dp.roomsize      = v3s16(2, 5, 2);
334                         dp.notifytype    = GENNOTIFY_TEMPLE;
335                 } else if (stone_type == SANDSTONE) {
336                         dp.c_cobble = c_sandstonebrick;
337                         dp.c_moss   = c_sandstonebrick;
338                         dp.c_stair  = c_sandstonebrick;
339
340                         dp.diagonal_dirs = false;
341                         dp.mossratio     = 0.f;
342                         dp.holesize      = v3s16(2, 2, 2);
343                         dp.roomsize      = v3s16(2, 0, 2);
344                         dp.notifytype    = GENNOTIFY_DUNGEON;
345                 }
346
347                 DungeonGen dgen(this, &dp);
348                 dgen.generate(blockseed, full_node_min, full_node_max);
349         }
350
351         // Generate the registered decorations
352         if (flags & MG_DECORATIONS)
353                 m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
354
355         // Generate the registered ores
356         m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max);
357
358         // Sprinkle some dust on top after everything else was generated
359         dustTopNodes();
360
361         //TimeTaker tll("liquid_lighting");
362
363         updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
364
365         if (flags & MG_LIGHT)
366                 calcLighting(
367                                 node_min - v3s16(0, 1, 0),
368                                 node_max + v3s16(0, 1, 0),
369                                 full_node_min,
370                                 full_node_max);
371
372         //mapgen_profiler->avg("liquid_lighting", tll.stop() / 1000.f);
373         //mapgen_profiler->avg("makeChunk", t.stop() / 1000.f);
374
375         this->generating = false;
376 }
377
378
379 // Populate the noise tables and do most of the
380 // calculation necessary to determine terrain height.
381 void MapgenValleys::calculateNoise()
382 {
383         //TimeTaker t("calculateNoise", NULL, PRECISION_MICRO);
384
385         int x = node_min.X;
386         int y = node_min.Y - 1;
387         int z = node_min.Z;
388
389         //TimeTaker tcn("actualNoise");
390
391         noise_filler_depth->perlinMap2D(x, z);
392         noise_inter_valley_slope->perlinMap2D(x, z);
393         noise_rivers->perlinMap2D(x, z);
394         noise_terrain_height->perlinMap2D(x, z);
395         noise_valley_depth->perlinMap2D(x, z);
396         noise_valley_profile->perlinMap2D(x, z);
397
398         noise_inter_valley_fill->perlinMap3D(x, y, z);
399
400         //mapgen_profiler->avg("noisemaps", tcn.stop() / 1000.f);
401
402         float heat_offset = 0.f;
403         float humidity_scale = 1.f;
404
405         // Altitude chill tends to reduce the average heat.
406         if (use_altitude_chill)
407                 heat_offset = 5.f;
408
409         // River humidity tends to increase the humidity range.
410         if (humid_rivers) {
411                 humidity_scale = 0.8f;
412         }
413
414         for (s32 index = 0; index < csize.X * csize.Z; index++) {
415                 m_bgen->heatmap[index] += heat_offset;
416                 m_bgen->humidmap[index] *= humidity_scale;
417         }
418
419         TerrainNoise tn;
420
421         u32 index = 0;
422         for (tn.z = node_min.Z; tn.z <= node_max.Z; tn.z++)
423         for (tn.x = node_min.X; tn.x <= node_max.X; tn.x++, index++) {
424                 // The parameters that we actually need to generate terrain
425                 //  are passed by address (and the return value).
426                 tn.terrain_height    = noise_terrain_height->result[index];
427                 // River noise is replaced with base terrain, which
428                 // is basically the height of the water table.
429                 tn.rivers            = &noise_rivers->result[index];
430                 // Valley depth noise is replaced with the valley
431                 // number that represents the height of terrain
432                 // over rivers and is used to determine about
433                 // how close a river is for humidity calculation.
434                 tn.valley            = &noise_valley_depth->result[index];
435                 tn.valley_profile    = noise_valley_profile->result[index];
436                 // Slope noise is replaced by the calculated slope
437                 // which is used to get terrain height in the slow
438                 // method, to create sharper mountains.
439                 tn.slope             = &noise_inter_valley_slope->result[index];
440                 tn.inter_valley_fill = noise_inter_valley_fill->result[index];
441
442                 // This is the actual terrain height.
443                 float mount = terrainLevelFromNoise(&tn);
444                 noise_terrain_height->result[index] = mount;
445         }
446 }
447
448
449 // This keeps us from having to maintain two similar sets of
450 //  complicated code to determine ground level.
451 float MapgenValleys::terrainLevelFromNoise(TerrainNoise *tn)
452 {
453         // The square function changes the behaviour of this noise:
454         //  very often small, and sometimes very high.
455         float valley_d = MYSQUARE(*tn->valley);
456
457         // valley_d is here because terrain is generally higher where valleys
458         //  are deep (mountains). base represents the height of the
459         //  rivers, most of the surface is above.
460         float base = tn->terrain_height + valley_d;
461
462         // "river" represents the distance from the river, in arbitrary units.
463         float river = fabs(*tn->rivers) - river_size_factor;
464
465         // Use the curve of the function 1-exp(-(x/a)^2) to model valleys.
466         //  Making "a" vary (0 < a <= 1) changes the shape of the valleys.
467         //  Try it with a geometry software !
468         //   (here x = "river" and a = valley_profile).
469         //  "valley" represents the height of the terrain, from the rivers.
470         {
471                 float t = river / tn->valley_profile;
472                 *tn->valley = valley_d * (1.f - exp(- MYSQUARE(t)));
473         }
474
475         // approximate height of the terrain at this point
476         float mount = base + *tn->valley;
477
478         *tn->slope *= *tn->valley;
479
480         // Rivers are placed where "river" is negative, so where the original
481         //  noise value is close to zero.
482         // Base ground is returned as rivers since it's basically the water table.
483         *tn->rivers = base;
484         if (river < 0.f) {
485                 // Use the the function -sqrt(1-x^2) which models a circle.
486                 float depth;
487                 {
488                         float t = river / river_size_factor + 1;
489                         depth = (river_depth_bed * sqrt(MYMAX(0, 1.f - MYSQUARE(t))));
490                 }
491
492                 // base - depth : height of the bottom of the river
493                 // water_level - 3 : don't make rivers below 3 nodes under the surface
494                 // We use three because that's as low as the swamp biomes go.
495                 // There is no logical equivalent to this using rangelim.
496                 mount = MYMIN(MYMAX(base - depth, (float)(water_level - 3)), mount);
497
498                 // Slope has no influence on rivers.
499                 *tn->slope = 0.f;
500         }
501
502         return mount;
503 }
504
505
506 // This avoids duplicating the code in terrainLevelFromNoise, adding
507 // only the final step of terrain generation without a noise map.
508 float MapgenValleys::adjustedTerrainLevelFromNoise(TerrainNoise *tn)
509 {
510         float mount = terrainLevelFromNoise(tn);
511         s16 y_start = myround(mount);
512
513         for (s16 y = y_start; y <= y_start + 1000; y++) {
514                 float fill = NoisePerlin3D(&noise_inter_valley_fill->np, tn->x, y, tn->z, seed);
515
516                 if (fill * *tn->slope < y - mount) {
517                         mount = MYMAX(y - 1, mount);
518                         break;
519                 }
520         }
521
522         return mount;
523 }
524
525
526 int MapgenValleys::getSpawnLevelAtPoint(v2s16 p)
527 {
528         // Check to make sure this isn't a request for a location in a river.
529         float rivers = NoisePerlin2D(&noise_rivers->np, p.X, p.Y, seed);
530         if (fabs(rivers) < river_size_factor)
531                 return MAX_MAP_GENERATION_LIMIT;  // Unsuitable spawn point
532
533         s16 level_at_point = terrainLevelAtPoint(p.X, p.Y);
534         if (level_at_point <= water_level ||
535                         level_at_point > water_level + 32)
536                 return MAX_MAP_GENERATION_LIMIT;  // Unsuitable spawn point
537         else
538                 return level_at_point;
539 }
540
541
542 float MapgenValleys::terrainLevelAtPoint(s16 x, s16 z)
543 {
544         TerrainNoise tn;
545
546         float rivers = NoisePerlin2D(&noise_rivers->np, x, z, seed);
547         float valley = NoisePerlin2D(&noise_valley_depth->np, x, z, seed);
548         float inter_valley_slope = NoisePerlin2D(&noise_inter_valley_slope->np, x, z, seed);
549
550         tn.x                 = x;
551         tn.z                 = z;
552         tn.terrain_height    = NoisePerlin2D(&noise_terrain_height->np, x, z, seed);
553         tn.rivers            = &rivers;
554         tn.valley            = &valley;
555         tn.valley_profile    = NoisePerlin2D(&noise_valley_profile->np, x, z, seed);
556         tn.slope             = &inter_valley_slope;
557         tn.inter_valley_fill = 0.f;
558
559         return adjustedTerrainLevelFromNoise(&tn);
560 }
561
562
563 int MapgenValleys::generateTerrain()
564 {
565         // Raising this reduces the rate of evaporation.
566         static const float evaporation = 300.f;
567         // from the lua
568         static const float humidity_dropoff = 4.f;
569         // constant to convert altitude chill (compatible with lua) to heat
570         static const float alt_to_heat = 20.f;
571         // humidity reduction by altitude
572         static const float alt_to_humid = 10.f;
573
574         MapNode n_air(CONTENT_AIR);
575         MapNode n_river_water(c_river_water_source);
576         MapNode n_sand(c_sand);
577         MapNode n_stone(c_stone);
578         MapNode n_water(c_water_source);
579
580         v3s16 em = vm->m_area.getExtent();
581         s16 surface_max_y = -MAX_MAP_GENERATION_LIMIT;
582         u32 index_2d = 0;
583
584         for (s16 z = node_min.Z; z <= node_max.Z; z++)
585         for (s16 x = node_min.X; x <= node_max.X; x++, index_2d++) {
586                 float river_y = noise_rivers->result[index_2d];
587                 float surface_y = noise_terrain_height->result[index_2d];
588                 float slope = noise_inter_valley_slope->result[index_2d];
589                 float t_heat = m_bgen->heatmap[index_2d];
590
591                 heightmap[index_2d] = -MAX_MAP_GENERATION_LIMIT;
592
593                 if (surface_y > surface_max_y)
594                         surface_max_y = ceil(surface_y);
595
596                 if (humid_rivers) {
597                         // Derive heat from (base) altitude. This will be most correct
598                         // at rivers, since other surface heights may vary below.
599                         if (use_altitude_chill && (surface_y > 0.f || river_y > 0.f))
600                                 t_heat -= alt_to_heat * MYMAX(surface_y, river_y) / altitude_chill;
601
602                         // If humidity is low or heat is high, lower the water table.
603                         float delta = m_bgen->humidmap[index_2d] - 50.f;
604                         if (delta < 0.f) {
605                                 float t_evap = (t_heat - 32.f) / evaporation;
606                                 river_y += delta * MYMAX(t_evap, 0.08f);
607                         }
608                 }
609
610                 u32 index_3d = (z - node_min.Z) * zstride + (x - node_min.X);
611                 u32 index_data = vm->m_area.index(x, node_min.Y - 1, z);
612
613                 // Mapgens concern themselves with stone and water.
614                 for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) {
615                         if (vm->m_data[index_data].getContent() == CONTENT_IGNORE) {
616                                 float fill = noise_inter_valley_fill->result[index_3d];
617                                 float surface_delta = (float)y - surface_y;
618                                 bool river = y + 1 < river_y;
619
620                                 if (fabs(surface_delta) <= 0.5f && y > water_level && river) {
621                                         // river bottom
622                                         vm->m_data[index_data] = n_sand;
623                                 } else if (slope * fill > surface_delta) {
624                                         // ground
625                                         vm->m_data[index_data] = n_stone;
626                                         if (y > heightmap[index_2d])
627                                                 heightmap[index_2d] = y;
628                                         if (y > surface_max_y)
629                                                 surface_max_y = y;
630                                 } else if (y <= water_level) {
631                                         // sea
632                                         vm->m_data[index_data] = n_water;
633                                 } else if (river) {
634                                         // river
635                                         vm->m_data[index_data] = n_river_water;
636                                 } else {
637                                         vm->m_data[index_data] = n_air;
638                                 }
639                         }
640
641                         vm->m_area.add_y(em, index_data, 1);
642                         index_3d += ystride;
643                 }
644
645                 // This happens if we're generating a chunk that doesn't
646                 // contain the terrain surface, in which case, we need
647                 // to set heightmap to a value outside of the chunk,
648                 // to avoid confusing lua mods that use heightmap.
649                 if (heightmap[index_2d] == -MAX_MAP_GENERATION_LIMIT) {
650                         s16 surface_y_int = myround(surface_y);
651                         if (surface_y_int > node_max.Y + 1 || surface_y_int < node_min.Y - 1) {
652                                 // If surface_y is outside the chunk, it's good enough.
653                                 heightmap[index_2d] = surface_y_int;
654                         } else {
655                                 // If the ground is outside of this chunk, but surface_y
656                                 // is within the chunk, give a value outside.
657                                 heightmap[index_2d] = node_min.Y - 2;
658                         }
659                 }
660
661                 if (humid_rivers) {
662                         // Use base ground (water table) in a riverbed, to
663                         // avoid an unnatural rise in humidity.
664                         float t_alt = MYMAX(noise_rivers->result[index_2d], (float)heightmap[index_2d]);
665                         float humid = m_bgen->humidmap[index_2d];
666                         float water_depth = (t_alt - river_y) / humidity_dropoff;
667                         humid *= 1.f + pow(0.5f, MYMAX(water_depth, 1.f));
668
669                         // Reduce humidity with altitude (ignoring riverbeds).
670                         // This is similar to the lua version's seawater adjustment,
671                         // but doesn't increase the base humidity, which causes
672                         // problems with the default biomes.
673                         if (t_alt > 0.f)
674                                 humid -= alt_to_humid * t_alt / altitude_chill;
675
676                         m_bgen->humidmap[index_2d] = humid;
677                 }
678
679                 // Assign the heat adjusted by any changed altitudes.
680                 // The altitude will change about half the time.
681                 if (use_altitude_chill) {
682                         // ground height ignoring riverbeds
683                         float t_alt = MYMAX(noise_rivers->result[index_2d], (float)heightmap[index_2d]);
684                         if (humid_rivers && heightmap[index_2d] == (s16)myround(surface_y))
685                                 // The altitude hasn't changed. Use the first result.
686                                 m_bgen->heatmap[index_2d] = t_heat;
687                         else if (t_alt > 0.f)
688                                 m_bgen->heatmap[index_2d] -= alt_to_heat * t_alt / altitude_chill;
689                 }
690         }
691
692         return surface_max_y;
693 }
694
695
696 MgStoneType MapgenValleys::generateBiomes()
697 {
698         v3s16 em = vm->m_area.getExtent();
699         u32 index = 0;
700         MgStoneType stone_type = STONE;
701
702         for (s16 z = node_min.Z; z <= node_max.Z; z++)
703         for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
704                 Biome *biome = NULL;
705                 u16 depth_top = 0;
706                 u16 base_filler = 0;
707                 u16 depth_water_top = 0;
708                 u32 vi = vm->m_area.index(x, node_max.Y, z);
709
710                 // Check node at base of mapchunk above, either a node of a previously
711                 // generated mapchunk or if not, a node of overgenerated base terrain.
712                 content_t c_above = vm->m_data[vi + em.X].getContent();
713                 bool air_above = c_above == CONTENT_AIR;
714                 bool water_above = (c_above == c_water_source || c_above == c_river_water_source);
715
716                 // If there is air or water above enable top/filler placement, otherwise force
717                 // nplaced to stone level by setting a number exceeding any possible filler depth.
718                 u16 nplaced = (air_above || water_above) ? 0 : U16_MAX;
719
720                 for (s16 y = node_max.Y; y >= node_min.Y; y--) {
721                         content_t c = vm->m_data[vi].getContent();
722
723                         // Biome is recalculated each time an upper surface is detected while
724                         // working down a column. The selected biome then remains in effect for
725                         // all nodes below until the next surface and biome recalculation.
726                         // Biome is recalculated:
727                         // 1. At the surface of stone below air or water.
728                         // 2. At the surface of water below air.
729                         // 3. When stone or water is detected but biome has not yet been calculated.
730                         if ((c == c_stone && (air_above || water_above || !biome))
731                                         || ((c == c_water_source || c == c_river_water_source)
732                                                 && (air_above || !biome))) {
733                                 // Both heat and humidity have already been adjusted for altitude.
734                                 biome = biomegen->getBiomeAtIndex(index, y);
735
736                                 depth_top = biome->depth_top;
737                                 base_filler = MYMAX(depth_top
738                                                 + biome->depth_filler
739                                                 + noise_filler_depth->result[index], 0.f);
740                                 depth_water_top = biome->depth_water_top;
741
742                                 // Detect stone type for dungeons during every biome calculation.
743                                 // This is more efficient than detecting per-node and will not
744                                 // miss any desert stone or sandstone biomes.
745                                 if (biome->c_stone == c_desert_stone)
746                                         stone_type = DESERT_STONE;
747                                 else if (biome->c_stone == c_sandstone)
748                                         stone_type = SANDSTONE;
749                         }
750
751                         if (c == c_stone) {
752                                 content_t c_below = vm->m_data[vi - em.X].getContent();
753
754                                 // If the node below isn't solid, make this node stone, so that
755                                 // any top/filler nodes above are structurally supported.
756                                 // This is done by aborting the cycle of top/filler placement
757                                 // immediately by forcing nplaced to stone level.
758                                 if (c_below == CONTENT_AIR
759                                                 || c_below == c_water_source
760                                                 || c_below == c_river_water_source)
761                                         nplaced = U16_MAX;
762
763                                 if (nplaced < depth_top) {
764                                         vm->m_data[vi] = MapNode(biome->c_top);
765                                         nplaced++;
766                                 } else if (nplaced < base_filler) {
767                                         vm->m_data[vi] = MapNode(biome->c_filler);
768                                         nplaced++;
769                                 } else {
770                                         vm->m_data[vi] = MapNode(biome->c_stone);
771                                 }
772
773                                 air_above = false;
774                                 water_above = false;
775                         } else if (c == c_water_source) {
776                                 vm->m_data[vi] = MapNode((y > (s32)(water_level - depth_water_top))
777                                                 ? biome->c_water_top : biome->c_water);
778                                 nplaced = 0;  // Enable top/filler placement for next surface
779                                 air_above = false;
780                                 water_above = true;
781                         } else if (c == c_river_water_source) {
782                                 vm->m_data[vi] = MapNode(biome->c_river_water);
783                                 nplaced = depth_top;  // Enable filler placement for next surface
784                                 air_above = false;
785                                 water_above = true;
786                         } else if (c == CONTENT_AIR) {
787                                 nplaced = 0;  // Enable top/filler placement for next surface
788                                 air_above = true;
789                                 water_above = false;
790                         } else {  // Possible various nodes overgenerated from neighbouring mapchunks
791                                 nplaced = U16_MAX;  // Disable top/filler placement
792                                 air_above = false;
793                                 water_above = false;
794                         }
795
796                         vm->m_area.add_y(em, vi, -1);
797                 }
798         }
799
800         return stone_type;
801 }
802
803
804 void MapgenValleys::dustTopNodes()
805 {
806         if (node_max.Y < water_level)
807                 return;
808
809         v3s16 em = vm->m_area.getExtent();
810         u32 index = 0;
811
812         for (s16 z = node_min.Z; z <= node_max.Z; z++)
813         for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
814                 Biome *biome = (Biome *)bmgr->getRaw(biomemap[index]);
815
816                 if (biome->c_dust == CONTENT_IGNORE)
817                         continue;
818
819                 u32 vi = vm->m_area.index(x, full_node_max.Y, z);
820                 content_t c_full_max = vm->m_data[vi].getContent();
821                 s16 y_start;
822
823                 if (c_full_max == CONTENT_AIR) {
824                         y_start = full_node_max.Y - 1;
825                 } else if (c_full_max == CONTENT_IGNORE) {
826                         vi = vm->m_area.index(x, node_max.Y + 1, z);
827                         content_t c_max = vm->m_data[vi].getContent();
828
829                         if (c_max == CONTENT_AIR)
830                                 y_start = node_max.Y;
831                         else
832                                 continue;
833                 } else {
834                         continue;
835                 }
836
837                 vi = vm->m_area.index(x, y_start, z);
838                 for (s16 y = y_start; y >= node_min.Y - 1; y--) {
839                         if (vm->m_data[vi].getContent() != CONTENT_AIR)
840                                 break;
841
842                         vm->m_area.add_y(em, vi, -1);
843                 }
844
845                 content_t c = vm->m_data[vi].getContent();
846                 if (!ndef->get(c).buildable_to && c != CONTENT_IGNORE && c != biome->c_dust) {
847                         vm->m_area.add_y(em, vi, 1);
848                         vm->m_data[vi] = MapNode(biome->c_dust);
849                 }
850         }
851 }
852
853
854 void MapgenValleys::generateCaves(s16 max_stone_y)
855 {
856         if (max_stone_y < node_min.Y)
857                 return;
858
859         noise_cave1->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
860         noise_cave2->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
861
862         PseudoRandom ps(blockseed + 72202);
863
864         MapNode n_air(CONTENT_AIR);
865         MapNode n_lava(c_lava_source);
866         MapNode n_water(c_river_water_source);
867
868         v3s16 em = vm->m_area.getExtent();
869
870         // Cave blend distance near YMIN, YMAX
871         const float massive_cave_blend = 128.f;
872         // noise threshold for massive caves
873         const float massive_cave_threshold = 0.6f;
874         // mct: 1 = small rare caves, 0.5 1/3rd ground volume, 0 = 1/2 ground volume.
875
876         float yblmin = -map_gen_limit + massive_cave_blend * 1.5f;
877         float yblmax = massive_cave_depth - massive_cave_blend * 1.5f;
878         bool made_a_big_one = false;
879
880         // Cache the tcave values as they only vary by altitude.
881         if (node_max.Y <= massive_cave_depth) {
882                 noise_massive_caves->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
883
884                 for (s16 y = node_min.Y - 1; y <= node_max.Y; y++) {
885                         float tcave = massive_cave_threshold;
886
887                         if (y < yblmin) {
888                                 float t = (yblmin - y) / massive_cave_blend;
889                                 tcave += MYSQUARE(t);
890                         } else if (y > yblmax) {
891                                 float t = (y - yblmax) / massive_cave_blend;
892                                 tcave += MYSQUARE(t);
893                         }
894
895                         tcave_cache[y - node_min.Y + 1] = tcave;
896                 }
897         }
898
899         // lava_depth varies between one and ten as you approach
900         //  the bottom of the world.
901         s16 lava_depth = ceil((lava_max_height - node_min.Y + 1) * 10.f / map_gen_limit);
902         // This allows random lava spawns to be less common at the surface.
903         s16 lava_chance = MYCUBE(lava_features_lim) * lava_depth;
904         // water_depth varies between ten and one on the way down.
905         s16 water_depth = ceil((map_gen_limit - abs(node_min.Y) + 1) * 10.f / map_gen_limit);
906         // This allows random water spawns to be more common at the surface.
907         s16 water_chance = MYCUBE(water_features_lim) * water_depth;
908
909         // Reduce the odds of overflows even further.
910         if (node_max.Y > water_level) {
911                 lava_chance /= 3;
912                 water_chance /= 3;
913         }
914
915         u32 index_2d = 0;
916         for (s16 z = node_min.Z; z <= node_max.Z; z++)
917         for (s16 x = node_min.X; x <= node_max.X; x++, index_2d++) {
918                 Biome *biome = (Biome *)bmgr->getRaw(biomemap[index_2d]);
919                 bool tunnel_air_above = false;
920                 bool underground = false;
921                 u32 index_data = vm->m_area.index(x, node_max.Y, z);
922                 u32 index_3d = (z - node_min.Z) * zstride_1d + csize.Y * ystride + (x - node_min.X);
923
924                 // Dig caves on down loop to check for air above.
925                 // Don't excavate the overgenerated stone at node_max.Y + 1,
926                 // this creates a 'roof' over the tunnel, preventing light in
927                 // tunnels at mapchunk borders when generating mapchunks upwards.
928                 // This 'roof' is removed when the mapchunk above is generated.
929                 for (s16 y = node_max.Y; y >= node_min.Y - 1; y--,
930                                 index_3d -= ystride,
931                                 vm->m_area.add_y(em, index_data, -1)) {
932
933                         float terrain = noise_terrain_height->result[index_2d];
934
935                         // Saves some time.
936                         if (y > terrain + 10)
937                                 continue;
938                         else if (y < terrain - 40)
939                                 underground = true;
940
941                         // Dig massive caves.
942                         if (node_max.Y <= massive_cave_depth
943                                         && noise_massive_caves->result[index_3d]
944                                         > tcave_cache[y - node_min.Y + 1]) {
945                                 vm->m_data[index_data] = n_air;
946                                 made_a_big_one = true;
947                                 continue;
948                         }
949
950                         content_t c = vm->m_data[index_data].getContent();
951                         float d1 = contour(noise_cave1->result[index_3d]);
952                         float d2 = contour(noise_cave2->result[index_3d]);
953
954                         // River water is not set as ground content
955                         // in the default game. This can produce strange results
956                         // when a tunnel undercuts a river. However, that's not for
957                         // the mapgen to correct. Fix it in lua.
958
959                         if (d1 * d2 > cave_width && ndef->get(c).is_ground_content) {
960                                 // in a tunnel
961                                 vm->m_data[index_data] = n_air;
962                                 tunnel_air_above = true;
963                         } else if (c == biome->c_filler || c == biome->c_stone) {
964                                 if (tunnel_air_above) {
965                                         // at the tunnel floor
966                                         s16 sr = ps.range(0, 39);
967                                         u32 j = index_data;
968                                         vm->m_area.add_y(em, j, 1);
969
970                                         if (sr > terrain - y) {
971                                                 // Put dirt in tunnels near the surface.
972                                                 if (underground)
973                                                         vm->m_data[index_data] = MapNode(biome->c_filler);
974                                                 else
975                                                         vm->m_data[index_data] = MapNode(biome->c_top);
976                                         } else if (sr < 3 && underground) {
977                                                 sr = abs(ps.next());
978                                                 if (lava_features_lim > 0 && y <= lava_max_height
979                                                                 && c == biome->c_stone && sr < lava_chance)
980                                                         vm->m_data[j] = n_lava;
981
982                                                 sr -= lava_chance;
983
984                                                 // If sr < 0 then we should have already placed lava --
985                                                 // don't immediately dump water on it.
986                                                 if (water_features_lim > 0 && y <= cave_water_max_height
987                                                                 && sr >= 0 && sr < water_chance)
988                                                         vm->m_data[j] = n_water;
989                                         }
990                                 }
991
992                                 tunnel_air_above = false;
993                                 underground = true;
994                         } else {
995                                 tunnel_air_above = false;
996                         }
997                 }
998         }
999
1000         if (node_max.Y <= large_cave_depth && !made_a_big_one) {
1001                 u32 bruises_count = ps.range(0, 2);
1002                 for (u32 i = 0; i < bruises_count; i++) {
1003                         CaveV5 cave(this, &ps);
1004                         cave.makeCave(node_min, node_max, max_stone_y);
1005                 }
1006         }
1007 }