init.lua 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125
  1. jarkati = jarkati or {}
  2. jarkati.modpath = minetest.get_modpath("jarkati")
  3. -- These match values in the realm-control mod.
  4. jarkati.REALM_START = 3600
  5. jarkati.REALM_END = 3900
  6. jarkati.SEA_LEVEL = 3740
  7. jarkati.LAVA_LEVEL = 3610
  8. jarkati.biomes = {}
  9. jarkati.decorations = {}
  10. -- Public API function.
  11. function jarkati.register_layer(data)
  12. local td = table.copy(data)
  13. assert(type(td.node) == "string")
  14. -- Convert string name to content ID.
  15. td.cid = minetest.get_content_id(td.node)
  16. td.min_level = td.min_level or 1
  17. td.max_level = td.max_level or 1
  18. assert(td.min_level <= td.max_level)
  19. td.min_depth = td.min_depth or 1
  20. td.max_depth = td.max_depth or 1
  21. assert(td.min_depth <= td.max_depth)
  22. jarkati.biomes[#jarkati.biomes + 1] = td
  23. end
  24. -- Public API function.
  25. function jarkati.register_decoration(data)
  26. local td = table.copy(data)
  27. -- Convert single node to table.
  28. if type(td.nodes) == "string" then
  29. td.nodes = {td.nodes}
  30. end
  31. if type(td.replace_surface) == "string" then
  32. td.replace_surface = {td.replace_surface}
  33. end
  34. if type(td.place_on) == "string" then
  35. td.place_on = {td.place_on}
  36. end
  37. -- Used only with the `nodes` parameter.
  38. td.param2 = data.param2 or {0}
  39. assert(type(td.nodes) == "table" or type(td.schematic) == "string" or type(td.schematic) == "table")
  40. assert(type(td.probability) == "number")
  41. assert(td.probability >= 1)
  42. -- Ensure all node names are actually registered!
  43. if td.nodes then
  44. for k, v in ipairs(td.nodes) do
  45. assert(minetest.registered_nodes[v])
  46. end
  47. end
  48. if not td.all_ceilings and not td.all_floors then
  49. td.ground_level = true
  50. end
  51. -- Default schematic parameters.
  52. td.rotation = data.rotation or "0"
  53. td.replacements = data.replacements or {}
  54. td.force_placement = data.force_placement or false
  55. td.flags = data.flags or ""
  56. -- Placement Y-offset is always 0 (ignored) if `place_center_y` is specified.
  57. if td.flags:find("place_center_y") then
  58. td.place_offset_y = 0
  59. else
  60. td.place_offset_y = data.place_offset_y or 0
  61. -- Invert for `all_ceilings` decorations.
  62. if td.all_ceilings and td.place_offset_y > 0 then
  63. td.place_offset_y = -td.place_offset_y
  64. end
  65. end
  66. -- The object or schematic's aprox `radius`, when checking for flat ground.
  67. -- Non-zero basically means all ground in the radius must be the same height.
  68. td.radius = data.radius or 0
  69. td.y_min = data.y_min or -31000
  70. td.y_max = data.y_max or 31000
  71. jarkati.decorations[#jarkati.decorations + 1] = td
  72. end
  73. jarkati.register_layer({
  74. node = "default:desert_sand",
  75. min_depth = 1,
  76. max_depth = 2,
  77. min_level = 1,
  78. max_level = 1,
  79. })
  80. jarkati.register_layer({
  81. node = "default:sand",
  82. min_depth = 3,
  83. max_depth = 3,
  84. min_level = 1,
  85. max_level = 1,
  86. })
  87. jarkati.register_layer({
  88. node = "default:desert_cobble",
  89. min_depth = 7,
  90. max_depth = 7,
  91. min_level = 1,
  92. max_level = 1,
  93. })
  94. jarkati.register_layer({
  95. node = "default:sandstone",
  96. min_depth = 4,
  97. max_depth = 6,
  98. min_level = 1,
  99. max_level = 1,
  100. })
  101. jarkati.register_decoration({
  102. nodes = "stairs:slab_desert_cobble",
  103. probability = 700,
  104. place_on = {"default:desert_sand"},
  105. })
  106. jarkati.register_decoration({
  107. nodes = "aloevera:aloe_plant_04",
  108. probability = 1500,
  109. place_on = {"default:desert_sand"},
  110. replace_surface = "default:dirt_with_dry_grass",
  111. })
  112. -- Scatter "rubble" around the bases of cliffs.
  113. jarkati.register_decoration({
  114. nodes = {"default:desert_cobble", "stairs:slab_desert_cobble"},
  115. probability = 10,
  116. spawn_by = {"default:desert_stone", "default:sandstone"},
  117. place_on = {"default:desert_sand"},
  118. })
  119. jarkati.register_decoration({
  120. nodes = "default:dry_shrub",
  121. probability = 110,
  122. place_on = {"default:desert_sand"},
  123. })
  124. -- These should add a decoration to the Jarkati landscape but couldn't get it to work. I modified the depends to use flowers but the way the flowers mod is set up seems to conflict with the way the jarkati mod interprets "nodes". Maybe you can look into it? I added these two items to flowers but did not otherwise put them in the mapgen. They will show up in the craftguide.
  125. --jarkati.register_decoration({
  126. -- nodes = "flowers:desertrose_red",
  127. -- probability = 100,
  128. -- place_on = {"default:desert_sand"},
  129. -- replace_surface = "default:dirt_with_dry_grass",
  130. --})
  131. --jarkati.register_decoration({
  132. -- nodes = "flowers:desertrose_pink",
  133. -- probability = 100,
  134. -- place_on = {"default:desert_sand"},
  135. -- replace_surface = "default:dirt_with_dry_grass",
  136. --})
  137. jarkati.register_decoration({
  138. nodes = {
  139. "default:dry_grass_1",
  140. "default:dry_grass_2",
  141. "default:dry_grass_3",
  142. "default:dry_grass_4",
  143. "default:dry_grass_5",
  144. },
  145. param2 = {2},
  146. probability = 50,
  147. place_on = {"default:desert_sand"},
  148. replace_surface = "default:dirt_with_dry_grass",
  149. })
  150. jarkati.register_decoration({
  151. nodes = {
  152. "cavestuff:redspike1",
  153. "cavestuff:redspike2",
  154. "cavestuff:redspike3",
  155. "cavestuff:redspike4",
  156. },
  157. param2 = {0, 1, 2, 3},
  158. probability = 120,
  159. all_floors = true,
  160. place_on = {"default:desert_stone"},
  161. replace_surface = {
  162. "default:desert_cobble",
  163. "default:desert_cobble2",
  164. "default:desert_cobble2",
  165. "default:desert_cobble2",
  166. },
  167. })
  168. jarkati.register_decoration({
  169. nodes = "default:tvine_stunted",
  170. probability = 1400,
  171. all_floors = true,
  172. place_on = "default:desert_stone",
  173. replace_surface = "talinite:desert_ore",
  174. })
  175. do
  176. local L = {name = "default:tvine"}
  177. local R = {name = "default:tvine_alt"}
  178. local S = {name = "default:tvine_top"}
  179. jarkati.register_decoration({
  180. schematic = {
  181. size = {x=1, y=3, z=1},
  182. data = {
  183. L,
  184. R,
  185. S,
  186. },
  187. },
  188. flags = "place_center_x,place_center_z",
  189. probability = 3400,
  190. all_floors = true,
  191. place_on = "default:desert_stone",
  192. replace_surface = "talinite:desert_ore",
  193. })
  194. end
  195. ---[[
  196. do
  197. local _ = {name = "air"}
  198. local X = {name = "default:gravel"}
  199. local C1 = {name = "stairs:micro_desert_sandstone", param2 = 1}
  200. local C2 = {name = "stairs:micro_desert_sandstone", param2 = 2}
  201. local C3 = {name = "stairs:micro_desert_sandstone", param2 = 0}
  202. local C4 = {name = "stairs:micro_desert_sandstone", param2 = 3}
  203. local L = {name = "stairs:slab_desert_sandstone"}
  204. local R = {name = "default:desert_sandstone"}
  205. local S = {name = "default:desert_sand"}
  206. jarkati.register_decoration({
  207. schematic = {
  208. size = {x=4, y=2, z=4},
  209. data = {
  210. S, R, R, S,
  211. C1, L, L, C3,
  212. R, X, X, R,
  213. L, _, _, L,
  214. R, X, X, R,
  215. L, _, _, L,
  216. S, R, R, S,
  217. C2, L, L, C4,
  218. },
  219. },
  220. force_placement = true,
  221. flags = "place_center_x,place_center_z",
  222. rotation = "random",
  223. place_offset_y = -1,
  224. radius = 3,
  225. probability = 800,
  226. place_on = {"default:desert_sand"},
  227. -- Called with 'pos', the placement position of the decoration.
  228. custom_func = function(...)
  229. pm.on_wisp_vent_place(...)
  230. end,
  231. y_max = 3760,
  232. y_min = 3730,
  233. })
  234. end
  235. --]]
  236. ---[[
  237. do
  238. local _ = {name = "air"}
  239. local X = {name = "default:gravel"}
  240. local C1 = {name = "stairs:micro_desert_sandstone", param2 = 1}
  241. local C2 = {name = "stairs:micro_desert_sandstone", param2 = 2}
  242. local C3 = {name = "stairs:micro_desert_sandstone", param2 = 0}
  243. local C4 = {name = "stairs:micro_desert_sandstone", param2 = 3}
  244. local L1 = {name = "stairs:stair_desert_sandstone", param2 = 0}
  245. local L2 = {name = "stairs:stair_desert_sandstone", param2 = 1}
  246. local L3 = {name = "stairs:stair_desert_sandstone", param2 = 2}
  247. local L4 = {name = "stairs:stair_desert_sandstone", param2 = 3}
  248. local R = {name = "default:desert_sandstone"}
  249. local S = {name = "default:desert_sand"}
  250. jarkati.register_decoration({
  251. schematic = {
  252. size = {x=4, y=2, z=4},
  253. data = {
  254. S, R, R, S,
  255. C1, L1, L1, C3,
  256. R, X, X, R,
  257. L2, _, _, L4,
  258. R, X, X, R,
  259. L2, _, _, L4,
  260. S, R, R, S,
  261. C2, L3, L3, C4,
  262. },
  263. },
  264. force_placement = true,
  265. flags = "place_center_x,place_center_z",
  266. rotation = "random",
  267. place_offset_y = -1,
  268. radius = 4,
  269. probability = 800,
  270. place_on = {"default:desert_sand"},
  271. -- Called with 'pos', the placement position of the decoration.
  272. custom_func = function(...)
  273. pm.on_wisp_vent_place(...)
  274. end,
  275. y_max = 3760,
  276. y_min = 3730,
  277. })
  278. end
  279. --]]
  280. ---[[
  281. do
  282. local _ = {name = "air"}
  283. local X = {name = "rackstone:nether_grit"}
  284. local C1 = {name = "stairs:micro_desert_sandstone", param2 = 1}
  285. local C2 = {name = "stairs:micro_desert_sandstone", param2 = 2}
  286. local C3 = {name = "stairs:micro_desert_sandstone", param2 = 0}
  287. local C4 = {name = "stairs:micro_desert_sandstone", param2 = 3}
  288. local L = {name = "stairs:slab_desert_sandstone"}
  289. local R = {name = "default:desert_sandstone"}
  290. local S = {name = "default:desert_sand"}
  291. jarkati.register_decoration({
  292. schematic = {
  293. size = {x=4, y=2, z=4},
  294. data = {
  295. S, R, R, S,
  296. C1, L, L, C3,
  297. R, X, X, R,
  298. L, _, _, L,
  299. R, X, X, R,
  300. L, _, _, L,
  301. S, R, R, S,
  302. C2, L, L, C4,
  303. },
  304. },
  305. force_placement = true,
  306. flags = "place_center_x,place_center_z",
  307. rotation = "random",
  308. place_offset_y = -1,
  309. radius = 3,
  310. probability = 2500,
  311. place_on = {"default:desert_sand"},
  312. y_max = 3750,
  313. y_min = 3730,
  314. })
  315. end
  316. --]]
  317. ---[[
  318. do
  319. local _ = {name = "air"}
  320. local X = {name = "rackstone:nether_grit"}
  321. local C1 = {name = "stairs:micro_desert_sandstone", param2 = 1}
  322. local C2 = {name = "stairs:micro_desert_sandstone", param2 = 2}
  323. local C3 = {name = "stairs:micro_desert_sandstone", param2 = 0}
  324. local C4 = {name = "stairs:micro_desert_sandstone", param2 = 3}
  325. local L1 = {name = "stairs:stair_desert_sandstone", param2 = 0}
  326. local L2 = {name = "stairs:stair_desert_sandstone", param2 = 1}
  327. local L3 = {name = "stairs:stair_desert_sandstone", param2 = 2}
  328. local L4 = {name = "stairs:stair_desert_sandstone", param2 = 3}
  329. local R = {name = "default:desert_sandstone"}
  330. local S = {name = "default:desert_sand"}
  331. jarkati.register_decoration({
  332. schematic = {
  333. size = {x=4, y=2, z=4},
  334. data = {
  335. S, R, R, S,
  336. C1, L1, L1, C3,
  337. R, X, X, R,
  338. L2, _, _, L4,
  339. R, X, X, R,
  340. L2, _, _, L4,
  341. S, R, R, S,
  342. C2, L3, L3, C4,
  343. },
  344. },
  345. force_placement = true,
  346. flags = "place_center_x,place_center_z",
  347. rotation = "random",
  348. place_offset_y = -1,
  349. radius = 4,
  350. probability = 2500,
  351. place_on = {"default:desert_sand"},
  352. y_max = 3750,
  353. y_min = 3730,
  354. })
  355. end
  356. --]]
  357. local NOISE_SCALE = 1
  358. -- Base terrain height (may be modified to be negative or positive).
  359. jarkati.noise1param2d = {
  360. offset = 0,
  361. scale = 1,
  362. spread = {x=128*NOISE_SCALE, y=128*NOISE_SCALE, z=128*NOISE_SCALE},
  363. seed = 5719,
  364. octaves = 6,
  365. persist = 0.5,
  366. lacunarity = 2,
  367. }
  368. -- Modifies frequency of vertical tunnel shafts.
  369. jarkati.noise2param2d = {
  370. offset = 0,
  371. scale = 1,
  372. spread = {x=64*NOISE_SCALE, y=64*NOISE_SCALE, z=64*NOISE_SCALE},
  373. seed = 8827,
  374. octaves = 6,
  375. persist = 0.4, -- Amplitude multiplier.
  376. lacunarity = 2, -- Wavelength divisor.
  377. }
  378. -- Mese/tableland terrain-height modifier.
  379. jarkati.noise3param2d = {
  380. offset = 0,
  381. scale = 1,
  382. spread = {x=64*NOISE_SCALE, y=64*NOISE_SCALE, z=64*NOISE_SCALE},
  383. seed = 54871,
  384. octaves = 5,
  385. persist = 0.5,
  386. lacunarity = 2,
  387. }
  388. -- Modifies the frequency (strength) of tablelands over big area.
  389. jarkati.noise4param2d = {
  390. offset = 0,
  391. scale = 1,
  392. spread = {x=128*NOISE_SCALE, y=128*NOISE_SCALE, z=128*NOISE_SCALE},
  393. seed = 2819,
  394. octaves = 3,
  395. persist = 0.5,
  396. lacunarity = 2,
  397. }
  398. -- Disjunction height modifier.
  399. jarkati.noise5param2d = {
  400. offset = 0,
  401. scale = 1,
  402. spread = {x=512*NOISE_SCALE, y=512*NOISE_SCALE, z=512*NOISE_SCALE},
  403. seed = 3819,
  404. octaves = 6,
  405. persist = 0.7,
  406. lacunarity = 2,
  407. }
  408. -- Primary cavern noise.
  409. jarkati.noise6param3d = {
  410. offset = 0,
  411. scale = 1,
  412. spread = {x=128*NOISE_SCALE, y=32*NOISE_SCALE, z=128*NOISE_SCALE},
  413. seed = 3817,
  414. octaves = 5,
  415. persist = 0.5,
  416. lacunarity = 2,
  417. }
  418. -- Vertical tunnel noise.
  419. jarkati.noise7param3d = {
  420. offset = 0,
  421. scale = 1,
  422. spread = {x=8*NOISE_SCALE, y=64*NOISE_SCALE, z=8*NOISE_SCALE},
  423. seed = 7848,
  424. octaves = 4,
  425. persist = 0.7,
  426. lacunarity = 1.5,
  427. }
  428. -- Content IDs used with the voxel manipulator.
  429. local c_air = minetest.get_content_id("air")
  430. local c_ignore = minetest.get_content_id("ignore")
  431. local c_desert_stone = minetest.get_content_id("default:desert_stone")
  432. local c_desert_cobble = minetest.get_content_id("default:desert_cobble")
  433. local c_bedrock = minetest.get_content_id("bedrock:bedrock")
  434. local c_sand = minetest.get_content_id("default:sand")
  435. local c_desert_sand = minetest.get_content_id("default:desert_sand")
  436. local c_water = minetest.get_content_id("default:water_source")
  437. local c_lava = minetest.get_content_id("default:lava_source")
  438. -- Externally located tables for performance.
  439. local vm_data = {}
  440. local biome_data = {}
  441. local heightmap = {}
  442. local noisemap1 = {}
  443. local noisemap2 = {}
  444. local noisemap3 = {}
  445. local noisemap4 = {}
  446. local noisemap5 = {}
  447. local noisemap6 = {}
  448. local noisemap7 = {}
  449. local perlin1
  450. local perlin2
  451. local perlin3
  452. local perlin4
  453. local perlin5
  454. local perlin6
  455. local perlin7
  456. jarkati.generate_realm = function(minp, maxp, seed)
  457. local nbeg = jarkati.REALM_START
  458. local nend = jarkati.REALM_END
  459. local slev = jarkati.SEA_LEVEL
  460. local lbeg = jarkati.REALM_START
  461. local lend = jarkati.LAVA_LEVEL
  462. -- Don't run for out-of-bounds mapchunks.
  463. if minp.y > nend or maxp.y < nbeg then
  464. return
  465. end
  466. -- Grab the voxel manipulator.
  467. -- Read current map data.
  468. local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
  469. vm:get_data(vm_data)
  470. local max_area = VoxelArea:new {MinEdge=emin, MaxEdge=emax}
  471. local min_area = VoxelArea:new {MinEdge=minp, MaxEdge=maxp}
  472. -- Actual emerged area should be bigger than the chunk we're generating!
  473. assert(emin.y < minp.y and emin.x < minp.x and emin.z < minp.z)
  474. assert(emax.y > maxp.y and emax.x > maxp.x and emax.z > maxp.z)
  475. local pr = PseudoRandom(seed + 351)
  476. local dpr = PseudoRandom(seed + 2891) -- For decoration placement probability.
  477. local x1 = maxp.x
  478. local y1 = maxp.y
  479. local z1 = maxp.z
  480. local x0 = minp.x
  481. local y0 = minp.y
  482. local z0 = minp.z
  483. -- Compute side lengths.
  484. local side_len_x = ((x1-x0)+1)
  485. local side_len_y = ((y1-y0)+1)
  486. local side_len_z = ((z1-z0)+1)
  487. local sides2D = {x=side_len_x, y=side_len_z}
  488. local sides3D = {x=side_len_x, y=side_len_z, z=side_len_y}
  489. local bp2d = {x=x0, y=z0}
  490. local bp3d = {x=x0, y=y0, z=z0}
  491. -- Get noisemaps.
  492. perlin1 = perlin1 or minetest.get_perlin_map(jarkati.noise1param2d, sides2D)
  493. perlin1:get2dMap_flat(bp2d, noisemap1)
  494. perlin2 = perlin2 or minetest.get_perlin_map(jarkati.noise2param2d, sides2D)
  495. perlin2:get2dMap_flat(bp2d, noisemap2)
  496. perlin3 = perlin3 or minetest.get_perlin_map(jarkati.noise3param2d, sides2D)
  497. perlin3:get2dMap_flat(bp2d, noisemap3)
  498. perlin4 = perlin4 or minetest.get_perlin_map(jarkati.noise4param2d, sides2D)
  499. perlin4:get2dMap_flat(bp2d, noisemap4)
  500. perlin5 = perlin5 or minetest.get_perlin_map(jarkati.noise5param2d, sides2D)
  501. perlin5:get2dMap_flat(bp2d, noisemap5)
  502. perlin6 = perlin6 or minetest.get_perlin_map(jarkati.noise6param3d, sides3D)
  503. perlin6:get3dMap_flat(bp3d, noisemap6)
  504. perlin7 = perlin7 or minetest.get_perlin_map(jarkati.noise7param3d, sides3D)
  505. perlin7:get3dMap_flat(bp3d, noisemap7)
  506. -- Localize commonly used functions for speed.
  507. local floor = math.floor
  508. local ceil = math.ceil
  509. local abs = math.abs
  510. local min = math.min
  511. local max = math.max
  512. -- Terrain height function (does not handle caves).
  513. local function height(z, x)
  514. -- Get index into 2D noise arrays.
  515. local nx = (x - x0)
  516. local nz = (z - z0)
  517. local ni2 = (side_len_z*nz+nx)
  518. -- Lua arrays start indexing at 1, not 0. Urrrrgh.
  519. ni2 = ni2 + 1
  520. local n1 = noisemap1[ni2]
  521. local n2 = noisemap2[ni2]
  522. local n3 = noisemap3[ni2]
  523. local n4 = noisemap4[ni2]
  524. local n5 = noisemap5[ni2]
  525. -- Calc base terrain height.
  526. local h = slev + (abs(n1) * 16)
  527. -- Modify the tableland noise parameter with this noise.
  528. n3 = n3 * abs(n4)
  529. n1 = n1 * abs(n5)
  530. -- If tableland noise over threshold, then flatten/invert terrain height.
  531. -- This generates "tablelands", buttes, etc.
  532. if n3 > -0.1 then
  533. h = slev + (n1 * 3)
  534. end
  535. -- If even farther over the threshold, then intensify/invert once again.
  536. -- This can result in apparent "land bridges" if the surrounding landscape
  537. -- is low, or it can create simple "canyons" if the surroundings are high.
  538. if n3 > 0.3 then
  539. h = slev - (n1 * 5)
  540. end
  541. if n3 > 0.6 then
  542. h = slev + (n1 * 8)
  543. end
  544. return h
  545. end
  546. local function cavern(x, y, z)
  547. local np = min_area:index(x, y, z)
  548. local n1 = noisemap6[np]
  549. local n2 = noisemap7[np]
  550. -- Get index into 2D noise arrays.
  551. local nx = (x - x0)
  552. local nz = (z - z0)
  553. local ni2 = (side_len_z*nz+nx)
  554. -- Lua arrays start indexing at 1, not 0. Urrrrgh.
  555. ni2 = ni2 + 1
  556. local n3 = abs(noisemap2[ni2])
  557. -- Reduce cavern noise at realm base.
  558. local d = (y - nbeg)
  559. if d < 0 then d = 0 end
  560. d = d / 16
  561. if d > 1 then d = 1 end
  562. if d < 0 then d = 0 end
  563. n1 = n1 * d
  564. -- Reduce cavern noise at surface level.
  565. local f = (slev - y)
  566. if f < 0 then f = 0 end
  567. f = f / 16
  568. if f > 1 then f = 1 end
  569. if f < 0 then f = 0 end
  570. n1 = n1 * f
  571. -- Expand cavern noise 50 meters below surface level, 10 meters above and below.
  572. local x = abs((slev - 50) - y)
  573. x = x * -1 + 16 -- Invert range.
  574. x = x / 16
  575. if x > 1 then x = 1 end
  576. if x < 0 then x = 0 end
  577. n1 = n1 * (1 + x)
  578. return (abs(n1) > 0.6 or (abs(n2) * (n3 * n3)) > 0.8)
  579. end
  580. -- Generic filler stone type.
  581. local c_stone = c_desert_stone
  582. -- First mapgen pass. Generate stone terrain shape, fill rest with air (critical).
  583. -- This also constructs the heightmap, which caches the height values.
  584. for z = z0, z1 do
  585. for x = x0, x1 do
  586. local ground = floor(height(z, x))
  587. heightmap[max_area:index(x, 0, z)] = ground
  588. local miny = (y0 - 0)
  589. local maxy = (y1 + 0)
  590. miny = max(miny, nbeg)
  591. maxy = min(maxy, nend)
  592. -- Flag set once a cave has carved away part of the surface in this column.
  593. -- Second flag set once the floor of the first cave is reached.
  594. -- Once the floor of the first cave is reached, the heightmap is adjusted.
  595. -- The heightmap is ONLY adjusted for caves that intersect with base ground level.
  596. local gc0 = false
  597. local gc1 = false
  598. -- First pass through column.
  599. -- Iterate downwards so we can detect when caves modify the surface height.
  600. for y = maxy, miny, -1 do
  601. local cave = cavern(x, y, z)
  602. local vp = max_area:index(x, y, z)
  603. local cid = vm_data[vp]
  604. -- Don't overwrite previously existing stuff (non-ignore, non-air).
  605. -- This avoids ruining schematics that were previously placed.
  606. if (cid == c_air or cid == c_ignore) then
  607. if cave then
  608. -- We've started carving a cave in this column.
  609. -- Don't bother flagging this unless the cave roof would be above ground level.
  610. if (y > ground and not gc0) then
  611. gc0 = true
  612. end
  613. if (y >= lbeg and y <= lend) then
  614. vm_data[vp] = c_lava
  615. else
  616. vm_data[vp] = c_air
  617. end
  618. else
  619. if y <= ground then
  620. -- We've finished carving a cave in this column.
  621. -- Adjust heightmap.
  622. -- But don't bother if cave floor would be above ground level.
  623. if (gc0 and not gc1) then
  624. heightmap[max_area:index(x, 0, z)] = y
  625. gc1 = true
  626. end
  627. vm_data[vp] = c_stone
  628. else
  629. if (y >= lbeg and y <= lend) then
  630. vm_data[vp] = c_lava
  631. else
  632. vm_data[vp] = c_air
  633. end
  634. end
  635. end
  636. end
  637. end -- End column loop.
  638. end
  639. end
  640. ---[[
  641. -- Localize for speed.
  642. local all_biomes = jarkati.biomes
  643. local function biomes(biomes)
  644. local biome_count = 0
  645. for k, v in ipairs(biomes) do
  646. biome_count = biome_count + 1
  647. biome_data[biome_count] = v
  648. end
  649. return biome_data, biome_count -- Table is continuously reused.
  650. end
  651. -- Second mapgen pass. Generate topsoil layers.
  652. for z = z0, z1 do
  653. for x = x0, x1 do
  654. local miny = (y0 - 0)
  655. local maxy = (y1 + 0)
  656. -- Get heightmap value at this location. This may have been adjusted by a surface cave.
  657. local ground = heightmap[max_area:index(x, 0, z)]
  658. -- Count of how many "surfaces" were detected (so far) while iterating down.
  659. -- 0 means we haven't found ground yet. 1 means found ground, >1 indicates a cave surface.
  660. local count = 0
  661. local depth = 0
  662. -- Get array and array-size of all biomes valid for this position.
  663. local vb, bc = biomes(all_biomes)
  664. -- Second pass through column. Iterate backwards for depth checking.
  665. for y = maxy, miny, -1 do
  666. if y >= nbeg and y <= nend then
  667. local vp0 = max_area:index(x, y, z)
  668. local vpu = max_area:index(x, (y - 1), z)
  669. if y <= ground then
  670. count = 1
  671. if vm_data[vp0] ~= c_air and vm_data[vpu] ~= c_air then
  672. depth = (ground - y) + 1
  673. else
  674. depth = 0
  675. end
  676. else
  677. count = 0
  678. depth = 0
  679. end
  680. -- Place topsoils & layers, etc. using current biome data.
  681. for i = 1, bc do
  682. -- Get biome data.
  683. local v = vb[i]
  684. if (count >= v.min_level and count <= v.max_level) then
  685. if (depth >= v.min_depth and depth <= v.max_depth) then
  686. vm_data[vp0] = v.cid
  687. end
  688. end
  689. end
  690. end
  691. end -- End column loop.
  692. end
  693. end
  694. --]]
  695. ---[[
  696. -- Third mapgen pass. Generate bedrock layer overwriting everything else (critical).
  697. if not (y1 < nbeg or y0 > (nbeg + 10)) then
  698. for z = z0, z1 do
  699. for x = x0, x1 do
  700. -- Randomize height of the bedrock a bit.
  701. local bedrock = (nbeg + pr:next(5, pr:next(6, 7)))
  702. local miny = max(y0, nbeg)
  703. local maxy = min(y1, bedrock)
  704. -- Third pass through column.
  705. for y = miny, maxy do
  706. local vp = max_area:index(x, y, z)
  707. vm_data[vp] = c_bedrock
  708. end -- End column loop.
  709. end
  710. end
  711. end
  712. --]]
  713. -- Finalize voxel manipulator.
  714. vm:set_data(vm_data)
  715. minetest.generate_ores(vm)
  716. vm:write_to_map(false)
  717. -- Not needed to do this, it will be done during the "mapfix" call.
  718. --vm:update_liquids()
  719. ---[[
  720. -- Localize for speed.
  721. local all_decorations = jarkati.decorations
  722. local decopos = {x=0, y=0, z=0}
  723. local set_node = minetest.set_node
  724. local get_node = minetest.get_node
  725. local put_schem = minetest.place_schematic
  726. local deconode = {name="", param2=0}
  727. local function decorate(v, x, y, z, d)
  728. -- Don't place decorations outside chunk boundaries.
  729. -- (X and Z are already checked.)
  730. if (y < y0 or y > y1) then
  731. return
  732. end
  733. if (y > v.y_max or y < v.y_min) then
  734. return
  735. end
  736. decopos.x = x
  737. decopos.y = y
  738. decopos.z = z
  739. if v.spawn_by then
  740. if not minetest.find_node_near(decopos, (v.radius + 1), v.spawn_by) then
  741. return
  742. end
  743. end
  744. -- Validate the ground/ceiling surface.
  745. do
  746. local x1 = decopos.x - v.radius
  747. local x2 = decopos.x + v.radius
  748. local z1 = decopos.z - v.radius
  749. local z2 = decopos.z + v.radius
  750. local nn
  751. -- All must be a valid floor/ceiling node!
  752. decopos.y = decopos.y + d
  753. for x = x1, x2 do
  754. for z = z1, z2 do
  755. decopos.x = x
  756. decopos.z = z
  757. nn = get_node(decopos).name
  758. -- Always check to make sure we're not air, here.
  759. -- This avoids spawning decorations on ground that was carved away by the cavegen.
  760. if nn == "air" or nn == "ignore" then
  761. return
  762. end
  763. -- If decoration requires specific node type, check if we have it.
  764. if v.place_on then
  765. local hs = false
  766. for t, j in ipairs(v.place_on) do
  767. if j == nn then
  768. hs = true
  769. break
  770. end
  771. end
  772. if not hs then
  773. return
  774. end
  775. end
  776. end
  777. end
  778. -- All must be empty air!
  779. decopos.y = decopos.y - d
  780. for x = x1, x2 do
  781. for z = z1, z2 do
  782. decopos.x = x
  783. decopos.z = z
  784. nn = get_node(decopos).name
  785. if nn ~= "air" then
  786. return
  787. end
  788. end
  789. end
  790. -- Back to ground. Replace ground surface!
  791. if v.replace_surface then
  792. decopos.y = decopos.y + d
  793. for x = x1, x2 do
  794. for z = z1, z2 do
  795. decopos.x = x
  796. decopos.z = z
  797. deconode.name = v.replace_surface[dpr:next(1, #v.replace_surface)]
  798. deconode.param2 = 0
  799. set_node(decopos, deconode)
  800. if v.custom_func then
  801. v.custom_func(decopos)
  802. end
  803. end
  804. end
  805. end
  806. -- Reset deco coordinates.
  807. decopos.x = x
  808. decopos.y = y
  809. decopos.z = z
  810. end
  811. if v.nodes then
  812. deconode.name = v.nodes[dpr:next(1, #v.nodes)]
  813. deconode.param2 = v.param2[dpr:next(1, #v.param2)]
  814. set_node(decopos, deconode)
  815. if v.custom_func then
  816. v.custom_func(decopos)
  817. end
  818. elseif v.schematic then
  819. decopos.y = decopos.y + v.place_offset_y
  820. put_schem(decopos, v.schematic, v.rotation, v.replacements, v.force_placement, v.flags)
  821. decopos.y = decopos.y - v.place_offset_y
  822. if v.custom_func then
  823. v.custom_func(decopos)
  824. end
  825. end
  826. end
  827. -- Fourth mapgen pass. Generate decorations using highlevel placement functions.
  828. -- Note: we still read the voxelmanip data! But we can't modify it.
  829. for z = z0, z1 do
  830. for x = x0, x1 do
  831. for k, v in ipairs(all_decorations) do
  832. if not (y0 > v.y_max or y1 < v.y_min) then
  833. if dpr:next(1, v.probability) == 1 then
  834. -- Don't bother with ground-level placement if 'all_floors' was specified.
  835. if (v.ground_level and not v.all_floors) then
  836. local g0 = heightmap[max_area:index(x, 0, z)]
  837. local g1 = (g0 + 1)
  838. decorate(v, x, g1, z, -1)
  839. end
  840. if (v.all_floors or v.all_ceilings) then
  841. local miny = (y0 - 1)
  842. local maxy = (y1 + 1)
  843. for y = maxy, miny, -1 do
  844. local vpa = max_area:index(x, y, z)
  845. local vpu = max_area:index(x, (y - 1), z)
  846. local cida = vm_data[vpa]
  847. local cidu = vm_data[vpu]
  848. if v.all_floors then
  849. if (cida == c_air and cidu ~= c_air) then
  850. decorate(v, x, y, z, -1)
  851. end
  852. end
  853. if v.all_ceilings then
  854. if (cida ~= c_air and cidu == c_air) then
  855. decorate(v, x, (y - 1), z, 1)
  856. end
  857. end
  858. end
  859. end
  860. end
  861. end
  862. end
  863. end
  864. end
  865. --]]
  866. -- Correct lighting and liquid flow.
  867. -- This works, but for some reason I have to grab a new voxelmanip object.
  868. -- I can't seem to fix lighting using the original mapgen object?
  869. -- Seems to require the full overgenerated mapchunk size if non-singlenode.
  870. mapfix.work(emin, emax)
  871. end
  872. if not jarkati.registered then
  873. -- Register the mapgen callback.
  874. minetest.register_on_generated(function(...)
  875. jarkati.generate_realm(...)
  876. end)
  877. oregen.register_ore({
  878. ore_type = "scatter",
  879. ore = "default:desert_stone_with_copper",
  880. wherein = {"default:desert_stone"},
  881. clust_scarcity = 6*6*6,
  882. clust_num_ores = 4,
  883. clust_size = 3,
  884. y_min = 3600,
  885. y_max = 3900,
  886. })
  887. oregen.register_ore({
  888. ore_type = "scatter",
  889. ore = "default:desert_stone_with_copper",
  890. wherein = {"default:desert_stone"},
  891. clust_scarcity = 15*15*15,
  892. clust_num_ores = 27,
  893. clust_size = 6,
  894. y_min = 3600,
  895. y_max = 3700,
  896. })
  897. oregen.register_ore({
  898. ore_type = "scatter",
  899. ore = "default:desert_stone_with_iron",
  900. wherein = {"default:desert_stone"},
  901. clust_scarcity = 10*10*10,
  902. clust_num_ores = 4,
  903. clust_size = 3,
  904. y_min = 3600,
  905. y_max = 3900,
  906. })
  907. oregen.register_ore({
  908. ore_type = "scatter",
  909. ore = "default:desert_stone_with_iron",
  910. wherein = {"default:desert_stone"},
  911. clust_scarcity = 24*24*24,
  912. clust_num_ores = 27,
  913. clust_size = 6,
  914. y_min = 3600,
  915. y_max = 3700,
  916. })
  917. oregen.register_ore({
  918. ore_type = "scatter",
  919. ore = "default:desert_stone_with_diamond",
  920. wherein = {"default:desert_stone"},
  921. clust_scarcity = 17*17*17,
  922. clust_num_ores = 4,
  923. clust_size = 3,
  924. y_min = 3600,
  925. y_max = 3900,
  926. })
  927. oregen.register_ore({
  928. ore_type = "scatter",
  929. ore = "default:desert_stone_with_diamond",
  930. wherein = {"default:desert_stone"},
  931. clust_scarcity = 15*15*15,
  932. clust_num_ores = 6,
  933. clust_size = 3,
  934. y_min = 3600,
  935. y_max = 3700,
  936. })
  937. oregen.register_ore({
  938. ore_type = "scatter",
  939. ore = "default:desert_stone_with_coal",
  940. wherein = {"default:desert_stone"},
  941. clust_scarcity = 8*8*8,
  942. clust_num_ores = 8,
  943. clust_size = 3,
  944. y_min = 3600,
  945. y_max = 3900,
  946. })
  947. oregen.register_ore({
  948. ore_type = "scatter",
  949. ore = "pm:quartz_ore",
  950. wherein = {"default:desert_sand"},
  951. clust_scarcity = 8*8*8,
  952. clust_num_ores = 8,
  953. clust_size = 3,
  954. y_min = 3600,
  955. y_max = 3900,
  956. })
  957. local c = "jarkati:core"
  958. local f = jarkati.modpath .. "/init.lua"
  959. reload.register_file(c, f, false)
  960. jarkati.registered = true
  961. end