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 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 dungeon_ymin = params->dungeon_ymin;
65 dungeon_ymax = params->dungeon_ymax;
67 grad_wl = 1 - water_level;
70 noise_base = new Noise(¶ms->np_base, seed, csize.X, csize.Z);
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()
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_base (12, 1, v3f(2557, 2557, 2557), 6538, 4, 0.8, 0.5),
114 np_filler_depth (0, 1, v3f(128, 128, 128), 261, 3, 0.7, 2.0),
115 np_height1 (0, 5, v3f(251, 251, 251), 9613, 5, 0.5, 2.0),
116 np_height2 (0, 5, v3f(383, 383, 383), 1949, 5, 0.5, 2.0),
117 np_height3 (0, 5, v3f(509, 509, 509), 3211, 5, 0.5, 2.0),
118 np_height4 (0, 5, v3f(631, 631, 631), 1583, 5, 0.5, 2.0),
119 np_hills_terrain (1, 1, v3f(1301, 1301, 1301), 1692, 5, 0.5, 2.0),
120 np_ridge_terrain (1, 1, v3f(1889, 1889, 1889), 3568, 5, 0.5, 2.0),
121 np_step_terrain (1, 1, v3f(1889, 1889, 1889), 4157, 5, 0.5, 2.0),
122 np_hills (0, 3, v3f(257, 257, 257), 6604, 6, 0.5, 2.0),
123 np_ridge_mnt (0, 12, v3f(743, 743, 743), 5520, 6, 0.7, 2.0),
124 np_step_mnt (0, 8, v3f(509, 509, 509), 2590, 6, 0.6, 2.0),
125 np_mnt_var (0, 1, v3f(499, 499, 499), 2490, 5, 0.55, 2.0),
126 np_cave1 (0, 12, v3f(61, 61, 61), 52534, 3, 0.5, 2.0),
127 np_cave2 (0, 12, v3f(67, 67, 67), 10325, 3, 0.5, 2.0),
128 np_cavern (0, 1, v3f(384, 128, 384), 723, 5, 0.63, 2.0)
133 void MapgenCarpathianParams::readParams(const Settings *settings)
135 settings->getFlagStrNoEx("mgcarpathian_spflags", spflags, flagdesc_mapgen_carpathian);
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_base", np_base);
146 settings->getNoiseParams("mgcarpathian_np_filler_depth", np_filler_depth);
147 settings->getNoiseParams("mgcarpathian_np_height1", np_height1);
148 settings->getNoiseParams("mgcarpathian_np_height2", np_height2);
149 settings->getNoiseParams("mgcarpathian_np_height3", np_height3);
150 settings->getNoiseParams("mgcarpathian_np_height4", np_height4);
151 settings->getNoiseParams("mgcarpathian_np_hills_terrain", np_hills_terrain);
152 settings->getNoiseParams("mgcarpathian_np_ridge_terrain", np_ridge_terrain);
153 settings->getNoiseParams("mgcarpathian_np_step_terrain", np_step_terrain);
154 settings->getNoiseParams("mgcarpathian_np_hills", np_hills);
155 settings->getNoiseParams("mgcarpathian_np_ridge_mnt", np_ridge_mnt);
156 settings->getNoiseParams("mgcarpathian_np_step_mnt", np_step_mnt);
157 settings->getNoiseParams("mgcarpathian_np_mnt_var", np_mnt_var);
158 settings->getNoiseParams("mgcarpathian_np_cave1", np_cave1);
159 settings->getNoiseParams("mgcarpathian_np_cave2", np_cave2);
160 settings->getNoiseParams("mgcarpathian_np_cavern", np_cavern);
164 void MapgenCarpathianParams::writeParams(Settings *settings) const
166 settings->setFlagStr("mgcarpathian_spflags", spflags, flagdesc_mapgen_carpathian, U32_MAX);
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_base", np_base);
177 settings->setNoiseParams("mgcarpathian_np_filler_depth", np_filler_depth);
178 settings->setNoiseParams("mgcarpathian_np_height1", np_height1);
179 settings->setNoiseParams("mgcarpathian_np_height2", np_height2);
180 settings->setNoiseParams("mgcarpathian_np_height3", np_height3);
181 settings->setNoiseParams("mgcarpathian_np_height4", np_height4);
182 settings->setNoiseParams("mgcarpathian_np_hills_terrain", np_hills_terrain);
183 settings->setNoiseParams("mgcarpathian_np_ridge_terrain", np_ridge_terrain);
184 settings->setNoiseParams("mgcarpathian_np_step_terrain", np_step_terrain);
185 settings->setNoiseParams("mgcarpathian_np_hills", np_hills);
186 settings->setNoiseParams("mgcarpathian_np_ridge_mnt", np_ridge_mnt);
187 settings->setNoiseParams("mgcarpathian_np_step_mnt", np_step_mnt);
188 settings->setNoiseParams("mgcarpathian_np_mnt_var", np_mnt_var);
189 settings->setNoiseParams("mgcarpathian_np_cave1", np_cave1);
190 settings->setNoiseParams("mgcarpathian_np_cave2", np_cave2);
191 settings->setNoiseParams("mgcarpathian_np_cavern", np_cavern);
195 ////////////////////////////////////////////////////////////////////////////////
199 inline float MapgenCarpathian::getLerp(float noise1, float noise2, float mod)
201 return noise1 + mod * (noise2 - noise1);
205 float MapgenCarpathian::getSteps(float noise)
208 float k = std::floor(noise / w);
209 float f = (noise - k * w) / w;
210 float s = std::fmin(2.f * f, 1.f);
215 ////////////////////////////////////////////////////////////////////////////////
218 void MapgenCarpathian::makeChunk(BlockMakeData *data)
221 assert(data->vmanip);
222 assert(data->nodedef);
223 assert(data->blockpos_requested.X >= data->blockpos_min.X &&
224 data->blockpos_requested.Y >= data->blockpos_min.Y &&
225 data->blockpos_requested.Z >= data->blockpos_min.Z);
226 assert(data->blockpos_requested.X <= data->blockpos_max.X &&
227 data->blockpos_requested.Y <= data->blockpos_max.Y &&
228 data->blockpos_requested.Z <= data->blockpos_max.Z);
230 this->generating = true;
231 this->vm = data->vmanip;
232 this->ndef = data->nodedef;
234 v3s16 blockpos_min = data->blockpos_min;
235 v3s16 blockpos_max = data->blockpos_max;
236 node_min = blockpos_min * MAP_BLOCKSIZE;
237 node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
238 full_node_min = (blockpos_min - 1) * MAP_BLOCKSIZE;
239 full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
241 // Create a block-specific seed
242 blockseed = getBlockSeed2(full_node_min, seed);
245 s16 stone_surface_max_y = generateTerrain();
248 updateHeightmap(node_min, node_max);
250 // Init biome generator, place biome-specific nodes, and build biomemap
251 biomegen->calcBiomeNoise(node_min);
253 MgStoneType mgstone_type;
254 content_t biome_stone;
255 generateBiomes(&mgstone_type, &biome_stone);
257 // Generate caverns, tunnels and classic caves
258 if (flags & MG_CAVES) {
259 bool has_cavern = false;
261 if (spflags & MGCARPATHIAN_CAVERNS)
262 has_cavern = generateCaverns(stone_surface_max_y);
263 // Generate tunnels and classic caves
265 // Disable classic caves in this mapchunk by setting
266 // 'large cave depth' to world base. Avoids excessive liquid in
267 // large caverns and floating blobs of overgenerated liquid.
268 generateCaves(stone_surface_max_y, -MAX_MAP_GENERATION_LIMIT);
270 generateCaves(stone_surface_max_y, large_cave_depth);
274 if ((flags & MG_DUNGEONS) && full_node_min.Y >= dungeon_ymin &&
275 full_node_max.Y <= dungeon_ymax)
276 generateDungeons(stone_surface_max_y, mgstone_type, biome_stone);
278 // Generate the registered decorations
279 if (flags & MG_DECORATIONS)
280 m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
282 // Generate the registered ores
283 m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max);
285 // Sprinkle some dust on top after everything else was generated
289 updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
291 // Calculate lighting
292 if (flags & MG_LIGHT) {
293 calcLighting(node_min - v3s16(0, 1, 0), node_max + v3s16(0, 1, 0),
294 full_node_min, full_node_max);
297 this->generating = false;
301 ////////////////////////////////////////////////////////////////////////////////
304 int MapgenCarpathian::getSpawnLevelAtPoint(v2s16 p)
306 s16 level_at_point = terrainLevelAtPoint(p.X, p.Y);
307 if (level_at_point <= water_level || level_at_point > water_level + 32)
308 return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
310 return level_at_point;
314 float MapgenCarpathian::terrainLevelAtPoint(s16 x, s16 z)
316 float ground = NoisePerlin2D(&noise_base->np, x, z, seed);
317 float height1 = NoisePerlin2D(&noise_height1->np, x, z, seed);
318 float height2 = NoisePerlin2D(&noise_height2->np, x, z, seed);
319 float height3 = NoisePerlin2D(&noise_height3->np, x, z, seed);
320 float height4 = NoisePerlin2D(&noise_height4->np, x, z, seed);
321 float hter = NoisePerlin2D(&noise_hills_terrain->np, x, z, seed);
322 float rter = NoisePerlin2D(&noise_ridge_terrain->np, x, z, seed);
323 float ster = NoisePerlin2D(&noise_step_terrain->np, x, z, seed);
324 float n_hills = NoisePerlin2D(&noise_hills->np, x, z, seed);
325 float n_ridge_mnt = NoisePerlin2D(&noise_ridge_mnt->np, x, z, seed);
326 float n_step_mnt = NoisePerlin2D(&noise_step_mnt->np, x, z, seed);
328 int height = -MAX_MAP_GENERATION_LIMIT;
330 for (s16 y = 1; y <= 30; y++) {
331 float mnt_var = NoisePerlin3D(&noise_mnt_var->np, x, y, z, seed);
333 // Gradient & shallow seabed
334 s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 : 1 - y;
336 // Hill/Mountain height (hilliness)
337 float hill1 = getLerp(height1, height2, mnt_var);
338 float hill2 = getLerp(height3, height4, mnt_var);
339 float hill3 = getLerp(height3, height2, mnt_var);
340 float hill4 = getLerp(height1, height4, mnt_var);
342 std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
345 float hill_mnt = hilliness * std::pow(n_hills, 2.f);
346 float hills = std::pow(hter, 3.f) * hill_mnt;
349 float ridge_mnt = hilliness * (1.f - std::fabs(n_ridge_mnt));
350 float ridged_mountains = pow(rter, 3.f) * ridge_mnt;
352 // Step (terraced) mountains
353 float step_mnt = hilliness * getSteps(n_step_mnt);
354 float step_mountains = pow(ster, 3.f) * step_mnt;
356 // Final terrain level
357 float mountains = hills + ridged_mountains + step_mountains;
358 float surface_level = ground + mountains + grad;
360 if (y > surface_level && height < 0)
368 ////////////////////////////////////////////////////////////////////////////////
371 int MapgenCarpathian::generateTerrain()
373 MapNode mn_air(CONTENT_AIR);
374 MapNode mn_stone(c_stone);
375 MapNode mn_water(c_water_source);
377 // Calculate noise for terrain generation
378 noise_base->perlinMap2D(node_min.X, node_min.Z);
379 noise_height1->perlinMap2D(node_min.X, node_min.Z);
380 noise_height2->perlinMap2D(node_min.X, node_min.Z);
381 noise_height3->perlinMap2D(node_min.X, node_min.Z);
382 noise_height4->perlinMap2D(node_min.X, node_min.Z);
383 noise_hills_terrain->perlinMap2D(node_min.X, node_min.Z);
384 noise_ridge_terrain->perlinMap2D(node_min.X, node_min.Z);
385 noise_step_terrain->perlinMap2D(node_min.X, node_min.Z);
386 noise_hills->perlinMap2D(node_min.X, node_min.Z);
387 noise_ridge_mnt->perlinMap2D(node_min.X, node_min.Z);
388 noise_step_mnt->perlinMap2D(node_min.X, node_min.Z);
389 noise_mnt_var->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
392 const v3s16 &em = vm->m_area.getExtent();
393 s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT;
396 for (s16 z = node_min.Z; z <= node_max.Z; z++)
397 for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
399 float ground = noise_base->result[index2d];
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];
408 float hterabs = std::fabs(noise_hills_terrain->result[index2d]);
409 float n_hills = noise_hills->result[index2d];
410 float hill_mnt = hterabs * hterabs * hterabs * n_hills * n_hills;
413 float rterabs = std::fabs(noise_ridge_terrain->result[index2d]);
414 float n_ridge_mnt = noise_ridge_mnt->result[index2d];
415 float ridge_mnt = rterabs * rterabs * rterabs *
416 (1.f - std::fabs(n_ridge_mnt));
418 // Step (terraced) mountains
419 float sterabs = std::fabs(noise_step_terrain->result[index2d]);
420 float n_step_mnt = noise_step_mnt->result[index2d];
421 float step_mnt = sterabs * sterabs * sterabs * getSteps(n_step_mnt);
423 // Initialise 3D noise index and voxelmanip index to column base
424 u32 index3d = (z - node_min.Z) * zstride_1u1d + (x - node_min.X);
425 u32 vi = vm->m_area.index(x, node_min.Y - 1, z);
427 for (s16 y = node_min.Y - 1; y <= node_max.Y + 1;
430 VoxelArea::add_y(em, vi, 1)) {
431 if (vm->m_data[vi].getContent() != CONTENT_IGNORE)
434 // Combine height noises and apply 3D variation
435 float mnt_var = noise_mnt_var->result[index3d];
436 float hill1 = getLerp(height1, height2, mnt_var);
437 float hill2 = getLerp(height3, height4, mnt_var);
438 float hill3 = getLerp(height3, height2, mnt_var);
439 float hill4 = getLerp(height1, height4, mnt_var);
441 // 'hilliness' determines whether hills/mountains are
444 std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
445 float hills = hill_mnt * hilliness;
446 float ridged_mountains = ridge_mnt * hilliness;
447 float step_mountains = step_mnt * hilliness;
449 // Gradient & shallow seabed
450 s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 :
453 // Final terrain level
454 float mountains = hills + ridged_mountains + step_mountains;
455 float surface_level = ground + mountains + grad;
457 if (y < surface_level) {
458 vm->m_data[vi] = mn_stone; // Stone
459 if (y > stone_surface_max_y)
460 stone_surface_max_y = y;
461 } else if (y <= water_level) {
462 vm->m_data[vi] = mn_water; // Sea water
464 vm->m_data[vi] = mn_air; // Air
469 return stone_surface_max_y;