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():
110 np_base (12, 1, v3f(2557, 2557, 2557), 6538, 4, 0.8, 0.5),
111 np_filler_depth (0, 1, v3f(128, 128, 128), 261, 3, 0.7, 2.0),
112 np_height1 (0, 5, v3f(251, 251, 251), 9613, 5, 0.5, 2.0),
113 np_height2 (0, 5, v3f(383, 383, 383), 1949, 5, 0.5, 2.0),
114 np_height3 (0, 5, v3f(509, 509, 509), 3211, 5, 0.5, 2.0),
115 np_height4 (0, 5, v3f(631, 631, 631), 1583, 5, 0.5, 2.0),
116 np_hills_terrain (1, 1, v3f(1301, 1301, 1301), 1692, 5, 0.5, 2.0),
117 np_ridge_terrain (1, 1, v3f(1889, 1889, 1889), 3568, 5, 0.5, 2.0),
118 np_step_terrain (1, 1, v3f(1889, 1889, 1889), 4157, 5, 0.5, 2.0),
119 np_hills (0, 3, v3f(257, 257, 257), 6604, 6, 0.5, 2.0),
120 np_ridge_mnt (0, 12, v3f(743, 743, 743), 5520, 6, 0.7, 2.0),
121 np_step_mnt (0, 8, v3f(509, 509, 509), 2590, 6, 0.6, 2.0),
122 np_mnt_var (0, 1, v3f(499, 499, 499), 2490, 5, 0.55, 2.0),
123 np_cave1 (0, 12, v3f(61, 61, 61), 52534, 3, 0.5, 2.0),
124 np_cave2 (0, 12, v3f(67, 67, 67), 10325, 3, 0.5, 2.0),
125 np_cavern (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 noise)
201 float k = floor(noise / w);
202 float f = (noise - 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);
246 MgStoneType mgstone_type;
247 content_t biome_stone;
248 generateBiomes(&mgstone_type, &biome_stone);
250 // Generate caverns, tunnels and classic caves
251 if (flags & MG_CAVES) {
252 bool has_cavern = false;
254 if (spflags & MGCARPATHIAN_CAVERNS)
255 has_cavern = generateCaverns(stone_surface_max_y);
256 // Generate tunnels and classic caves
258 // Disable classic caves in this mapchunk by setting
259 // 'large cave depth' to world base. Avoids excessive liquid in
260 // large caverns and floating blobs of overgenerated liquid.
261 generateCaves(stone_surface_max_y, -MAX_MAP_GENERATION_LIMIT);
263 generateCaves(stone_surface_max_y, large_cave_depth);
267 if (flags & MG_DUNGEONS)
268 generateDungeons(stone_surface_max_y, mgstone_type, biome_stone);
270 // Generate the registered decorations
271 if (flags & MG_DECORATIONS)
272 m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
274 // Generate the registered ores
275 m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max);
277 // Sprinkle some dust on top after everything else was generated
281 updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
283 // Calculate lighting
284 if (flags & MG_LIGHT) {
285 calcLighting(node_min - v3s16(0, 1, 0), node_max + v3s16(0, 1, 0),
286 full_node_min, full_node_max);
289 this->generating = false;
293 ///////////////////////////////////////////////////////////////////////////////
296 int MapgenCarpathian::getSpawnLevelAtPoint(v2s16 p)
298 s16 level_at_point = terrainLevelAtPoint(p.X, p.Y);
299 if (level_at_point <= water_level || level_at_point > water_level + 32)
300 return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
302 return level_at_point;
306 float MapgenCarpathian::terrainLevelAtPoint(s16 x, s16 z)
308 float ground = NoisePerlin2D(&noise_base->np, x, z, seed);
309 float height1 = NoisePerlin2D(&noise_height1->np, x, z, seed);
310 float height2 = NoisePerlin2D(&noise_height2->np, x, z, seed);
311 float height3 = NoisePerlin2D(&noise_height3->np, x, z, seed);
312 float height4 = NoisePerlin2D(&noise_height4->np, x, z, seed);
313 float hter = NoisePerlin2D(&noise_hills_terrain->np, x, z, seed);
314 float rter = NoisePerlin2D(&noise_ridge_terrain->np, x, z, seed);
315 float ster = NoisePerlin2D(&noise_step_terrain->np, x, z, seed);
316 float n_hills = NoisePerlin2D(&noise_hills->np, x, z, seed);
317 float n_ridge_mnt = NoisePerlin2D(&noise_ridge_mnt->np, x, z, seed);
318 float n_step_mnt = NoisePerlin2D(&noise_step_mnt->np, x, z, seed);
320 int height = -MAX_MAP_GENERATION_LIMIT;
322 for (s16 y = 1; y <= 30; y++) {
323 float mnt_var = NoisePerlin3D(&noise_mnt_var->np, x, y, z, seed);
325 // Gradient & shallow seabed
326 s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 : 1 - y;
328 // Hill/Mountain height (hilliness)
329 float hill1 = getLerp(height1, height2, mnt_var);
330 float hill2 = getLerp(height3, height4, mnt_var);
331 float hill3 = getLerp(height3, height2, mnt_var);
332 float hill4 = getLerp(height1, height4, mnt_var);
333 float hilliness = std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
336 float hill_mnt = hilliness * pow(n_hills, 2.f);
337 float hills = pow(hter, 3.f) * hill_mnt;
340 float ridge_mnt = hilliness * (1.f - fabs(n_ridge_mnt));
341 float ridged_mountains = pow(rter, 3.f) * ridge_mnt;
343 // Step (terraced) mountains
344 float step_mnt = hilliness * getSteps(n_step_mnt);
345 float step_mountains = pow(ster, 3.f) * step_mnt;
347 // Final terrain level
348 float mountains = hills + ridged_mountains + step_mountains;
349 float surface_level = ground + mountains + grad;
351 if (y > surface_level && height < 0)
359 ///////////////////////////////////////////////////////////////////////////////
362 int MapgenCarpathian::generateTerrain()
364 MapNode mn_air(CONTENT_AIR);
365 MapNode mn_stone(c_stone);
366 MapNode mn_water(c_water_source);
368 s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT;
372 // Calculate noise for terrain generation
373 noise_base->perlinMap2D(node_min.X, node_min.Z);
374 noise_height1->perlinMap2D(node_min.X, node_min.Z);
375 noise_height2->perlinMap2D(node_min.X, node_min.Z);
376 noise_height3->perlinMap2D(node_min.X, node_min.Z);
377 noise_height4->perlinMap2D(node_min.X, node_min.Z);
378 noise_hills_terrain->perlinMap2D(node_min.X, node_min.Z);
379 noise_ridge_terrain->perlinMap2D(node_min.X, node_min.Z);
380 noise_step_terrain->perlinMap2D(node_min.X, node_min.Z);
381 noise_hills->perlinMap2D(node_min.X, node_min.Z);
382 noise_ridge_mnt->perlinMap2D(node_min.X, node_min.Z);
383 noise_step_mnt->perlinMap2D(node_min.X, node_min.Z);
384 noise_mnt_var->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
387 for (s16 z = node_min.Z; z <= node_max.Z; z++) {
388 for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) {
389 u32 vi = vm->m_area.index(node_min.X, y, z);
390 for (s16 x = node_min.X; x <= node_max.X;
391 x++, vi++, index2d++, index3d++) {
392 if (vm->m_data[vi].getContent() != CONTENT_IGNORE)
396 float ground = noise_base->result[index2d];
398 // Gradient & shallow seabed
399 s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 : 1 - y;
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];
406 float mnt_var = noise_mnt_var->result[index3d];
407 // Combine height noises and apply 3D variation
408 float hill1 = getLerp(height1, height2, mnt_var);
409 float hill2 = getLerp(height3, height4, mnt_var);
410 float hill3 = getLerp(height3, height2, mnt_var);
411 float hill4 = getLerp(height1, height4, mnt_var);
412 // 'hilliness' determines whether hills/mountains are
414 float hilliness = std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
417 float hter = noise_hills_terrain->result[index2d];
418 float n_hills = noise_hills->result[index2d];
419 float hill_mnt = hilliness * pow(n_hills, 2.f);
420 float hills = pow(fabs(hter), 3.f) * hill_mnt;
423 float rter = noise_ridge_terrain->result[index2d];
424 float n_ridge_mnt = noise_ridge_mnt->result[index2d];
425 float ridge_mnt = hilliness * (1.f - fabs(n_ridge_mnt));
426 float ridged_mountains = pow(fabs(rter), 3.f) * ridge_mnt;
428 // Step (terraced) mountains
429 float ster = noise_step_terrain->result[index2d];
430 float n_step_mnt = noise_step_mnt->result[index2d];
431 float step_mnt = hilliness * getSteps(n_step_mnt);
432 float step_mountains = pow(fabs(ster), 3.f) * step_mnt;
434 // Final terrain level
435 float mountains = hills + ridged_mountains + step_mountains;
436 float surface_level = ground + mountains + grad;
438 if (y < surface_level) {
439 vm->m_data[vi] = mn_stone; // Stone
440 if (y > stone_surface_max_y)
441 stone_surface_max_y = y;
442 } else if (y <= water_level) {
443 vm->m_data[vi] = mn_water; // Sea water
445 vm->m_data[vi] = mn_air; // Air
453 return stone_surface_max_y;