init.lua 28 KB

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