mapgen_carpathian.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  1. /*
  2. Minetest
  3. Copyright (C) 2017-2019 vlapsley, Vaughan Lapsley <vlapsley@gmail.com>
  4. Copyright (C) 2017-2019 paramat
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU Lesser General Public License as published by
  7. the Free Software Foundation; either version 2.1 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public License along
  14. with this program; if not, write to the Free Software Foundation, Inc.,
  15. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  16. */
  17. #include <cmath>
  18. #include "mapgen.h"
  19. #include "voxel.h"
  20. #include "noise.h"
  21. #include "mapblock.h"
  22. #include "mapnode.h"
  23. #include "map.h"
  24. #include "nodedef.h"
  25. #include "voxelalgorithms.h"
  26. //#include "profiler.h" // For TimeTaker
  27. #include "settings.h" // For g_settings
  28. #include "emerge.h"
  29. #include "dungeongen.h"
  30. #include "cavegen.h"
  31. #include "mg_biome.h"
  32. #include "mg_ore.h"
  33. #include "mg_decoration.h"
  34. #include "mapgen_carpathian.h"
  35. FlagDesc flagdesc_mapgen_carpathian[] = {
  36. {"caverns", MGCARPATHIAN_CAVERNS},
  37. {"rivers", MGCARPATHIAN_RIVERS},
  38. {NULL, 0}
  39. };
  40. ///////////////////////////////////////////////////////////////////////////////
  41. MapgenCarpathian::MapgenCarpathian(MapgenCarpathianParams *params, EmergeParams *emerge)
  42. : MapgenBasic(MAPGEN_CARPATHIAN, params, emerge)
  43. {
  44. base_level = params->base_level;
  45. river_width = params->river_width;
  46. river_depth = params->river_depth;
  47. valley_width = params->valley_width;
  48. spflags = params->spflags;
  49. cave_width = params->cave_width;
  50. large_cave_depth = params->large_cave_depth;
  51. small_cave_num_min = params->small_cave_num_min;
  52. small_cave_num_max = params->small_cave_num_max;
  53. large_cave_num_min = params->large_cave_num_min;
  54. large_cave_num_max = params->large_cave_num_max;
  55. large_cave_flooded = params->large_cave_flooded;
  56. cavern_limit = params->cavern_limit;
  57. cavern_taper = params->cavern_taper;
  58. cavern_threshold = params->cavern_threshold;
  59. dungeon_ymin = params->dungeon_ymin;
  60. dungeon_ymax = params->dungeon_ymax;
  61. grad_wl = 1 - water_level;
  62. //// 2D Terrain noise
  63. noise_filler_depth = new Noise(&params->np_filler_depth, seed, csize.X, csize.Z);
  64. noise_height1 = new Noise(&params->np_height1, seed, csize.X, csize.Z);
  65. noise_height2 = new Noise(&params->np_height2, seed, csize.X, csize.Z);
  66. noise_height3 = new Noise(&params->np_height3, seed, csize.X, csize.Z);
  67. noise_height4 = new Noise(&params->np_height4, seed, csize.X, csize.Z);
  68. noise_hills_terrain = new Noise(&params->np_hills_terrain, seed, csize.X, csize.Z);
  69. noise_ridge_terrain = new Noise(&params->np_ridge_terrain, seed, csize.X, csize.Z);
  70. noise_step_terrain = new Noise(&params->np_step_terrain, seed, csize.X, csize.Z);
  71. noise_hills = new Noise(&params->np_hills, seed, csize.X, csize.Z);
  72. noise_ridge_mnt = new Noise(&params->np_ridge_mnt, seed, csize.X, csize.Z);
  73. noise_step_mnt = new Noise(&params->np_step_mnt, seed, csize.X, csize.Z);
  74. if (spflags & MGCARPATHIAN_RIVERS)
  75. noise_rivers = new Noise(&params->np_rivers, seed, csize.X, csize.Z);
  76. //// 3D terrain noise
  77. // 1 up 1 down overgeneration
  78. noise_mnt_var = new Noise(&params->np_mnt_var, seed, csize.X, csize.Y + 2, csize.Z);
  79. //// Cave noise
  80. MapgenBasic::np_cave1 = params->np_cave1;
  81. MapgenBasic::np_cave2 = params->np_cave2;
  82. MapgenBasic::np_cavern = params->np_cavern;
  83. MapgenBasic::np_dungeons = params->np_dungeons;
  84. }
  85. MapgenCarpathian::~MapgenCarpathian()
  86. {
  87. delete noise_filler_depth;
  88. delete noise_height1;
  89. delete noise_height2;
  90. delete noise_height3;
  91. delete noise_height4;
  92. delete noise_hills_terrain;
  93. delete noise_ridge_terrain;
  94. delete noise_step_terrain;
  95. delete noise_hills;
  96. delete noise_ridge_mnt;
  97. delete noise_step_mnt;
  98. if (spflags & MGCARPATHIAN_RIVERS)
  99. delete noise_rivers;
  100. delete noise_mnt_var;
  101. }
  102. MapgenCarpathianParams::MapgenCarpathianParams():
  103. np_filler_depth (0, 1, v3f(128, 128, 128), 261, 3, 0.7, 2.0),
  104. np_height1 (0, 5, v3f(251, 251, 251), 9613, 5, 0.5, 2.0),
  105. np_height2 (0, 5, v3f(383, 383, 383), 1949, 5, 0.5, 2.0),
  106. np_height3 (0, 5, v3f(509, 509, 509), 3211, 5, 0.5, 2.0),
  107. np_height4 (0, 5, v3f(631, 631, 631), 1583, 5, 0.5, 2.0),
  108. np_hills_terrain (1, 1, v3f(1301, 1301, 1301), 1692, 5, 0.5, 2.0),
  109. np_ridge_terrain (1, 1, v3f(1889, 1889, 1889), 3568, 5, 0.5, 2.0),
  110. np_step_terrain (1, 1, v3f(1889, 1889, 1889), 4157, 5, 0.5, 2.0),
  111. np_hills (0, 3, v3f(257, 257, 257), 6604, 6, 0.5, 2.0),
  112. np_ridge_mnt (0, 12, v3f(743, 743, 743), 5520, 6, 0.7, 2.0),
  113. np_step_mnt (0, 8, v3f(509, 509, 509), 2590, 6, 0.6, 2.0),
  114. np_rivers (0, 1, v3f(1000, 1000, 1000), 85039, 5, 0.6, 2.0),
  115. np_mnt_var (0, 1, v3f(499, 499, 499), 2490, 5, 0.55, 2.0),
  116. np_cave1 (0, 12, v3f(61, 61, 61), 52534, 3, 0.5, 2.0),
  117. np_cave2 (0, 12, v3f(67, 67, 67), 10325, 3, 0.5, 2.0),
  118. np_cavern (0, 1, v3f(384, 128, 384), 723, 5, 0.63, 2.0),
  119. np_dungeons (0.9, 0.5, v3f(500, 500, 500), 0, 2, 0.8, 2.0)
  120. {
  121. }
  122. void MapgenCarpathianParams::readParams(const Settings *settings)
  123. {
  124. settings->getFlagStrNoEx("mgcarpathian_spflags", spflags, flagdesc_mapgen_carpathian);
  125. settings->getFloatNoEx("mgcarpathian_base_level", base_level);
  126. settings->getFloatNoEx("mgcarpathian_river_width", river_width);
  127. settings->getFloatNoEx("mgcarpathian_river_depth", river_depth);
  128. settings->getFloatNoEx("mgcarpathian_valley_width", valley_width);
  129. settings->getFloatNoEx("mgcarpathian_cave_width", cave_width);
  130. settings->getS16NoEx("mgcarpathian_large_cave_depth", large_cave_depth);
  131. settings->getU16NoEx("mgcarpathian_small_cave_num_min", small_cave_num_min);
  132. settings->getU16NoEx("mgcarpathian_small_cave_num_max", small_cave_num_max);
  133. settings->getU16NoEx("mgcarpathian_large_cave_num_min", large_cave_num_min);
  134. settings->getU16NoEx("mgcarpathian_large_cave_num_max", large_cave_num_max);
  135. settings->getFloatNoEx("mgcarpathian_large_cave_flooded", large_cave_flooded);
  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. settings->getS16NoEx("mgcarpathian_dungeon_ymin", dungeon_ymin);
  140. settings->getS16NoEx("mgcarpathian_dungeon_ymax", dungeon_ymax);
  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_rivers", np_rivers);
  153. settings->getNoiseParams("mgcarpathian_np_mnt_var", np_mnt_var);
  154. settings->getNoiseParams("mgcarpathian_np_cave1", np_cave1);
  155. settings->getNoiseParams("mgcarpathian_np_cave2", np_cave2);
  156. settings->getNoiseParams("mgcarpathian_np_cavern", np_cavern);
  157. settings->getNoiseParams("mgcarpathian_np_dungeons", np_dungeons);
  158. }
  159. void MapgenCarpathianParams::writeParams(Settings *settings) const
  160. {
  161. settings->setFlagStr("mgcarpathian_spflags", spflags, flagdesc_mapgen_carpathian);
  162. settings->setFloat("mgcarpathian_base_level", base_level);
  163. settings->setFloat("mgcarpathian_river_width", river_width);
  164. settings->setFloat("mgcarpathian_river_depth", river_depth);
  165. settings->setFloat("mgcarpathian_valley_width", valley_width);
  166. settings->setFloat("mgcarpathian_cave_width", cave_width);
  167. settings->setS16("mgcarpathian_large_cave_depth", large_cave_depth);
  168. settings->setU16("mgcarpathian_small_cave_num_min", small_cave_num_min);
  169. settings->setU16("mgcarpathian_small_cave_num_max", small_cave_num_max);
  170. settings->setU16("mgcarpathian_large_cave_num_min", large_cave_num_min);
  171. settings->setU16("mgcarpathian_large_cave_num_max", large_cave_num_max);
  172. settings->setFloat("mgcarpathian_large_cave_flooded", large_cave_flooded);
  173. settings->setS16("mgcarpathian_cavern_limit", cavern_limit);
  174. settings->setS16("mgcarpathian_cavern_taper", cavern_taper);
  175. settings->setFloat("mgcarpathian_cavern_threshold", cavern_threshold);
  176. settings->setS16("mgcarpathian_dungeon_ymin", dungeon_ymin);
  177. settings->setS16("mgcarpathian_dungeon_ymax", dungeon_ymax);
  178. settings->setNoiseParams("mgcarpathian_np_filler_depth", np_filler_depth);
  179. settings->setNoiseParams("mgcarpathian_np_height1", np_height1);
  180. settings->setNoiseParams("mgcarpathian_np_height2", np_height2);
  181. settings->setNoiseParams("mgcarpathian_np_height3", np_height3);
  182. settings->setNoiseParams("mgcarpathian_np_height4", np_height4);
  183. settings->setNoiseParams("mgcarpathian_np_hills_terrain", np_hills_terrain);
  184. settings->setNoiseParams("mgcarpathian_np_ridge_terrain", np_ridge_terrain);
  185. settings->setNoiseParams("mgcarpathian_np_step_terrain", np_step_terrain);
  186. settings->setNoiseParams("mgcarpathian_np_hills", np_hills);
  187. settings->setNoiseParams("mgcarpathian_np_ridge_mnt", np_ridge_mnt);
  188. settings->setNoiseParams("mgcarpathian_np_step_mnt", np_step_mnt);
  189. settings->setNoiseParams("mgcarpathian_np_rivers", np_rivers);
  190. settings->setNoiseParams("mgcarpathian_np_mnt_var", np_mnt_var);
  191. settings->setNoiseParams("mgcarpathian_np_cave1", np_cave1);
  192. settings->setNoiseParams("mgcarpathian_np_cave2", np_cave2);
  193. settings->setNoiseParams("mgcarpathian_np_cavern", np_cavern);
  194. settings->setNoiseParams("mgcarpathian_np_dungeons", np_dungeons);
  195. }
  196. void MapgenCarpathianParams::setDefaultSettings(Settings *settings)
  197. {
  198. settings->setDefault("mgcarpathian_spflags", flagdesc_mapgen_carpathian,
  199. MGCARPATHIAN_CAVERNS);
  200. }
  201. ////////////////////////////////////////////////////////////////////////////////
  202. // Lerp function
  203. inline float MapgenCarpathian::getLerp(float noise1, float noise2, float mod)
  204. {
  205. return noise1 + mod * (noise2 - noise1);
  206. }
  207. // Steps function
  208. float MapgenCarpathian::getSteps(float noise)
  209. {
  210. float w = 0.5f;
  211. float k = std::floor(noise / w);
  212. float f = (noise - k * w) / w;
  213. float s = std::fmin(2.f * f, 1.f);
  214. return (k + s) * w;
  215. }
  216. ////////////////////////////////////////////////////////////////////////////////
  217. void MapgenCarpathian::makeChunk(BlockMakeData *data)
  218. {
  219. // Pre-conditions
  220. assert(data->vmanip);
  221. assert(data->nodedef);
  222. this->generating = true;
  223. this->vm = data->vmanip;
  224. this->ndef = data->nodedef;
  225. v3s16 blockpos_min = data->blockpos_min;
  226. v3s16 blockpos_max = data->blockpos_max;
  227. node_min = blockpos_min * MAP_BLOCKSIZE;
  228. node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
  229. full_node_min = (blockpos_min - 1) * MAP_BLOCKSIZE;
  230. 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);
  233. // Generate terrain
  234. s16 stone_surface_max_y = generateTerrain();
  235. // Create heightmap
  236. updateHeightmap(node_min, node_max);
  237. // Init biome generator, place biome-specific nodes, and build biomemap
  238. if (flags & MG_BIOMES) {
  239. biomegen->calcBiomeNoise(node_min);
  240. generateBiomes();
  241. }
  242. // Generate tunnels, caverns and large randomwalk caves
  243. if (flags & MG_CAVES) {
  244. // Generate tunnels first as caverns confuse them
  245. generateCavesNoiseIntersection(stone_surface_max_y);
  246. // Generate caverns
  247. bool near_cavern = false;
  248. if (spflags & MGCARPATHIAN_CAVERNS)
  249. near_cavern = generateCavernsNoise(stone_surface_max_y);
  250. // Generate large randomwalk caves
  251. if (near_cavern)
  252. // Disable large randomwalk 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. generateCavesRandomWalk(stone_surface_max_y,
  256. -MAX_MAP_GENERATION_LIMIT);
  257. else
  258. generateCavesRandomWalk(stone_surface_max_y, large_cave_depth);
  259. }
  260. // Generate the registered ores
  261. if (flags & MG_ORES)
  262. m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max);
  263. // Generate dungeons
  264. if (flags & MG_DUNGEONS)
  265. generateDungeons(stone_surface_max_y);
  266. // Generate the registered decorations
  267. if (flags & MG_DECORATIONS)
  268. m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
  269. // Sprinkle some dust on top after everything else was generated
  270. if (flags & MG_BIOMES)
  271. dustTopNodes();
  272. // Update liquids
  273. updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
  274. // Calculate lighting
  275. if (flags & MG_LIGHT) {
  276. calcLighting(node_min - v3s16(0, 1, 0), node_max + v3s16(0, 1, 0),
  277. full_node_min, full_node_max);
  278. }
  279. this->generating = false;
  280. }
  281. ////////////////////////////////////////////////////////////////////////////////
  282. int MapgenCarpathian::getSpawnLevelAtPoint(v2s16 p)
  283. {
  284. // If rivers are enabled, first check if in a river channel
  285. if (spflags & MGCARPATHIAN_RIVERS) {
  286. float river = std::fabs(NoisePerlin2D(&noise_rivers->np, p.X, p.Y, seed)) -
  287. river_width;
  288. if (river < 0.0f)
  289. return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
  290. }
  291. float height1 = NoisePerlin2D(&noise_height1->np, p.X, p.Y, seed);
  292. float height2 = NoisePerlin2D(&noise_height2->np, p.X, p.Y, seed);
  293. float height3 = NoisePerlin2D(&noise_height3->np, p.X, p.Y, seed);
  294. float height4 = NoisePerlin2D(&noise_height4->np, p.X, p.Y, seed);
  295. float hterabs = std::fabs(NoisePerlin2D(&noise_hills_terrain->np, p.X, p.Y, seed));
  296. float n_hills = NoisePerlin2D(&noise_hills->np, p.X, p.Y, seed);
  297. float hill_mnt = hterabs * hterabs * hterabs * n_hills * n_hills;
  298. float rterabs = std::fabs(NoisePerlin2D(&noise_ridge_terrain->np, p.X, p.Y, seed));
  299. float n_ridge_mnt = NoisePerlin2D(&noise_ridge_mnt->np, p.X, p.Y, seed);
  300. float ridge_mnt = rterabs * rterabs * rterabs * (1.0f - std::fabs(n_ridge_mnt));
  301. float sterabs = std::fabs(NoisePerlin2D(&noise_step_terrain->np, p.X, p.Y, seed));
  302. float n_step_mnt = NoisePerlin2D(&noise_step_mnt->np, p.X, p.Y, seed);
  303. float step_mnt = sterabs * sterabs * sterabs * getSteps(n_step_mnt);
  304. float valley = 1.0f;
  305. float river = 0.0f;
  306. if ((spflags & MGCARPATHIAN_RIVERS) && node_max.Y >= water_level - 16) {
  307. river = std::fabs(NoisePerlin2D(&noise_rivers->np, p.X, p.Y, seed)) - river_width;
  308. if (river <= valley_width) {
  309. // Within river valley
  310. if (river < 0.0f) {
  311. // River channel
  312. valley = river;
  313. } else {
  314. // Valley slopes.
  315. // 0 at river edge, 1 at valley edge.
  316. float riversc = river / valley_width;
  317. // Smoothstep
  318. valley = riversc * riversc * (3.0f - 2.0f * riversc);
  319. }
  320. }
  321. }
  322. bool solid_below = false;
  323. u8 cons_non_solid = 0; // consecutive non-solid nodes
  324. for (s16 y = water_level; y <= water_level + 32; y++) {
  325. float mnt_var = NoisePerlin3D(&noise_mnt_var->np, p.X, y, p.Y, seed);
  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));
  331. float hills = hill_mnt * hilliness;
  332. float ridged_mountains = ridge_mnt * hilliness;
  333. float step_mountains = step_mnt * hilliness;
  334. s32 grad = 1 - y;
  335. float mountains = hills + ridged_mountains + step_mountains;
  336. float surface_level = base_level + mountains + grad;
  337. if ((spflags & MGCARPATHIAN_RIVERS) && river <= valley_width) {
  338. if (valley < 0.0f) {
  339. // River channel
  340. surface_level = std::fmin(surface_level,
  341. water_level - std::sqrt(-valley) * river_depth);
  342. } else if (surface_level > water_level) {
  343. // Valley slopes
  344. surface_level = water_level + (surface_level - water_level) * valley;
  345. }
  346. }
  347. if (y < surface_level) { //TODO '<=' fix from generateTerrain()
  348. // solid node
  349. solid_below = true;
  350. cons_non_solid = 0;
  351. } else {
  352. // non-solid node
  353. cons_non_solid++;
  354. if (cons_non_solid == 3 && solid_below)
  355. return y - 1;
  356. }
  357. }
  358. return MAX_MAP_GENERATION_LIMIT; // No suitable spawn point found
  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. // Calculate noise for terrain generation
  367. noise_height1->perlinMap2D(node_min.X, node_min.Z);
  368. noise_height2->perlinMap2D(node_min.X, node_min.Z);
  369. noise_height3->perlinMap2D(node_min.X, node_min.Z);
  370. noise_height4->perlinMap2D(node_min.X, node_min.Z);
  371. noise_hills_terrain->perlinMap2D(node_min.X, node_min.Z);
  372. noise_ridge_terrain->perlinMap2D(node_min.X, node_min.Z);
  373. noise_step_terrain->perlinMap2D(node_min.X, node_min.Z);
  374. noise_hills->perlinMap2D(node_min.X, node_min.Z);
  375. noise_ridge_mnt->perlinMap2D(node_min.X, node_min.Z);
  376. noise_step_mnt->perlinMap2D(node_min.X, node_min.Z);
  377. noise_mnt_var->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
  378. if (spflags & MGCARPATHIAN_RIVERS)
  379. noise_rivers->perlinMap2D(node_min.X, node_min.Z);
  380. //// Place nodes
  381. const v3s16 &em = vm->m_area.getExtent();
  382. s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT;
  383. u32 index2d = 0;
  384. for (s16 z = node_min.Z; z <= node_max.Z; z++)
  385. for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
  386. // Hill/Mountain height (hilliness)
  387. float height1 = noise_height1->result[index2d];
  388. float height2 = noise_height2->result[index2d];
  389. float height3 = noise_height3->result[index2d];
  390. float height4 = noise_height4->result[index2d];
  391. // Rolling hills
  392. float hterabs = std::fabs(noise_hills_terrain->result[index2d]);
  393. float n_hills = noise_hills->result[index2d];
  394. float hill_mnt = hterabs * hterabs * hterabs * n_hills * n_hills;
  395. // Ridged mountains
  396. float rterabs = std::fabs(noise_ridge_terrain->result[index2d]);
  397. float n_ridge_mnt = noise_ridge_mnt->result[index2d];
  398. float ridge_mnt = rterabs * rterabs * rterabs *
  399. (1.0f - std::fabs(n_ridge_mnt));
  400. // Step (terraced) mountains
  401. float sterabs = std::fabs(noise_step_terrain->result[index2d]);
  402. float n_step_mnt = noise_step_mnt->result[index2d];
  403. float step_mnt = sterabs * sterabs * sterabs * getSteps(n_step_mnt);
  404. // Rivers
  405. float valley = 1.0f;
  406. float river = 0.0f;
  407. if ((spflags & MGCARPATHIAN_RIVERS) && node_max.Y >= water_level - 16) {
  408. river = std::fabs(noise_rivers->result[index2d]) - river_width;
  409. if (river <= valley_width) {
  410. // Within river valley
  411. if (river < 0.0f) {
  412. // River channel
  413. valley = river;
  414. } else {
  415. // Valley slopes.
  416. // 0 at river edge, 1 at valley edge.
  417. float riversc = river / valley_width;
  418. // Smoothstep
  419. valley = riversc * riversc * (3.0f - 2.0f * riversc);
  420. }
  421. }
  422. }
  423. // Initialise 3D noise index and voxelmanip index to column base
  424. u32 index3d = (z - node_min.Z) * zstride_1u1d + (x - node_min.X);
  425. u32 vi = vm->m_area.index(x, node_min.Y - 1, z);
  426. for (s16 y = node_min.Y - 1; y <= node_max.Y + 1;
  427. y++,
  428. index3d += ystride,
  429. VoxelArea::add_y(em, vi, 1)) {
  430. if (vm->m_data[vi].getContent() != CONTENT_IGNORE)
  431. continue;
  432. // Combine height noises and apply 3D variation
  433. float mnt_var = noise_mnt_var->result[index3d];
  434. float hill1 = getLerp(height1, height2, mnt_var);
  435. float hill2 = getLerp(height3, height4, mnt_var);
  436. float hill3 = getLerp(height3, height2, mnt_var);
  437. float hill4 = getLerp(height1, height4, mnt_var);
  438. // 'hilliness' determines whether hills/mountains are
  439. // small or large
  440. float hilliness =
  441. std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
  442. float hills = hill_mnt * hilliness;
  443. float ridged_mountains = ridge_mnt * hilliness;
  444. float step_mountains = step_mnt * hilliness;
  445. // Gradient & shallow seabed
  446. s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 :
  447. 1 - y;
  448. // Final terrain level
  449. float mountains = hills + ridged_mountains + step_mountains;
  450. float surface_level = base_level + mountains + grad;
  451. // Rivers
  452. if ((spflags & MGCARPATHIAN_RIVERS) && node_max.Y >= water_level - 16 &&
  453. river <= valley_width) {
  454. if (valley < 0.0f) {
  455. // River channel
  456. surface_level = std::fmin(surface_level,
  457. water_level - std::sqrt(-valley) * river_depth);
  458. } else if (surface_level > water_level) {
  459. // Valley slopes
  460. surface_level = water_level + (surface_level - water_level) * valley;
  461. }
  462. }
  463. if (y < surface_level) { //TODO '<='
  464. vm->m_data[vi] = mn_stone; // Stone
  465. if (y > stone_surface_max_y)
  466. stone_surface_max_y = y;
  467. } else if (y <= water_level) {
  468. vm->m_data[vi] = mn_water; // Sea water
  469. } else {
  470. vm->m_data[vi] = mn_air; // Air
  471. }
  472. }
  473. }
  474. return stone_surface_max_y;
  475. }