mapgen_valleys.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. /*
  2. Minetest Valleys C
  3. Copyright (C) 2016-2017 Duane Robertson <duane@duanerobertson.com>
  4. Copyright (C) 2016-2017 paramat
  5. Based on Valleys Mapgen by Gael de Sailly
  6. (https://forum.minetest.net/viewtopic.php?f=9&t=11430)
  7. and mapgen_v7, mapgen_flat by kwolekr and paramat.
  8. Licensing changed by permission of Gael de Sailly.
  9. This program is free software; you can redistribute it and/or modify
  10. it under the terms of the GNU Lesser General Public License as published by
  11. the Free Software Foundation; either version 2.1 of the License, or
  12. (at your option) any later version.
  13. This program is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. 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.
  20. */
  21. #include "mapgen.h"
  22. #include "voxel.h"
  23. #include "noise.h"
  24. #include "mapblock.h"
  25. #include "mapnode.h"
  26. #include "map.h"
  27. #include "content_sao.h"
  28. #include "nodedef.h"
  29. #include "voxelalgorithms.h"
  30. #include "settings.h" // For g_settings
  31. #include "emerge.h"
  32. #include "dungeongen.h"
  33. #include "mg_biome.h"
  34. #include "mg_ore.h"
  35. #include "mg_decoration.h"
  36. #include "mapgen_valleys.h"
  37. #include "cavegen.h"
  38. //#undef NDEBUG
  39. //#include "assert.h"
  40. //#include "util/timetaker.h"
  41. //#include "profiler.h"
  42. //static Profiler mapgen_prof;
  43. //Profiler *mapgen_profiler = &mapgen_prof;
  44. static FlagDesc flagdesc_mapgen_valleys[] = {
  45. {"altitude_chill", MGVALLEYS_ALT_CHILL},
  46. {"humid_rivers", MGVALLEYS_HUMID_RIVERS},
  47. {NULL, 0}
  48. };
  49. ///////////////////////////////////////////////////////////////////////////////
  50. MapgenValleys::MapgenValleys(int mapgenid, MapgenValleysParams *params, EmergeManager *emerge)
  51. : MapgenBasic(mapgenid, params, emerge)
  52. {
  53. // NOTE: MapgenValleys has a hard dependency on BiomeGenOriginal
  54. this->m_bgen = (BiomeGenOriginal *)biomegen;
  55. BiomeParamsOriginal *bp = (BiomeParamsOriginal *)params->bparams;
  56. this->spflags = params->spflags;
  57. this->altitude_chill = params->altitude_chill;
  58. this->large_cave_depth = params->large_cave_depth;
  59. this->lava_features_lim = rangelim(params->lava_features, 0, 10);
  60. this->massive_cave_depth = params->massive_cave_depth;
  61. this->river_depth_bed = params->river_depth + 1.f;
  62. this->river_size_factor = params->river_size / 100.f;
  63. this->water_features_lim = rangelim(params->water_features, 0, 10);
  64. this->cave_width = params->cave_width;
  65. //// 2D Terrain noise
  66. noise_filler_depth = new Noise(&params->np_filler_depth, seed, csize.X, csize.Z);
  67. noise_inter_valley_slope = new Noise(&params->np_inter_valley_slope, seed, csize.X, csize.Z);
  68. noise_rivers = new Noise(&params->np_rivers, seed, csize.X, csize.Z);
  69. noise_terrain_height = new Noise(&params->np_terrain_height, seed, csize.X, csize.Z);
  70. noise_valley_depth = new Noise(&params->np_valley_depth, seed, csize.X, csize.Z);
  71. noise_valley_profile = new Noise(&params->np_valley_profile, seed, csize.X, csize.Z);
  72. //// 3D Terrain noise
  73. // 1-up 1-down overgeneration
  74. noise_inter_valley_fill = new Noise(&params->np_inter_valley_fill, seed, csize.X, csize.Y + 2, csize.Z);
  75. // 1-down overgeneraion
  76. noise_cave1 = new Noise(&params->np_cave1, seed, csize.X, csize.Y + 1, csize.Z);
  77. noise_cave2 = new Noise(&params->np_cave2, seed, csize.X, csize.Y + 1, csize.Z);
  78. noise_massive_caves = new Noise(&params->np_massive_caves, seed, csize.X, csize.Y + 1, csize.Z);
  79. this->humid_rivers = (spflags & MGVALLEYS_HUMID_RIVERS);
  80. this->use_altitude_chill = (spflags & MGVALLEYS_ALT_CHILL);
  81. this->humidity_adjust = bp->np_humidity.offset - 50.f;
  82. // a small chance of overflows if the settings are very high
  83. this->cave_water_max_height = water_level + MYMAX(0, water_features_lim - 4) * 50;
  84. this->lava_max_height = water_level + MYMAX(0, lava_features_lim - 4) * 50;
  85. tcave_cache = new float[csize.Y + 2];
  86. }
  87. MapgenValleys::~MapgenValleys()
  88. {
  89. delete noise_cave1;
  90. delete noise_cave2;
  91. delete noise_filler_depth;
  92. delete noise_inter_valley_fill;
  93. delete noise_inter_valley_slope;
  94. delete noise_rivers;
  95. delete noise_massive_caves;
  96. delete noise_terrain_height;
  97. delete noise_valley_depth;
  98. delete noise_valley_profile;
  99. delete[] tcave_cache;
  100. }
  101. MapgenValleysParams::MapgenValleysParams()
  102. {
  103. np_cave1 = NoiseParams(0, 12, v3f(61, 61, 61), 52534, 3, 0.5, 2.0);
  104. np_cave2 = NoiseParams(0, 12, v3f(67, 67, 67), 10325, 3, 0.5, 2.0);
  105. np_filler_depth = NoiseParams(0.f, 1.2f, v3f(256, 256, 256), 1605, 3, 0.5f, 2.f);
  106. np_inter_valley_fill = NoiseParams(0.f, 1.f, v3f(256, 512, 256), 1993, 6, 0.8f, 2.f);
  107. np_inter_valley_slope = NoiseParams(0.5f, 0.5f, v3f(128, 128, 128), 746, 1, 1.f, 2.f);
  108. np_rivers = NoiseParams(0.f, 1.f, v3f(256, 256, 256), -6050, 5, 0.6f, 2.f);
  109. np_massive_caves = NoiseParams(0.f, 1.f, v3f(768, 256, 768), 59033, 6, 0.63f, 2.f);
  110. np_terrain_height = NoiseParams(-10.f, 50.f, v3f(1024, 1024, 1024), 5202, 6, 0.4f, 2.f);
  111. np_valley_depth = NoiseParams(5.f, 4.f, v3f(512, 512, 512), -1914, 1, 1.f, 2.f);
  112. np_valley_profile = NoiseParams(0.6f, 0.5f, v3f(512, 512, 512), 777, 1, 1.f, 2.f);
  113. }
  114. void MapgenValleysParams::readParams(const Settings *settings)
  115. {
  116. settings->getFlagStrNoEx("mgvalleys_spflags", spflags, flagdesc_mapgen_valleys);
  117. settings->getU16NoEx("mgvalleys_altitude_chill", altitude_chill);
  118. settings->getS16NoEx("mgvalleys_large_cave_depth", large_cave_depth);
  119. settings->getU16NoEx("mgvalleys_lava_features", lava_features);
  120. settings->getS16NoEx("mgvalleys_massive_cave_depth", massive_cave_depth);
  121. settings->getU16NoEx("mgvalleys_river_depth", river_depth);
  122. settings->getU16NoEx("mgvalleys_river_size", river_size);
  123. settings->getU16NoEx("mgvalleys_water_features", water_features);
  124. settings->getFloatNoEx("mgvalleys_cave_width", cave_width);
  125. settings->getNoiseParams("mgvalleys_np_cave1", np_cave1);
  126. settings->getNoiseParams("mgvalleys_np_cave2", np_cave2);
  127. settings->getNoiseParams("mgvalleys_np_filler_depth", np_filler_depth);
  128. settings->getNoiseParams("mgvalleys_np_inter_valley_fill", np_inter_valley_fill);
  129. settings->getNoiseParams("mgvalleys_np_inter_valley_slope", np_inter_valley_slope);
  130. settings->getNoiseParams("mgvalleys_np_rivers", np_rivers);
  131. settings->getNoiseParams("mgvalleys_np_massive_caves", np_massive_caves);
  132. settings->getNoiseParams("mgvalleys_np_terrain_height", np_terrain_height);
  133. settings->getNoiseParams("mgvalleys_np_valley_depth", np_valley_depth);
  134. settings->getNoiseParams("mgvalleys_np_valley_profile", np_valley_profile);
  135. }
  136. void MapgenValleysParams::writeParams(Settings *settings) const
  137. {
  138. settings->setFlagStr("mgvalleys_spflags", spflags, flagdesc_mapgen_valleys, U32_MAX);
  139. settings->setU16("mgvalleys_altitude_chill", altitude_chill);
  140. settings->setS16("mgvalleys_large_cave_depth", large_cave_depth);
  141. settings->setU16("mgvalleys_lava_features", lava_features);
  142. settings->setS16("mgvalleys_massive_cave_depth", massive_cave_depth);
  143. settings->setU16("mgvalleys_river_depth", river_depth);
  144. settings->setU16("mgvalleys_river_size", river_size);
  145. settings->setU16("mgvalleys_water_features", water_features);
  146. settings->setFloat("mgvalleys_cave_width", cave_width);
  147. settings->setNoiseParams("mgvalleys_np_cave1", np_cave1);
  148. settings->setNoiseParams("mgvalleys_np_cave2", np_cave2);
  149. settings->setNoiseParams("mgvalleys_np_filler_depth", np_filler_depth);
  150. settings->setNoiseParams("mgvalleys_np_inter_valley_fill", np_inter_valley_fill);
  151. settings->setNoiseParams("mgvalleys_np_inter_valley_slope", np_inter_valley_slope);
  152. settings->setNoiseParams("mgvalleys_np_rivers", np_rivers);
  153. settings->setNoiseParams("mgvalleys_np_massive_caves", np_massive_caves);
  154. settings->setNoiseParams("mgvalleys_np_terrain_height", np_terrain_height);
  155. settings->setNoiseParams("mgvalleys_np_valley_depth", np_valley_depth);
  156. settings->setNoiseParams("mgvalleys_np_valley_profile", np_valley_profile);
  157. }
  158. ///////////////////////////////////////
  159. void MapgenValleys::makeChunk(BlockMakeData *data)
  160. {
  161. // Pre-conditions
  162. assert(data->vmanip);
  163. assert(data->nodedef);
  164. assert(data->blockpos_requested.X >= data->blockpos_min.X &&
  165. data->blockpos_requested.Y >= data->blockpos_min.Y &&
  166. data->blockpos_requested.Z >= data->blockpos_min.Z);
  167. assert(data->blockpos_requested.X <= data->blockpos_max.X &&
  168. data->blockpos_requested.Y <= data->blockpos_max.Y &&
  169. data->blockpos_requested.Z <= data->blockpos_max.Z);
  170. this->generating = true;
  171. this->vm = data->vmanip;
  172. this->ndef = data->nodedef;
  173. //TimeTaker t("makeChunk");
  174. v3s16 blockpos_min = data->blockpos_min;
  175. v3s16 blockpos_max = data->blockpos_max;
  176. node_min = blockpos_min * MAP_BLOCKSIZE;
  177. node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
  178. full_node_min = (blockpos_min - 1) * MAP_BLOCKSIZE;
  179. full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
  180. blockseed = getBlockSeed2(full_node_min, seed);
  181. // Generate biome noises. Note this must be executed strictly before
  182. // generateTerrain, because generateTerrain depends on intermediate
  183. // biome-related noises.
  184. m_bgen->calcBiomeNoise(node_min);
  185. // Generate noise maps and base terrain height.
  186. // Modify heat and humidity maps.
  187. calculateNoise();
  188. // Generate base terrain with initial heightmaps
  189. s16 stone_surface_max_y = generateTerrain();
  190. // Recalculate heightmap
  191. updateHeightmap(node_min, node_max);
  192. // Place biome-specific nodes and build biomemap
  193. MgStoneType stone_type = generateBiomes();
  194. // Cave creation.
  195. if (flags & MG_CAVES)
  196. generateCaves(stone_surface_max_y, large_cave_depth);
  197. // Dungeon creation
  198. if ((flags & MG_DUNGEONS) && node_max.Y < 50)
  199. generateDungeons(stone_surface_max_y, stone_type);
  200. // Generate the registered decorations
  201. if (flags & MG_DECORATIONS)
  202. m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
  203. // Generate the registered ores
  204. m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max);
  205. // Sprinkle some dust on top after everything else was generated
  206. dustTopNodes();
  207. //TimeTaker tll("liquid_lighting");
  208. updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
  209. if (flags & MG_LIGHT)
  210. calcLighting(
  211. node_min - v3s16(0, 1, 0),
  212. node_max + v3s16(0, 1, 0),
  213. full_node_min,
  214. full_node_max);
  215. //mapgen_profiler->avg("liquid_lighting", tll.stop() / 1000.f);
  216. //mapgen_profiler->avg("makeChunk", t.stop() / 1000.f);
  217. this->generating = false;
  218. }
  219. // Populate the noise tables and do most of the
  220. // calculation necessary to determine terrain height.
  221. void MapgenValleys::calculateNoise()
  222. {
  223. //TimeTaker t("calculateNoise", NULL, PRECISION_MICRO);
  224. int x = node_min.X;
  225. int y = node_min.Y - 1;
  226. int z = node_min.Z;
  227. //TimeTaker tcn("actualNoise");
  228. noise_inter_valley_slope->perlinMap2D(x, z);
  229. noise_rivers->perlinMap2D(x, z);
  230. noise_terrain_height->perlinMap2D(x, z);
  231. noise_valley_depth->perlinMap2D(x, z);
  232. noise_valley_profile->perlinMap2D(x, z);
  233. noise_inter_valley_fill->perlinMap3D(x, y, z);
  234. //mapgen_profiler->avg("noisemaps", tcn.stop() / 1000.f);
  235. float heat_offset = 0.f;
  236. float humidity_scale = 1.f;
  237. // Altitude chill tends to reduce the average heat.
  238. if (use_altitude_chill)
  239. heat_offset = 5.f;
  240. // River humidity tends to increase the humidity range.
  241. if (humid_rivers) {
  242. humidity_scale = 0.8f;
  243. }
  244. for (s32 index = 0; index < csize.X * csize.Z; index++) {
  245. m_bgen->heatmap[index] += heat_offset;
  246. m_bgen->humidmap[index] *= humidity_scale;
  247. }
  248. TerrainNoise tn;
  249. u32 index = 0;
  250. for (tn.z = node_min.Z; tn.z <= node_max.Z; tn.z++)
  251. for (tn.x = node_min.X; tn.x <= node_max.X; tn.x++, index++) {
  252. // The parameters that we actually need to generate terrain
  253. // are passed by address (and the return value).
  254. tn.terrain_height = noise_terrain_height->result[index];
  255. // River noise is replaced with base terrain, which
  256. // is basically the height of the water table.
  257. tn.rivers = &noise_rivers->result[index];
  258. // Valley depth noise is replaced with the valley
  259. // number that represents the height of terrain
  260. // over rivers and is used to determine about
  261. // how close a river is for humidity calculation.
  262. tn.valley = &noise_valley_depth->result[index];
  263. tn.valley_profile = noise_valley_profile->result[index];
  264. // Slope noise is replaced by the calculated slope
  265. // which is used to get terrain height in the slow
  266. // method, to create sharper mountains.
  267. tn.slope = &noise_inter_valley_slope->result[index];
  268. tn.inter_valley_fill = noise_inter_valley_fill->result[index];
  269. // This is the actual terrain height.
  270. float mount = terrainLevelFromNoise(&tn);
  271. noise_terrain_height->result[index] = mount;
  272. }
  273. }
  274. // This keeps us from having to maintain two similar sets of
  275. // complicated code to determine ground level.
  276. float MapgenValleys::terrainLevelFromNoise(TerrainNoise *tn)
  277. {
  278. // The square function changes the behaviour of this noise:
  279. // very often small, and sometimes very high.
  280. float valley_d = MYSQUARE(*tn->valley);
  281. // valley_d is here because terrain is generally higher where valleys
  282. // are deep (mountains). base represents the height of the
  283. // rivers, most of the surface is above.
  284. float base = tn->terrain_height + valley_d;
  285. // "river" represents the distance from the river, in arbitrary units.
  286. float river = fabs(*tn->rivers) - river_size_factor;
  287. // Use the curve of the function 1-exp(-(x/a)^2) to model valleys.
  288. // Making "a" vary (0 < a <= 1) changes the shape of the valleys.
  289. // Try it with a geometry software !
  290. // (here x = "river" and a = valley_profile).
  291. // "valley" represents the height of the terrain, from the rivers.
  292. {
  293. float t = river / tn->valley_profile;
  294. *tn->valley = valley_d * (1.f - exp(- MYSQUARE(t)));
  295. }
  296. // approximate height of the terrain at this point
  297. float mount = base + *tn->valley;
  298. *tn->slope *= *tn->valley;
  299. // Rivers are placed where "river" is negative, so where the original
  300. // noise value is close to zero.
  301. // Base ground is returned as rivers since it's basically the water table.
  302. *tn->rivers = base;
  303. if (river < 0.f) {
  304. // Use the the function -sqrt(1-x^2) which models a circle.
  305. float depth;
  306. {
  307. float t = river / river_size_factor + 1;
  308. depth = (river_depth_bed * sqrt(MYMAX(0, 1.f - MYSQUARE(t))));
  309. }
  310. // base - depth : height of the bottom of the river
  311. // water_level - 3 : don't make rivers below 3 nodes under the surface
  312. // We use three because that's as low as the swamp biomes go.
  313. // There is no logical equivalent to this using rangelim.
  314. mount = MYMIN(MYMAX(base - depth, (float)(water_level - 3)), mount);
  315. // Slope has no influence on rivers.
  316. *tn->slope = 0.f;
  317. }
  318. return mount;
  319. }
  320. // This avoids duplicating the code in terrainLevelFromNoise, adding
  321. // only the final step of terrain generation without a noise map.
  322. float MapgenValleys::adjustedTerrainLevelFromNoise(TerrainNoise *tn)
  323. {
  324. float mount = terrainLevelFromNoise(tn);
  325. s16 y_start = myround(mount);
  326. for (s16 y = y_start; y <= y_start + 1000; y++) {
  327. float fill = NoisePerlin3D(&noise_inter_valley_fill->np, tn->x, y, tn->z, seed);
  328. if (fill * *tn->slope < y - mount) {
  329. mount = MYMAX(y - 1, mount);
  330. break;
  331. }
  332. }
  333. return mount;
  334. }
  335. int MapgenValleys::getSpawnLevelAtPoint(v2s16 p)
  336. {
  337. // Check to make sure this isn't a request for a location in a river.
  338. float rivers = NoisePerlin2D(&noise_rivers->np, p.X, p.Y, seed);
  339. if (fabs(rivers) < river_size_factor)
  340. return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
  341. s16 level_at_point = terrainLevelAtPoint(p.X, p.Y);
  342. if (level_at_point <= water_level ||
  343. level_at_point > water_level + 32)
  344. return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
  345. else
  346. return level_at_point;
  347. }
  348. float MapgenValleys::terrainLevelAtPoint(s16 x, s16 z)
  349. {
  350. TerrainNoise tn;
  351. float rivers = NoisePerlin2D(&noise_rivers->np, x, z, seed);
  352. float valley = NoisePerlin2D(&noise_valley_depth->np, x, z, seed);
  353. float inter_valley_slope = NoisePerlin2D(&noise_inter_valley_slope->np, x, z, seed);
  354. tn.x = x;
  355. tn.z = z;
  356. tn.terrain_height = NoisePerlin2D(&noise_terrain_height->np, x, z, seed);
  357. tn.rivers = &rivers;
  358. tn.valley = &valley;
  359. tn.valley_profile = NoisePerlin2D(&noise_valley_profile->np, x, z, seed);
  360. tn.slope = &inter_valley_slope;
  361. tn.inter_valley_fill = 0.f;
  362. return adjustedTerrainLevelFromNoise(&tn);
  363. }
  364. int MapgenValleys::generateTerrain()
  365. {
  366. // Raising this reduces the rate of evaporation.
  367. static const float evaporation = 300.f;
  368. // from the lua
  369. static const float humidity_dropoff = 4.f;
  370. // constant to convert altitude chill (compatible with lua) to heat
  371. static const float alt_to_heat = 20.f;
  372. // humidity reduction by altitude
  373. static const float alt_to_humid = 10.f;
  374. MapNode n_air(CONTENT_AIR);
  375. MapNode n_river_water(c_river_water_source);
  376. MapNode n_stone(c_stone);
  377. MapNode n_water(c_water_source);
  378. v3s16 em = vm->m_area.getExtent();
  379. s16 surface_max_y = -MAX_MAP_GENERATION_LIMIT;
  380. u32 index_2d = 0;
  381. for (s16 z = node_min.Z; z <= node_max.Z; z++)
  382. for (s16 x = node_min.X; x <= node_max.X; x++, index_2d++) {
  383. float river_y = noise_rivers->result[index_2d];
  384. float surface_y = noise_terrain_height->result[index_2d];
  385. float slope = noise_inter_valley_slope->result[index_2d];
  386. float t_heat = m_bgen->heatmap[index_2d];
  387. heightmap[index_2d] = -MAX_MAP_GENERATION_LIMIT;
  388. if (surface_y > surface_max_y)
  389. surface_max_y = ceil(surface_y);
  390. if (humid_rivers) {
  391. // Derive heat from (base) altitude. This will be most correct
  392. // at rivers, since other surface heights may vary below.
  393. if (use_altitude_chill && (surface_y > 0.f || river_y > 0.f))
  394. t_heat -= alt_to_heat * MYMAX(surface_y, river_y) / altitude_chill;
  395. // If humidity is low or heat is high, lower the water table.
  396. float delta = m_bgen->humidmap[index_2d] - 50.f;
  397. if (delta < 0.f) {
  398. float t_evap = (t_heat - 32.f) / evaporation;
  399. river_y += delta * MYMAX(t_evap, 0.08f);
  400. }
  401. }
  402. u32 index_3d = (z - node_min.Z) * zstride_1u1d + (x - node_min.X);
  403. u32 index_data = vm->m_area.index(x, node_min.Y - 1, z);
  404. // Mapgens concern themselves with stone and water.
  405. for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) {
  406. if (vm->m_data[index_data].getContent() == CONTENT_IGNORE) {
  407. float fill = noise_inter_valley_fill->result[index_3d];
  408. float surface_delta = (float)y - surface_y;
  409. bool river = y + 1 < river_y;
  410. if (slope * fill > surface_delta) {
  411. // ground
  412. vm->m_data[index_data] = n_stone;
  413. if (y > heightmap[index_2d])
  414. heightmap[index_2d] = y;
  415. if (y > surface_max_y)
  416. surface_max_y = y;
  417. } else if (y <= water_level) {
  418. // sea
  419. vm->m_data[index_data] = n_water;
  420. } else if (river) {
  421. // river
  422. vm->m_data[index_data] = n_river_water;
  423. } else { // air
  424. vm->m_data[index_data] = n_air;
  425. }
  426. }
  427. vm->m_area.add_y(em, index_data, 1);
  428. index_3d += ystride;
  429. }
  430. if (heightmap[index_2d] == -MAX_MAP_GENERATION_LIMIT) {
  431. s16 surface_y_int = myround(surface_y);
  432. if (surface_y_int > node_max.Y + 1 || surface_y_int < node_min.Y - 1) {
  433. // If surface_y is outside the chunk, it's good enough.
  434. heightmap[index_2d] = surface_y_int;
  435. } else {
  436. // If the ground is outside of this chunk, but surface_y
  437. // is within the chunk, give a value outside.
  438. heightmap[index_2d] = node_min.Y - 2;
  439. }
  440. }
  441. if (humid_rivers) {
  442. // Use base ground (water table) in a riverbed, to
  443. // avoid an unnatural rise in humidity.
  444. float t_alt = MYMAX(noise_rivers->result[index_2d], (float)heightmap[index_2d]);
  445. float humid = m_bgen->humidmap[index_2d];
  446. float water_depth = (t_alt - river_y) / humidity_dropoff;
  447. humid *= 1.f + pow(0.5f, MYMAX(water_depth, 1.f));
  448. // Reduce humidity with altitude (ignoring riverbeds).
  449. // This is similar to the lua version's seawater adjustment,
  450. // but doesn't increase the base humidity, which causes
  451. // problems with the default biomes.
  452. if (t_alt > 0.f)
  453. humid -= alt_to_humid * t_alt / altitude_chill;
  454. m_bgen->humidmap[index_2d] = humid;
  455. }
  456. // Assign the heat adjusted by any changed altitudes.
  457. // The altitude will change about half the time.
  458. if (use_altitude_chill) {
  459. // ground height ignoring riverbeds
  460. float t_alt = MYMAX(noise_rivers->result[index_2d], (float)heightmap[index_2d]);
  461. if (humid_rivers && heightmap[index_2d] == (s16)myround(surface_y))
  462. // The altitude hasn't changed. Use the first result.
  463. m_bgen->heatmap[index_2d] = t_heat;
  464. else if (t_alt > 0.f)
  465. m_bgen->heatmap[index_2d] -= alt_to_heat * t_alt / altitude_chill;
  466. }
  467. }
  468. return surface_max_y;
  469. }
  470. void MapgenValleys::generateCaves(s16 max_stone_y, s16 large_cave_depth)
  471. {
  472. if (max_stone_y < node_min.Y)
  473. return;
  474. noise_cave1->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
  475. noise_cave2->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
  476. PseudoRandom ps(blockseed + 72202);
  477. MapNode n_air(CONTENT_AIR);
  478. MapNode n_lava(c_lava_source);
  479. MapNode n_water(c_river_water_source);
  480. v3s16 em = vm->m_area.getExtent();
  481. // Cave blend distance near YMIN, YMAX
  482. const float massive_cave_blend = 128.f;
  483. // noise threshold for massive caves
  484. const float massive_cave_threshold = 0.6f;
  485. // mct: 1 = small rare caves, 0.5 1/3rd ground volume, 0 = 1/2 ground volume.
  486. float yblmin = -mapgen_limit + massive_cave_blend * 1.5f;
  487. float yblmax = massive_cave_depth - massive_cave_blend * 1.5f;
  488. bool made_a_big_one = false;
  489. // Cache the tcave values as they only vary by altitude.
  490. if (node_max.Y <= massive_cave_depth) {
  491. noise_massive_caves->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
  492. for (s16 y = node_min.Y - 1; y <= node_max.Y; y++) {
  493. float tcave = massive_cave_threshold;
  494. if (y < yblmin) {
  495. float t = (yblmin - y) / massive_cave_blend;
  496. tcave += MYSQUARE(t);
  497. } else if (y > yblmax) {
  498. float t = (y - yblmax) / massive_cave_blend;
  499. tcave += MYSQUARE(t);
  500. }
  501. tcave_cache[y - node_min.Y + 1] = tcave;
  502. }
  503. }
  504. // lava_depth varies between one and ten as you approach
  505. // the bottom of the world.
  506. s16 lava_depth = ceil((lava_max_height - node_min.Y + 1) * 10.f / mapgen_limit);
  507. // This allows random lava spawns to be less common at the surface.
  508. s16 lava_chance = MYCUBE(lava_features_lim) * lava_depth;
  509. // water_depth varies between ten and one on the way down.
  510. s16 water_depth = ceil((mapgen_limit - abs(node_min.Y) + 1) * 10.f / mapgen_limit);
  511. // This allows random water spawns to be more common at the surface.
  512. s16 water_chance = MYCUBE(water_features_lim) * water_depth;
  513. // Reduce the odds of overflows even further.
  514. if (node_max.Y > water_level) {
  515. lava_chance /= 3;
  516. water_chance /= 3;
  517. }
  518. u32 index_2d = 0;
  519. for (s16 z = node_min.Z; z <= node_max.Z; z++)
  520. for (s16 x = node_min.X; x <= node_max.X; x++, index_2d++) {
  521. Biome *biome = (Biome *)m_bmgr->getRaw(biomemap[index_2d]);
  522. bool tunnel_air_above = false;
  523. bool is_under_river = false;
  524. bool underground = false;
  525. u32 index_data = vm->m_area.index(x, node_max.Y, z);
  526. u32 index_3d = (z - node_min.Z) * zstride_1d + csize.Y * ystride + (x - node_min.X);
  527. // Dig caves on down loop to check for air above.
  528. // Don't excavate the overgenerated stone at node_max.Y + 1,
  529. // this creates a 'roof' over the tunnel, preventing light in
  530. // tunnels at mapchunk borders when generating mapchunks upwards.
  531. // This 'roof' is removed when the mapchunk above is generated.
  532. for (s16 y = node_max.Y; y >= node_min.Y - 1; y--,
  533. index_3d -= ystride,
  534. vm->m_area.add_y(em, index_data, -1)) {
  535. float terrain = noise_terrain_height->result[index_2d];
  536. // Saves some time.
  537. if (y > terrain + 10)
  538. continue;
  539. else if (y < terrain - 40)
  540. underground = true;
  541. // Dig massive caves.
  542. if (node_max.Y <= massive_cave_depth
  543. && noise_massive_caves->result[index_3d]
  544. > tcave_cache[y - node_min.Y + 1]) {
  545. vm->m_data[index_data] = n_air;
  546. made_a_big_one = true;
  547. continue;
  548. }
  549. content_t c = vm->m_data[index_data].getContent();
  550. // Detect river water to place riverbed nodes in tunnels
  551. if (c == biome->c_river_water)
  552. is_under_river = true;
  553. float d1 = contour(noise_cave1->result[index_3d]);
  554. float d2 = contour(noise_cave2->result[index_3d]);
  555. if (d1 * d2 > cave_width && ndef->get(c).is_ground_content) {
  556. // in a tunnel
  557. vm->m_data[index_data] = n_air;
  558. tunnel_air_above = true;
  559. } else if (c == biome->c_filler || c == biome->c_stone) {
  560. if (tunnel_air_above) {
  561. // at the tunnel floor
  562. s16 sr = ps.range(0, 39);
  563. u32 j = index_data;
  564. vm->m_area.add_y(em, j, 1);
  565. if (sr > terrain - y) {
  566. // Put biome nodes in tunnels near the surface
  567. if (is_under_river)
  568. vm->m_data[index_data] = MapNode(biome->c_riverbed);
  569. else if (underground)
  570. vm->m_data[index_data] = MapNode(biome->c_filler);
  571. else
  572. vm->m_data[index_data] = MapNode(biome->c_top);
  573. } else if (sr < 3 && underground) {
  574. sr = abs(ps.next());
  575. if (lava_features_lim > 0 && y <= lava_max_height
  576. && c == biome->c_stone && sr < lava_chance)
  577. vm->m_data[j] = n_lava;
  578. sr -= lava_chance;
  579. // If sr < 0 then we should have already placed lava --
  580. // don't immediately dump water on it.
  581. if (water_features_lim > 0 && y <= cave_water_max_height
  582. && sr >= 0 && sr < water_chance)
  583. vm->m_data[j] = n_water;
  584. }
  585. }
  586. tunnel_air_above = false;
  587. underground = true;
  588. } else {
  589. tunnel_air_above = false;
  590. }
  591. }
  592. }
  593. if (node_max.Y <= large_cave_depth && !made_a_big_one) {
  594. u32 bruises_count = ps.range(0, 2);
  595. for (u32 i = 0; i < bruises_count; i++) {
  596. CavesRandomWalk cave(ndef, &gennotify, seed, water_level,
  597. c_water_source, c_lava_source);
  598. cave.makeCave(vm, node_min, node_max, &ps, true, max_stone_y, heightmap);
  599. }
  600. }
  601. }