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