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