3 Copyright (C) 2017-2018 vlapsley, Vaughan Lapsley <vlapsley@gmail.com>
4 Copyright (C) 2010-2018 paramat
5 Copyright (C) 2010-2018 kwolekr, Ryan Kwolek <kwolekr@minetest.net>
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.
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.
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.
30 #include "content_sao.h"
32 #include "voxelalgorithms.h"
33 //#include "profiler.h" // For TimeTaker
34 #include "settings.h" // For g_settings
36 #include "dungeongen.h"
40 #include "mg_decoration.h"
41 #include "mapgen_carpathian.h"
44 FlagDesc flagdesc_mapgen_carpathian[] = {
45 {"caverns", MGCARPATHIAN_CAVERNS},
50 ///////////////////////////////////////////////////////////////////////////////
53 MapgenCarpathian::MapgenCarpathian(MapgenCarpathianParams *params, EmergeManager *emerge)
54 : MapgenBasic(MAPGEN_CARPATHIAN, params, emerge)
56 base_level = params->base_level;
58 spflags = params->spflags;
59 cave_width = params->cave_width;
60 large_cave_depth = params->large_cave_depth;
61 lava_depth = params->lava_depth;
62 cavern_limit = params->cavern_limit;
63 cavern_taper = params->cavern_taper;
64 cavern_threshold = params->cavern_threshold;
65 dungeon_ymin = params->dungeon_ymin;
66 dungeon_ymax = params->dungeon_ymax;
68 grad_wl = 1 - water_level;
71 noise_filler_depth = new Noise(¶ms->np_filler_depth, seed, csize.X, csize.Z);
72 noise_height1 = new Noise(¶ms->np_height1, seed, csize.X, csize.Z);
73 noise_height2 = new Noise(¶ms->np_height2, seed, csize.X, csize.Z);
74 noise_height3 = new Noise(¶ms->np_height3, seed, csize.X, csize.Z);
75 noise_height4 = new Noise(¶ms->np_height4, seed, csize.X, csize.Z);
76 noise_hills_terrain = new Noise(¶ms->np_hills_terrain, seed, csize.X, csize.Z);
77 noise_ridge_terrain = new Noise(¶ms->np_ridge_terrain, seed, csize.X, csize.Z);
78 noise_step_terrain = new Noise(¶ms->np_step_terrain, seed, csize.X, csize.Z);
79 noise_hills = new Noise(¶ms->np_hills, seed, csize.X, csize.Z);
80 noise_ridge_mnt = new Noise(¶ms->np_ridge_mnt, seed, csize.X, csize.Z);
81 noise_step_mnt = new Noise(¶ms->np_step_mnt, seed, csize.X, csize.Z);
84 // 1 up 1 down overgeneration
85 noise_mnt_var = new Noise(¶ms->np_mnt_var, seed, csize.X, csize.Y + 2, csize.Z);
88 MapgenBasic::np_cave1 = params->np_cave1;
89 MapgenBasic::np_cave2 = params->np_cave2;
90 MapgenBasic::np_cavern = params->np_cavern;
94 MapgenCarpathian::~MapgenCarpathian()
96 delete noise_filler_depth;
100 delete noise_height4;
101 delete noise_hills_terrain;
102 delete noise_ridge_terrain;
103 delete noise_step_terrain;
105 delete noise_ridge_mnt;
106 delete noise_step_mnt;
107 delete noise_mnt_var;
111 MapgenCarpathianParams::MapgenCarpathianParams():
112 np_filler_depth (0, 1, v3f(128, 128, 128), 261, 3, 0.7, 2.0),
113 np_height1 (0, 5, v3f(251, 251, 251), 9613, 5, 0.5, 2.0),
114 np_height2 (0, 5, v3f(383, 383, 383), 1949, 5, 0.5, 2.0),
115 np_height3 (0, 5, v3f(509, 509, 509), 3211, 5, 0.5, 2.0),
116 np_height4 (0, 5, v3f(631, 631, 631), 1583, 5, 0.5, 2.0),
117 np_hills_terrain (1, 1, v3f(1301, 1301, 1301), 1692, 5, 0.5, 2.0),
118 np_ridge_terrain (1, 1, v3f(1889, 1889, 1889), 3568, 5, 0.5, 2.0),
119 np_step_terrain (1, 1, v3f(1889, 1889, 1889), 4157, 5, 0.5, 2.0),
120 np_hills (0, 3, v3f(257, 257, 257), 6604, 6, 0.5, 2.0),
121 np_ridge_mnt (0, 12, v3f(743, 743, 743), 5520, 6, 0.7, 2.0),
122 np_step_mnt (0, 8, v3f(509, 509, 509), 2590, 6, 0.6, 2.0),
123 np_mnt_var (0, 1, v3f(499, 499, 499), 2490, 5, 0.55, 2.0),
124 np_cave1 (0, 12, v3f(61, 61, 61), 52534, 3, 0.5, 2.0),
125 np_cave2 (0, 12, v3f(67, 67, 67), 10325, 3, 0.5, 2.0),
126 np_cavern (0, 1, v3f(384, 128, 384), 723, 5, 0.63, 2.0)
131 void MapgenCarpathianParams::readParams(const Settings *settings)
133 settings->getFlagStrNoEx("mgcarpathian_spflags", spflags, flagdesc_mapgen_carpathian);
134 settings->getFloatNoEx("mgcarpathian_base_level", base_level);
135 settings->getFloatNoEx("mgcarpathian_cave_width", cave_width);
136 settings->getS16NoEx("mgcarpathian_large_cave_depth", large_cave_depth);
137 settings->getS16NoEx("mgcarpathian_lava_depth", lava_depth);
138 settings->getS16NoEx("mgcarpathian_cavern_limit", cavern_limit);
139 settings->getS16NoEx("mgcarpathian_cavern_taper", cavern_taper);
140 settings->getFloatNoEx("mgcarpathian_cavern_threshold", cavern_threshold);
141 settings->getS16NoEx("mgcarpathian_dungeon_ymin", dungeon_ymin);
142 settings->getS16NoEx("mgcarpathian_dungeon_ymax", dungeon_ymax);
144 settings->getNoiseParams("mgcarpathian_np_filler_depth", np_filler_depth);
145 settings->getNoiseParams("mgcarpathian_np_height1", np_height1);
146 settings->getNoiseParams("mgcarpathian_np_height2", np_height2);
147 settings->getNoiseParams("mgcarpathian_np_height3", np_height3);
148 settings->getNoiseParams("mgcarpathian_np_height4", np_height4);
149 settings->getNoiseParams("mgcarpathian_np_hills_terrain", np_hills_terrain);
150 settings->getNoiseParams("mgcarpathian_np_ridge_terrain", np_ridge_terrain);
151 settings->getNoiseParams("mgcarpathian_np_step_terrain", np_step_terrain);
152 settings->getNoiseParams("mgcarpathian_np_hills", np_hills);
153 settings->getNoiseParams("mgcarpathian_np_ridge_mnt", np_ridge_mnt);
154 settings->getNoiseParams("mgcarpathian_np_step_mnt", np_step_mnt);
155 settings->getNoiseParams("mgcarpathian_np_mnt_var", np_mnt_var);
156 settings->getNoiseParams("mgcarpathian_np_cave1", np_cave1);
157 settings->getNoiseParams("mgcarpathian_np_cave2", np_cave2);
158 settings->getNoiseParams("mgcarpathian_np_cavern", np_cavern);
162 void MapgenCarpathianParams::writeParams(Settings *settings) const
164 settings->setFlagStr("mgcarpathian_spflags", spflags, flagdesc_mapgen_carpathian, U32_MAX);
165 settings->setFloat("mgcarpathian_base_level", base_level);
166 settings->setFloat("mgcarpathian_cave_width", cave_width);
167 settings->setS16("mgcarpathian_large_cave_depth", large_cave_depth);
168 settings->setS16("mgcarpathian_lava_depth", lava_depth);
169 settings->setS16("mgcarpathian_cavern_limit", cavern_limit);
170 settings->setS16("mgcarpathian_cavern_taper", cavern_taper);
171 settings->setFloat("mgcarpathian_cavern_threshold", cavern_threshold);
172 settings->setS16("mgcarpathian_dungeon_ymin", dungeon_ymin);
173 settings->setS16("mgcarpathian_dungeon_ymax", dungeon_ymax);
175 settings->setNoiseParams("mgcarpathian_np_filler_depth", np_filler_depth);
176 settings->setNoiseParams("mgcarpathian_np_height1", np_height1);
177 settings->setNoiseParams("mgcarpathian_np_height2", np_height2);
178 settings->setNoiseParams("mgcarpathian_np_height3", np_height3);
179 settings->setNoiseParams("mgcarpathian_np_height4", np_height4);
180 settings->setNoiseParams("mgcarpathian_np_hills_terrain", np_hills_terrain);
181 settings->setNoiseParams("mgcarpathian_np_ridge_terrain", np_ridge_terrain);
182 settings->setNoiseParams("mgcarpathian_np_step_terrain", np_step_terrain);
183 settings->setNoiseParams("mgcarpathian_np_hills", np_hills);
184 settings->setNoiseParams("mgcarpathian_np_ridge_mnt", np_ridge_mnt);
185 settings->setNoiseParams("mgcarpathian_np_step_mnt", np_step_mnt);
186 settings->setNoiseParams("mgcarpathian_np_mnt_var", np_mnt_var);
187 settings->setNoiseParams("mgcarpathian_np_cave1", np_cave1);
188 settings->setNoiseParams("mgcarpathian_np_cave2", np_cave2);
189 settings->setNoiseParams("mgcarpathian_np_cavern", np_cavern);
193 ////////////////////////////////////////////////////////////////////////////////
197 inline float MapgenCarpathian::getLerp(float noise1, float noise2, float mod)
199 return noise1 + mod * (noise2 - noise1);
203 float MapgenCarpathian::getSteps(float noise)
206 float k = std::floor(noise / w);
207 float f = (noise - k * w) / w;
208 float s = std::fmin(2.f * f, 1.f);
213 ////////////////////////////////////////////////////////////////////////////////
216 void MapgenCarpathian::makeChunk(BlockMakeData *data)
219 assert(data->vmanip);
220 assert(data->nodedef);
221 assert(data->blockpos_requested.X >= data->blockpos_min.X &&
222 data->blockpos_requested.Y >= data->blockpos_min.Y &&
223 data->blockpos_requested.Z >= data->blockpos_min.Z);
224 assert(data->blockpos_requested.X <= data->blockpos_max.X &&
225 data->blockpos_requested.Y <= data->blockpos_max.Y &&
226 data->blockpos_requested.Z <= data->blockpos_max.Z);
228 this->generating = true;
229 this->vm = data->vmanip;
230 this->ndef = data->nodedef;
232 v3s16 blockpos_min = data->blockpos_min;
233 v3s16 blockpos_max = data->blockpos_max;
234 node_min = blockpos_min * MAP_BLOCKSIZE;
235 node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
236 full_node_min = (blockpos_min - 1) * MAP_BLOCKSIZE;
237 full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
239 // Create a block-specific seed
240 blockseed = getBlockSeed2(full_node_min, seed);
243 s16 stone_surface_max_y = generateTerrain();
246 updateHeightmap(node_min, node_max);
248 // Init biome generator, place biome-specific nodes, and build biomemap
249 if (flags & MG_BIOMES) {
250 biomegen->calcBiomeNoise(node_min);
254 // Generate tunnels, caverns and large randomwalk caves
255 if (flags & MG_CAVES) {
256 // Generate tunnels first as caverns confuse them
257 generateCavesNoiseIntersection(stone_surface_max_y);
260 bool near_cavern = false;
261 if (spflags & MGCARPATHIAN_CAVERNS)
262 near_cavern = generateCavernsNoise(stone_surface_max_y);
264 // Generate large randomwalk caves
266 // Disable large randomwalk caves in this mapchunk by setting
267 // 'large cave depth' to world base. Avoids excessive liquid in
268 // large caverns and floating blobs of overgenerated liquid.
269 generateCavesRandomWalk(stone_surface_max_y,
270 -MAX_MAP_GENERATION_LIMIT);
272 generateCavesRandomWalk(stone_surface_max_y, large_cave_depth);
275 // Generate the registered ores
276 m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max);
279 if ((flags & MG_DUNGEONS) && full_node_min.Y >= dungeon_ymin &&
280 full_node_max.Y <= dungeon_ymax)
281 generateDungeons(stone_surface_max_y);
283 // Generate the registered decorations
284 if (flags & MG_DECORATIONS)
285 m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
287 // Sprinkle some dust on top after everything else was generated
288 if (flags & MG_BIOMES)
292 updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
294 // Calculate lighting
295 if (flags & MG_LIGHT) {
296 calcLighting(node_min - v3s16(0, 1, 0), node_max + v3s16(0, 1, 0),
297 full_node_min, full_node_max);
300 this->generating = false;
304 ////////////////////////////////////////////////////////////////////////////////
307 int MapgenCarpathian::getSpawnLevelAtPoint(v2s16 p)
309 s16 level_at_point = terrainLevelAtPoint(p.X, p.Y);
310 if (level_at_point <= water_level || level_at_point > water_level + 32)
311 return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
313 return level_at_point;
317 float MapgenCarpathian::terrainLevelAtPoint(s16 x, s16 z)
319 float height1 = NoisePerlin2D(&noise_height1->np, x, z, seed);
320 float height2 = NoisePerlin2D(&noise_height2->np, x, z, seed);
321 float height3 = NoisePerlin2D(&noise_height3->np, x, z, seed);
322 float height4 = NoisePerlin2D(&noise_height4->np, x, z, seed);
323 float hter = NoisePerlin2D(&noise_hills_terrain->np, x, z, seed);
324 float rter = NoisePerlin2D(&noise_ridge_terrain->np, x, z, seed);
325 float ster = NoisePerlin2D(&noise_step_terrain->np, x, z, seed);
326 float n_hills = NoisePerlin2D(&noise_hills->np, x, z, seed);
327 float n_ridge_mnt = NoisePerlin2D(&noise_ridge_mnt->np, x, z, seed);
328 float n_step_mnt = NoisePerlin2D(&noise_step_mnt->np, x, z, seed);
330 int height = -MAX_MAP_GENERATION_LIMIT;
332 for (s16 y = 1; y <= 30; y++) {
333 float mnt_var = NoisePerlin3D(&noise_mnt_var->np, x, y, z, seed);
335 // Gradient & shallow seabed
336 s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 : 1 - y;
338 // Hill/Mountain height (hilliness)
339 float hill1 = getLerp(height1, height2, mnt_var);
340 float hill2 = getLerp(height3, height4, mnt_var);
341 float hill3 = getLerp(height3, height2, mnt_var);
342 float hill4 = getLerp(height1, height4, mnt_var);
344 std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
347 float hill_mnt = hilliness * std::pow(n_hills, 2.f);
348 float hills = std::pow(std::fabs(hter), 3.f) * hill_mnt;
351 float ridge_mnt = hilliness * (1.f - std::fabs(n_ridge_mnt));
352 float ridged_mountains = std::pow(std::fabs(rter), 3.f) * ridge_mnt;
354 // Step (terraced) mountains
355 float step_mnt = hilliness * getSteps(n_step_mnt);
356 float step_mountains = std::pow(std::fabs(ster), 3.f) * step_mnt;
358 // Final terrain level
359 float mountains = hills + ridged_mountains + step_mountains;
360 float surface_level = base_level + mountains + grad;
362 if (y > surface_level && height < 0)
370 ////////////////////////////////////////////////////////////////////////////////
373 int MapgenCarpathian::generateTerrain()
375 MapNode mn_air(CONTENT_AIR);
376 MapNode mn_stone(c_stone);
377 MapNode mn_water(c_water_source);
379 // Calculate noise for terrain generation
380 noise_height1->perlinMap2D(node_min.X, node_min.Z);
381 noise_height2->perlinMap2D(node_min.X, node_min.Z);
382 noise_height3->perlinMap2D(node_min.X, node_min.Z);
383 noise_height4->perlinMap2D(node_min.X, node_min.Z);
384 noise_hills_terrain->perlinMap2D(node_min.X, node_min.Z);
385 noise_ridge_terrain->perlinMap2D(node_min.X, node_min.Z);
386 noise_step_terrain->perlinMap2D(node_min.X, node_min.Z);
387 noise_hills->perlinMap2D(node_min.X, node_min.Z);
388 noise_ridge_mnt->perlinMap2D(node_min.X, node_min.Z);
389 noise_step_mnt->perlinMap2D(node_min.X, node_min.Z);
390 noise_mnt_var->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
393 const v3s16 &em = vm->m_area.getExtent();
394 s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT;
397 for (s16 z = node_min.Z; z <= node_max.Z; z++)
398 for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
399 // Hill/Mountain height (hilliness)
400 float height1 = noise_height1->result[index2d];
401 float height2 = noise_height2->result[index2d];
402 float height3 = noise_height3->result[index2d];
403 float height4 = noise_height4->result[index2d];
406 float hterabs = std::fabs(noise_hills_terrain->result[index2d]);
407 float n_hills = noise_hills->result[index2d];
408 float hill_mnt = hterabs * hterabs * hterabs * n_hills * n_hills;
411 float rterabs = std::fabs(noise_ridge_terrain->result[index2d]);
412 float n_ridge_mnt = noise_ridge_mnt->result[index2d];
413 float ridge_mnt = rterabs * rterabs * rterabs *
414 (1.f - std::fabs(n_ridge_mnt));
416 // Step (terraced) mountains
417 float sterabs = std::fabs(noise_step_terrain->result[index2d]);
418 float n_step_mnt = noise_step_mnt->result[index2d];
419 float step_mnt = sterabs * sterabs * sterabs * getSteps(n_step_mnt);
421 // Initialise 3D noise index and voxelmanip index to column base
422 u32 index3d = (z - node_min.Z) * zstride_1u1d + (x - node_min.X);
423 u32 vi = vm->m_area.index(x, node_min.Y - 1, z);
425 for (s16 y = node_min.Y - 1; y <= node_max.Y + 1;
428 VoxelArea::add_y(em, vi, 1)) {
429 if (vm->m_data[vi].getContent() != CONTENT_IGNORE)
432 // Combine height noises and apply 3D variation
433 float mnt_var = noise_mnt_var->result[index3d];
434 float hill1 = getLerp(height1, height2, mnt_var);
435 float hill2 = getLerp(height3, height4, mnt_var);
436 float hill3 = getLerp(height3, height2, mnt_var);
437 float hill4 = getLerp(height1, height4, mnt_var);
439 // 'hilliness' determines whether hills/mountains are
442 std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
443 float hills = hill_mnt * hilliness;
444 float ridged_mountains = ridge_mnt * hilliness;
445 float step_mountains = step_mnt * hilliness;
447 // Gradient & shallow seabed
448 s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 :
451 // Final terrain level
452 float mountains = hills + ridged_mountains + step_mountains;
453 float surface_level = base_level + mountains + grad;
455 if (y < surface_level) {
456 vm->m_data[vi] = mn_stone; // Stone
457 if (y > stone_surface_max_y)
458 stone_surface_max_y = y;
459 } else if (y <= water_level) {
460 vm->m_data[vi] = mn_water; // Sea water
462 vm->m_data[vi] = mn_air; // Air
467 return stone_surface_max_y;