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>
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 grad_wl = 1 - water_level;
67 noise_base = new Noise(¶ms->np_base, seed, csize.X, csize.Z);
68 noise_filler_depth = new Noise(¶ms->np_filler_depth, seed, csize.X, csize.Z);
69 noise_height1 = new Noise(¶ms->np_height1, seed, csize.X, csize.Z);
70 noise_height2 = new Noise(¶ms->np_height2, seed, csize.X, csize.Z);
71 noise_height3 = new Noise(¶ms->np_height3, seed, csize.X, csize.Z);
72 noise_height4 = new Noise(¶ms->np_height4, seed, csize.X, csize.Z);
73 noise_hills_terrain = new Noise(¶ms->np_hills_terrain, seed, csize.X, csize.Z);
74 noise_ridge_terrain = new Noise(¶ms->np_ridge_terrain, seed, csize.X, csize.Z);
75 noise_step_terrain = new Noise(¶ms->np_step_terrain, seed, csize.X, csize.Z);
76 noise_hills = new Noise(¶ms->np_hills, seed, csize.X, csize.Z);
77 noise_ridge_mnt = new Noise(¶ms->np_ridge_mnt, seed, csize.X, csize.Z);
78 noise_step_mnt = new Noise(¶ms->np_step_mnt, seed, csize.X, csize.Z);
81 // 1 up 1 down overgeneration
82 noise_mnt_var = new Noise(¶ms->np_mnt_var, seed, csize.X, csize.Y + 2, csize.Z);
85 MapgenBasic::np_cave1 = params->np_cave1;
86 MapgenBasic::np_cave2 = params->np_cave2;
87 MapgenBasic::np_cavern = params->np_cavern;
91 MapgenCarpathian::~MapgenCarpathian()
94 delete noise_filler_depth;
99 delete noise_hills_terrain;
100 delete noise_ridge_terrain;
101 delete noise_step_terrain;
103 delete noise_ridge_mnt;
104 delete noise_step_mnt;
105 delete noise_mnt_var;
109 MapgenCarpathianParams::MapgenCarpathianParams()
111 np_base = NoiseParams(12, 1, v3f(2557, 2557, 2557), 6538, 4, 0.8, 0.5);
112 np_filler_depth = NoiseParams(0, 1, v3f(128, 128, 128), 261, 3, 0.7, 2.0);
113 np_height1 = NoiseParams(0, 5, v3f(251, 251, 251), 9613, 5, 0.5, 2.0);
114 np_height2 = NoiseParams(0, 5, v3f(383, 383, 383), 1949, 5, 0.5, 2.0);
115 np_height3 = NoiseParams(0, 5, v3f(509, 509, 509), 3211, 5, 0.5, 2.0);
116 np_height4 = NoiseParams(0, 5, v3f(631, 631, 631), 1583, 5, 0.5, 2.0);
117 np_hills_terrain = NoiseParams(1, 1, v3f(1301, 1301, 1301), 1692, 5, 0.5, 2.0);
118 np_ridge_terrain = NoiseParams(1, 1, v3f(1889, 1889, 1889), 3568, 5, 0.5, 2.0);
119 np_step_terrain = NoiseParams(1, 1, v3f(1889, 1889, 1889), 4157, 5, 0.5, 2.0);
120 np_hills = NoiseParams(0, 3, v3f(257, 257, 257), 6604, 6, 0.5, 2.0);
121 np_ridge_mnt = NoiseParams(0, 12, v3f(743, 743, 743), 5520, 6, 0.7, 2.0);
122 np_step_mnt = NoiseParams(0, 8, v3f(509, 509, 509), 2590, 6, 0.6, 2.0);
123 np_mnt_var = NoiseParams(0, 1, v3f(499, 499, 499), 2490, 5, 0.6, 2.0);
124 np_cave1 = NoiseParams(0, 12, v3f(61, 61, 61), 52534, 3, 0.5, 2.0);
125 np_cave2 = NoiseParams(0, 12, v3f(67, 67, 67), 10325, 3, 0.5, 2.0);
126 np_cavern = NoiseParams(0, 1, v3f(384, 128, 384), 723, 5, 0.63, 2.0);
130 void MapgenCarpathianParams::readParams(const Settings *settings)
132 settings->getFlagStrNoEx("mgcarpathian_spflags", spflags, flagdesc_mapgen_carpathian);
133 settings->getFloatNoEx("mgcarpathian_cave_width", cave_width);
134 settings->getS16NoEx("mgcarpathian_large_cave_depth", large_cave_depth);
135 settings->getS16NoEx("mgcarpathian_lava_depth", lava_depth);
136 settings->getS16NoEx("mgcarpathian_cavern_limit", cavern_limit);
137 settings->getS16NoEx("mgcarpathian_cavern_taper", cavern_taper);
138 settings->getFloatNoEx("mgcarpathian_cavern_threshold", cavern_threshold);
140 settings->getNoiseParams("mgcarpathian_np_base", np_base);
141 settings->getNoiseParams("mgcarpathian_np_filler_depth", np_filler_depth);
142 settings->getNoiseParams("mgcarpathian_np_height1", np_height1);
143 settings->getNoiseParams("mgcarpathian_np_height2", np_height2);
144 settings->getNoiseParams("mgcarpathian_np_height3", np_height3);
145 settings->getNoiseParams("mgcarpathian_np_height4", np_height4);
146 settings->getNoiseParams("mgcarpathian_np_hills_terrain", np_hills_terrain);
147 settings->getNoiseParams("mgcarpathian_np_ridge_terrain", np_ridge_terrain);
148 settings->getNoiseParams("mgcarpathian_np_step_terrain", np_step_terrain);
149 settings->getNoiseParams("mgcarpathian_np_hills", np_hills);
150 settings->getNoiseParams("mgcarpathian_np_ridge_mnt", np_ridge_mnt);
151 settings->getNoiseParams("mgcarpathian_np_step_mnt", np_step_mnt);
152 settings->getNoiseParams("mgcarpathian_np_mnt_var", np_mnt_var);
153 settings->getNoiseParams("mgcarpathian_np_cave1", np_cave1);
154 settings->getNoiseParams("mgcarpathian_np_cave2", np_cave2);
155 settings->getNoiseParams("mgcarpathian_np_cavern", np_cavern);
159 void MapgenCarpathianParams::writeParams(Settings *settings) const
161 settings->setFlagStr("mgcarpathian_spflags", spflags, flagdesc_mapgen_carpathian, U32_MAX);
162 settings->setFloat("mgcarpathian_cave_width", cave_width);
163 settings->setS16("mgcarpathian_large_cave_depth", large_cave_depth);
164 settings->setS16("mgcarpathian_lava_depth", lava_depth);
165 settings->setS16("mgcarpathian_cavern_limit", cavern_limit);
166 settings->setS16("mgcarpathian_cavern_taper", cavern_taper);
167 settings->setFloat("mgcarpathian_cavern_threshold", cavern_threshold);
169 settings->setNoiseParams("mgcarpathian_np_base", np_base);
170 settings->setNoiseParams("mgcarpathian_np_filler_depth", np_filler_depth);
171 settings->setNoiseParams("mgcarpathian_np_height1", np_height1);
172 settings->setNoiseParams("mgcarpathian_np_height2", np_height2);
173 settings->setNoiseParams("mgcarpathian_np_height3", np_height3);
174 settings->setNoiseParams("mgcarpathian_np_height4", np_height4);
175 settings->setNoiseParams("mgcarpathian_np_hills_terrain", np_hills_terrain);
176 settings->setNoiseParams("mgcarpathian_np_ridge_terrain", np_ridge_terrain);
177 settings->setNoiseParams("mgcarpathian_np_step_terrain", np_step_terrain);
178 settings->setNoiseParams("mgcarpathian_np_hills", np_hills);
179 settings->setNoiseParams("mgcarpathian_np_ridge_mnt", np_ridge_mnt);
180 settings->setNoiseParams("mgcarpathian_np_step_mnt", np_step_mnt);
181 settings->setNoiseParams("mgcarpathian_np_mnt_var", np_mnt_var);
182 settings->setNoiseParams("mgcarpathian_np_cave1", np_cave1);
183 settings->setNoiseParams("mgcarpathian_np_cave2", np_cave2);
184 settings->setNoiseParams("mgcarpathian_np_cavern", np_cavern);
188 ///////////////////////////////////////////////////////////////////////////////
192 inline float MapgenCarpathian::getLerp(float noise1, float noise2, float mod)
194 return noise1 + mod * (noise2 - noise1);
198 float MapgenCarpathian::getSteps(float noise1, float noise2)
200 float w = fabs(noise2);
201 float k = floor(noise1 / w);
202 float f = (noise1 - k * w) / w;
203 float s = std::fmin(2.f * f, 1.f);
208 ///////////////////////////////////////////////////////////////////////////////
211 void MapgenCarpathian::makeChunk(BlockMakeData *data)
214 assert(data->vmanip);
215 assert(data->nodedef);
216 assert(data->blockpos_requested.X >= data->blockpos_min.X &&
217 data->blockpos_requested.Y >= data->blockpos_min.Y &&
218 data->blockpos_requested.Z >= data->blockpos_min.Z);
219 assert(data->blockpos_requested.X <= data->blockpos_max.X &&
220 data->blockpos_requested.Y <= data->blockpos_max.Y &&
221 data->blockpos_requested.Z <= data->blockpos_max.Z);
223 this->generating = true;
224 this->vm = data->vmanip;
225 this->ndef = data->nodedef;
227 v3s16 blockpos_min = data->blockpos_min;
228 v3s16 blockpos_max = data->blockpos_max;
229 node_min = blockpos_min * MAP_BLOCKSIZE;
230 node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
231 full_node_min = (blockpos_min - 1) * MAP_BLOCKSIZE;
232 full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
234 // Create a block-specific seed
235 blockseed = getBlockSeed2(full_node_min, seed);
238 s16 stone_surface_max_y = generateTerrain();
241 updateHeightmap(node_min, node_max);
243 // Init biome generator, place biome-specific nodes, and build biomemap
244 biomegen->calcBiomeNoise(node_min);
245 MgStoneType stone_type = generateBiomes();
247 // Generate caverns, tunnels and classic caves
248 if (flags & MG_CAVES) {
249 bool has_cavern = false;
251 if (spflags & MGCARPATHIAN_CAVERNS)
252 has_cavern = generateCaverns(stone_surface_max_y);
253 // Generate tunnels and classic caves
255 // Disable classic caves in this mapchunk by setting
256 // 'large cave depth' to world base. Avoids excessive liquid in
257 // large caverns and floating blobs of overgenerated liquid.
258 generateCaves(stone_surface_max_y, -MAX_MAP_GENERATION_LIMIT);
260 generateCaves(stone_surface_max_y, large_cave_depth);
264 if (flags & MG_DUNGEONS)
265 generateDungeons(stone_surface_max_y, stone_type);
267 // Generate the registered decorations
268 if (flags & MG_DECORATIONS)
269 m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
271 // Generate the registered ores
272 m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max);
274 // Sprinkle some dust on top after everything else was generated
278 updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
280 // Calculate lighting
281 if (flags & MG_LIGHT) {
282 calcLighting(node_min - v3s16(0, 1, 0), node_max + v3s16(0, 1, 0),
283 full_node_min, full_node_max);
286 this->generating = false;
290 ///////////////////////////////////////////////////////////////////////////////
293 int MapgenCarpathian::getSpawnLevelAtPoint(v2s16 p)
295 s16 level_at_point = terrainLevelAtPoint(p.X, p.Y);
296 if (level_at_point <= water_level || level_at_point > water_level + 32)
297 return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
299 return level_at_point;
303 float MapgenCarpathian::terrainLevelAtPoint(s16 x, s16 z)
305 float ground = NoisePerlin2D(&noise_base->np, x, z, seed);
306 float height1 = NoisePerlin2D(&noise_height1->np, x, z, seed);
307 float height2 = NoisePerlin2D(&noise_height2->np, x, z, seed);
308 float height3 = NoisePerlin2D(&noise_height3->np, x, z, seed);
309 float height4 = NoisePerlin2D(&noise_height4->np, x, z, seed);
310 float hter = NoisePerlin2D(&noise_hills_terrain->np, x, z, seed);
311 float rter = NoisePerlin2D(&noise_ridge_terrain->np, x, z, seed);
312 float ster = NoisePerlin2D(&noise_step_terrain->np, x, z, seed);
313 float n_hills = NoisePerlin2D(&noise_hills->np, x, z, seed);
314 float n_ridge_mnt = NoisePerlin2D(&noise_ridge_mnt->np, x, z, seed);
315 float n_step_mnt = NoisePerlin2D(&noise_step_mnt->np, x, z, seed);
317 int height = -MAX_MAP_GENERATION_LIMIT;
319 for (s16 y = 1; y <= 30; y++) {
320 float mnt_var = NoisePerlin3D(&noise_mnt_var->np, x, y, z, seed);
322 // Gradient & shallow seabed
323 s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 : 1 - y;
325 // Hill/Mountain height (hilliness)
326 float hill1 = getLerp(height1, height2, mnt_var);
327 float hill2 = getLerp(height3, height4, mnt_var);
328 float hill3 = getLerp(height3, height2, mnt_var);
329 float hill4 = getLerp(height1, height4, mnt_var);
330 float hilliness = std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
333 float hill_mnt = hilliness * pow(n_hills, 2.f);
334 float hills = pow(hter, 3.f) * hill_mnt;
337 float ridge_mnt = hilliness * (1.f - fabs(n_ridge_mnt));
338 float ridged_mountains = pow(rter, 3.f) * ridge_mnt;
340 // Step (terraced) mountains
341 float step_mnt = hilliness * getSteps(n_step_mnt, fabs(mnt_var));
342 float step_mountains = pow(ster, 3.f) * step_mnt;
344 // Final terrain level
345 float mountains = hills + ridged_mountains + step_mountains;
346 float surface_level = ground + mountains + grad;
348 if (y > surface_level && height < 0)
356 ///////////////////////////////////////////////////////////////////////////////
359 int MapgenCarpathian::generateTerrain()
361 MapNode mn_air(CONTENT_AIR);
362 MapNode mn_stone(c_stone);
363 MapNode mn_water(c_water_source);
365 s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT;
369 // Calculate noise for terrain generation
370 noise_base->perlinMap2D(node_min.X, node_min.Z);
371 noise_height1->perlinMap2D(node_min.X, node_min.Z);
372 noise_height2->perlinMap2D(node_min.X, node_min.Z);
373 noise_height3->perlinMap2D(node_min.X, node_min.Z);
374 noise_height4->perlinMap2D(node_min.X, node_min.Z);
375 noise_hills_terrain->perlinMap2D(node_min.X, node_min.Z);
376 noise_ridge_terrain->perlinMap2D(node_min.X, node_min.Z);
377 noise_step_terrain->perlinMap2D(node_min.X, node_min.Z);
378 noise_hills->perlinMap2D(node_min.X, node_min.Z);
379 noise_ridge_mnt->perlinMap2D(node_min.X, node_min.Z);
380 noise_step_mnt->perlinMap2D(node_min.X, node_min.Z);
381 noise_mnt_var->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
384 for (s16 z = node_min.Z; z <= node_max.Z; z++) {
385 for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) {
386 u32 vi = vm->m_area.index(node_min.X, y, z);
387 for (s16 x = node_min.X; x <= node_max.X;
388 x++, vi++, index2d++, index3d++) {
389 if (vm->m_data[vi].getContent() != CONTENT_IGNORE)
393 float ground = noise_base->result[index2d];
395 // Gradient & shallow seabed
396 s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 : 1 - y;
398 // Hill/Mountain height (hilliness)
399 float height1 = noise_height1->result[index2d];
400 float height2 = noise_height2->result[index2d];
401 float height3 = noise_height3->result[index2d];
402 float height4 = noise_height4->result[index2d];
403 float mnt_var = noise_mnt_var->result[index3d];
404 // Combine height noises and apply 3D variation
405 float hill1 = getLerp(height1, height2, mnt_var);
406 float hill2 = getLerp(height3, height4, mnt_var);
407 float hill3 = getLerp(height3, height2, mnt_var);
408 float hill4 = getLerp(height1, height4, mnt_var);
409 // 'hilliness' determines whether hills/mountains are
411 float hilliness = std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
414 float hter = noise_hills_terrain->result[index2d];
415 float n_hills = noise_hills->result[index2d];
416 float hill_mnt = hilliness * pow(n_hills, 2.f);
417 float hills = pow(fabs(hter), 3.f) * hill_mnt;
420 float rter = noise_ridge_terrain->result[index2d];
421 float n_ridge_mnt = noise_ridge_mnt->result[index2d];
422 float ridge_mnt = hilliness * (1.f - fabs(n_ridge_mnt));
423 float ridged_mountains = pow(fabs(rter), 3.f) * ridge_mnt;
425 // Step (terraced) mountains
426 float ster = noise_step_terrain->result[index2d];
427 float n_step_mnt = noise_step_mnt->result[index2d];
428 float step_mnt = hilliness * getSteps(n_step_mnt, fabs(mnt_var));
429 float step_mountains = pow(fabs(ster), 3.f) * step_mnt;
431 // Final terrain level
432 float mountains = hills + ridged_mountains + step_mountains;
433 float surface_level = ground + mountains + grad;
435 if (y < surface_level) {
436 vm->m_data[vi] = mn_stone; // Stone
437 if (y > stone_surface_max_y)
438 stone_surface_max_y = y;
439 } else if (y <= water_level) {
440 vm->m_data[vi] = mn_water; // Sea water
442 vm->m_data[vi] = mn_air; // Air
450 return stone_surface_max_y;