mapgen_flat.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. /*
  2. Minetest
  3. Copyright (C) 2015-2020 paramat
  4. Copyright (C) 2015-2016 kwolekr, Ryan Kwolek <kwolekr@minetest.net>
  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 "mapgen.h"
  18. #include "voxel.h"
  19. #include "noise.h"
  20. #include "mapblock.h"
  21. #include "mapnode.h"
  22. #include "map.h"
  23. #include "nodedef.h"
  24. #include "voxelalgorithms.h"
  25. //#include "profiler.h" // For TimeTaker
  26. #include "settings.h" // For g_settings
  27. #include "emerge.h"
  28. #include "dungeongen.h"
  29. #include "cavegen.h"
  30. #include "mg_biome.h"
  31. #include "mg_ore.h"
  32. #include "mg_decoration.h"
  33. #include "mapgen_flat.h"
  34. FlagDesc flagdesc_mapgen_flat[] = {
  35. {"lakes", MGFLAT_LAKES},
  36. {"hills", MGFLAT_HILLS},
  37. {"caverns", MGFLAT_CAVERNS},
  38. {NULL, 0}
  39. };
  40. ///////////////////////////////////////////////////////////////////////////////////////
  41. MapgenFlat::MapgenFlat(MapgenFlatParams *params, EmergeParams *emerge)
  42. : MapgenBasic(MAPGEN_FLAT, params, emerge)
  43. {
  44. spflags = params->spflags;
  45. ground_level = params->ground_level;
  46. lake_threshold = params->lake_threshold;
  47. lake_steepness = params->lake_steepness;
  48. hill_threshold = params->hill_threshold;
  49. hill_steepness = params->hill_steepness;
  50. cave_width = params->cave_width;
  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_depth = params->large_cave_depth;
  56. large_cave_flooded = params->large_cave_flooded;
  57. cavern_limit = params->cavern_limit;
  58. cavern_taper = params->cavern_taper;
  59. cavern_threshold = params->cavern_threshold;
  60. dungeon_ymin = params->dungeon_ymin;
  61. dungeon_ymax = params->dungeon_ymax;
  62. // 2D noise
  63. noise_filler_depth = new Noise(&params->np_filler_depth, seed, csize.X, csize.Z);
  64. if ((spflags & MGFLAT_LAKES) || (spflags & MGFLAT_HILLS))
  65. noise_terrain = new Noise(&params->np_terrain, seed, csize.X, csize.Z);
  66. // 3D noise
  67. MapgenBasic::np_cave1 = params->np_cave1;
  68. MapgenBasic::np_cave2 = params->np_cave2;
  69. MapgenBasic::np_cavern = params->np_cavern;
  70. MapgenBasic::np_dungeons = params->np_dungeons;
  71. }
  72. MapgenFlat::~MapgenFlat()
  73. {
  74. delete noise_filler_depth;
  75. if ((spflags & MGFLAT_LAKES) || (spflags & MGFLAT_HILLS))
  76. delete noise_terrain;
  77. }
  78. MapgenFlatParams::MapgenFlatParams():
  79. np_terrain (0, 1, v3f(600, 600, 600), 7244, 5, 0.6, 2.0),
  80. np_filler_depth (0, 1.2, v3f(150, 150, 150), 261, 3, 0.7, 2.0),
  81. np_cavern (0.0, 1.0, v3f(384, 128, 384), 723, 5, 0.63, 2.0),
  82. np_cave1 (0, 12, v3f(61, 61, 61), 52534, 3, 0.5, 2.0),
  83. np_cave2 (0, 12, v3f(67, 67, 67), 10325, 3, 0.5, 2.0),
  84. np_dungeons (0.9, 0.5, v3f(500, 500, 500), 0, 2, 0.8, 2.0)
  85. {
  86. }
  87. void MapgenFlatParams::readParams(const Settings *settings)
  88. {
  89. settings->getFlagStrNoEx("mgflat_spflags", spflags, flagdesc_mapgen_flat);
  90. settings->getS16NoEx("mgflat_ground_level", ground_level);
  91. settings->getS16NoEx("mgflat_large_cave_depth", large_cave_depth);
  92. settings->getU16NoEx("mgflat_small_cave_num_min", small_cave_num_min);
  93. settings->getU16NoEx("mgflat_small_cave_num_max", small_cave_num_max);
  94. settings->getU16NoEx("mgflat_large_cave_num_min", large_cave_num_min);
  95. settings->getU16NoEx("mgflat_large_cave_num_max", large_cave_num_max);
  96. settings->getFloatNoEx("mgflat_large_cave_flooded", large_cave_flooded);
  97. settings->getFloatNoEx("mgflat_cave_width", cave_width);
  98. settings->getFloatNoEx("mgflat_lake_threshold", lake_threshold);
  99. settings->getFloatNoEx("mgflat_lake_steepness", lake_steepness);
  100. settings->getFloatNoEx("mgflat_hill_threshold", hill_threshold);
  101. settings->getFloatNoEx("mgflat_hill_steepness", hill_steepness);
  102. settings->getS16NoEx("mgflat_cavern_limit", cavern_limit);
  103. settings->getS16NoEx("mgflat_cavern_taper", cavern_taper);
  104. settings->getFloatNoEx("mgflat_cavern_threshold", cavern_threshold);
  105. settings->getS16NoEx("mgflat_dungeon_ymin", dungeon_ymin);
  106. settings->getS16NoEx("mgflat_dungeon_ymax", dungeon_ymax);
  107. settings->getNoiseParams("mgflat_np_terrain", np_terrain);
  108. settings->getNoiseParams("mgflat_np_filler_depth", np_filler_depth);
  109. settings->getNoiseParams("mgflat_np_cavern", np_cavern);
  110. settings->getNoiseParams("mgflat_np_cave1", np_cave1);
  111. settings->getNoiseParams("mgflat_np_cave2", np_cave2);
  112. settings->getNoiseParams("mgflat_np_dungeons", np_dungeons);
  113. }
  114. void MapgenFlatParams::writeParams(Settings *settings) const
  115. {
  116. settings->setFlagStr("mgflat_spflags", spflags, flagdesc_mapgen_flat);
  117. settings->setS16("mgflat_ground_level", ground_level);
  118. settings->setS16("mgflat_large_cave_depth", large_cave_depth);
  119. settings->setU16("mgflat_small_cave_num_min", small_cave_num_min);
  120. settings->setU16("mgflat_small_cave_num_max", small_cave_num_max);
  121. settings->setU16("mgflat_large_cave_num_min", large_cave_num_min);
  122. settings->setU16("mgflat_large_cave_num_max", large_cave_num_max);
  123. settings->setFloat("mgflat_large_cave_flooded", large_cave_flooded);
  124. settings->setFloat("mgflat_cave_width", cave_width);
  125. settings->setFloat("mgflat_lake_threshold", lake_threshold);
  126. settings->setFloat("mgflat_lake_steepness", lake_steepness);
  127. settings->setFloat("mgflat_hill_threshold", hill_threshold);
  128. settings->setFloat("mgflat_hill_steepness", hill_steepness);
  129. settings->setS16("mgflat_cavern_limit", cavern_limit);
  130. settings->setS16("mgflat_cavern_taper", cavern_taper);
  131. settings->setFloat("mgflat_cavern_threshold", cavern_threshold);
  132. settings->setS16("mgflat_dungeon_ymin", dungeon_ymin);
  133. settings->setS16("mgflat_dungeon_ymax", dungeon_ymax);
  134. settings->setNoiseParams("mgflat_np_terrain", np_terrain);
  135. settings->setNoiseParams("mgflat_np_filler_depth", np_filler_depth);
  136. settings->setNoiseParams("mgflat_np_cavern", np_cavern);
  137. settings->setNoiseParams("mgflat_np_cave1", np_cave1);
  138. settings->setNoiseParams("mgflat_np_cave2", np_cave2);
  139. settings->setNoiseParams("mgflat_np_dungeons", np_dungeons);
  140. }
  141. void MapgenFlatParams::setDefaultSettings(Settings *settings)
  142. {
  143. settings->setDefault("mgflat_spflags", flagdesc_mapgen_flat, 0);
  144. }
  145. /////////////////////////////////////////////////////////////////
  146. int MapgenFlat::getSpawnLevelAtPoint(v2s16 p)
  147. {
  148. s16 stone_level = ground_level;
  149. float n_terrain =
  150. ((spflags & MGFLAT_LAKES) || (spflags & MGFLAT_HILLS)) ?
  151. NoisePerlin2D(&noise_terrain->np, p.X, p.Y, seed) :
  152. 0.0f;
  153. if ((spflags & MGFLAT_LAKES) && n_terrain < lake_threshold) {
  154. s16 depress = (lake_threshold - n_terrain) * lake_steepness;
  155. stone_level = ground_level - depress;
  156. } else if ((spflags & MGFLAT_HILLS) && n_terrain > hill_threshold) {
  157. s16 rise = (n_terrain - hill_threshold) * hill_steepness;
  158. stone_level = ground_level + rise;
  159. }
  160. if (ground_level < water_level)
  161. // Ocean world, may not have islands so allow spawn in water
  162. return MYMAX(stone_level + 2, water_level);
  163. if (stone_level >= water_level)
  164. // Spawn on land
  165. // + 2 not + 1, to spawn above biome 'dust' nodes
  166. return stone_level + 2;
  167. // Unsuitable spawn point
  168. return MAX_MAP_GENERATION_LIMIT;
  169. }
  170. void MapgenFlat::makeChunk(BlockMakeData *data)
  171. {
  172. // Pre-conditions
  173. assert(data->vmanip);
  174. assert(data->nodedef);
  175. this->generating = true;
  176. this->vm = data->vmanip;
  177. this->ndef = data->nodedef;
  178. //TimeTaker t("makeChunk");
  179. v3s16 blockpos_min = data->blockpos_min;
  180. v3s16 blockpos_max = data->blockpos_max;
  181. node_min = blockpos_min * MAP_BLOCKSIZE;
  182. node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
  183. full_node_min = (blockpos_min - 1) * MAP_BLOCKSIZE;
  184. full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
  185. blockseed = getBlockSeed2(full_node_min, seed);
  186. // Generate base terrain, mountains, and ridges with initial heightmaps
  187. s16 stone_surface_max_y = generateTerrain();
  188. // Create heightmap
  189. updateHeightmap(node_min, node_max);
  190. // Init biome generator, place biome-specific nodes, and build biomemap
  191. if (flags & MG_BIOMES) {
  192. biomegen->calcBiomeNoise(node_min);
  193. generateBiomes();
  194. }
  195. // Generate tunnels, caverns and large randomwalk caves
  196. if (flags & MG_CAVES) {
  197. // Generate tunnels first as caverns confuse them
  198. generateCavesNoiseIntersection(stone_surface_max_y);
  199. // Generate caverns
  200. bool near_cavern = false;
  201. if (spflags & MGFLAT_CAVERNS)
  202. near_cavern = generateCavernsNoise(stone_surface_max_y);
  203. // Generate large randomwalk caves
  204. if (near_cavern)
  205. // Disable large randomwalk caves in this mapchunk by setting
  206. // 'large cave depth' to world base. Avoids excessive liquid in
  207. // large caverns and floating blobs of overgenerated liquid.
  208. generateCavesRandomWalk(stone_surface_max_y,
  209. -MAX_MAP_GENERATION_LIMIT);
  210. else
  211. generateCavesRandomWalk(stone_surface_max_y, large_cave_depth);
  212. }
  213. // Generate the registered ores
  214. if (flags & MG_ORES)
  215. m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max);
  216. if (flags & MG_DUNGEONS)
  217. generateDungeons(stone_surface_max_y);
  218. // Generate the registered decorations
  219. if (flags & MG_DECORATIONS)
  220. m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
  221. // Sprinkle some dust on top after everything else was generated
  222. if (flags & MG_BIOMES)
  223. dustTopNodes();
  224. //printf("makeChunk: %dms\n", t.stop());
  225. updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
  226. if (flags & MG_LIGHT)
  227. calcLighting(node_min - v3s16(0, 1, 0), node_max + v3s16(0, 1, 0),
  228. full_node_min, full_node_max);
  229. //setLighting(node_min - v3s16(1, 0, 1) * MAP_BLOCKSIZE,
  230. // node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE, 0xFF);
  231. this->generating = false;
  232. }
  233. s16 MapgenFlat::generateTerrain()
  234. {
  235. MapNode n_air(CONTENT_AIR);
  236. MapNode n_stone(c_stone);
  237. MapNode n_water(c_water_source);
  238. const v3s16 &em = vm->m_area.getExtent();
  239. s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT;
  240. u32 ni2d = 0;
  241. bool use_noise = (spflags & MGFLAT_LAKES) || (spflags & MGFLAT_HILLS);
  242. if (use_noise)
  243. noise_terrain->perlinMap2D(node_min.X, node_min.Z);
  244. for (s16 z = node_min.Z; z <= node_max.Z; z++)
  245. for (s16 x = node_min.X; x <= node_max.X; x++, ni2d++) {
  246. s16 stone_level = ground_level;
  247. float n_terrain = use_noise ? noise_terrain->result[ni2d] : 0.0f;
  248. if ((spflags & MGFLAT_LAKES) && n_terrain < lake_threshold) {
  249. s16 depress = (lake_threshold - n_terrain) * lake_steepness;
  250. stone_level = ground_level - depress;
  251. } else if ((spflags & MGFLAT_HILLS) && n_terrain > hill_threshold) {
  252. s16 rise = (n_terrain - hill_threshold) * hill_steepness;
  253. stone_level = ground_level + rise;
  254. }
  255. u32 vi = vm->m_area.index(x, node_min.Y - 1, z);
  256. for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) {
  257. if (vm->m_data[vi].getContent() == CONTENT_IGNORE) {
  258. if (y <= stone_level) {
  259. vm->m_data[vi] = n_stone;
  260. if (y > stone_surface_max_y)
  261. stone_surface_max_y = y;
  262. } else if (y <= water_level) {
  263. vm->m_data[vi] = n_water;
  264. } else {
  265. vm->m_data[vi] = n_air;
  266. }
  267. }
  268. VoxelArea::add_y(em, vi, 1);
  269. }
  270. }
  271. return stone_surface_max_y;
  272. }