init.lua 25 KB

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