Add LuaEntity on_death callback (#6177)
[oweals/minetest.git] / src / mapgen_carpathian.cpp
1 /*
2 Minetest
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>
6
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.
11
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.
16
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.
20 */
21
22
23 #include <cmath>
24 #include "mapgen.h"
25 #include "voxel.h"
26 #include "noise.h"
27 #include "mapblock.h"
28 #include "mapnode.h"
29 #include "map.h"
30 #include "content_sao.h"
31 #include "nodedef.h"
32 #include "voxelalgorithms.h"
33 //#include "profiler.h" // For TimeTaker
34 #include "settings.h" // For g_settings
35 #include "emerge.h"
36 #include "dungeongen.h"
37 #include "cavegen.h"
38 #include "mg_biome.h"
39 #include "mg_ore.h"
40 #include "mg_decoration.h"
41 #include "mapgen_carpathian.h"
42
43
44 FlagDesc flagdesc_mapgen_carpathian[] = {
45         {"caverns", MGCARPATHIAN_CAVERNS},
46         {NULL,      0}
47 };
48
49
50 ///////////////////////////////////////////////////////////////////////////////
51
52
53 MapgenCarpathian::MapgenCarpathian(
54                 int mapgenid, MapgenCarpathianParams *params, EmergeManager *emerge)
55         : MapgenBasic(mapgenid, params, emerge)
56 {
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;
65
66         //// 2D Terrain noise
67         noise_base          = new Noise(&params->np_base,          seed, csize.X, csize.Z);
68         noise_filler_depth  = new Noise(&params->np_filler_depth,  seed, csize.X, csize.Z);
69         noise_height1       = new Noise(&params->np_height1,       seed, csize.X, csize.Z);
70         noise_height2       = new Noise(&params->np_height2,       seed, csize.X, csize.Z);
71         noise_height3       = new Noise(&params->np_height3,       seed, csize.X, csize.Z);
72         noise_height4       = new Noise(&params->np_height4,       seed, csize.X, csize.Z);
73         noise_hills_terrain = new Noise(&params->np_hills_terrain, seed, csize.X, csize.Z);
74         noise_ridge_terrain = new Noise(&params->np_ridge_terrain, seed, csize.X, csize.Z);
75         noise_step_terrain  = new Noise(&params->np_step_terrain,  seed, csize.X, csize.Z);
76         noise_hills         = new Noise(&params->np_hills,         seed, csize.X, csize.Z);
77         noise_ridge_mnt     = new Noise(&params->np_ridge_mnt,     seed, csize.X, csize.Z);
78         noise_step_mnt      = new Noise(&params->np_step_mnt,      seed, csize.X, csize.Z);
79
80         //// 3D terrain noise
81         // 1 up 1 down overgeneration
82         noise_mnt_var = new Noise(&params->np_mnt_var, seed, csize.X, csize.Y + 2, csize.Z);
83
84         //// Cave noise
85         MapgenBasic::np_cave1  = params->np_cave1;
86         MapgenBasic::np_cave2  = params->np_cave2;
87         MapgenBasic::np_cavern = params->np_cavern;
88 }
89
90
91 MapgenCarpathian::~MapgenCarpathian()
92 {
93         delete noise_base;
94         delete noise_filler_depth;
95         delete noise_height1;
96         delete noise_height2;
97         delete noise_height3;
98         delete noise_height4;
99         delete noise_hills_terrain;
100         delete noise_ridge_terrain;
101         delete noise_step_terrain;
102         delete noise_hills;
103         delete noise_ridge_mnt;
104         delete noise_step_mnt;
105         delete noise_mnt_var;
106 }
107
108
109 MapgenCarpathianParams::MapgenCarpathianParams()
110 {
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);
127 }
128
129
130 void MapgenCarpathianParams::readParams(const Settings *settings)
131 {
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);
139
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);
156 }
157
158
159 void MapgenCarpathianParams::writeParams(Settings *settings) const
160 {
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);
168
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);
185 }
186
187
188 ///////////////////////////////////////////////////////////////////////////////
189
190
191 // Lerp function
192 inline float MapgenCarpathian::getLerp(float noise1, float noise2, float mod)
193 {
194         return noise1 + mod * (noise2 - noise1);
195 }
196
197 // Steps function
198 float MapgenCarpathian::getSteps(float noise1, float noise2)
199 {
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);
204         return (k + s) * w;
205 }
206
207
208 ///////////////////////////////////////////////////////////////////////////////
209
210
211 void MapgenCarpathian::makeChunk(BlockMakeData *data)
212 {
213         // Pre-conditions
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);
222
223         this->generating = true;
224         this->vm = data->vmanip;
225         this->ndef = data->nodedef;
226
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);
233
234         // Create a block-specific seed
235         blockseed = getBlockSeed2(full_node_min, seed);
236
237         // Generate terrain
238         s16 stone_surface_max_y = generateTerrain();
239
240         // Create heightmap
241         updateHeightmap(node_min, node_max);
242
243         // Init biome generator, place biome-specific nodes, and build biomemap
244         biomegen->calcBiomeNoise(node_min);
245         MgStoneType stone_type = generateBiomes(water_level - 1);
246
247         // Generate caverns, tunnels and classic caves
248         if (flags & MG_CAVES) {
249                 bool has_cavern = false;
250                 // Generate caverns
251                 if (spflags & MGCARPATHIAN_CAVERNS)
252                         has_cavern = generateCaverns(stone_surface_max_y);
253                 // Generate tunnels and classic caves
254                 if (has_cavern)
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);
259                 else
260                         generateCaves(stone_surface_max_y, large_cave_depth);
261         }
262
263         // Generate dungeons
264         if (flags & MG_DUNGEONS)
265                 generateDungeons(stone_surface_max_y, stone_type);
266
267         // Generate the registered decorations
268         if (flags & MG_DECORATIONS)
269                 m_emerge->decomgr->placeAllDecos(this, blockseed,
270                         node_min, node_max, water_level - 1);
271
272         // Generate the registered ores
273         m_emerge->oremgr->placeAllOres(this, blockseed,
274                 node_min, node_max, water_level - 1);
275
276         // Sprinkle some dust on top after everything else was generated
277         dustTopNodes();
278
279         // Update liquids
280         updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
281
282         // Calculate lighting
283         if (flags & MG_LIGHT) {
284                 calcLighting(node_min - v3s16(0, 1, 0), node_max + v3s16(0, 1, 0),
285                                 full_node_min, full_node_max);
286         }
287
288         this->generating = false;
289 }
290
291
292 ///////////////////////////////////////////////////////////////////////////////
293
294
295 int MapgenCarpathian::getSpawnLevelAtPoint(v2s16 p)
296 {
297         s16 level_at_point = terrainLevelAtPoint(p.X, p.Y);
298         if (level_at_point <= water_level || level_at_point > water_level + 32)
299                 return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
300         else
301                 return level_at_point;
302 }
303
304
305 float MapgenCarpathian::terrainLevelAtPoint(s16 x, s16 z)
306 {
307         float ground = NoisePerlin2D(&noise_base->np, x, z, seed);
308         float height1 = NoisePerlin2D(&noise_height1->np, x, z, seed);
309         float height2 = NoisePerlin2D(&noise_height2->np, x, z, seed);
310         float height3 = NoisePerlin2D(&noise_height3->np, x, z, seed);
311         float height4 = NoisePerlin2D(&noise_height4->np, x, z, seed);
312         float hter = NoisePerlin2D(&noise_hills_terrain->np, x, z, seed);
313         float rter = NoisePerlin2D(&noise_ridge_terrain->np, x, z, seed);
314         float ster = NoisePerlin2D(&noise_step_terrain->np, x, z, seed);
315         float n_hills = NoisePerlin2D(&noise_hills->np, x, z, seed);
316         float n_ridge_mnt = NoisePerlin2D(&noise_ridge_mnt->np, x, z, seed);
317         float n_step_mnt = NoisePerlin2D(&noise_step_mnt->np, x, z, seed);
318
319         int height = -MAX_MAP_GENERATION_LIMIT;
320
321         for (s16 y = 1; y <= 30; y++) {
322                 float mnt_var = NoisePerlin3D(&noise_mnt_var->np, x, y, z, seed);
323
324                 // Gradient & shallow seabed
325                 s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 : 1 - y;
326
327                 // Hill/Mountain height (hilliness)
328                 float hill1 = getLerp(height1, height2, mnt_var);
329                 float hill2 = getLerp(height3, height4, mnt_var);
330                 float hill3 = getLerp(height3, height2, mnt_var);
331                 float hill4 = getLerp(height1, height4, mnt_var);
332                 float hilliness = std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
333
334                 // Rolling hills
335                 float hill_mnt = hilliness * pow(n_hills, 2.f);
336                 float hills = pow(hter, 3.f) * hill_mnt;
337
338                 // Ridged mountains
339                 float ridge_mnt = hilliness * (1.f - fabs(n_ridge_mnt));
340                 float ridged_mountains = pow(rter, 3.f) * ridge_mnt;
341
342                 // Step (terraced) mountains
343                 float step_mnt = hilliness * getSteps(n_step_mnt, fabs(mnt_var));
344                 float step_mountains = pow(ster, 3.f) * step_mnt;
345
346                 // Final terrain level
347                 float mountains = hills + ridged_mountains + step_mountains;
348                 float surface_level = ground + mountains + grad;
349
350                 if (y > surface_level && height < 0)
351                         height = y;
352         }
353
354         return height;
355 }
356
357
358 ///////////////////////////////////////////////////////////////////////////////
359
360
361 int MapgenCarpathian::generateTerrain()
362 {
363         MapNode mn_air(CONTENT_AIR);
364         MapNode mn_stone(c_stone);
365         MapNode mn_water(c_water_source);
366
367         s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT;
368         u32 index2d = 0;
369         u32 index3d = 0;
370
371         // Calculate noise for terrain generation
372         noise_base->perlinMap2D(node_min.X, node_min.Z);
373         noise_height1->perlinMap2D(node_min.X, node_min.Z);
374         noise_height2->perlinMap2D(node_min.X, node_min.Z);
375         noise_height3->perlinMap2D(node_min.X, node_min.Z);
376         noise_height4->perlinMap2D(node_min.X, node_min.Z);
377         noise_hills_terrain->perlinMap2D(node_min.X, node_min.Z);
378         noise_ridge_terrain->perlinMap2D(node_min.X, node_min.Z);
379         noise_step_terrain->perlinMap2D(node_min.X, node_min.Z);
380         noise_hills->perlinMap2D(node_min.X, node_min.Z);
381         noise_ridge_mnt->perlinMap2D(node_min.X, node_min.Z);
382         noise_step_mnt->perlinMap2D(node_min.X, node_min.Z);
383         noise_mnt_var->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
384
385         //// Place nodes
386         for (s16 z = node_min.Z; z <= node_max.Z; z++) {
387                 for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) {
388                         u32 vi = vm->m_area.index(node_min.X, y, z);
389                         for (s16 x = node_min.X; x <= node_max.X;
390                                         x++, vi++, index2d++, index3d++) {
391                                 if (vm->m_data[vi].getContent() != CONTENT_IGNORE)
392                                         continue;
393
394                                 // Base terrain
395                                 float ground = noise_base->result[index2d];
396
397                                 // Gradient & shallow seabed
398                                 s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 : 1 - y;
399
400                                 // Hill/Mountain height (hilliness)
401                                 float height1 = noise_height1->result[index2d];
402                                 float height2 = noise_height2->result[index2d];
403                                 float height3 = noise_height3->result[index2d];
404                                 float height4 = noise_height4->result[index2d];
405                                 float mnt_var = noise_mnt_var->result[index3d];
406                                 // Combine height noises and apply 3D variation
407                                 float hill1 = getLerp(height1, height2, mnt_var);
408                                 float hill2 = getLerp(height3, height4, mnt_var);
409                                 float hill3 = getLerp(height3, height2, mnt_var);
410                                 float hill4 = getLerp(height1, height4, mnt_var);
411                                 // 'hilliness' determines whether hills/mountains are
412                                 // small or large
413                                 float hilliness = std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
414
415                                 // Rolling hills
416                                 float hter = noise_hills_terrain->result[index2d];
417                                 float n_hills = noise_hills->result[index2d];
418                                 float hill_mnt = hilliness * pow(n_hills, 2.f);
419                                 float hills = pow(fabs(hter), 3.f) * hill_mnt;
420
421                                 // Ridged mountains
422                                 float rter = noise_ridge_terrain->result[index2d];
423                                 float n_ridge_mnt = noise_ridge_mnt->result[index2d];
424                                 float ridge_mnt = hilliness * (1.f - fabs(n_ridge_mnt));
425                                 float ridged_mountains = pow(fabs(rter), 3.f) * ridge_mnt;
426
427                                 // Step (terraced) mountains
428                                 float ster = noise_step_terrain->result[index2d];
429                                 float n_step_mnt = noise_step_mnt->result[index2d];
430                                 float step_mnt = hilliness * getSteps(n_step_mnt, fabs(mnt_var));
431                                 float step_mountains = pow(fabs(ster), 3.f) * step_mnt;
432
433                                 // Final terrain level
434                                 float mountains = hills + ridged_mountains + step_mountains;
435                                 float surface_level = ground + mountains + grad;
436
437                                 if (y < surface_level) {
438                                         vm->m_data[vi] = mn_stone; // Stone
439                                         if (y > stone_surface_max_y)
440                                                 stone_surface_max_y = y;
441                                 } else if (y <= water_level) {
442                                         vm->m_data[vi] = mn_water; // Sea water
443                                 } else {
444                                         vm->m_data[vi] = mn_air; // Air
445                                 }
446                         }
447                         index2d -= ystride;
448                 }
449                 index2d += ystride;
450         }
451
452         return stone_surface_max_y;
453 }