init.lua 27 KB

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