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 cavern_limit = params->cavern_limit;
61 cavern_taper = params->cavern_taper;
62 cavern_threshold = params->cavern_threshold;
63 grad_wl = 1 - water_level;
66 noise_base = new Noise(¶ms->np_base, seed, csize.X, csize.Z);
67 noise_filler_depth = new Noise(¶ms->np_filler_depth, seed, csize.X, csize.Z);
68 noise_height1 = new Noise(¶ms->np_height1, seed, csize.X, csize.Z);
69 noise_height2 = new Noise(¶ms->np_height2, seed, csize.X, csize.Z);
70 noise_height3 = new Noise(¶ms->np_height3, seed, csize.X, csize.Z);
71 noise_height4 = new Noise(¶ms->np_height4, seed, csize.X, csize.Z);
72 noise_hills_terrain = new Noise(¶ms->np_hills_terrain, seed, csize.X, csize.Z);
73 noise_ridge_terrain = new Noise(¶ms->np_ridge_terrain, seed, csize.X, csize.Z);
74 noise_step_terrain = new Noise(¶ms->np_step_terrain, seed, csize.X, csize.Z);
75 noise_hills = new Noise(¶ms->np_hills, seed, csize.X, csize.Z);
76 noise_ridge_mnt = new Noise(¶ms->np_ridge_mnt, seed, csize.X, csize.Z);
77 noise_step_mnt = new Noise(¶ms->np_step_mnt, seed, csize.X, csize.Z);
80 // 1 up 1 down overgeneration
81 noise_mnt_var = new Noise(¶ms->np_mnt_var, seed, csize.X, csize.Y + 2, csize.Z);
84 MapgenBasic::np_cave1 = params->np_cave1;
85 MapgenBasic::np_cave2 = params->np_cave2;
86 MapgenBasic::np_cavern = params->np_cavern;
90 MapgenCarpathian::~MapgenCarpathian()
93 delete noise_filler_depth;
98 delete noise_hills_terrain;
99 delete noise_ridge_terrain;
100 delete noise_step_terrain;
102 delete noise_ridge_mnt;
103 delete noise_step_mnt;
104 delete noise_mnt_var;
108 MapgenCarpathianParams::MapgenCarpathianParams()
110 np_base = NoiseParams(12, 1, v3f(2557, 2557, 2557), 6538, 4, 0.8, 0.5);
111 np_filler_depth = NoiseParams(0, 1, v3f(128, 128, 128), 261, 3, 0.7, 2.0);
112 np_height1 = NoiseParams(0, 5, v3f(251, 251, 251), 9613, 5, 0.5, 2.0);
113 np_height2 = NoiseParams(0, 5, v3f(383, 383, 383), 1949, 5, 0.5, 2.0);
114 np_height3 = NoiseParams(0, 5, v3f(509, 509, 509), 3211, 5, 0.5, 2.0);
115 np_height4 = NoiseParams(0, 5, v3f(631, 631, 631), 1583, 5, 0.5, 2.0);
116 np_hills_terrain = NoiseParams(1, 1, v3f(1301, 1301, 1301), 1692, 5, 0.5, 2.0);
117 np_ridge_terrain = NoiseParams(1, 1, v3f(1889, 1889, 1889), 3568, 5, 0.5, 2.0);
118 np_step_terrain = NoiseParams(1, 1, v3f(1889, 1889, 1889), 4157, 5, 0.5, 2.0);
119 np_hills = NoiseParams(0, 3, v3f(257, 257, 257), 6604, 6, 0.5, 2.0);
120 np_ridge_mnt = NoiseParams(0, 12, v3f(743, 743, 743), 5520, 6, 0.7, 2.0);
121 np_step_mnt = NoiseParams(0, 8, v3f(509, 509, 509), 2590, 6, 0.6, 2.0);
122 np_mnt_var = NoiseParams(0, 1, v3f(499, 499, 499), 2490, 5, 0.6, 2.0);
123 np_cave1 = NoiseParams(0, 12, v3f(61, 61, 61), 52534, 3, 0.5, 2.0);
124 np_cave2 = NoiseParams(0, 12, v3f(67, 67, 67), 10325, 3, 0.5, 2.0);
125 np_cavern = NoiseParams(0, 1, v3f(384, 128, 384), 723, 5, 0.63, 2.0);
129 void MapgenCarpathianParams::readParams(const Settings *settings)
131 settings->getFlagStrNoEx("mgcarpathian_spflags", spflags, flagdesc_mapgen_carpathian);
132 settings->getFloatNoEx("mgcarpathian_cave_width", cave_width);
133 settings->getS16NoEx("mgcarpathian_large_cave_depth", large_cave_depth);
134 settings->getS16NoEx("mgcarpathian_cavern_limit", cavern_limit);
135 settings->getS16NoEx("mgcarpathian_cavern_taper", cavern_taper);
136 settings->getFloatNoEx("mgcarpathian_cavern_threshold", cavern_threshold);
138 settings->getNoiseParams("mgcarpathian_np_base", np_base);
139 settings->getNoiseParams("mgcarpathian_np_filler_depth", np_filler_depth);
140 settings->getNoiseParams("mgcarpathian_np_height1", np_height1);
141 settings->getNoiseParams("mgcarpathian_np_height2", np_height2);
142 settings->getNoiseParams("mgcarpathian_np_height3", np_height3);
143 settings->getNoiseParams("mgcarpathian_np_height4", np_height4);
144 settings->getNoiseParams("mgcarpathian_np_hills_terrain", np_hills_terrain);
145 settings->getNoiseParams("mgcarpathian_np_ridge_terrain", np_ridge_terrain);
146 settings->getNoiseParams("mgcarpathian_np_step_terrain", np_step_terrain);
147 settings->getNoiseParams("mgcarpathian_np_hills", np_hills);
148 settings->getNoiseParams("mgcarpathian_np_ridge_mnt", np_ridge_mnt);
149 settings->getNoiseParams("mgcarpathian_np_step_mnt", np_step_mnt);
150 settings->getNoiseParams("mgcarpathian_np_mnt_var", np_mnt_var);
151 settings->getNoiseParams("mgcarpathian_np_cave1", np_cave1);
152 settings->getNoiseParams("mgcarpathian_np_cave2", np_cave2);
153 settings->getNoiseParams("mgcarpathian_np_cavern", np_cavern);
157 void MapgenCarpathianParams::writeParams(Settings *settings) const
159 settings->setFlagStr("mgcarpathian_spflags", spflags, flagdesc_mapgen_carpathian, U32_MAX);
160 settings->setFloat("mgcarpathian_cave_width", cave_width);
161 settings->setS16("mgcarpathian_large_cave_depth", large_cave_depth);
162 settings->setS16("mgcarpathian_cavern_limit", cavern_limit);
163 settings->setS16("mgcarpathian_cavern_taper", cavern_taper);
164 settings->setFloat("mgcarpathian_cavern_threshold", cavern_threshold);
166 settings->setNoiseParams("mgcarpathian_np_base", np_base);
167 settings->setNoiseParams("mgcarpathian_np_filler_depth", np_filler_depth);
168 settings->setNoiseParams("mgcarpathian_np_height1", np_height1);
169 settings->setNoiseParams("mgcarpathian_np_height2", np_height2);
170 settings->setNoiseParams("mgcarpathian_np_height3", np_height3);
171 settings->setNoiseParams("mgcarpathian_np_height4", np_height4);
172 settings->setNoiseParams("mgcarpathian_np_hills_terrain", np_hills_terrain);
173 settings->setNoiseParams("mgcarpathian_np_ridge_terrain", np_ridge_terrain);
174 settings->setNoiseParams("mgcarpathian_np_step_terrain", np_step_terrain);
175 settings->setNoiseParams("mgcarpathian_np_hills", np_hills);
176 settings->setNoiseParams("mgcarpathian_np_ridge_mnt", np_ridge_mnt);
177 settings->setNoiseParams("mgcarpathian_np_step_mnt", np_step_mnt);
178 settings->setNoiseParams("mgcarpathian_np_mnt_var", np_mnt_var);
179 settings->setNoiseParams("mgcarpathian_np_cave1", np_cave1);
180 settings->setNoiseParams("mgcarpathian_np_cave2", np_cave2);
181 settings->setNoiseParams("mgcarpathian_np_cavern", np_cavern);
185 ///////////////////////////////////////////////////////////////////////////////
189 inline float MapgenCarpathian::getLerp(float noise1, float noise2, float mod)
191 return noise1 + mod * (noise2 - noise1);
195 float MapgenCarpathian::getSteps(float noise1, float noise2)
197 float w = fabs(noise2);
198 float k = floor(noise1 / w);
199 float f = (noise1 - k * w) / w;
200 float s = std::fmin(2.f * f, 1.f);
205 ///////////////////////////////////////////////////////////////////////////////
208 void MapgenCarpathian::makeChunk(BlockMakeData *data)
211 assert(data->vmanip);
212 assert(data->nodedef);
213 assert(data->blockpos_requested.X >= data->blockpos_min.X &&
214 data->blockpos_requested.Y >= data->blockpos_min.Y &&
215 data->blockpos_requested.Z >= data->blockpos_min.Z);
216 assert(data->blockpos_requested.X <= data->blockpos_max.X &&
217 data->blockpos_requested.Y <= data->blockpos_max.Y &&
218 data->blockpos_requested.Z <= data->blockpos_max.Z);
220 this->generating = true;
221 this->vm = data->vmanip;
222 this->ndef = data->nodedef;
224 v3s16 blockpos_min = data->blockpos_min;
225 v3s16 blockpos_max = data->blockpos_max;
226 node_min = blockpos_min * MAP_BLOCKSIZE;
227 node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
228 full_node_min = (blockpos_min - 1) * MAP_BLOCKSIZE;
229 full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
231 // Create a block-specific seed
232 blockseed = getBlockSeed2(full_node_min, seed);
235 s16 stone_surface_max_y = generateTerrain();
238 updateHeightmap(node_min, node_max);
240 // Init biome generator, place biome-specific nodes, and build biomemap
241 biomegen->calcBiomeNoise(node_min);
242 MgStoneType stone_type = generateBiomes();
244 // Generate caverns, tunnels and classic caves
245 if (flags & MG_CAVES) {
246 bool has_cavern = false;
248 if (spflags & MGCARPATHIAN_CAVERNS)
249 has_cavern = generateCaverns(stone_surface_max_y);
250 // Generate tunnels and classic caves
252 // Disable classic caves in this mapchunk by setting
253 // 'large cave depth' to world base. Avoids excessive liquid in
254 // large caverns and floating blobs of overgenerated liquid.
255 generateCaves(stone_surface_max_y, -MAX_MAP_GENERATION_LIMIT);
257 generateCaves(stone_surface_max_y, large_cave_depth);
261 if (flags & MG_DUNGEONS)
262 generateDungeons(stone_surface_max_y, stone_type);
264 // Generate the registered decorations
265 if (flags & MG_DECORATIONS)
266 m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
268 // Generate the registered ores
269 m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max);
271 // Sprinkle some dust on top after everything else was generated
275 updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
277 // Calculate lighting
278 if (flags & MG_LIGHT) {
279 calcLighting(node_min - v3s16(0, 1, 0), node_max + v3s16(0, 1, 0),
280 full_node_min, full_node_max);
283 this->generating = false;
287 ///////////////////////////////////////////////////////////////////////////////
290 int MapgenCarpathian::getSpawnLevelAtPoint(v2s16 p)
292 s16 level_at_point = terrainLevelAtPoint(p.X, p.Y);
293 if (level_at_point <= water_level || level_at_point > water_level + 32)
294 return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
296 return level_at_point;
300 float MapgenCarpathian::terrainLevelAtPoint(s16 x, s16 z)
302 float ground = NoisePerlin2D(&noise_base->np, x, z, seed);
303 float height1 = NoisePerlin2D(&noise_height1->np, x, z, seed);
304 float height2 = NoisePerlin2D(&noise_height2->np, x, z, seed);
305 float height3 = NoisePerlin2D(&noise_height3->np, x, z, seed);
306 float height4 = NoisePerlin2D(&noise_height4->np, x, z, seed);
307 float hter = NoisePerlin2D(&noise_hills_terrain->np, x, z, seed);
308 float rter = NoisePerlin2D(&noise_ridge_terrain->np, x, z, seed);
309 float ster = NoisePerlin2D(&noise_step_terrain->np, x, z, seed);
310 float n_hills = NoisePerlin2D(&noise_hills->np, x, z, seed);
311 float n_ridge_mnt = NoisePerlin2D(&noise_ridge_mnt->np, x, z, seed);
312 float n_step_mnt = NoisePerlin2D(&noise_step_mnt->np, x, z, seed);
314 int height = -MAX_MAP_GENERATION_LIMIT;
316 for (s16 y = 1; y <= 30; y++) {
317 float mnt_var = NoisePerlin3D(&noise_mnt_var->np, x, y, z, seed);
319 // Gradient & shallow seabed
320 s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 : 1 - y;
322 // Hill/Mountain height (hilliness)
323 float hill1 = getLerp(height1, height2, mnt_var);
324 float hill2 = getLerp(height3, height4, mnt_var);
325 float hill3 = getLerp(height3, height2, mnt_var);
326 float hill4 = getLerp(height1, height4, mnt_var);
327 float hilliness = std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
330 float hill_mnt = hilliness * pow(n_hills, 2.f);
331 float hills = pow(hter, 3.f) * hill_mnt;
334 float ridge_mnt = hilliness * (1.f - fabs(n_ridge_mnt));
335 float ridged_mountains = pow(rter, 3.f) * ridge_mnt;
337 // Step (terraced) mountains
338 float step_mnt = hilliness * getSteps(n_step_mnt, fabs(mnt_var));
339 float step_mountains = pow(ster, 3.f) * step_mnt;
341 // Final terrain level
342 float mountains = hills + ridged_mountains + step_mountains;
343 float surface_level = ground + mountains + grad;
345 if (y > surface_level && height < 0)
353 ///////////////////////////////////////////////////////////////////////////////
356 int MapgenCarpathian::generateTerrain()
358 MapNode mn_air(CONTENT_AIR);
359 MapNode mn_stone(c_stone);
360 MapNode mn_water(c_water_source);
362 s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT;
366 // Calculate noise for terrain generation
367 noise_base->perlinMap2D(node_min.X, node_min.Z);
368 noise_height1->perlinMap2D(node_min.X, node_min.Z);
369 noise_height2->perlinMap2D(node_min.X, node_min.Z);
370 noise_height3->perlinMap2D(node_min.X, node_min.Z);
371 noise_height4->perlinMap2D(node_min.X, node_min.Z);
372 noise_hills_terrain->perlinMap2D(node_min.X, node_min.Z);
373 noise_ridge_terrain->perlinMap2D(node_min.X, node_min.Z);
374 noise_step_terrain->perlinMap2D(node_min.X, node_min.Z);
375 noise_hills->perlinMap2D(node_min.X, node_min.Z);
376 noise_ridge_mnt->perlinMap2D(node_min.X, node_min.Z);
377 noise_step_mnt->perlinMap2D(node_min.X, node_min.Z);
378 noise_mnt_var->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
381 for (s16 z = node_min.Z; z <= node_max.Z; z++) {
382 for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) {
383 u32 vi = vm->m_area.index(node_min.X, y, z);
384 for (s16 x = node_min.X; x <= node_max.X;
385 x++, vi++, index2d++, index3d++) {
386 if (vm->m_data[vi].getContent() != CONTENT_IGNORE)
390 float ground = noise_base->result[index2d];
392 // Gradient & shallow seabed
393 s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 : 1 - y;
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];
400 float mnt_var = noise_mnt_var->result[index3d];
401 // Combine height noises and apply 3D variation
402 float hill1 = getLerp(height1, height2, mnt_var);
403 float hill2 = getLerp(height3, height4, mnt_var);
404 float hill3 = getLerp(height3, height2, mnt_var);
405 float hill4 = getLerp(height1, height4, mnt_var);
406 // 'hilliness' determines whether hills/mountains are
408 float hilliness = std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
411 float hter = noise_hills_terrain->result[index2d];
412 float n_hills = noise_hills->result[index2d];
413 float hill_mnt = hilliness * pow(n_hills, 2.f);
414 float hills = pow(fabs(hter), 3.f) * hill_mnt;
417 float rter = noise_ridge_terrain->result[index2d];
418 float n_ridge_mnt = noise_ridge_mnt->result[index2d];
419 float ridge_mnt = hilliness * (1.f - fabs(n_ridge_mnt));
420 float ridged_mountains = pow(fabs(rter), 3.f) * ridge_mnt;
422 // Step (terraced) mountains
423 float ster = noise_step_terrain->result[index2d];
424 float n_step_mnt = noise_step_mnt->result[index2d];
425 float step_mnt = hilliness * getSteps(n_step_mnt, fabs(mnt_var));
426 float step_mountains = pow(fabs(ster), 3.f) * step_mnt;
428 // Final terrain level
429 float mountains = hills + ridged_mountains + step_mountains;
430 float surface_level = ground + mountains + grad;
432 if (y < surface_level) {
433 vm->m_data[vi] = mn_stone; // Stone
434 if (y > stone_surface_max_y)
435 stone_surface_max_y = y;
436 } else if (y <= water_level) {
437 vm->m_data[vi] = mn_water; // Sea water
439 vm->m_data[vi] = mn_air; // Air
447 return stone_surface_max_y;