init.lua 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  1. if not minetest.global_exists("cw") then cw = {} end
  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*500
  233. fdef.damage_per_second = 1*500
  234. sdef._damage_per_second_type = "fleshy"
  235. fdef._damage_per_second_type = "fleshy"
  236. sdef._death_message = "the piranha got <player>."
  237. fdef._death_message = "the piranha got <player>."
  238. sdef.liquid_alternative_flowing = "cw:water_flowing"
  239. sdef.liquid_alternative_source = "cw:water_source"
  240. fdef.liquid_alternative_flowing = "cw:water_flowing"
  241. fdef.liquid_alternative_source = "cw:water_source"
  242. minetest.register_node("cw:water_source", sdef)
  243. minetest.register_node("cw:water_flowing", fdef)
  244. end
  245. cw.REALM_START = 3050
  246. cw.BEDROCK_DEPTH = 4
  247. cw.OCEAN_DEPTH = 16
  248. cw.GROUND_DEPTH = 11
  249. cw.GROUND_HEIGHT_VARIATION = 4
  250. -- Controls land height.
  251. cw.noise1param2d = {
  252. offset = 0,
  253. scale = 1,
  254. spread = {x=128, y=128, z=128},
  255. seed = 3717,
  256. octaves = 5,
  257. persist = 0.5,
  258. lacunarity = 2,
  259. }
  260. cw.noise2param2d = {
  261. offset = 0,
  262. scale = 1,
  263. spread = {x=32, y=32, z=32},
  264. seed = 5817,
  265. octaves = 4,
  266. persist = 0.8,
  267. lacunarity = 2,
  268. }
  269. -- Content IDs used with the voxel manipulator.
  270. local c_air = minetest.get_content_id("air")
  271. local c_ignore = minetest.get_content_id("ignore")
  272. local c_stone = minetest.get_content_id("default:stone")
  273. local c_bedrock = minetest.get_content_id("bedrock:bedrock")
  274. local c_water = minetest.get_content_id("cw:water_source")
  275. local c_dirt = minetest.get_content_id("darkage:darkdirt")
  276. local c_silt = minetest.get_content_id("darkage:silt")
  277. local c_mud = minetest.get_content_id("darkage:mud")
  278. local c_clay = minetest.get_content_id("default:clay")
  279. local c_lily = minetest.get_content_id("flowers:waterlily")
  280. -- Externally located tables for performance.
  281. local data = {}
  282. local noisemap1 = {}
  283. local noisemap2 = {}
  284. local JUNGLETREE_REPLACEMENTS = {
  285. ["default:jungletree"] = "basictrees:jungletree_cube",
  286. ["default:jungleleaves"] = "basictrees:jungletree_leaves2",
  287. }
  288. local RANDPOS = {
  289. {x=1, y=0, z=0},
  290. {x=-1, y=0, z=0},
  291. {x=0, y=0, z=1},
  292. {x=0, y=0, z=-1},
  293. -- 3 times to increase probability.
  294. {x=0, y=0, z=0},
  295. {x=0, y=0, z=0},
  296. {x=0, y=0, z=0},
  297. }
  298. cw.generate_realm = function(minp, maxp, seed)
  299. local nstart = cw.REALM_START
  300. minp = table.copy(minp)
  301. maxp = table.copy(maxp)
  302. -- Don't run for out-of-bounds mapchunks.
  303. local nfinish = nstart + 100
  304. if minp.y > nfinish or maxp.y < nstart then
  305. return
  306. end
  307. -- Generate the full column all at once.
  308. if minp.y > nstart then
  309. minp.y = nstart
  310. end
  311. if maxp.y < nfinish then
  312. maxp.y = nfinish
  313. end
  314. -- Grab the voxel manipulator.
  315. -- Read current map data.
  316. local vm = VoxelManip()
  317. vm:read_from_map(vector.subtract(minp, 16), vector.add(maxp, 16))
  318. local emin, emax = vm:get_emerged_area()
  319. vm:get_data(data)
  320. local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax})
  321. local pr = PseudoRandom(seed + 381)
  322. local x1 = maxp.x
  323. local y1 = maxp.y
  324. local z1 = maxp.z
  325. local x0 = minp.x
  326. local y0 = minp.y
  327. local z0 = minp.z
  328. -- Compute side lengths.
  329. local side_len_x = ((x1-x0)+1)
  330. local side_len_z = ((z1-z0)+1)
  331. local sides2D = {x=side_len_x, y=side_len_z}
  332. local bp2d = {x=x0, y=z0}
  333. -- Get noisemaps.
  334. local perlin1 = minetest.get_perlin_map(cw.noise1param2d, sides2D)
  335. perlin1:get_2d_map_flat(bp2d, noisemap1)
  336. local perlin2 = minetest.get_perlin_map(cw.noise2param2d, sides2D)
  337. perlin2:get_2d_map_flat(bp2d, noisemap2)
  338. -- Localize commonly used functions.
  339. local floor = math.floor
  340. local ceil = math.ceil
  341. local abs = math.abs
  342. local od = cw.OCEAN_DEPTH
  343. local bd = cw.BEDROCK_DEPTH
  344. local gd = cw.GROUND_DEPTH
  345. local ghv = cw.GROUND_HEIGHT_VARIATION
  346. local tree_positions1 = {}
  347. local lily_positions1 = {}
  348. -- First mapgen pass.
  349. for z = z0, z1 do
  350. for x = x0, x1 do
  351. -- Get index into 2D noise arrays.
  352. local nx = (x-x0)
  353. local nz = (z-z0)
  354. local ni2 = (side_len_z*nz+nx)
  355. -- Lua arrays start indexing at 1, not 0. Urrrrgh.
  356. ni2 = ni2 + 1
  357. local n1 = noisemap1[ni2]
  358. local n2 = noisemap2[ni2]
  359. -- Randomize height of the bedrock a bit.
  360. local bedrock_adjust = (nstart + bd + pr:next(0, pr:next(1, 2)))
  361. local clay_depth = (nstart + bd + pr:next(1, 2))
  362. -- Fixed ocean height.
  363. local ocean_depth = (nstart + od)
  364. local ocean_surface = ocean_depth + 1
  365. -- Ground height.
  366. local an1 = abs(n1)
  367. local ground_depth = (nstart + gd + floor(an1 * ghv))
  368. local water_depth = (ocean_depth - ground_depth)
  369. local lily_chance = 1000
  370. if water_depth <= 2 then
  371. if pr:next(1, 16) == 1 then
  372. tree_positions1[#tree_positions1+1] = {x=x, y=ground_depth, z=z, w=an1}
  373. end
  374. lily_chance = 50
  375. elseif water_depth == 3 then
  376. if pr:next(1, 40) == 1 then
  377. tree_positions1[#tree_positions1+1] = {x=x, y=ground_depth, z=z, w=an1}
  378. end
  379. lily_chance = 150
  380. elseif water_depth == 4 then
  381. if pr:next(1, 300) == 1 then
  382. tree_positions1[#tree_positions1+1] = {x=x, y=ground_depth, z=z, w=an1}
  383. end
  384. lily_chance = 200
  385. end
  386. -- Enable waterlilies.
  387. local want_waterlily = false
  388. if pr:next(1, lily_chance) == 1 then
  389. want_waterlily = true
  390. end
  391. -- First pass through column.
  392. for y = y0, y1 do
  393. local vp = area:index(x, y, z)
  394. if y >= nstart and y <= nfinish then
  395. -- Get what's already here.
  396. local cid = data[vp]
  397. if cid == c_air or cid == c_ignore then
  398. -- Place bedrock layer.
  399. if y <= bedrock_adjust then
  400. data[vp] = c_bedrock
  401. elseif y <= clay_depth and water_depth >= 5 then
  402. data[vp] = c_clay
  403. elseif y < ground_depth then
  404. data[vp] = c_dirt
  405. elseif y == ground_depth then
  406. -- Mud appears when silt rises to water surface and above.
  407. if ground_depth >= (ocean_depth - 1) then
  408. data[vp] = c_mud
  409. else
  410. data[vp] = c_silt
  411. end
  412. elseif y <= ocean_depth then
  413. data[vp] = c_water
  414. elseif y == ocean_surface then
  415. if want_waterlily then
  416. data[vp] = c_lily
  417. end
  418. end
  419. end
  420. end
  421. end
  422. end
  423. end
  424. vm:set_data(data)
  425. for k, v_orig in ipairs(tree_positions1) do
  426. local v = table.copy(v_orig)
  427. local bottom = v.y
  428. local w = v.w
  429. if w > 1.0 then
  430. w = 1.0
  431. end
  432. local h = 13 * w
  433. v.w = nil
  434. -- Schematic horizontal offset.
  435. v.x = v.x - 2
  436. v.z = v.z - 2
  437. local path = cw.worldpath .. "/cw_jungletree_base.mts"
  438. local path2 = cw.worldpath .. "/cw_jungletree_top.mts"
  439. local path3 = path2
  440. if h > 10 then
  441. path2 = path
  442. end
  443. local force_place = false
  444. minetest.place_schematic_on_vmanip(vm, v, path, "random", JUNGLETREE_REPLACEMENTS, force_place)
  445. if pr:next(1, 5) <= 4 then
  446. v.y = v.y + h
  447. if h > 10 then
  448. minetest.place_schematic_on_vmanip(vm, vector.add(v, RANDPOS[math_random(1, #RANDPOS)]), path2, "random", JUNGLETREE_REPLACEMENTS, force_place)
  449. else
  450. minetest.place_schematic_on_vmanip(vm, v, path2, "random", JUNGLETREE_REPLACEMENTS, force_place)
  451. end
  452. if pr:next(1, 3) <= 2 then
  453. v.y = v.y + h
  454. if h > 10 then
  455. minetest.place_schematic_on_vmanip(vm, vector.add(v, RANDPOS[math_random(1, #RANDPOS)]), path2, "random", JUNGLETREE_REPLACEMENTS, force_place)
  456. else
  457. minetest.place_schematic_on_vmanip(vm, v, path2, "random", JUNGLETREE_REPLACEMENTS, force_place)
  458. end
  459. if h >= 10 then
  460. if pr:next(1, 2) == 1 then
  461. v.y = v.y + 13
  462. minetest.place_schematic_on_vmanip(vm, v, path3, "random", JUNGLETREE_REPLACEMENTS, force_place)
  463. if h > 10 and pr:next(1, 3) == 1 then
  464. v.y = v.y + 13
  465. minetest.place_schematic_on_vmanip(vm, v, path3, "random", JUNGLETREE_REPLACEMENTS, force_place)
  466. end
  467. end
  468. elseif h >= 8 then
  469. if pr:next(1, 3) == 1 then
  470. v.y = v.y + 12
  471. minetest.place_schematic_on_vmanip(vm, v, path3, "random", JUNGLETREE_REPLACEMENTS, force_place)
  472. end
  473. end
  474. end
  475. end
  476. -- Store tree bottom/top.
  477. v_orig.b = bottom
  478. v_orig.t = v.y + 17
  479. end
  480. -- Finalize voxel manipulator.
  481. -- Note: we specifically do not generate ores! The value of this realm is in
  482. -- its trees.
  483. vm:set_lighting({day=0, night=0})
  484. vm:calc_lighting()
  485. -- Liquid is never added in a way that would require flowing update.
  486. --vm:update_liquids()
  487. vm:write_to_map()
  488. for k, v in ipairs(tree_positions1) do
  489. local bottom = v.y
  490. local top = v.t
  491. -- This is somewhat intensive, so don't run for every single tree.
  492. if math_random(1, 5) == 1 then
  493. local minp = {x=v.x - 2, y=bottom, z=v.z - 2}
  494. local maxp = {x=v.x + 2, y=top, z=v.z + 2}
  495. dryleaves.replace_leaves(minp, maxp, 5)
  496. end
  497. end
  498. end
  499. if not cw.registered then
  500. -- Register the mapgen callback.
  501. minetest.register_on_generated(function(...)
  502. cw.generate_realm(...)
  503. end)
  504. local c = "cw:core"
  505. local f = cw.modpath .. "/init.lua"
  506. reload.register_file(c, f, false)
  507. cw.registered = true
  508. end