mapgen_decorations.lua 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. --[[
  2. Register decorations for Nether mapgen
  3. Copyright (C) 2020 Treer
  4. Permission to use, copy, modify, and/or distribute this software for
  5. any purpose with or without fee is hereby granted, provided that the
  6. above copyright notice and this permission notice appear in all copies.
  7. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  8. WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  9. WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
  10. BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
  11. OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  12. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  13. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  14. SOFTWARE.
  15. ]]--
  16. -- Lava is unreliable in the old Nether mapgen because it removes lava
  17. -- from the overdraw areas, so any decorations involving lava will often
  18. -- have the lava missing depending on whether nearby chunks were already
  19. -- emerged or not before the decoration was placed.
  20. local allow_lava_decorations = nether.useBiomes
  21. -- Keep compatibility with mapgen_nobiomes.lua, so hardcoding 128
  22. -- instead of using nether.mapgen.BLEND
  23. local decoration_ceiling = nether.DEPTH_CEILING - 128
  24. local decoration_floor = nether.DEPTH_FLOOR + 128
  25. local _ = {name = "air", prob = 0}
  26. local A = {name = "air", prob = 255, force_place = true}
  27. local G = {name = "nether:glowstone", prob = 255, force_place = true}
  28. local N = {name = "nether:rack", prob = 255}
  29. local D = {name = "nether:rack_deep", prob = 255}
  30. local S = {name = "nether:sand", prob = 255, force_place = true}
  31. local L = {name = "default:lava_source", prob = 255, force_place = true}
  32. local F = {name = "nether:fumarole", prob = 255, force_place = true}
  33. local FS = {name = "nether:fumarole_slab", prob = 255, force_place = true}
  34. local F1 = {name = "nether:fumarole_corner", prob = 255, force_place = true, param2 = 0}
  35. local F2 = {name = "nether:fumarole_corner", prob = 255, force_place = true, param2 = 1}
  36. local F3 = {name = "nether:fumarole_corner", prob = 255, force_place = true, param2 = 2}
  37. local F4 = {name = "nether:fumarole_corner", prob = 255, force_place = true, param2 = 3}
  38. local S1 = {name = "stairs:stair_netherrack", prob = 255, force_place = true, param2 = 5}
  39. local S2 = {name = "stairs:stair_netherrack", prob = 255, force_place = true, param2 = 7}
  40. local S3 = {name = "stairs:stair_netherrack", prob = 255, force_place = true, param2 = 12}
  41. local S4 = {name = "stairs:stair_netherrack", prob = 255, force_place = true, param2 = 16}
  42. -- =================
  43. -- Stalactites
  44. -- =================
  45. local schematic_GlowstoneStalactite = {
  46. size = {x = 5, y = 10, z = 5},
  47. data = { -- note that data is upside down
  48. _, _, _, _, _,
  49. _, _, _, _, _,
  50. _, _, _, _, _,
  51. _, _, _, _, _,
  52. _, _, _, _, _,
  53. _, _, _, _, _,
  54. _, _, _, _, _,
  55. _, _, _, _, _,
  56. _, N, G, N, _,
  57. _, N, N, N, _,
  58. _, _, _, _, _,
  59. _, _, _, _, _,
  60. _, _, _, _, _,
  61. _, _, _, _, _,
  62. _, _, _, _, _,
  63. _, _, G, _, _,
  64. _, _, G, _, _,
  65. _, G, G, G, _,
  66. N, G, G, G, N,
  67. N, N, G, N, N,
  68. _, _, N, _, _, -- ypos 0, prob 25% (64/256)
  69. _, _, G, _, _, -- ypos 1, prob 37% (96/256)
  70. _, _, G, _, _, -- ypos 2, prob 100%
  71. _, _, G, _, _, -- ypos 3, prob 100%
  72. _, _, G, G, _, -- ypos 4, prob 50% (128/256) to make half of stalactites asymmetric
  73. _, G, G, G, _, -- ypos 5, prob 75% (192/256)
  74. _, G, G, G, _, -- ypos 6, prob 75% (192/256)
  75. _, G, G, G, _, -- ypos 7, prob 100%
  76. G, G, G, G, G, -- ypos 8, prob 100%
  77. N, G, G, G, N, -- ypos 9, prob 75% (192/256)
  78. _, _, _, _, _,
  79. _, _, _, _, _,
  80. _, _, _, _, _,
  81. _, _, _, _, _,
  82. _, _, G, _, _,
  83. _, _, G, _, _,
  84. _, _, G, _, _,
  85. _, G, G, G, _,
  86. N, G, G, G, N,
  87. N, N, G, N, N,
  88. _, _, _, _, _,
  89. _, _, _, _, _,
  90. _, _, _, _, _,
  91. _, _, _, _, _,
  92. _, _, _, _, _,
  93. _, _, _, _, _,
  94. _, _, _, _, _,
  95. _, _, _, _, _,
  96. _, N, G, N, _,
  97. _, N, N, N, _
  98. },
  99. -- Y-slice probabilities do not function correctly for ceiling schematic
  100. -- decorations because they are inverted, so ypos numbers have been inverted
  101. -- to match, and a larger offset in place_offset_y should be used (e.g. -3).
  102. yslice_prob = {
  103. {ypos = 9, prob = 192},
  104. {ypos = 6, prob = 192},
  105. {ypos = 5, prob = 192},
  106. {ypos = 4, prob = 128},
  107. {ypos = 1, prob = 96},
  108. {ypos = 0, prob = 64}
  109. }
  110. }
  111. minetest.register_decoration({
  112. name = "Glowstone stalactite",
  113. deco_type = "schematic",
  114. place_on = "nether:rack",
  115. sidelen = 80,
  116. fill_ratio = 0.0003,
  117. biomes = {"nether_caverns"},
  118. y_max = decoration_ceiling,
  119. y_min = decoration_floor,
  120. schematic = schematic_GlowstoneStalactite,
  121. flags = "place_center_x,place_center_z,force_placement,all_ceilings",
  122. place_offset_y=-3
  123. })
  124. minetest.register_decoration({
  125. name = "Netherrack stalactite",
  126. deco_type = "schematic",
  127. place_on = "nether:rack",
  128. sidelen = 80,
  129. fill_ratio = 0.0008,
  130. biomes = {"nether_caverns"},
  131. y_max = decoration_ceiling,
  132. y_min = decoration_floor,
  133. schematic = schematic_GlowstoneStalactite,
  134. replacements = {["nether:glowstone"] = "nether:rack"},
  135. flags = "place_center_x,place_center_z,all_ceilings",
  136. place_offset_y=-3
  137. })
  138. local schematic_GreaterStalactite = {
  139. size = {x = 3, y = 23, z = 3},
  140. data = { -- note that data is upside down
  141. _, _, _,
  142. _, _, _,
  143. _, _, _,
  144. _, _, _,
  145. _, _, _,
  146. _, _, _,
  147. _, _, _,
  148. _, _, _,
  149. _, _, _,
  150. _, _, _,
  151. _, _, _,
  152. _, _, _,
  153. _, _, _,
  154. _, D, _,
  155. _, D, _,
  156. _, D, _,
  157. _, D, _,
  158. D, D, D,
  159. D, D, D,
  160. D, D, D,
  161. _, D, _,
  162. _, _, _,
  163. _, _, _,
  164. _, D, _, -- ypos 0, prob 85% (218/255)
  165. _, D, _, -- ypos 1, prob 85% (218/255)
  166. _, D, _, -- ypos 2, prob 85% (218/255)
  167. _, D, _, -- ypos 3, prob 85% (218/255)
  168. _, D, _, -- ypos 4, prob 85% (218/255)
  169. _, D, _, -- ypos 5, prob 85% (218/255)
  170. _, D, _, -- ypos 6, prob 85% (218/255)
  171. _, D, _, -- ypos 7, prob 85% (218/255)
  172. _, D, _, -- ypos 8, prob 85% (218/255)
  173. _, D, D, -- ypos 9, prob 50% (128/256) to make half of stalactites asymmetric
  174. _, D, D, -- ypos 10, prob 50% (128/256) to make half of stalactites asymmetric
  175. _, D, D, -- ypos 11, prob 50% (128/256) to make half of stalactites asymmetric
  176. _, D, D, -- ypos 12, prob 50% (128/256) to make half of stalactites asymmetric
  177. D, D, D, -- ypos 13, prob 75% (192/256)
  178. D, D, D, -- ypos 14, prob 75% (192/256)
  179. D, D, D, -- ypos 15, prob 100%
  180. D, D, D, -- ypos 16, prob 100%
  181. D, D, D, -- ypos 17, prob 100%
  182. D, D, D, -- ypos 18, prob 100%
  183. D, D, D, -- ypos 19, prob 75% (192/256)
  184. D, D, D, -- ypos 20, prob 85% (218/255)
  185. _, D, D, -- ypos 21, prob 50% (128/256) to make half of stalactites asymmetric
  186. _, D, _, -- ypos 22, prob 100%
  187. _, _, _,
  188. _, _, _,
  189. _, _, _,
  190. _, _, _,
  191. _, _, _,
  192. _, _, _,
  193. _, _, _,
  194. _, _, _,
  195. _, _, _,
  196. _, _, _,
  197. _, _, _,
  198. _, _, _,
  199. _, D, _,
  200. _, D, _,
  201. _, D, _,
  202. _, D, _,
  203. _, D, _,
  204. D, D, D,
  205. D, D, D,
  206. D, D, D,
  207. _, D, _,
  208. _, D, _,
  209. _, _, _,
  210. },
  211. -- Y-slice probabilities do not function correctly for ceiling schematic
  212. -- decorations because they are inverted, so ypos numbers have been inverted
  213. -- to match, and a larger offset in place_offset_y should be used (e.g. -3).
  214. yslice_prob = {
  215. {ypos = 21, prob = 128},
  216. {ypos = 20, prob = 218},
  217. {ypos = 19, prob = 192},
  218. {ypos = 14, prob = 192},
  219. {ypos = 13, prob = 192},
  220. {ypos = 12, prob = 128},
  221. {ypos = 11, prob = 128},
  222. {ypos = 10, prob = 128},
  223. {ypos = 9, prob = 128},
  224. {ypos = 8, prob = 218},
  225. {ypos = 7, prob = 218},
  226. {ypos = 6, prob = 218},
  227. {ypos = 5, prob = 218},
  228. {ypos = 4, prob = 218},
  229. {ypos = 3, prob = 218},
  230. {ypos = 2, prob = 218},
  231. {ypos = 1, prob = 218},
  232. {ypos = 0, prob = 218}
  233. }
  234. }
  235. -- A stalagmite is an upsidedown stalactite, so
  236. -- use the GreaterStalactite to create a ToweringStalagmite schematic
  237. local schematic_ToweringStalagmite = {
  238. size = schematic_GreaterStalactite.size,
  239. data = {},
  240. yslice_prob = {}
  241. }
  242. local array_length = #schematic_GreaterStalactite.data + 1
  243. for i, node in ipairs(schematic_GreaterStalactite.data) do
  244. schematic_ToweringStalagmite.data[array_length - i] = node
  245. end
  246. y_size = schematic_GreaterStalactite.size.y
  247. for i, node in ipairs(schematic_GreaterStalactite.yslice_prob) do
  248. schematic_ToweringStalagmite.yslice_prob[i] = {
  249. -- we can safely lower the prob. to gain more variance because floor based schematics
  250. -- don't have the bug where missing lines moves them away from the surface
  251. prob = schematic_GreaterStalactite.yslice_prob[i].prob - 20,
  252. ypos = y_size - 1 - schematic_GreaterStalactite.yslice_prob[i].ypos
  253. }
  254. end
  255. minetest.register_decoration({
  256. name = "Deep-glowstone stalactite",
  257. deco_type = "schematic",
  258. place_on = "nether:rack_deep",
  259. sidelen = 80,
  260. fill_ratio = 0.0003,
  261. biomes = {"nether_caverns"},
  262. y_max = decoration_ceiling,
  263. y_min = decoration_floor,
  264. schematic = schematic_GlowstoneStalactite,
  265. replacements = {["nether:rack"] = "nether:rack_deep", ["nether:glowstone"] = "nether:glowstone_deep"},
  266. flags = "place_center_x,place_center_z,force_placement,all_ceilings",
  267. place_offset_y=-3
  268. })
  269. minetest.register_decoration({
  270. name = "Deep-glowstone stalactite outgrowth",
  271. deco_type = "schematic",
  272. place_on = "nether:glowstone_deep",
  273. sidelen = 40,
  274. fill_ratio = 0.15,
  275. biomes = {"nether_caverns"},
  276. y_max = decoration_ceiling,
  277. y_min = decoration_floor,
  278. schematic = {
  279. size = {x = 1, y = 4, z = 1},
  280. data = { G, G, G, G }
  281. },
  282. replacements = {["nether:glowstone"] = "nether:glowstone_deep"},
  283. flags = "place_center_x,place_center_z,all_ceilings",
  284. })
  285. minetest.register_decoration({
  286. name = "Deep-netherrack stalactite",
  287. deco_type = "schematic",
  288. place_on = "nether:rack_deep",
  289. sidelen = 80,
  290. fill_ratio = 0.0003,
  291. biomes = {"nether_caverns"},
  292. y_max = decoration_ceiling,
  293. y_min = decoration_floor,
  294. schematic = schematic_GlowstoneStalactite,
  295. replacements = {["nether:rack"] = "nether:rack_deep", ["nether:glowstone"] = "nether:rack_deep"},
  296. flags = "place_center_x,place_center_z,force_placement,all_ceilings",
  297. place_offset_y=-3
  298. })
  299. minetest.register_decoration({
  300. name = "Deep-netherrack towering stalagmite",
  301. deco_type = "schematic",
  302. place_on = "nether:rack_deep",
  303. sidelen = 80,
  304. fill_ratio = 0.001,
  305. biomes = {"nether_caverns"},
  306. y_max = decoration_ceiling,
  307. y_min = decoration_floor,
  308. schematic = schematic_ToweringStalagmite,
  309. replacements = {["nether:basalt"] = "nether:rack_deep"},
  310. flags = "place_center_x,place_center_z,force_placement,all_floors",
  311. place_offset_y=-2
  312. })
  313. -- =======================================
  314. -- Concealed crevice / Lava sinkhole
  315. -- =======================================
  316. -- if player places a torch/block on this sand or digs it while standing on it, it sinks into lava
  317. if allow_lava_decorations then
  318. minetest.register_decoration({
  319. name = "Weak trap",
  320. deco_type = "schematic",
  321. place_on = "nether:rack",
  322. sidelen = 80,
  323. fill_ratio = 0.002,
  324. biomes = {"nether_caverns"},
  325. y_max = decoration_ceiling,
  326. y_min = decoration_floor,
  327. schematic = {
  328. size = {x = 4, y = 7, z = 4},
  329. data = { -- note that data is upside down
  330. _, _, _, _,
  331. _, _, _, _,
  332. _, N, _, _,
  333. _, N, N, _,
  334. _, N, N, _,
  335. _, N, N, _,
  336. _, _, _, _,
  337. _, N, _, _, -- make it look like a stalactite if it protrudes out the bottom of a landform
  338. _, N, _, _,
  339. N, L, N, _,
  340. N, L, L, N,
  341. N, L, L, N,
  342. N, A, A, N,
  343. _, S, S, _,
  344. _, _, _, _,
  345. _, _, _, _,
  346. _, N, N, _,
  347. N, L, L, N,
  348. N, L, L, N,
  349. N, A, A, N,
  350. _, S, S, _,
  351. _, _, _, _,
  352. _, _, _, _,
  353. _, _, _, _,
  354. _, N, N, _,
  355. _, N, N, _,
  356. _, N, N, _,
  357. _, _, _, _,
  358. }
  359. },
  360. replacements = {["nether:glowstone"] = "nether:rack"},
  361. flags = "place_center_x,place_center_z,force_placement, all_floors",
  362. place_offset_y=-6,
  363. rotation = "random"
  364. })
  365. end
  366. -- ==========================
  367. -- Fumaroles (Chimneys)
  368. -- ==========================
  369. local replacements_slab = {}
  370. local replacements_full = {["nether:fumarole_slab"] = "nether:fumarole"}
  371. if allow_lava_decorations then
  372. -- Minetest engine limitations mean any mesh or nodebox node (like nether:fumarole)
  373. -- will light up if it has lava below it, so replace the air node over the lava with
  374. -- a node that prevents light propagation.
  375. -- (Unfortunately this also means if a player digs down to get the lava block it'll
  376. -- look like the lighting wasn't set in the block above the lava)
  377. replacements_slab["air"] = "nether:airlike_darkness"
  378. replacements_full["air"] = "nether:airlike_darkness"
  379. else
  380. -- Lava is frequently removed by the old mapgen, so put sand at the bottom
  381. -- of fumaroles.
  382. replacements_slab["default:lava_source"] = "nether:sand"
  383. replacements_full["default:lava_source"] = "nether:sand"
  384. end
  385. local schematic_fumarole = {
  386. size = {x = 3, y = 5, z = 3},
  387. data = { -- note that data is upside down
  388. _, _, _,
  389. _, N, _,
  390. _, N, _,
  391. _, _, _,
  392. _, _, _,
  393. _, N, _,
  394. N, L, N,
  395. N, A, N,
  396. _, F, _,
  397. _,FS, _,
  398. _, _, _,
  399. _, N, _,
  400. _, N, _,
  401. _, _, _,
  402. _, _, _,
  403. },
  404. }
  405. -- Common fumarole decoration that's flush with the floor and spawns everywhere
  406. minetest.register_decoration({
  407. name = "Sunken nether fumarole",
  408. deco_type = "schematic",
  409. place_on = {"nether:rack"},
  410. sidelen = 80,
  411. fill_ratio = 0.005,
  412. biomes = {"nether_caverns"},
  413. y_max = decoration_ceiling,
  414. y_min = decoration_floor,
  415. schematic = schematic_fumarole,
  416. replacements = replacements_full,
  417. flags = "place_center_x,place_center_z,all_floors",
  418. place_offset_y=-4
  419. })
  420. -- Rarer formations of raised fumaroles in clumps
  421. local fumarole_clump_noise_offset = -0.58
  422. local fumarole_clump_noise = {
  423. offset = fumarole_clump_noise_offset,
  424. scale = 0.5,
  425. spread = {x = 40, y = 40, z = 15},
  426. octaves = 4,
  427. persist = 0.65,
  428. lacunarity = 2.0,
  429. }
  430. fumarole_clump_noise.offset = fumarole_clump_noise_offset - 0.035
  431. minetest.register_decoration({
  432. name = "Raised Nether fumarole",
  433. deco_type = "schematic",
  434. place_on = {"nether:rack"},
  435. sidelen = 8,
  436. noise_params = fumarole_clump_noise,
  437. biomes = {"nether_caverns"},
  438. y_max = decoration_ceiling,
  439. y_min = decoration_floor,
  440. schematic = schematic_fumarole,
  441. replacements = replacements_full,
  442. flags = "place_center_x,place_center_z,all_floors",
  443. place_offset_y=-3
  444. })
  445. fumarole_clump_noise.offset = fumarole_clump_noise_offset
  446. minetest.register_decoration({
  447. name = "Half-raised Nether fumarole",
  448. deco_type = "schematic",
  449. place_on = {"nether:rack"},
  450. sidelen = 8,
  451. noise_params = fumarole_clump_noise,
  452. biomes = {"nether_caverns"},
  453. y_max = decoration_ceiling,
  454. y_min = decoration_floor,
  455. schematic = schematic_fumarole,
  456. replacements = replacements_slab,
  457. flags = "place_center_x,place_center_z,all_floors",
  458. place_offset_y=-3
  459. })
  460. fumarole_clump_noise.offset = fumarole_clump_noise_offset - 0.035
  461. minetest.register_decoration({
  462. name = "Nether fumarole mound",
  463. deco_type = "schematic",
  464. place_on = {"nether:rack"},
  465. sidelen = 8,
  466. noise_params = fumarole_clump_noise,
  467. biomes = {"nether_caverns"},
  468. y_max = decoration_ceiling,
  469. y_min = decoration_floor,
  470. schematic = {
  471. size = {x = 4, y = 4, z = 4},
  472. data = { -- note that data is upside down
  473. _, _, _, _,
  474. _, N, N, _,
  475. _, _, _, _,
  476. _, _, _, _,
  477. _, S, S, _,
  478. N, A, A, N,
  479. _, S2, S1, _,
  480. _, F2, F1, _,
  481. _, S, S, _,
  482. N, A, A, N,
  483. _, S3, S4, _,
  484. _, F3, F4, _,
  485. _, _, _, _,
  486. _, N, N, _,
  487. _, _, _, _,
  488. _, _, _, _
  489. },
  490. yslice_prob = {{ypos = 3, prob = 192}} -- occasionally leave the fumarole cap off
  491. },
  492. flags = "place_center_x,place_center_z,all_floors",
  493. place_offset_y = -2
  494. })
  495. fumarole_clump_noise.offset = fumarole_clump_noise_offset - 0.01
  496. minetest.register_decoration({
  497. name = "Double Nether fumarole",
  498. deco_type = "schematic",
  499. place_on = {"nether:rack"},
  500. sidelen = 8,
  501. noise_params = fumarole_clump_noise,
  502. biomes = {"nether_caverns"},
  503. y_max = decoration_ceiling,
  504. y_min = decoration_floor,
  505. schematic = {
  506. size = {x = 4, y = 5, z = 4},
  507. data = { -- note that data is upside down
  508. _, _, _, _,
  509. _, N, N, _,
  510. _, _, _, _,
  511. _, _, _, _,
  512. _, _, _, _,
  513. _, S, S, _,
  514. N, A, A, N,
  515. _, S2, S1, _,
  516. _, F2, F, _,
  517. _, _, FS, _,
  518. _, S, S, _,
  519. F, A, A, N, -- the F may add slight variance in landforms where it gets exposed
  520. _, S3, S4, _,
  521. _, F3, F4, _,
  522. _, _, _, _,
  523. _, _, _, _,
  524. _, N, N, _,
  525. _, _, _, _,
  526. _, _, _, _,
  527. _, _, _, _
  528. }
  529. },
  530. flags = "place_center_x,place_center_z,all_floors",
  531. place_offset_y = -2,
  532. rotation = "random"
  533. })