mapgen_carpathian.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  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. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU Lesser General Public License as published by
  8. the Free Software Foundation; either version 2.1 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU Lesser General Public License for more details.
  14. You should have received a copy of the GNU Lesser General Public License along
  15. with this program; if not, write to the Free Software Foundation, Inc.,
  16. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  17. */
  18. #include <cmath>
  19. #include "mapgen.h"
  20. #include "voxel.h"
  21. #include "noise.h"
  22. #include "mapblock.h"
  23. #include "mapnode.h"
  24. #include "map.h"
  25. #include "content_sao.h"
  26. #include "nodedef.h"
  27. #include "voxelalgorithms.h"
  28. //#include "profiler.h" // For TimeTaker
  29. #include "settings.h" // For g_settings
  30. #include "emerge.h"
  31. #include "dungeongen.h"
  32. #include "cavegen.h"
  33. #include "mg_biome.h"
  34. #include "mg_ore.h"
  35. #include "mg_decoration.h"
  36. #include "mapgen_carpathian.h"
  37. FlagDesc flagdesc_mapgen_carpathian[] = {
  38. {"caverns", MGCARPATHIAN_CAVERNS},
  39. {NULL, 0}
  40. };
  41. ///////////////////////////////////////////////////////////////////////////////
  42. MapgenCarpathian::MapgenCarpathian(
  43. int mapgenid, MapgenCarpathianParams *params, EmergeManager *emerge)
  44. : MapgenBasic(mapgenid, params, emerge)
  45. {
  46. spflags = params->spflags;
  47. cave_width = params->cave_width;
  48. large_cave_depth = params->large_cave_depth;
  49. lava_depth = params->lava_depth;
  50. cavern_limit = params->cavern_limit;
  51. cavern_taper = params->cavern_taper;
  52. cavern_threshold = params->cavern_threshold;
  53. grad_wl = 1 - water_level;
  54. //// 2D Terrain noise
  55. noise_base = new Noise(&params->np_base, seed, csize.X, csize.Z);
  56. noise_filler_depth = new Noise(&params->np_filler_depth, seed, csize.X, csize.Z);
  57. noise_height1 = new Noise(&params->np_height1, seed, csize.X, csize.Z);
  58. noise_height2 = new Noise(&params->np_height2, seed, csize.X, csize.Z);
  59. noise_height3 = new Noise(&params->np_height3, seed, csize.X, csize.Z);
  60. noise_height4 = new Noise(&params->np_height4, seed, csize.X, csize.Z);
  61. noise_hills_terrain = new Noise(&params->np_hills_terrain, seed, csize.X, csize.Z);
  62. noise_ridge_terrain = new Noise(&params->np_ridge_terrain, seed, csize.X, csize.Z);
  63. noise_step_terrain = new Noise(&params->np_step_terrain, seed, csize.X, csize.Z);
  64. noise_hills = new Noise(&params->np_hills, seed, csize.X, csize.Z);
  65. noise_ridge_mnt = new Noise(&params->np_ridge_mnt, seed, csize.X, csize.Z);
  66. noise_step_mnt = new Noise(&params->np_step_mnt, seed, csize.X, csize.Z);
  67. //// 3D terrain noise
  68. // 1 up 1 down overgeneration
  69. noise_mnt_var = new Noise(&params->np_mnt_var, seed, csize.X, csize.Y + 2, csize.Z);
  70. //// Cave noise
  71. MapgenBasic::np_cave1 = params->np_cave1;
  72. MapgenBasic::np_cave2 = params->np_cave2;
  73. MapgenBasic::np_cavern = params->np_cavern;
  74. }
  75. MapgenCarpathian::~MapgenCarpathian()
  76. {
  77. delete noise_base;
  78. delete noise_filler_depth;
  79. delete noise_height1;
  80. delete noise_height2;
  81. delete noise_height3;
  82. delete noise_height4;
  83. delete noise_hills_terrain;
  84. delete noise_ridge_terrain;
  85. delete noise_step_terrain;
  86. delete noise_hills;
  87. delete noise_ridge_mnt;
  88. delete noise_step_mnt;
  89. delete noise_mnt_var;
  90. }
  91. MapgenCarpathianParams::MapgenCarpathianParams():
  92. np_base (12, 1, v3f(2557, 2557, 2557), 6538, 4, 0.8, 0.5),
  93. np_filler_depth (0, 1, v3f(128, 128, 128), 261, 3, 0.7, 2.0),
  94. np_height1 (0, 5, v3f(251, 251, 251), 9613, 5, 0.5, 2.0),
  95. np_height2 (0, 5, v3f(383, 383, 383), 1949, 5, 0.5, 2.0),
  96. np_height3 (0, 5, v3f(509, 509, 509), 3211, 5, 0.5, 2.0),
  97. np_height4 (0, 5, v3f(631, 631, 631), 1583, 5, 0.5, 2.0),
  98. np_hills_terrain (1, 1, v3f(1301, 1301, 1301), 1692, 5, 0.5, 2.0),
  99. np_ridge_terrain (1, 1, v3f(1889, 1889, 1889), 3568, 5, 0.5, 2.0),
  100. np_step_terrain (1, 1, v3f(1889, 1889, 1889), 4157, 5, 0.5, 2.0),
  101. np_hills (0, 3, v3f(257, 257, 257), 6604, 6, 0.5, 2.0),
  102. np_ridge_mnt (0, 12, v3f(743, 743, 743), 5520, 6, 0.7, 2.0),
  103. np_step_mnt (0, 8, v3f(509, 509, 509), 2590, 6, 0.6, 2.0),
  104. np_mnt_var (0, 1, v3f(499, 499, 499), 2490, 5, 0.55, 2.0),
  105. np_cave1 (0, 12, v3f(61, 61, 61), 52534, 3, 0.5, 2.0),
  106. np_cave2 (0, 12, v3f(67, 67, 67), 10325, 3, 0.5, 2.0),
  107. np_cavern (0, 1, v3f(384, 128, 384), 723, 5, 0.63, 2.0)
  108. {
  109. }
  110. void MapgenCarpathianParams::readParams(const Settings *settings)
  111. {
  112. settings->getFlagStrNoEx("mgcarpathian_spflags", spflags, flagdesc_mapgen_carpathian);
  113. settings->getFloatNoEx("mgcarpathian_cave_width", cave_width);
  114. settings->getS16NoEx("mgcarpathian_large_cave_depth", large_cave_depth);
  115. settings->getS16NoEx("mgcarpathian_lava_depth", lava_depth);
  116. settings->getS16NoEx("mgcarpathian_cavern_limit", cavern_limit);
  117. settings->getS16NoEx("mgcarpathian_cavern_taper", cavern_taper);
  118. settings->getFloatNoEx("mgcarpathian_cavern_threshold", cavern_threshold);
  119. settings->getNoiseParams("mgcarpathian_np_base", np_base);
  120. settings->getNoiseParams("mgcarpathian_np_filler_depth", np_filler_depth);
  121. settings->getNoiseParams("mgcarpathian_np_height1", np_height1);
  122. settings->getNoiseParams("mgcarpathian_np_height2", np_height2);
  123. settings->getNoiseParams("mgcarpathian_np_height3", np_height3);
  124. settings->getNoiseParams("mgcarpathian_np_height4", np_height4);
  125. settings->getNoiseParams("mgcarpathian_np_hills_terrain", np_hills_terrain);
  126. settings->getNoiseParams("mgcarpathian_np_ridge_terrain", np_ridge_terrain);
  127. settings->getNoiseParams("mgcarpathian_np_step_terrain", np_step_terrain);
  128. settings->getNoiseParams("mgcarpathian_np_hills", np_hills);
  129. settings->getNoiseParams("mgcarpathian_np_ridge_mnt", np_ridge_mnt);
  130. settings->getNoiseParams("mgcarpathian_np_step_mnt", np_step_mnt);
  131. settings->getNoiseParams("mgcarpathian_np_mnt_var", np_mnt_var);
  132. settings->getNoiseParams("mgcarpathian_np_cave1", np_cave1);
  133. settings->getNoiseParams("mgcarpathian_np_cave2", np_cave2);
  134. settings->getNoiseParams("mgcarpathian_np_cavern", np_cavern);
  135. }
  136. void MapgenCarpathianParams::writeParams(Settings *settings) const
  137. {
  138. settings->setFlagStr("mgcarpathian_spflags", spflags, flagdesc_mapgen_carpathian, U32_MAX);
  139. settings->setFloat("mgcarpathian_cave_width", cave_width);
  140. settings->setS16("mgcarpathian_large_cave_depth", large_cave_depth);
  141. settings->setS16("mgcarpathian_lava_depth", lava_depth);
  142. settings->setS16("mgcarpathian_cavern_limit", cavern_limit);
  143. settings->setS16("mgcarpathian_cavern_taper", cavern_taper);
  144. settings->setFloat("mgcarpathian_cavern_threshold", cavern_threshold);
  145. settings->setNoiseParams("mgcarpathian_np_base", np_base);
  146. settings->setNoiseParams("mgcarpathian_np_filler_depth", np_filler_depth);
  147. settings->setNoiseParams("mgcarpathian_np_height1", np_height1);
  148. settings->setNoiseParams("mgcarpathian_np_height2", np_height2);
  149. settings->setNoiseParams("mgcarpathian_np_height3", np_height3);
  150. settings->setNoiseParams("mgcarpathian_np_height4", np_height4);
  151. settings->setNoiseParams("mgcarpathian_np_hills_terrain", np_hills_terrain);
  152. settings->setNoiseParams("mgcarpathian_np_ridge_terrain", np_ridge_terrain);
  153. settings->setNoiseParams("mgcarpathian_np_step_terrain", np_step_terrain);
  154. settings->setNoiseParams("mgcarpathian_np_hills", np_hills);
  155. settings->setNoiseParams("mgcarpathian_np_ridge_mnt", np_ridge_mnt);
  156. settings->setNoiseParams("mgcarpathian_np_step_mnt", np_step_mnt);
  157. settings->setNoiseParams("mgcarpathian_np_mnt_var", np_mnt_var);
  158. settings->setNoiseParams("mgcarpathian_np_cave1", np_cave1);
  159. settings->setNoiseParams("mgcarpathian_np_cave2", np_cave2);
  160. settings->setNoiseParams("mgcarpathian_np_cavern", np_cavern);
  161. }
  162. ///////////////////////////////////////////////////////////////////////////////
  163. // Lerp function
  164. inline float MapgenCarpathian::getLerp(float noise1, float noise2, float mod)
  165. {
  166. return noise1 + mod * (noise2 - noise1);
  167. }
  168. // Steps function
  169. float MapgenCarpathian::getSteps(float noise)
  170. {
  171. float w = 0.5f;
  172. float k = floor(noise / w);
  173. float f = (noise - k * w) / w;
  174. float s = std::fmin(2.f * f, 1.f);
  175. return (k + s) * w;
  176. }
  177. ///////////////////////////////////////////////////////////////////////////////
  178. void MapgenCarpathian::makeChunk(BlockMakeData *data)
  179. {
  180. // Pre-conditions
  181. assert(data->vmanip);
  182. assert(data->nodedef);
  183. assert(data->blockpos_requested.X >= data->blockpos_min.X &&
  184. data->blockpos_requested.Y >= data->blockpos_min.Y &&
  185. data->blockpos_requested.Z >= data->blockpos_min.Z);
  186. assert(data->blockpos_requested.X <= data->blockpos_max.X &&
  187. data->blockpos_requested.Y <= data->blockpos_max.Y &&
  188. data->blockpos_requested.Z <= data->blockpos_max.Z);
  189. this->generating = true;
  190. this->vm = data->vmanip;
  191. this->ndef = data->nodedef;
  192. v3s16 blockpos_min = data->blockpos_min;
  193. v3s16 blockpos_max = data->blockpos_max;
  194. node_min = blockpos_min * MAP_BLOCKSIZE;
  195. node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
  196. full_node_min = (blockpos_min - 1) * MAP_BLOCKSIZE;
  197. full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
  198. // Create a block-specific seed
  199. blockseed = getBlockSeed2(full_node_min, seed);
  200. // Generate terrain
  201. s16 stone_surface_max_y = generateTerrain();
  202. // Create heightmap
  203. updateHeightmap(node_min, node_max);
  204. // Init biome generator, place biome-specific nodes, and build biomemap
  205. biomegen->calcBiomeNoise(node_min);
  206. MgStoneType mgstone_type;
  207. content_t biome_stone;
  208. generateBiomes(&mgstone_type, &biome_stone);
  209. // Generate caverns, tunnels and classic caves
  210. if (flags & MG_CAVES) {
  211. bool has_cavern = false;
  212. // Generate caverns
  213. if (spflags & MGCARPATHIAN_CAVERNS)
  214. has_cavern = generateCaverns(stone_surface_max_y);
  215. // Generate tunnels and classic caves
  216. if (has_cavern)
  217. // Disable classic caves in this mapchunk by setting
  218. // 'large cave depth' to world base. Avoids excessive liquid in
  219. // large caverns and floating blobs of overgenerated liquid.
  220. generateCaves(stone_surface_max_y, -MAX_MAP_GENERATION_LIMIT);
  221. else
  222. generateCaves(stone_surface_max_y, large_cave_depth);
  223. }
  224. // Generate dungeons
  225. if (flags & MG_DUNGEONS)
  226. generateDungeons(stone_surface_max_y, mgstone_type, biome_stone);
  227. // Generate the registered decorations
  228. if (flags & MG_DECORATIONS)
  229. m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
  230. // Generate the registered ores
  231. m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max);
  232. // Sprinkle some dust on top after everything else was generated
  233. dustTopNodes();
  234. // Update liquids
  235. updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
  236. // Calculate lighting
  237. if (flags & MG_LIGHT) {
  238. calcLighting(node_min - v3s16(0, 1, 0), node_max + v3s16(0, 1, 0),
  239. full_node_min, full_node_max);
  240. }
  241. this->generating = false;
  242. }
  243. ///////////////////////////////////////////////////////////////////////////////
  244. int MapgenCarpathian::getSpawnLevelAtPoint(v2s16 p)
  245. {
  246. s16 level_at_point = terrainLevelAtPoint(p.X, p.Y);
  247. if (level_at_point <= water_level || level_at_point > water_level + 32)
  248. return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
  249. return level_at_point;
  250. }
  251. float MapgenCarpathian::terrainLevelAtPoint(s16 x, s16 z)
  252. {
  253. float ground = NoisePerlin2D(&noise_base->np, x, z, seed);
  254. float height1 = NoisePerlin2D(&noise_height1->np, x, z, seed);
  255. float height2 = NoisePerlin2D(&noise_height2->np, x, z, seed);
  256. float height3 = NoisePerlin2D(&noise_height3->np, x, z, seed);
  257. float height4 = NoisePerlin2D(&noise_height4->np, x, z, seed);
  258. float hter = NoisePerlin2D(&noise_hills_terrain->np, x, z, seed);
  259. float rter = NoisePerlin2D(&noise_ridge_terrain->np, x, z, seed);
  260. float ster = NoisePerlin2D(&noise_step_terrain->np, x, z, seed);
  261. float n_hills = NoisePerlin2D(&noise_hills->np, x, z, seed);
  262. float n_ridge_mnt = NoisePerlin2D(&noise_ridge_mnt->np, x, z, seed);
  263. float n_step_mnt = NoisePerlin2D(&noise_step_mnt->np, x, z, seed);
  264. int height = -MAX_MAP_GENERATION_LIMIT;
  265. for (s16 y = 1; y <= 30; y++) {
  266. float mnt_var = NoisePerlin3D(&noise_mnt_var->np, x, y, z, seed);
  267. // Gradient & shallow seabed
  268. s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 : 1 - y;
  269. // Hill/Mountain height (hilliness)
  270. float hill1 = getLerp(height1, height2, mnt_var);
  271. float hill2 = getLerp(height3, height4, mnt_var);
  272. float hill3 = getLerp(height3, height2, mnt_var);
  273. float hill4 = getLerp(height1, height4, mnt_var);
  274. float hilliness = std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
  275. // Rolling hills
  276. float hill_mnt = hilliness * pow(n_hills, 2.f);
  277. float hills = pow(hter, 3.f) * hill_mnt;
  278. // Ridged mountains
  279. float ridge_mnt = hilliness * (1.f - fabs(n_ridge_mnt));
  280. float ridged_mountains = pow(rter, 3.f) * ridge_mnt;
  281. // Step (terraced) mountains
  282. float step_mnt = hilliness * getSteps(n_step_mnt);
  283. float step_mountains = pow(ster, 3.f) * step_mnt;
  284. // Final terrain level
  285. float mountains = hills + ridged_mountains + step_mountains;
  286. float surface_level = ground + mountains + grad;
  287. if (y > surface_level && height < 0)
  288. height = y;
  289. }
  290. return height;
  291. }
  292. ///////////////////////////////////////////////////////////////////////////////
  293. int MapgenCarpathian::generateTerrain()
  294. {
  295. MapNode mn_air(CONTENT_AIR);
  296. MapNode mn_stone(c_stone);
  297. MapNode mn_water(c_water_source);
  298. s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT;
  299. u32 index2d = 0;
  300. u32 index3d = 0;
  301. // Calculate noise for terrain generation
  302. noise_base->perlinMap2D(node_min.X, node_min.Z);
  303. noise_height1->perlinMap2D(node_min.X, node_min.Z);
  304. noise_height2->perlinMap2D(node_min.X, node_min.Z);
  305. noise_height3->perlinMap2D(node_min.X, node_min.Z);
  306. noise_height4->perlinMap2D(node_min.X, node_min.Z);
  307. noise_hills_terrain->perlinMap2D(node_min.X, node_min.Z);
  308. noise_ridge_terrain->perlinMap2D(node_min.X, node_min.Z);
  309. noise_step_terrain->perlinMap2D(node_min.X, node_min.Z);
  310. noise_hills->perlinMap2D(node_min.X, node_min.Z);
  311. noise_ridge_mnt->perlinMap2D(node_min.X, node_min.Z);
  312. noise_step_mnt->perlinMap2D(node_min.X, node_min.Z);
  313. noise_mnt_var->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
  314. //// Place nodes
  315. for (s16 z = node_min.Z; z <= node_max.Z; z++) {
  316. for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) {
  317. u32 vi = vm->m_area.index(node_min.X, y, z);
  318. for (s16 x = node_min.X; x <= node_max.X;
  319. x++, vi++, index2d++, index3d++) {
  320. if (vm->m_data[vi].getContent() != CONTENT_IGNORE)
  321. continue;
  322. // Base terrain
  323. float ground = noise_base->result[index2d];
  324. // Gradient & shallow seabed
  325. s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 : 1 - y;
  326. // Hill/Mountain height (hilliness)
  327. float height1 = noise_height1->result[index2d];
  328. float height2 = noise_height2->result[index2d];
  329. float height3 = noise_height3->result[index2d];
  330. float height4 = noise_height4->result[index2d];
  331. float mnt_var = noise_mnt_var->result[index3d];
  332. // Combine height noises and apply 3D variation
  333. float hill1 = getLerp(height1, height2, mnt_var);
  334. float hill2 = getLerp(height3, height4, mnt_var);
  335. float hill3 = getLerp(height3, height2, mnt_var);
  336. float hill4 = getLerp(height1, height4, mnt_var);
  337. // 'hilliness' determines whether hills/mountains are
  338. // small or large
  339. float hilliness = std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
  340. // Rolling hills
  341. float hter = noise_hills_terrain->result[index2d];
  342. float n_hills = noise_hills->result[index2d];
  343. float hill_mnt = hilliness * pow(n_hills, 2.f);
  344. float hills = pow(fabs(hter), 3.f) * hill_mnt;
  345. // Ridged mountains
  346. float rter = noise_ridge_terrain->result[index2d];
  347. float n_ridge_mnt = noise_ridge_mnt->result[index2d];
  348. float ridge_mnt = hilliness * (1.f - fabs(n_ridge_mnt));
  349. float ridged_mountains = pow(fabs(rter), 3.f) * ridge_mnt;
  350. // Step (terraced) mountains
  351. float ster = noise_step_terrain->result[index2d];
  352. float n_step_mnt = noise_step_mnt->result[index2d];
  353. float step_mnt = hilliness * getSteps(n_step_mnt);
  354. float step_mountains = pow(fabs(ster), 3.f) * step_mnt;
  355. // Final terrain level
  356. float mountains = hills + ridged_mountains + step_mountains;
  357. float surface_level = ground + mountains + grad;
  358. if (y < surface_level) {
  359. vm->m_data[vi] = mn_stone; // Stone
  360. if (y > stone_surface_max_y)
  361. stone_surface_max_y = y;
  362. } else if (y <= water_level) {
  363. vm->m_data[vi] = mn_water; // Sea water
  364. } else {
  365. vm->m_data[vi] = mn_air; // Air
  366. }
  367. }
  368. index2d -= ystride;
  369. }
  370. index2d += ystride;
  371. }
  372. return stone_surface_max_y;
  373. }