init.lua 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  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. -- Externally located tables for performance.
  276. local data = {}
  277. local noisemap1 = {}
  278. local noisemap2 = {}
  279. local JUNGLETREE_REPLACEMENTS = {
  280. ["default:jungletree"] = "basictrees:jungletree_cube",
  281. ["default:jungleleaves"] = "basictrees:jungletree_leaves2",
  282. }
  283. local RANDPOS = {
  284. {x=1, y=0, z=0},
  285. {x=-1, y=0, z=0},
  286. {x=0, y=0, z=1},
  287. {x=0, y=0, z=-1},
  288. -- 3 times to increase probability.
  289. {x=0, y=0, z=0},
  290. {x=0, y=0, z=0},
  291. {x=0, y=0, z=0},
  292. }
  293. cw.generate_realm = function(minp, maxp, seed)
  294. local nstart = cw.REALM_START
  295. -- Don't run for out-of-bounds mapchunks.
  296. local nfinish = nstart + 100
  297. if minp.y > nfinish or maxp.y < nstart then
  298. return
  299. end
  300. -- Grab the voxel manipulator.
  301. -- Read current map data.
  302. local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
  303. vm:get_data(data)
  304. local area = VoxelArea:new {MinEdge=emin, MaxEdge=emax}
  305. local pr = PseudoRandom(seed + 381)
  306. local x1 = maxp.x
  307. local y1 = maxp.y
  308. local z1 = maxp.z
  309. local x0 = minp.x
  310. local y0 = minp.y
  311. local z0 = minp.z
  312. -- Compute side lengths.
  313. local side_len_x = ((x1-x0)+1)
  314. local side_len_z = ((z1-z0)+1)
  315. local sides2D = {x=side_len_x, y=side_len_z}
  316. local bp2d = {x=x0, y=z0}
  317. -- Get noisemaps.
  318. local perlin1 = minetest.get_perlin_map(cw.noise1param2d, sides2D)
  319. perlin1:get2dMap_flat(bp2d, noisemap1)
  320. local perlin2 = minetest.get_perlin_map(cw.noise2param2d, sides2D)
  321. perlin2:get2dMap_flat(bp2d, noisemap2)
  322. -- Localize commonly used functions.
  323. local floor = math.floor
  324. local ceil = math.ceil
  325. local abs = math.abs
  326. local od = cw.OCEAN_DEPTH
  327. local bd = cw.BEDROCK_DEPTH
  328. local gd = cw.GROUND_DEPTH
  329. local ghv = cw.GROUND_HEIGHT_VARIATION
  330. local tree_positions1 = {}
  331. -- First mapgen pass.
  332. for z = z0, z1 do
  333. for x = x0, x1 do
  334. -- Get index into 2D noise arrays.
  335. local nx = (x-x0)
  336. local nz = (z-z0)
  337. local ni2 = (side_len_z*nz+nx)
  338. -- Lua arrays start indexing at 1, not 0. Urrrrgh.
  339. ni2 = ni2 + 1
  340. local n1 = noisemap1[ni2]
  341. local n2 = noisemap2[ni2]
  342. -- Randomize height of the bedrock a bit.
  343. local bedrock_adjust = (nstart + bd + pr:next(0, pr:next(1, 2)))
  344. local clay_depth = (nstart + bd + pr:next(1, 2))
  345. -- Fixed ocean height.
  346. local ocean_depth = (nstart + od)
  347. -- Ground height.
  348. local an1 = abs(n1)
  349. local ground_depth = (nstart + gd + floor(an1 * ghv))
  350. local water_depth = (ocean_depth - ground_depth)
  351. if water_depth <= 2 then
  352. if pr:next(1, 16) == 1 then
  353. tree_positions1[#tree_positions1+1] = {x=x, y=ground_depth, z=z, w=an1}
  354. end
  355. elseif water_depth == 3 then
  356. if pr:next(1, 40) == 1 then
  357. tree_positions1[#tree_positions1+1] = {x=x, y=ground_depth, z=z, w=an1}
  358. end
  359. elseif water_depth == 4 then
  360. if pr:next(1, 300) == 1 then
  361. tree_positions1[#tree_positions1+1] = {x=x, y=ground_depth, z=z, w=an1}
  362. end
  363. end
  364. -- First pass through column.
  365. for y = y0, y1 do
  366. local vp = area:index(x, y, z)
  367. if y >= nstart and y <= nfinish then
  368. -- Get what's already here.
  369. local cid = data[vp]
  370. if cid == c_air or cid == c_ignore then
  371. -- Place bedrock layer.
  372. if y <= bedrock_adjust then
  373. data[vp] = c_bedrock
  374. elseif y <= clay_depth and water_depth >= 5 then
  375. data[vp] = c_clay
  376. elseif y < ground_depth then
  377. data[vp] = c_dirt
  378. elseif y == ground_depth then
  379. -- Mud appears when silt rises to water surface and above.
  380. if ground_depth >= (ocean_depth - 1) then
  381. data[vp] = c_mud
  382. else
  383. data[vp] = c_silt
  384. end
  385. elseif y <= ocean_depth then
  386. data[vp] = c_water
  387. end
  388. end
  389. end
  390. end
  391. end
  392. end
  393. -- Finalize voxel manipulator.
  394. -- Note: we specifically do not generate ores! The value of this realm is in
  395. -- its trees.
  396. vm:set_data(data)
  397. vm:set_lighting({day=0, night=0})
  398. vm:calc_lighting()
  399. vm:update_liquids()
  400. vm:write_to_map()
  401. for k, v in ipairs(tree_positions1) do
  402. local w = v.w
  403. if w > 1.0 then
  404. w = 1.0
  405. end
  406. local h = 13 * w
  407. v.w = nil
  408. -- Schematic horizontal offset.
  409. v.x = v.x - 2
  410. v.z = v.z - 2
  411. local path = cw.worldpath .. "/cw_jungletree_base.mts"
  412. local path2 = cw.worldpath .. "/cw_jungletree_top.mts"
  413. local path3 = path2
  414. if h > 10 then
  415. path2 = path
  416. end
  417. local force_place = false
  418. minetest.place_schematic(v, path, "random", JUNGLETREE_REPLACEMENTS, force_place)
  419. if pr:next(1, 5) <= 4 then
  420. v.y = v.y + h
  421. if h > 10 then
  422. minetest.place_schematic(vector.add(v, RANDPOS[math_random(1, #RANDPOS)]), path2, "random", JUNGLETREE_REPLACEMENTS, force_place)
  423. else
  424. minetest.place_schematic(v, path2, "random", JUNGLETREE_REPLACEMENTS, force_place)
  425. end
  426. if pr:next(1, 3) <= 2 then
  427. v.y = v.y + h
  428. if h > 10 then
  429. minetest.place_schematic(vector.add(v, RANDPOS[math_random(1, #RANDPOS)]), path2, "random", JUNGLETREE_REPLACEMENTS, force_place)
  430. else
  431. minetest.place_schematic(v, path2, "random", JUNGLETREE_REPLACEMENTS, force_place)
  432. end
  433. if h >= 10 then
  434. if pr:next(1, 2) == 1 then
  435. v.y = v.y + 13
  436. minetest.place_schematic(v, path3, "random", JUNGLETREE_REPLACEMENTS, force_place)
  437. if h > 10 and pr:next(1, 3) == 1 then
  438. v.y = v.y + 13
  439. minetest.place_schematic(v, path3, "random", JUNGLETREE_REPLACEMENTS, force_place)
  440. end
  441. end
  442. elseif h >= 8 then
  443. if pr:next(1, 3) == 1 then
  444. v.y = v.y + 12
  445. minetest.place_schematic(v, path3, "random", JUNGLETREE_REPLACEMENTS, force_place)
  446. end
  447. end
  448. end
  449. end
  450. end
  451. end
  452. if not cw.registered then
  453. -- Register the mapgen callback.
  454. minetest.register_on_generated(function(...)
  455. cw.generate_realm(...)
  456. end)
  457. local c = "cw:core"
  458. local f = cw.modpath .. "/init.lua"
  459. reload.register_file(c, f, false)
  460. cw.registered = true
  461. end