init.lua 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. cw = cw or {}
  2. cw.modpath = minetest.get_modpath("cw")
  3. cw.worldpath = minetest.get_worldpath()
  4. -- Localize for performance.
  5. local math_random = math.random
  6. if not cw.jungletree_registered then
  7. local _ = {name = "air", prob = 0}
  8. local L = {name = "default:jungleleaves", prob = 255}
  9. local N = {name = "default:jungleleaves", prob = 223}
  10. local M = {name = "default:jungleleaves", prob = 191}
  11. local B = {name = "default:jungletree", prob = 255, force_place = true}
  12. local Y = {name = "default:jungletree", prob = 191, force_place = true}
  13. local U = {name = "default:jungletree", prob = 127, force_place = true}
  14. local I = {name = "default:jungletree", prob = 255}
  15. do
  16. local jungletree_data = {
  17. size = {x = 5, y = 17, z = 5},
  18. data = {
  19. _, _, _, _, _,
  20. _, _, _, _, _,
  21. _, _, _, _, _,
  22. _, _, _, _, _,
  23. _, _, _, _, _,
  24. _, _, _, _, _,
  25. _, _, _, _, _,
  26. _, _, _, _, _,
  27. _, _, _, _, _,
  28. _, _, _, _, _,
  29. N, L, N, _, _,
  30. _, _, N, L, N,
  31. _, _, _, _, _,
  32. _, _, _, _, _,
  33. M, N, N, N, M,
  34. M, N, N, N, M,
  35. _, _, _, _, _,
  36. _, _, B, _, _,
  37. _, _, B, _, _,
  38. _, _, U, _, _,
  39. _, _, _, _, _,
  40. _, _, _, _, _,
  41. _, _, _, _, _,
  42. _, _, _, _, _,
  43. _, _, _, _, _,
  44. _, _, _, _, _,
  45. _, _, _, _, _,
  46. L, B, L, _, _,
  47. _, _, L, B, L,
  48. _, _, _, _, _,
  49. _, _, _, _, _,
  50. N, B, L, B, N,
  51. N, L, L, L, N,
  52. _, N, N, N, _,
  53. _, B, B, B, _,
  54. _, B, B, B, _,
  55. _, U, B, U, _,
  56. _, _, B, _, _,
  57. _, _, B, _, _,
  58. _, _, B, _, _,
  59. _, _, B, _, _,
  60. _, _, B, _, _,
  61. _, _, B, L, N,
  62. N, L, B, _, _,
  63. N, L, B, _, _,
  64. _, _, B, L, N,
  65. _, _, B, L, N,
  66. _, _, B, _, _,
  67. N, L, L, L, N,
  68. N, L, L, L, N,
  69. _, N, L, N, _,
  70. _, _, B, _, _,
  71. _, _, B, _, _,
  72. _, _, U, _, _,
  73. _, _, _, _, _,
  74. _, _, _, _, _,
  75. _, _, _, _, _,
  76. _, _, _, _, _,
  77. _, _, _, _, _,
  78. _, _, L, B, L,
  79. L, B, L, _, _,
  80. _, _, _, _, _,
  81. _, _, _, _, _,
  82. _, _, L, B, L,
  83. _, _, _, _, _,
  84. N, B, L, B, N,
  85. N, L, L, L, N,
  86. _, N, N, N, _,
  87. _, _, _, _, _,
  88. _, _, _, _, _,
  89. _, _, _, _, _,
  90. _, _, _, _, _,
  91. _, _, _, _, _,
  92. _, _, _, _, _,
  93. _, _, _, _, _,
  94. _, _, _, _, _,
  95. _, _, N, L, N,
  96. N, L, N, _, _,
  97. _, _, _, _, _,
  98. _, _, _, _, _,
  99. _, _, N, L, N,
  100. _, _, _, _, _,
  101. M, N, N, N, M,
  102. M, N, N, N, M,
  103. _, _, _, _, _,
  104. },
  105. yslice_prob = {
  106. {ypos=6, prob=191},
  107. {ypos=7, prob=191},
  108. {ypos=8, prob=191},
  109. {ypos=9, prob=191},
  110. {ypos=10, prob=191},
  111. },
  112. }
  113. local data = minetest.serialize_schematic(jungletree_data, "mts", {})
  114. local file = io.open(cw.worldpath .. "/cw_jungletree_base.mts", "w")
  115. file:write(data)
  116. file:close()
  117. end
  118. do
  119. -- Main difference is the trunk base doesn't have extra nodes around it.
  120. local jungletree_data = {
  121. size = {x = 5, y = 17, z = 5},
  122. data = {
  123. _, _, _, _, _,
  124. _, _, _, _, _,
  125. _, _, _, _, _,
  126. _, _, _, _, _,
  127. _, _, _, _, _,
  128. _, _, _, _, _,
  129. _, _, _, _, _,
  130. _, _, _, _, _,
  131. _, _, _, _, _,
  132. _, _, _, _, _,
  133. N, L, N, _, _,
  134. _, _, N, L, N,
  135. _, _, _, _, _,
  136. _, _, _, _, _,
  137. M, N, N, N, M,
  138. M, N, N, N, M,
  139. _, _, _, _, _,
  140. _, _, _, _, _,
  141. _, _, _, _, _,
  142. _, _, _, _, _,
  143. _, _, _, _, _,
  144. _, _, _, _, _,
  145. _, _, _, _, _,
  146. _, _, _, _, _,
  147. _, _, _, _, _,
  148. _, _, _, _, _,
  149. _, _, _, _, _,
  150. L, B, L, _, _,
  151. _, _, L, B, L,
  152. _, _, _, _, _,
  153. _, _, _, _, _,
  154. N, B, L, B, N,
  155. N, L, L, L, N,
  156. _, N, N, N, _,
  157. _, _, B, _, _,
  158. _, _, B, _, _,
  159. _, _, B, _, _,
  160. _, _, B, _, _,
  161. _, _, B, _, _,
  162. _, _, B, _, _,
  163. _, _, B, _, _,
  164. _, _, B, _, _,
  165. _, _, B, L, N,
  166. N, L, B, _, _,
  167. N, L, B, _, _,
  168. _, _, B, L, N,
  169. _, _, B, L, N,
  170. _, _, B, _, _,
  171. N, L, L, L, N,
  172. N, L, L, L, N,
  173. _, N, L, N, _,
  174. _, _, _, _, _,
  175. _, _, _, _, _,
  176. _, _, _, _, _,
  177. _, _, _, _, _,
  178. _, _, _, _, _,
  179. _, _, _, _, _,
  180. _, _, _, _, _,
  181. _, _, _, _, _,
  182. _, _, L, B, L,
  183. L, B, L, _, _,
  184. _, _, _, _, _,
  185. _, _, _, _, _,
  186. _, _, L, B, L,
  187. _, _, _, _, _,
  188. N, B, L, B, N,
  189. N, L, L, L, N,
  190. _, N, N, N, _,
  191. _, _, _, _, _,
  192. _, _, _, _, _,
  193. _, _, _, _, _,
  194. _, _, _, _, _,
  195. _, _, _, _, _,
  196. _, _, _, _, _,
  197. _, _, _, _, _,
  198. _, _, _, _, _,
  199. _, _, N, L, N,
  200. N, L, N, _, _,
  201. _, _, _, _, _,
  202. _, _, _, _, _,
  203. _, _, N, L, N,
  204. _, _, _, _, _,
  205. M, N, N, N, M,
  206. M, N, N, N, M,
  207. _, _, _, _, _,
  208. },
  209. yslice_prob = {
  210. {ypos=6, prob=191},
  211. {ypos=7, prob=191},
  212. {ypos=8, prob=191},
  213. {ypos=9, prob=191},
  214. {ypos=10, prob=191},
  215. },
  216. }
  217. local data = minetest.serialize_schematic(jungletree_data, "mts", {})
  218. local file = io.open(cw.worldpath .. "/cw_jungletree_top.mts", "w")
  219. file:write(data)
  220. file:close()
  221. end
  222. cw.jungletree_registered = true
  223. end
  224. -- A Channelwood-like realm. Endless, shallow water in all directions, with
  225. -- trees growing out of the ocean. Trees are huge and extremely tall. Water is
  226. -- dangerious, filled with flesh-eating fish! Trees do not burn (too wet).
  227. -- Register deadly water.
  228. if not cw.registered then
  229. -- Basically just a copy of regular water, with damage_per_second.
  230. local sdef = table.copy(minetest.registered_nodes["default:water_source"])
  231. local fdef = table.copy(minetest.registered_nodes["default:water_flowing"])
  232. sdef.damage_per_second = 1
  233. fdef.damage_per_second = 1
  234. sdef.liquid_alternative_flowing = "cw:water_flowing"
  235. sdef.liquid_alternative_source = "cw:water_source"
  236. fdef.liquid_alternative_flowing = "cw:water_flowing"
  237. fdef.liquid_alternative_source = "cw:water_source"
  238. minetest.register_node("cw:water_source", sdef)
  239. minetest.register_node("cw:water_flowing", fdef)
  240. end
  241. cw.REALM_START = 3050
  242. cw.BEDROCK_DEPTH = 4
  243. cw.OCEAN_DEPTH = 16
  244. cw.GROUND_DEPTH = 11
  245. cw.GROUND_HEIGHT_VARIATION = 4
  246. -- Controls land height.
  247. cw.noise1param2d = {
  248. offset = 0,
  249. scale = 1,
  250. spread = {x=128, y=128, z=128},
  251. seed = 3717,
  252. octaves = 5,
  253. persist = 0.5,
  254. lacunarity = 2,
  255. }
  256. cw.noise2param2d = {
  257. offset = 0,
  258. scale = 1,
  259. spread = {x=32, y=32, z=32},
  260. seed = 5817,
  261. octaves = 4,
  262. persist = 0.8,
  263. lacunarity = 2,
  264. }
  265. -- Content IDs used with the voxel manipulator.
  266. local c_air = minetest.get_content_id("air")
  267. local c_ignore = minetest.get_content_id("ignore")
  268. local c_stone = minetest.get_content_id("default:stone")
  269. local c_bedrock = minetest.get_content_id("bedrock:bedrock")
  270. local c_water = minetest.get_content_id("cw:water_source")
  271. local c_dirt = minetest.get_content_id("darkage:darkdirt")
  272. local c_silt = minetest.get_content_id("darkage:silt")
  273. local c_mud = minetest.get_content_id("darkage:mud")
  274. local c_clay = minetest.get_content_id("default:clay")
  275. local c_lily = minetest.get_content_id("flowers:waterlily")
  276. -- Externally located tables for performance.
  277. local data = {}
  278. local noisemap1 = {}
  279. local noisemap2 = {}
  280. local JUNGLETREE_REPLACEMENTS = {
  281. ["default:jungletree"] = "basictrees:jungletree_cube",
  282. ["default:jungleleaves"] = "basictrees:jungletree_leaves2",
  283. }
  284. local RANDPOS = {
  285. {x=1, y=0, z=0},
  286. {x=-1, y=0, z=0},
  287. {x=0, y=0, z=1},
  288. {x=0, y=0, z=-1},
  289. -- 3 times to increase probability.
  290. {x=0, y=0, z=0},
  291. {x=0, y=0, z=0},
  292. {x=0, y=0, z=0},
  293. }
  294. cw.generate_realm = function(minp, maxp, seed)
  295. local nstart = cw.REALM_START
  296. minp = table.copy(minp)
  297. maxp = table.copy(maxp)
  298. -- Don't run for out-of-bounds mapchunks.
  299. local nfinish = nstart + 100
  300. if minp.y > nfinish or maxp.y < nstart then
  301. return
  302. end
  303. -- Generate the full column all at once.
  304. if minp.y > nstart then
  305. minp.y = nstart
  306. end
  307. if maxp.y < nfinish then
  308. maxp.y = nfinish
  309. end
  310. -- Grab the voxel manipulator.
  311. -- Read current map data.
  312. local vm = VoxelManip()
  313. vm:read_from_map(vector.subtract(minp, 16), vector.add(maxp, 16))
  314. local emin, emax = vm:get_emerged_area()
  315. vm:get_data(data)
  316. local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax})
  317. local pr = PseudoRandom(seed + 381)
  318. local x1 = maxp.x
  319. local y1 = maxp.y
  320. local z1 = maxp.z
  321. local x0 = minp.x
  322. local y0 = minp.y
  323. local z0 = minp.z
  324. -- Compute side lengths.
  325. local side_len_x = ((x1-x0)+1)
  326. local side_len_z = ((z1-z0)+1)
  327. local sides2D = {x=side_len_x, y=side_len_z}
  328. local bp2d = {x=x0, y=z0}
  329. -- Get noisemaps.
  330. local perlin1 = minetest.get_perlin_map(cw.noise1param2d, sides2D)
  331. perlin1:get2dMap_flat(bp2d, noisemap1)
  332. local perlin2 = minetest.get_perlin_map(cw.noise2param2d, sides2D)
  333. perlin2:get2dMap_flat(bp2d, noisemap2)
  334. -- Localize commonly used functions.
  335. local floor = math.floor
  336. local ceil = math.ceil
  337. local abs = math.abs
  338. local od = cw.OCEAN_DEPTH
  339. local bd = cw.BEDROCK_DEPTH
  340. local gd = cw.GROUND_DEPTH
  341. local ghv = cw.GROUND_HEIGHT_VARIATION
  342. local tree_positions1 = {}
  343. local lily_positions1 = {}
  344. -- First mapgen pass.
  345. for z = z0, z1 do
  346. for x = x0, x1 do
  347. -- Get index into 2D noise arrays.
  348. local nx = (x-x0)
  349. local nz = (z-z0)
  350. local ni2 = (side_len_z*nz+nx)
  351. -- Lua arrays start indexing at 1, not 0. Urrrrgh.
  352. ni2 = ni2 + 1
  353. local n1 = noisemap1[ni2]
  354. local n2 = noisemap2[ni2]
  355. -- Randomize height of the bedrock a bit.
  356. local bedrock_adjust = (nstart + bd + pr:next(0, pr:next(1, 2)))
  357. local clay_depth = (nstart + bd + pr:next(1, 2))
  358. -- Fixed ocean height.
  359. local ocean_depth = (nstart + od)
  360. local ocean_surface = ocean_depth + 1
  361. -- Ground height.
  362. local an1 = abs(n1)
  363. local ground_depth = (nstart + gd + floor(an1 * ghv))
  364. local water_depth = (ocean_depth - ground_depth)
  365. local lily_chance = 1000
  366. if water_depth <= 2 then
  367. if pr:next(1, 16) == 1 then
  368. tree_positions1[#tree_positions1+1] = {x=x, y=ground_depth, z=z, w=an1}
  369. end
  370. lily_chance = 50
  371. elseif water_depth == 3 then
  372. if pr:next(1, 40) == 1 then
  373. tree_positions1[#tree_positions1+1] = {x=x, y=ground_depth, z=z, w=an1}
  374. end
  375. lily_chance = 150
  376. elseif water_depth == 4 then
  377. if pr:next(1, 300) == 1 then
  378. tree_positions1[#tree_positions1+1] = {x=x, y=ground_depth, z=z, w=an1}
  379. end
  380. lily_chance = 200
  381. end
  382. -- Enable waterlilies.
  383. local want_waterlily = false
  384. if pr:next(1, lily_chance) == 1 then
  385. want_waterlily = true
  386. end
  387. -- First pass through column.
  388. for y = y0, y1 do
  389. local vp = area:index(x, y, z)
  390. if y >= nstart and y <= nfinish then
  391. -- Get what's already here.
  392. local cid = data[vp]
  393. if cid == c_air or cid == c_ignore then
  394. -- Place bedrock layer.
  395. if y <= bedrock_adjust then
  396. data[vp] = c_bedrock
  397. elseif y <= clay_depth and water_depth >= 5 then
  398. data[vp] = c_clay
  399. elseif y < ground_depth then
  400. data[vp] = c_dirt
  401. elseif y == ground_depth then
  402. -- Mud appears when silt rises to water surface and above.
  403. if ground_depth >= (ocean_depth - 1) then
  404. data[vp] = c_mud
  405. else
  406. data[vp] = c_silt
  407. end
  408. elseif y <= ocean_depth then
  409. data[vp] = c_water
  410. elseif y == ocean_surface then
  411. if want_waterlily then
  412. data[vp] = c_lily
  413. end
  414. end
  415. end
  416. end
  417. end
  418. end
  419. end
  420. vm:set_data(data)
  421. for k, v_orig in ipairs(tree_positions1) do
  422. local v = table.copy(v_orig)
  423. local bottom = v.y
  424. local w = v.w
  425. if w > 1.0 then
  426. w = 1.0
  427. end
  428. local h = 13 * w
  429. v.w = nil
  430. -- Schematic horizontal offset.
  431. v.x = v.x - 2
  432. v.z = v.z - 2
  433. local path = cw.worldpath .. "/cw_jungletree_base.mts"
  434. local path2 = cw.worldpath .. "/cw_jungletree_top.mts"
  435. local path3 = path2
  436. if h > 10 then
  437. path2 = path
  438. end
  439. local force_place = false
  440. minetest.place_schematic_on_vmanip(vm, v, path, "random", JUNGLETREE_REPLACEMENTS, force_place)
  441. if pr:next(1, 5) <= 4 then
  442. v.y = v.y + h
  443. if h > 10 then
  444. minetest.place_schematic_on_vmanip(vm, vector.add(v, RANDPOS[math_random(1, #RANDPOS)]), path2, "random", JUNGLETREE_REPLACEMENTS, force_place)
  445. else
  446. minetest.place_schematic_on_vmanip(vm, v, path2, "random", JUNGLETREE_REPLACEMENTS, force_place)
  447. end
  448. if pr:next(1, 3) <= 2 then
  449. v.y = v.y + h
  450. if h > 10 then
  451. minetest.place_schematic_on_vmanip(vm, vector.add(v, RANDPOS[math_random(1, #RANDPOS)]), path2, "random", JUNGLETREE_REPLACEMENTS, force_place)
  452. else
  453. minetest.place_schematic_on_vmanip(vm, v, path2, "random", JUNGLETREE_REPLACEMENTS, force_place)
  454. end
  455. if h >= 10 then
  456. if pr:next(1, 2) == 1 then
  457. v.y = v.y + 13
  458. minetest.place_schematic_on_vmanip(vm, v, path3, "random", JUNGLETREE_REPLACEMENTS, force_place)
  459. if h > 10 and pr:next(1, 3) == 1 then
  460. v.y = v.y + 13
  461. minetest.place_schematic_on_vmanip(vm, v, path3, "random", JUNGLETREE_REPLACEMENTS, force_place)
  462. end
  463. end
  464. elseif h >= 8 then
  465. if pr:next(1, 3) == 1 then
  466. v.y = v.y + 12
  467. minetest.place_schematic_on_vmanip(vm, v, path3, "random", JUNGLETREE_REPLACEMENTS, force_place)
  468. end
  469. end
  470. end
  471. end
  472. -- Store tree bottom/top.
  473. v_orig.b = bottom
  474. v_orig.t = v.y + 17
  475. end
  476. -- Finalize voxel manipulator.
  477. -- Note: we specifically do not generate ores! The value of this realm is in
  478. -- its trees.
  479. vm:set_lighting({day=0, night=0})
  480. vm:calc_lighting()
  481. -- Liquid is never added in a way that would require flowing update.
  482. --vm:update_liquids()
  483. vm:write_to_map()
  484. for k, v in ipairs(tree_positions1) do
  485. local bottom = v.y
  486. local top = v.t
  487. -- This is somewhat intensive, so don't run for every single tree.
  488. if math_random(1, 5) == 1 then
  489. local minp = {x=v.x - 2, y=bottom, z=v.z - 2}
  490. local maxp = {x=v.x + 2, y=top, z=v.z + 2}
  491. dryleaves.replace_leaves(minp, maxp, 5)
  492. end
  493. end
  494. end
  495. if not cw.registered then
  496. -- Register the mapgen callback.
  497. minetest.register_on_generated(function(...)
  498. cw.generate_realm(...)
  499. end)
  500. local c = "cw:core"
  501. local f = cw.modpath .. "/init.lua"
  502. reload.register_file(c, f, false)
  503. cw.registered = true
  504. end