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 biomegen->calcBiomeNoise(node_min);
252 MgStoneType mgstone_type;
253 content_t biome_stone;
254 generateBiomes(&mgstone_type, &biome_stone);
256 // Generate caverns, tunnels and classic caves
257 if (flags & MG_CAVES) {
258 bool has_cavern = false;
260 if (spflags & MGCARPATHIAN_CAVERNS)
261 has_cavern = generateCaverns(stone_surface_max_y);
262 // Generate tunnels and classic caves
264 // Disable classic caves in this mapchunk by setting
265 // 'large cave depth' to world base. Avoids excessive liquid in
266 // large caverns and floating blobs of overgenerated liquid.
267 generateCaves(stone_surface_max_y, -MAX_MAP_GENERATION_LIMIT);
269 generateCaves(stone_surface_max_y, large_cave_depth);
273 if ((flags & MG_DUNGEONS) && full_node_min.Y >= dungeon_ymin &&
274 full_node_max.Y <= dungeon_ymax)
275 generateDungeons(stone_surface_max_y, mgstone_type, biome_stone);
277 // Generate the registered decorations
278 if (flags & MG_DECORATIONS)
279 m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
281 // Generate the registered ores
282 m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max);
284 // Sprinkle some dust on top after everything else was generated
288 updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
290 // Calculate lighting
291 if (flags & MG_LIGHT) {
292 calcLighting(node_min - v3s16(0, 1, 0), node_max + v3s16(0, 1, 0),
293 full_node_min, full_node_max);
296 this->generating = false;
300 ////////////////////////////////////////////////////////////////////////////////
303 int MapgenCarpathian::getSpawnLevelAtPoint(v2s16 p)
305 s16 level_at_point = terrainLevelAtPoint(p.X, p.Y);
306 if (level_at_point <= water_level || level_at_point > water_level + 32)
307 return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
309 return level_at_point;
313 float MapgenCarpathian::terrainLevelAtPoint(s16 x, s16 z)
315 float height1 = NoisePerlin2D(&noise_height1->np, x, z, seed);
316 float height2 = NoisePerlin2D(&noise_height2->np, x, z, seed);
317 float height3 = NoisePerlin2D(&noise_height3->np, x, z, seed);
318 float height4 = NoisePerlin2D(&noise_height4->np, x, z, seed);
319 float hter = NoisePerlin2D(&noise_hills_terrain->np, x, z, seed);
320 float rter = NoisePerlin2D(&noise_ridge_terrain->np, x, z, seed);
321 float ster = NoisePerlin2D(&noise_step_terrain->np, x, z, seed);
322 float n_hills = NoisePerlin2D(&noise_hills->np, x, z, seed);
323 float n_ridge_mnt = NoisePerlin2D(&noise_ridge_mnt->np, x, z, seed);
324 float n_step_mnt = NoisePerlin2D(&noise_step_mnt->np, x, z, seed);
326 int height = -MAX_MAP_GENERATION_LIMIT;
328 for (s16 y = 1; y <= 30; y++) {
329 float mnt_var = NoisePerlin3D(&noise_mnt_var->np, x, y, z, seed);
331 // Gradient & shallow seabed
332 s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 : 1 - y;
334 // Hill/Mountain height (hilliness)
335 float hill1 = getLerp(height1, height2, mnt_var);
336 float hill2 = getLerp(height3, height4, mnt_var);
337 float hill3 = getLerp(height3, height2, mnt_var);
338 float hill4 = getLerp(height1, height4, mnt_var);
340 std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
343 float hill_mnt = hilliness * std::pow(n_hills, 2.f);
344 float hills = std::pow(std::fabs(hter), 3.f) * hill_mnt;
347 float ridge_mnt = hilliness * (1.f - std::fabs(n_ridge_mnt));
348 float ridged_mountains = std::pow(std::fabs(rter), 3.f) * ridge_mnt;
350 // Step (terraced) mountains
351 float step_mnt = hilliness * getSteps(n_step_mnt);
352 float step_mountains = std::pow(std::fabs(ster), 3.f) * step_mnt;
354 // Final terrain level
355 float mountains = hills + ridged_mountains + step_mountains;
356 float surface_level = base_level + mountains + grad;
358 if (y > surface_level && height < 0)
366 ////////////////////////////////////////////////////////////////////////////////
369 int MapgenCarpathian::generateTerrain()
371 MapNode mn_air(CONTENT_AIR);
372 MapNode mn_stone(c_stone);
373 MapNode mn_water(c_water_source);
375 // Calculate noise for terrain generation
376 noise_height1->perlinMap2D(node_min.X, node_min.Z);
377 noise_height2->perlinMap2D(node_min.X, node_min.Z);
378 noise_height3->perlinMap2D(node_min.X, node_min.Z);
379 noise_height4->perlinMap2D(node_min.X, node_min.Z);
380 noise_hills_terrain->perlinMap2D(node_min.X, node_min.Z);
381 noise_ridge_terrain->perlinMap2D(node_min.X, node_min.Z);
382 noise_step_terrain->perlinMap2D(node_min.X, node_min.Z);
383 noise_hills->perlinMap2D(node_min.X, node_min.Z);
384 noise_ridge_mnt->perlinMap2D(node_min.X, node_min.Z);
385 noise_step_mnt->perlinMap2D(node_min.X, node_min.Z);
386 noise_mnt_var->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
389 const v3s16 &em = vm->m_area.getExtent();
390 s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT;
393 for (s16 z = node_min.Z; z <= node_max.Z; z++)
394 for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
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];
402 float hterabs = std::fabs(noise_hills_terrain->result[index2d]);
403 float n_hills = noise_hills->result[index2d];
404 float hill_mnt = hterabs * hterabs * hterabs * n_hills * n_hills;
407 float rterabs = std::fabs(noise_ridge_terrain->result[index2d]);
408 float n_ridge_mnt = noise_ridge_mnt->result[index2d];
409 float ridge_mnt = rterabs * rterabs * rterabs *
410 (1.f - std::fabs(n_ridge_mnt));
412 // Step (terraced) mountains
413 float sterabs = std::fabs(noise_step_terrain->result[index2d]);
414 float n_step_mnt = noise_step_mnt->result[index2d];
415 float step_mnt = sterabs * sterabs * sterabs * getSteps(n_step_mnt);
417 // Initialise 3D noise index and voxelmanip index to column base
418 u32 index3d = (z - node_min.Z) * zstride_1u1d + (x - node_min.X);
419 u32 vi = vm->m_area.index(x, node_min.Y - 1, z);
421 for (s16 y = node_min.Y - 1; y <= node_max.Y + 1;
424 VoxelArea::add_y(em, vi, 1)) {
425 if (vm->m_data[vi].getContent() != CONTENT_IGNORE)
428 // Combine height noises and apply 3D variation
429 float mnt_var = noise_mnt_var->result[index3d];
430 float hill1 = getLerp(height1, height2, mnt_var);
431 float hill2 = getLerp(height3, height4, mnt_var);
432 float hill3 = getLerp(height3, height2, mnt_var);
433 float hill4 = getLerp(height1, height4, mnt_var);
435 // 'hilliness' determines whether hills/mountains are
438 std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
439 float hills = hill_mnt * hilliness;
440 float ridged_mountains = ridge_mnt * hilliness;
441 float step_mountains = step_mnt * hilliness;
443 // Gradient & shallow seabed
444 s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 :
447 // Final terrain level
448 float mountains = hills + ridged_mountains + step_mountains;
449 float surface_level = base_level + mountains + grad;
451 if (y < surface_level) {
452 vm->m_data[vi] = mn_stone; // Stone
453 if (y > stone_surface_max_y)
454 stone_surface_max_y = y;
455 } else if (y <= water_level) {
456 vm->m_data[vi] = mn_water; // Sea water
458 vm->m_data[vi] = mn_air; // Air
463 return stone_surface_max_y;