mapgen_decorations.lua 19 KB

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