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(
54 int mapgenid, MapgenCarpathianParams *params, EmergeManager *emerge)
55 : MapgenBasic(mapgenid, params, emerge)
57 base_level = params->base_level;
59 spflags = params->spflags;
60 cave_width = params->cave_width;
61 large_cave_depth = params->large_cave_depth;
62 lava_depth = params->lava_depth;
63 cavern_limit = params->cavern_limit;
64 cavern_taper = params->cavern_taper;
65 cavern_threshold = params->cavern_threshold;
66 dungeon_ymin = params->dungeon_ymin;
67 dungeon_ymax = params->dungeon_ymax;
69 grad_wl = 1 - water_level;
72 noise_filler_depth = new Noise(¶ms->np_filler_depth, seed, csize.X, csize.Z);
73 noise_height1 = new Noise(¶ms->np_height1, seed, csize.X, csize.Z);
74 noise_height2 = new Noise(¶ms->np_height2, seed, csize.X, csize.Z);
75 noise_height3 = new Noise(¶ms->np_height3, seed, csize.X, csize.Z);
76 noise_height4 = new Noise(¶ms->np_height4, seed, csize.X, csize.Z);
77 noise_hills_terrain = new Noise(¶ms->np_hills_terrain, seed, csize.X, csize.Z);
78 noise_ridge_terrain = new Noise(¶ms->np_ridge_terrain, seed, csize.X, csize.Z);
79 noise_step_terrain = new Noise(¶ms->np_step_terrain, seed, csize.X, csize.Z);
80 noise_hills = new Noise(¶ms->np_hills, seed, csize.X, csize.Z);
81 noise_ridge_mnt = new Noise(¶ms->np_ridge_mnt, seed, csize.X, csize.Z);
82 noise_step_mnt = new Noise(¶ms->np_step_mnt, seed, csize.X, csize.Z);
85 // 1 up 1 down overgeneration
86 noise_mnt_var = new Noise(¶ms->np_mnt_var, seed, csize.X, csize.Y + 2, csize.Z);
89 MapgenBasic::np_cave1 = params->np_cave1;
90 MapgenBasic::np_cave2 = params->np_cave2;
91 MapgenBasic::np_cavern = params->np_cavern;
95 MapgenCarpathian::~MapgenCarpathian()
97 delete noise_filler_depth;
100 delete noise_height3;
101 delete noise_height4;
102 delete noise_hills_terrain;
103 delete noise_ridge_terrain;
104 delete noise_step_terrain;
106 delete noise_ridge_mnt;
107 delete noise_step_mnt;
108 delete noise_mnt_var;
112 MapgenCarpathianParams::MapgenCarpathianParams():
113 np_filler_depth (0, 1, v3f(128, 128, 128), 261, 3, 0.7, 2.0),
114 np_height1 (0, 5, v3f(251, 251, 251), 9613, 5, 0.5, 2.0),
115 np_height2 (0, 5, v3f(383, 383, 383), 1949, 5, 0.5, 2.0),
116 np_height3 (0, 5, v3f(509, 509, 509), 3211, 5, 0.5, 2.0),
117 np_height4 (0, 5, v3f(631, 631, 631), 1583, 5, 0.5, 2.0),
118 np_hills_terrain (1, 1, v3f(1301, 1301, 1301), 1692, 5, 0.5, 2.0),
119 np_ridge_terrain (1, 1, v3f(1889, 1889, 1889), 3568, 5, 0.5, 2.0),
120 np_step_terrain (1, 1, v3f(1889, 1889, 1889), 4157, 5, 0.5, 2.0),
121 np_hills (0, 3, v3f(257, 257, 257), 6604, 6, 0.5, 2.0),
122 np_ridge_mnt (0, 12, v3f(743, 743, 743), 5520, 6, 0.7, 2.0),
123 np_step_mnt (0, 8, v3f(509, 509, 509), 2590, 6, 0.6, 2.0),
124 np_mnt_var (0, 1, v3f(499, 499, 499), 2490, 5, 0.55, 2.0),
125 np_cave1 (0, 12, v3f(61, 61, 61), 52534, 3, 0.5, 2.0),
126 np_cave2 (0, 12, v3f(67, 67, 67), 10325, 3, 0.5, 2.0),
127 np_cavern (0, 1, v3f(384, 128, 384), 723, 5, 0.63, 2.0)
132 void MapgenCarpathianParams::readParams(const Settings *settings)
134 settings->getFlagStrNoEx("mgcarpathian_spflags", spflags, flagdesc_mapgen_carpathian);
135 settings->getFloatNoEx("mgcarpathian_base_level", base_level);
136 settings->getFloatNoEx("mgcarpathian_cave_width", cave_width);
137 settings->getS16NoEx("mgcarpathian_large_cave_depth", large_cave_depth);
138 settings->getS16NoEx("mgcarpathian_lava_depth", lava_depth);
139 settings->getS16NoEx("mgcarpathian_cavern_limit", cavern_limit);
140 settings->getS16NoEx("mgcarpathian_cavern_taper", cavern_taper);
141 settings->getFloatNoEx("mgcarpathian_cavern_threshold", cavern_threshold);
142 settings->getS16NoEx("mgcarpathian_dungeon_ymin", dungeon_ymin);
143 settings->getS16NoEx("mgcarpathian_dungeon_ymax", dungeon_ymax);
145 settings->getNoiseParams("mgcarpathian_np_filler_depth", np_filler_depth);
146 settings->getNoiseParams("mgcarpathian_np_height1", np_height1);
147 settings->getNoiseParams("mgcarpathian_np_height2", np_height2);
148 settings->getNoiseParams("mgcarpathian_np_height3", np_height3);
149 settings->getNoiseParams("mgcarpathian_np_height4", np_height4);
150 settings->getNoiseParams("mgcarpathian_np_hills_terrain", np_hills_terrain);
151 settings->getNoiseParams("mgcarpathian_np_ridge_terrain", np_ridge_terrain);
152 settings->getNoiseParams("mgcarpathian_np_step_terrain", np_step_terrain);
153 settings->getNoiseParams("mgcarpathian_np_hills", np_hills);
154 settings->getNoiseParams("mgcarpathian_np_ridge_mnt", np_ridge_mnt);
155 settings->getNoiseParams("mgcarpathian_np_step_mnt", np_step_mnt);
156 settings->getNoiseParams("mgcarpathian_np_mnt_var", np_mnt_var);
157 settings->getNoiseParams("mgcarpathian_np_cave1", np_cave1);
158 settings->getNoiseParams("mgcarpathian_np_cave2", np_cave2);
159 settings->getNoiseParams("mgcarpathian_np_cavern", np_cavern);
163 void MapgenCarpathianParams::writeParams(Settings *settings) const
165 settings->setFlagStr("mgcarpathian_spflags", spflags, flagdesc_mapgen_carpathian, U32_MAX);
166 settings->setFloat("mgcarpathian_base_level", base_level);
167 settings->setFloat("mgcarpathian_cave_width", cave_width);
168 settings->setS16("mgcarpathian_large_cave_depth", large_cave_depth);
169 settings->setS16("mgcarpathian_lava_depth", lava_depth);
170 settings->setS16("mgcarpathian_cavern_limit", cavern_limit);
171 settings->setS16("mgcarpathian_cavern_taper", cavern_taper);
172 settings->setFloat("mgcarpathian_cavern_threshold", cavern_threshold);
173 settings->setS16("mgcarpathian_dungeon_ymin", dungeon_ymin);
174 settings->setS16("mgcarpathian_dungeon_ymax", dungeon_ymax);
176 settings->setNoiseParams("mgcarpathian_np_filler_depth", np_filler_depth);
177 settings->setNoiseParams("mgcarpathian_np_height1", np_height1);
178 settings->setNoiseParams("mgcarpathian_np_height2", np_height2);
179 settings->setNoiseParams("mgcarpathian_np_height3", np_height3);
180 settings->setNoiseParams("mgcarpathian_np_height4", np_height4);
181 settings->setNoiseParams("mgcarpathian_np_hills_terrain", np_hills_terrain);
182 settings->setNoiseParams("mgcarpathian_np_ridge_terrain", np_ridge_terrain);
183 settings->setNoiseParams("mgcarpathian_np_step_terrain", np_step_terrain);
184 settings->setNoiseParams("mgcarpathian_np_hills", np_hills);
185 settings->setNoiseParams("mgcarpathian_np_ridge_mnt", np_ridge_mnt);
186 settings->setNoiseParams("mgcarpathian_np_step_mnt", np_step_mnt);
187 settings->setNoiseParams("mgcarpathian_np_mnt_var", np_mnt_var);
188 settings->setNoiseParams("mgcarpathian_np_cave1", np_cave1);
189 settings->setNoiseParams("mgcarpathian_np_cave2", np_cave2);
190 settings->setNoiseParams("mgcarpathian_np_cavern", np_cavern);
194 ////////////////////////////////////////////////////////////////////////////////
198 inline float MapgenCarpathian::getLerp(float noise1, float noise2, float mod)
200 return noise1 + mod * (noise2 - noise1);
204 float MapgenCarpathian::getSteps(float noise)
207 float k = std::floor(noise / w);
208 float f = (noise - k * w) / w;
209 float s = std::fmin(2.f * f, 1.f);
214 ////////////////////////////////////////////////////////////////////////////////
217 void MapgenCarpathian::makeChunk(BlockMakeData *data)
220 assert(data->vmanip);
221 assert(data->nodedef);
222 assert(data->blockpos_requested.X >= data->blockpos_min.X &&
223 data->blockpos_requested.Y >= data->blockpos_min.Y &&
224 data->blockpos_requested.Z >= data->blockpos_min.Z);
225 assert(data->blockpos_requested.X <= data->blockpos_max.X &&
226 data->blockpos_requested.Y <= data->blockpos_max.Y &&
227 data->blockpos_requested.Z <= data->blockpos_max.Z);
229 this->generating = true;
230 this->vm = data->vmanip;
231 this->ndef = data->nodedef;
233 v3s16 blockpos_min = data->blockpos_min;
234 v3s16 blockpos_max = data->blockpos_max;
235 node_min = blockpos_min * MAP_BLOCKSIZE;
236 node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
237 full_node_min = (blockpos_min - 1) * MAP_BLOCKSIZE;
238 full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
240 // Create a block-specific seed
241 blockseed = getBlockSeed2(full_node_min, seed);
244 s16 stone_surface_max_y = generateTerrain();
247 updateHeightmap(node_min, node_max);
249 // Init biome generator, place biome-specific nodes, and build biomemap
250 if (flags & MG_BIOMES) {
251 biomegen->calcBiomeNoise(node_min);
255 // Generate tunnels, caverns and large randomwalk caves
256 if (flags & MG_CAVES) {
257 // Generate tunnels first as caverns confuse them
258 generateCavesNoiseIntersection(stone_surface_max_y);
261 bool near_cavern = false;
262 if (spflags & MGCARPATHIAN_CAVERNS)
263 near_cavern = generateCavernsNoise(stone_surface_max_y);
265 // Generate large randomwalk caves
267 // Disable large randomwalk caves in this mapchunk by setting
268 // 'large cave depth' to world base. Avoids excessive liquid in
269 // large caverns and floating blobs of overgenerated liquid.
270 generateCavesRandomWalk(stone_surface_max_y,
271 -MAX_MAP_GENERATION_LIMIT);
273 generateCavesRandomWalk(stone_surface_max_y, large_cave_depth);
277 if ((flags & MG_DUNGEONS) && full_node_min.Y >= dungeon_ymin &&
278 full_node_max.Y <= dungeon_ymax)
279 generateDungeons(stone_surface_max_y);
281 // Generate the registered decorations
282 if (flags & MG_DECORATIONS)
283 m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
285 // Generate the registered ores
286 m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max);
288 // Sprinkle some dust on top after everything else was generated
289 if (flags & MG_BIOMES)
293 updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
295 // Calculate lighting
296 if (flags & MG_LIGHT) {
297 calcLighting(node_min - v3s16(0, 1, 0), node_max + v3s16(0, 1, 0),
298 full_node_min, full_node_max);
301 this->generating = false;
305 ////////////////////////////////////////////////////////////////////////////////
308 int MapgenCarpathian::getSpawnLevelAtPoint(v2s16 p)
310 s16 level_at_point = terrainLevelAtPoint(p.X, p.Y);
311 if (level_at_point <= water_level || level_at_point > water_level + 32)
312 return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
314 return level_at_point;
318 float MapgenCarpathian::terrainLevelAtPoint(s16 x, s16 z)
320 float height1 = NoisePerlin2D(&noise_height1->np, x, z, seed);
321 float height2 = NoisePerlin2D(&noise_height2->np, x, z, seed);
322 float height3 = NoisePerlin2D(&noise_height3->np, x, z, seed);
323 float height4 = NoisePerlin2D(&noise_height4->np, x, z, seed);
324 float hter = NoisePerlin2D(&noise_hills_terrain->np, x, z, seed);
325 float rter = NoisePerlin2D(&noise_ridge_terrain->np, x, z, seed);
326 float ster = NoisePerlin2D(&noise_step_terrain->np, x, z, seed);
327 float n_hills = NoisePerlin2D(&noise_hills->np, x, z, seed);
328 float n_ridge_mnt = NoisePerlin2D(&noise_ridge_mnt->np, x, z, seed);
329 float n_step_mnt = NoisePerlin2D(&noise_step_mnt->np, x, z, seed);
331 int height = -MAX_MAP_GENERATION_LIMIT;
333 for (s16 y = 1; y <= 30; y++) {
334 float mnt_var = NoisePerlin3D(&noise_mnt_var->np, x, y, z, seed);
336 // Gradient & shallow seabed
337 s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 : 1 - y;
339 // Hill/Mountain height (hilliness)
340 float hill1 = getLerp(height1, height2, mnt_var);
341 float hill2 = getLerp(height3, height4, mnt_var);
342 float hill3 = getLerp(height3, height2, mnt_var);
343 float hill4 = getLerp(height1, height4, mnt_var);
345 std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
348 float hill_mnt = hilliness * std::pow(n_hills, 2.f);
349 float hills = std::pow(std::fabs(hter), 3.f) * hill_mnt;
352 float ridge_mnt = hilliness * (1.f - std::fabs(n_ridge_mnt));
353 float ridged_mountains = std::pow(std::fabs(rter), 3.f) * ridge_mnt;
355 // Step (terraced) mountains
356 float step_mnt = hilliness * getSteps(n_step_mnt);
357 float step_mountains = std::pow(std::fabs(ster), 3.f) * step_mnt;
359 // Final terrain level
360 float mountains = hills + ridged_mountains + step_mountains;
361 float surface_level = base_level + mountains + grad;
363 if (y > surface_level && height < 0)
371 ////////////////////////////////////////////////////////////////////////////////
374 int MapgenCarpathian::generateTerrain()
376 MapNode mn_air(CONTENT_AIR);
377 MapNode mn_stone(c_stone);
378 MapNode mn_water(c_water_source);
380 // Calculate noise for terrain generation
381 noise_height1->perlinMap2D(node_min.X, node_min.Z);
382 noise_height2->perlinMap2D(node_min.X, node_min.Z);
383 noise_height3->perlinMap2D(node_min.X, node_min.Z);
384 noise_height4->perlinMap2D(node_min.X, node_min.Z);
385 noise_hills_terrain->perlinMap2D(node_min.X, node_min.Z);
386 noise_ridge_terrain->perlinMap2D(node_min.X, node_min.Z);
387 noise_step_terrain->perlinMap2D(node_min.X, node_min.Z);
388 noise_hills->perlinMap2D(node_min.X, node_min.Z);
389 noise_ridge_mnt->perlinMap2D(node_min.X, node_min.Z);
390 noise_step_mnt->perlinMap2D(node_min.X, node_min.Z);
391 noise_mnt_var->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
394 const v3s16 &em = vm->m_area.getExtent();
395 s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT;
398 for (s16 z = node_min.Z; z <= node_max.Z; z++)
399 for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
400 // Hill/Mountain height (hilliness)
401 float height1 = noise_height1->result[index2d];
402 float height2 = noise_height2->result[index2d];
403 float height3 = noise_height3->result[index2d];
404 float height4 = noise_height4->result[index2d];
407 float hterabs = std::fabs(noise_hills_terrain->result[index2d]);
408 float n_hills = noise_hills->result[index2d];
409 float hill_mnt = hterabs * hterabs * hterabs * n_hills * n_hills;
412 float rterabs = std::fabs(noise_ridge_terrain->result[index2d]);
413 float n_ridge_mnt = noise_ridge_mnt->result[index2d];
414 float ridge_mnt = rterabs * rterabs * rterabs *
415 (1.f - std::fabs(n_ridge_mnt));
417 // Step (terraced) mountains
418 float sterabs = std::fabs(noise_step_terrain->result[index2d]);
419 float n_step_mnt = noise_step_mnt->result[index2d];
420 float step_mnt = sterabs * sterabs * sterabs * getSteps(n_step_mnt);
422 // Initialise 3D noise index and voxelmanip index to column base
423 u32 index3d = (z - node_min.Z) * zstride_1u1d + (x - node_min.X);
424 u32 vi = vm->m_area.index(x, node_min.Y - 1, z);
426 for (s16 y = node_min.Y - 1; y <= node_max.Y + 1;
429 VoxelArea::add_y(em, vi, 1)) {
430 if (vm->m_data[vi].getContent() != CONTENT_IGNORE)
433 // Combine height noises and apply 3D variation
434 float mnt_var = noise_mnt_var->result[index3d];
435 float hill1 = getLerp(height1, height2, mnt_var);
436 float hill2 = getLerp(height3, height4, mnt_var);
437 float hill3 = getLerp(height3, height2, mnt_var);
438 float hill4 = getLerp(height1, height4, mnt_var);
440 // 'hilliness' determines whether hills/mountains are
443 std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
444 float hills = hill_mnt * hilliness;
445 float ridged_mountains = ridge_mnt * hilliness;
446 float step_mountains = step_mnt * hilliness;
448 // Gradient & shallow seabed
449 s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 :
452 // Final terrain level
453 float mountains = hills + ridged_mountains + step_mountains;
454 float surface_level = base_level + mountains + grad;
456 if (y < surface_level) {
457 vm->m_data[vi] = mn_stone; // Stone
458 if (y > stone_surface_max_y)
459 stone_surface_max_y = y;
460 } else if (y <= water_level) {
461 vm->m_data[vi] = mn_water; // Sea water
463 vm->m_data[vi] = mn_air; // Air
468 return stone_surface_max_y;