Move files to subdirectories (#6599)
[oweals/minetest.git] / src / mapgen / mapgen_carpathian.cpp
1 /*
2 Minetest
3 Copyright (C) 2010-2016 paramat, Matt Gregory
4 Copyright (C) 2010-2016 kwolekr, Ryan Kwolek <kwolekr@minetest.net>
5 Copyright (C) 2017 vlapsley, Vaughan Lapsley <vlapsley@gmail.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22
23 #include <cmath>
24 #include "mapgen.h"
25 #include "voxel.h"
26 #include "noise.h"
27 #include "mapblock.h"
28 #include "mapnode.h"
29 #include "map.h"
30 #include "content_sao.h"
31 #include "nodedef.h"
32 #include "voxelalgorithms.h"
33 //#include "profiler.h" // For TimeTaker
34 #include "settings.h" // For g_settings
35 #include "emerge.h"
36 #include "dungeongen.h"
37 #include "cavegen.h"
38 #include "mg_biome.h"
39 #include "mg_ore.h"
40 #include "mg_decoration.h"
41 #include "mapgen_carpathian.h"
42
43
44 FlagDesc flagdesc_mapgen_carpathian[] = {
45         {"caverns", MGCARPATHIAN_CAVERNS},
46         {NULL,      0}
47 };
48
49
50 ///////////////////////////////////////////////////////////////////////////////
51
52
53 MapgenCarpathian::MapgenCarpathian(
54                 int mapgenid, MapgenCarpathianParams *params, EmergeManager *emerge)
55         : MapgenBasic(mapgenid, params, emerge)
56 {
57         spflags          = params->spflags;
58         cave_width       = params->cave_width;
59         large_cave_depth = params->large_cave_depth;
60         lava_depth       = params->lava_depth;
61         cavern_limit     = params->cavern_limit;
62         cavern_taper     = params->cavern_taper;
63         cavern_threshold = params->cavern_threshold;
64         grad_wl          = 1 - water_level;
65
66         //// 2D Terrain noise
67         noise_base          = new Noise(&params->np_base,          seed, csize.X, csize.Z);
68         noise_filler_depth  = new Noise(&params->np_filler_depth,  seed, csize.X, csize.Z);
69         noise_height1       = new Noise(&params->np_height1,       seed, csize.X, csize.Z);
70         noise_height2       = new Noise(&params->np_height2,       seed, csize.X, csize.Z);
71         noise_height3       = new Noise(&params->np_height3,       seed, csize.X, csize.Z);
72         noise_height4       = new Noise(&params->np_height4,       seed, csize.X, csize.Z);
73         noise_hills_terrain = new Noise(&params->np_hills_terrain, seed, csize.X, csize.Z);
74         noise_ridge_terrain = new Noise(&params->np_ridge_terrain, seed, csize.X, csize.Z);
75         noise_step_terrain  = new Noise(&params->np_step_terrain,  seed, csize.X, csize.Z);
76         noise_hills         = new Noise(&params->np_hills,         seed, csize.X, csize.Z);
77         noise_ridge_mnt     = new Noise(&params->np_ridge_mnt,     seed, csize.X, csize.Z);
78         noise_step_mnt      = new Noise(&params->np_step_mnt,      seed, csize.X, csize.Z);
79
80         //// 3D terrain noise
81         // 1 up 1 down overgeneration
82         noise_mnt_var = new Noise(&params->np_mnt_var, seed, csize.X, csize.Y + 2, csize.Z);
83
84         //// Cave noise
85         MapgenBasic::np_cave1  = params->np_cave1;
86         MapgenBasic::np_cave2  = params->np_cave2;
87         MapgenBasic::np_cavern = params->np_cavern;
88 }
89
90
91 MapgenCarpathian::~MapgenCarpathian()
92 {
93         delete noise_base;
94         delete noise_filler_depth;
95         delete noise_height1;
96         delete noise_height2;
97         delete noise_height3;
98         delete noise_height4;
99         delete noise_hills_terrain;
100         delete noise_ridge_terrain;
101         delete noise_step_terrain;
102         delete noise_hills;
103         delete noise_ridge_mnt;
104         delete noise_step_mnt;
105         delete noise_mnt_var;
106 }
107
108
109 MapgenCarpathianParams::MapgenCarpathianParams():
110         np_base          (12, 1,  v3f(2557, 2557, 2557), 6538,  4, 0.8,  0.5),
111         np_filler_depth  (0,  1,  v3f(128,  128,  128),  261,   3, 0.7,  2.0),
112         np_height1       (0,  5,  v3f(251,  251,  251),  9613,  5, 0.5,  2.0),
113         np_height2       (0,  5,  v3f(383,  383,  383),  1949,  5, 0.5,  2.0),
114         np_height3       (0,  5,  v3f(509,  509,  509),  3211,  5, 0.5,  2.0),
115         np_height4       (0,  5,  v3f(631,  631,  631),  1583,  5, 0.5,  2.0),
116         np_hills_terrain (1,  1,  v3f(1301, 1301, 1301), 1692,  5, 0.5,  2.0),
117         np_ridge_terrain (1,  1,  v3f(1889, 1889, 1889), 3568,  5, 0.5,  2.0),
118         np_step_terrain  (1,  1,  v3f(1889, 1889, 1889), 4157,  5, 0.5,  2.0),
119         np_hills         (0,  3,  v3f(257,  257,  257),  6604,  6, 0.5,  2.0),
120         np_ridge_mnt     (0,  12, v3f(743,  743,  743),  5520,  6, 0.7,  2.0),
121         np_step_mnt      (0,  8,  v3f(509,  509,  509),  2590,  6, 0.6,  2.0),
122         np_mnt_var       (0,  1,  v3f(499,  499,  499),  2490,  5, 0.55, 2.0),
123         np_cave1         (0,  12, v3f(61,   61,   61),   52534, 3, 0.5,  2.0),
124         np_cave2         (0,  12, v3f(67,   67,   67),   10325, 3, 0.5,  2.0),
125         np_cavern        (0,  1,  v3f(384,  128,  384),  723,   5, 0.63, 2.0)
126 {
127 }
128
129
130 void MapgenCarpathianParams::readParams(const Settings *settings)
131 {
132         settings->getFlagStrNoEx("mgcarpathian_spflags", spflags, flagdesc_mapgen_carpathian);
133         settings->getFloatNoEx("mgcarpathian_cave_width",       cave_width);
134         settings->getS16NoEx("mgcarpathian_large_cave_depth",   large_cave_depth);
135         settings->getS16NoEx("mgcarpathian_lava_depth",         lava_depth);
136         settings->getS16NoEx("mgcarpathian_cavern_limit",       cavern_limit);
137         settings->getS16NoEx("mgcarpathian_cavern_taper",       cavern_taper);
138         settings->getFloatNoEx("mgcarpathian_cavern_threshold", cavern_threshold);
139
140         settings->getNoiseParams("mgcarpathian_np_base",          np_base);
141         settings->getNoiseParams("mgcarpathian_np_filler_depth",  np_filler_depth);
142         settings->getNoiseParams("mgcarpathian_np_height1",       np_height1);
143         settings->getNoiseParams("mgcarpathian_np_height2",       np_height2);
144         settings->getNoiseParams("mgcarpathian_np_height3",       np_height3);
145         settings->getNoiseParams("mgcarpathian_np_height4",       np_height4);
146         settings->getNoiseParams("mgcarpathian_np_hills_terrain", np_hills_terrain);
147         settings->getNoiseParams("mgcarpathian_np_ridge_terrain", np_ridge_terrain);
148         settings->getNoiseParams("mgcarpathian_np_step_terrain",  np_step_terrain);
149         settings->getNoiseParams("mgcarpathian_np_hills",         np_hills);
150         settings->getNoiseParams("mgcarpathian_np_ridge_mnt",     np_ridge_mnt);
151         settings->getNoiseParams("mgcarpathian_np_step_mnt",      np_step_mnt);
152         settings->getNoiseParams("mgcarpathian_np_mnt_var",       np_mnt_var);
153         settings->getNoiseParams("mgcarpathian_np_cave1",         np_cave1);
154         settings->getNoiseParams("mgcarpathian_np_cave2",         np_cave2);
155         settings->getNoiseParams("mgcarpathian_np_cavern",        np_cavern);
156 }
157
158
159 void MapgenCarpathianParams::writeParams(Settings *settings) const
160 {
161         settings->setFlagStr("mgcarpathian_spflags", spflags, flagdesc_mapgen_carpathian, U32_MAX);
162         settings->setFloat("mgcarpathian_cave_width",       cave_width);
163         settings->setS16("mgcarpathian_large_cave_depth",   large_cave_depth);
164         settings->setS16("mgcarpathian_lava_depth",         lava_depth);
165         settings->setS16("mgcarpathian_cavern_limit",       cavern_limit);
166         settings->setS16("mgcarpathian_cavern_taper",       cavern_taper);
167         settings->setFloat("mgcarpathian_cavern_threshold", cavern_threshold);
168
169         settings->setNoiseParams("mgcarpathian_np_base",          np_base);
170         settings->setNoiseParams("mgcarpathian_np_filler_depth",  np_filler_depth);
171         settings->setNoiseParams("mgcarpathian_np_height1",       np_height1);
172         settings->setNoiseParams("mgcarpathian_np_height2",       np_height2);
173         settings->setNoiseParams("mgcarpathian_np_height3",       np_height3);
174         settings->setNoiseParams("mgcarpathian_np_height4",       np_height4);
175         settings->setNoiseParams("mgcarpathian_np_hills_terrain", np_hills_terrain);
176         settings->setNoiseParams("mgcarpathian_np_ridge_terrain", np_ridge_terrain);
177         settings->setNoiseParams("mgcarpathian_np_step_terrain",  np_step_terrain);
178         settings->setNoiseParams("mgcarpathian_np_hills",         np_hills);
179         settings->setNoiseParams("mgcarpathian_np_ridge_mnt",     np_ridge_mnt);
180         settings->setNoiseParams("mgcarpathian_np_step_mnt",      np_step_mnt);
181         settings->setNoiseParams("mgcarpathian_np_mnt_var",       np_mnt_var);
182         settings->setNoiseParams("mgcarpathian_np_cave1",         np_cave1);
183         settings->setNoiseParams("mgcarpathian_np_cave2",         np_cave2);
184         settings->setNoiseParams("mgcarpathian_np_cavern",        np_cavern);
185 }
186
187
188 ///////////////////////////////////////////////////////////////////////////////
189
190
191 // Lerp function
192 inline float MapgenCarpathian::getLerp(float noise1, float noise2, float mod)
193 {
194         return noise1 + mod * (noise2 - noise1);
195 }
196
197 // Steps function
198 float MapgenCarpathian::getSteps(float noise)
199 {
200         float w = 0.5f;
201         float k = floor(noise / w);
202         float f = (noise - k * w) / w;
203         float s = std::fmin(2.f * f, 1.f);
204         return (k + s) * w;
205 }
206
207
208 ///////////////////////////////////////////////////////////////////////////////
209
210
211 void MapgenCarpathian::makeChunk(BlockMakeData *data)
212 {
213         // Pre-conditions
214         assert(data->vmanip);
215         assert(data->nodedef);
216         assert(data->blockpos_requested.X >= data->blockpos_min.X &&
217                         data->blockpos_requested.Y >= data->blockpos_min.Y &&
218                         data->blockpos_requested.Z >= data->blockpos_min.Z);
219         assert(data->blockpos_requested.X <= data->blockpos_max.X &&
220                         data->blockpos_requested.Y <= data->blockpos_max.Y &&
221                         data->blockpos_requested.Z <= data->blockpos_max.Z);
222
223         this->generating = true;
224         this->vm = data->vmanip;
225         this->ndef = data->nodedef;
226
227         v3s16 blockpos_min = data->blockpos_min;
228         v3s16 blockpos_max = data->blockpos_max;
229         node_min = blockpos_min * MAP_BLOCKSIZE;
230         node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
231         full_node_min = (blockpos_min - 1) * MAP_BLOCKSIZE;
232         full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
233
234         // Create a block-specific seed
235         blockseed = getBlockSeed2(full_node_min, seed);
236
237         // Generate terrain
238         s16 stone_surface_max_y = generateTerrain();
239
240         // Create heightmap
241         updateHeightmap(node_min, node_max);
242
243         // Init biome generator, place biome-specific nodes, and build biomemap
244         biomegen->calcBiomeNoise(node_min);
245
246         MgStoneType mgstone_type;
247         content_t biome_stone;
248         generateBiomes(&mgstone_type, &biome_stone);
249
250         // Generate caverns, tunnels and classic caves
251         if (flags & MG_CAVES) {
252                 bool has_cavern = false;
253                 // Generate caverns
254                 if (spflags & MGCARPATHIAN_CAVERNS)
255                         has_cavern = generateCaverns(stone_surface_max_y);
256                 // Generate tunnels and classic caves
257                 if (has_cavern)
258                         // Disable classic caves in this mapchunk by setting
259                         // 'large cave depth' to world base. Avoids excessive liquid in
260                         // large caverns and floating blobs of overgenerated liquid.
261                         generateCaves(stone_surface_max_y, -MAX_MAP_GENERATION_LIMIT);
262                 else
263                         generateCaves(stone_surface_max_y, large_cave_depth);
264         }
265
266         // Generate dungeons
267         if (flags & MG_DUNGEONS)
268                 generateDungeons(stone_surface_max_y, mgstone_type, biome_stone);
269
270         // Generate the registered decorations
271         if (flags & MG_DECORATIONS)
272                 m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
273
274         // Generate the registered ores
275         m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max);
276
277         // Sprinkle some dust on top after everything else was generated
278         dustTopNodes();
279
280         // Update liquids
281         updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
282
283         // Calculate lighting
284         if (flags & MG_LIGHT) {
285                 calcLighting(node_min - v3s16(0, 1, 0), node_max + v3s16(0, 1, 0),
286                                 full_node_min, full_node_max);
287         }
288
289         this->generating = false;
290 }
291
292
293 ///////////////////////////////////////////////////////////////////////////////
294
295
296 int MapgenCarpathian::getSpawnLevelAtPoint(v2s16 p)
297 {
298         s16 level_at_point = terrainLevelAtPoint(p.X, p.Y);
299         if (level_at_point <= water_level || level_at_point > water_level + 32)
300                 return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
301
302         return level_at_point;
303 }
304
305
306 float MapgenCarpathian::terrainLevelAtPoint(s16 x, s16 z)
307 {
308         float ground = NoisePerlin2D(&noise_base->np, x, z, seed);
309         float height1 = NoisePerlin2D(&noise_height1->np, x, z, seed);
310         float height2 = NoisePerlin2D(&noise_height2->np, x, z, seed);
311         float height3 = NoisePerlin2D(&noise_height3->np, x, z, seed);
312         float height4 = NoisePerlin2D(&noise_height4->np, x, z, seed);
313         float hter = NoisePerlin2D(&noise_hills_terrain->np, x, z, seed);
314         float rter = NoisePerlin2D(&noise_ridge_terrain->np, x, z, seed);
315         float ster = NoisePerlin2D(&noise_step_terrain->np, x, z, seed);
316         float n_hills = NoisePerlin2D(&noise_hills->np, x, z, seed);
317         float n_ridge_mnt = NoisePerlin2D(&noise_ridge_mnt->np, x, z, seed);
318         float n_step_mnt = NoisePerlin2D(&noise_step_mnt->np, x, z, seed);
319
320         int height = -MAX_MAP_GENERATION_LIMIT;
321
322         for (s16 y = 1; y <= 30; y++) {
323                 float mnt_var = NoisePerlin3D(&noise_mnt_var->np, x, y, z, seed);
324
325                 // Gradient & shallow seabed
326                 s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 : 1 - y;
327
328                 // Hill/Mountain height (hilliness)
329                 float hill1 = getLerp(height1, height2, mnt_var);
330                 float hill2 = getLerp(height3, height4, mnt_var);
331                 float hill3 = getLerp(height3, height2, mnt_var);
332                 float hill4 = getLerp(height1, height4, mnt_var);
333                 float hilliness = std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
334
335                 // Rolling hills
336                 float hill_mnt = hilliness * pow(n_hills, 2.f);
337                 float hills = pow(hter, 3.f) * hill_mnt;
338
339                 // Ridged mountains
340                 float ridge_mnt = hilliness * (1.f - fabs(n_ridge_mnt));
341                 float ridged_mountains = pow(rter, 3.f) * ridge_mnt;
342
343                 // Step (terraced) mountains
344                 float step_mnt = hilliness * getSteps(n_step_mnt);
345                 float step_mountains = pow(ster, 3.f) * step_mnt;
346
347                 // Final terrain level
348                 float mountains = hills + ridged_mountains + step_mountains;
349                 float surface_level = ground + mountains + grad;
350
351                 if (y > surface_level && height < 0)
352                         height = y;
353         }
354
355         return height;
356 }
357
358
359 ///////////////////////////////////////////////////////////////////////////////
360
361
362 int MapgenCarpathian::generateTerrain()
363 {
364         MapNode mn_air(CONTENT_AIR);
365         MapNode mn_stone(c_stone);
366         MapNode mn_water(c_water_source);
367
368         s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT;
369         u32 index2d = 0;
370         u32 index3d = 0;
371
372         // Calculate noise for terrain generation
373         noise_base->perlinMap2D(node_min.X, node_min.Z);
374         noise_height1->perlinMap2D(node_min.X, node_min.Z);
375         noise_height2->perlinMap2D(node_min.X, node_min.Z);
376         noise_height3->perlinMap2D(node_min.X, node_min.Z);
377         noise_height4->perlinMap2D(node_min.X, node_min.Z);
378         noise_hills_terrain->perlinMap2D(node_min.X, node_min.Z);
379         noise_ridge_terrain->perlinMap2D(node_min.X, node_min.Z);
380         noise_step_terrain->perlinMap2D(node_min.X, node_min.Z);
381         noise_hills->perlinMap2D(node_min.X, node_min.Z);
382         noise_ridge_mnt->perlinMap2D(node_min.X, node_min.Z);
383         noise_step_mnt->perlinMap2D(node_min.X, node_min.Z);
384         noise_mnt_var->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
385
386         //// Place nodes
387         for (s16 z = node_min.Z; z <= node_max.Z; z++) {
388                 for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) {
389                         u32 vi = vm->m_area.index(node_min.X, y, z);
390                         for (s16 x = node_min.X; x <= node_max.X;
391                                         x++, vi++, index2d++, index3d++) {
392                                 if (vm->m_data[vi].getContent() != CONTENT_IGNORE)
393                                         continue;
394
395                                 // Base terrain
396                                 float ground = noise_base->result[index2d];
397
398                                 // Gradient & shallow seabed
399                                 s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 : 1 - y;
400
401                                 // Hill/Mountain height (hilliness)
402                                 float height1 = noise_height1->result[index2d];
403                                 float height2 = noise_height2->result[index2d];
404                                 float height3 = noise_height3->result[index2d];
405                                 float height4 = noise_height4->result[index2d];
406                                 float mnt_var = noise_mnt_var->result[index3d];
407                                 // Combine height noises and apply 3D variation
408                                 float hill1 = getLerp(height1, height2, mnt_var);
409                                 float hill2 = getLerp(height3, height4, mnt_var);
410                                 float hill3 = getLerp(height3, height2, mnt_var);
411                                 float hill4 = getLerp(height1, height4, mnt_var);
412                                 // 'hilliness' determines whether hills/mountains are
413                                 // small or large
414                                 float hilliness = std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
415
416                                 // Rolling hills
417                                 float hter = noise_hills_terrain->result[index2d];
418                                 float n_hills = noise_hills->result[index2d];
419                                 float hill_mnt = hilliness * pow(n_hills, 2.f);
420                                 float hills = pow(fabs(hter), 3.f) * hill_mnt;
421
422                                 // Ridged mountains
423                                 float rter = noise_ridge_terrain->result[index2d];
424                                 float n_ridge_mnt = noise_ridge_mnt->result[index2d];
425                                 float ridge_mnt = hilliness * (1.f - fabs(n_ridge_mnt));
426                                 float ridged_mountains = pow(fabs(rter), 3.f) * ridge_mnt;
427
428                                 // Step (terraced) mountains
429                                 float ster = noise_step_terrain->result[index2d];
430                                 float n_step_mnt = noise_step_mnt->result[index2d];
431                                 float step_mnt = hilliness * getSteps(n_step_mnt);
432                                 float step_mountains = pow(fabs(ster), 3.f) * step_mnt;
433
434                                 // Final terrain level
435                                 float mountains = hills + ridged_mountains + step_mountains;
436                                 float surface_level = ground + mountains + grad;
437
438                                 if (y < surface_level) {
439                                         vm->m_data[vi] = mn_stone; // Stone
440                                         if (y > stone_surface_max_y)
441                                                 stone_surface_max_y = y;
442                                 } else if (y <= water_level) {
443                                         vm->m_data[vi] = mn_water; // Sea water
444                                 } else {
445                                         vm->m_data[vi] = mn_air; // Air
446                                 }
447                         }
448                         index2d -= ystride;
449                 }
450                 index2d += ystride;
451         }
452
453         return stone_surface_max_y;
454 }