init.lua 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. caverealms = {} --create a container for functions and constants
  2. --grab a shorthand for the filepath of the mod
  3. local modpath = minetest.get_modpath(minetest.get_current_modname())
  4. --load companion lua files
  5. dofile(modpath .. "/config.lua") --configuration file; holds various constants
  6. dofile(modpath .. "/crafting.lua") --crafting recipes
  7. dofile(modpath .. "/nodes.lua") --node definitions
  8. dofile(modpath .. "/plants.lua")
  9. dofile(modpath .. "/functions.lua") --function definitions
  10. if minetest.get_modpath("mobs_monster") then
  11. if caverealms.config.dm_spawn == true then
  12. dofile(modpath .. "/dungeon_master.lua") --special DMs for DM's Lair biome
  13. end
  14. end
  15. -- Parameters
  16. local YMIN = caverealms.config.ymin -- Approximate realm limits.
  17. local YMAX = caverealms.config.ymax
  18. local TCAVE = caverealms.config.tcave --0.5 -- Cave threshold. 1 = small rare caves, 0.5 = 1/3rd ground volume, 0 = 1/2 ground volume
  19. local BLEND = 128 -- Cave blend distance near YMIN, YMAX
  20. local STAGCHA = caverealms.config.stagcha --0.002 --chance of stalagmites
  21. local STALCHA = caverealms.config.stalcha --0.003 --chance of stalactites
  22. local CRYSTAL = caverealms.config.crystal --0.007 --chance of glow crystal formations
  23. local GEMCHA = caverealms.config.gemcha --0.03 --chance of small glow gems
  24. local MUSHCHA = caverealms.config.mushcha --0.04 --chance of mushrooms
  25. local MYCCHA = caverealms.config.myccha --0.03 --chance of mycena mushrooms
  26. local WORMCHA = caverealms.config.wormcha --0.03 --chance of glow worms
  27. local GIANTCHA = caverealms.config.giantcha --0.001 -- chance of giant mushrooms
  28. local ICICHA = caverealms.config.icicha --0.035 -- chance of icicles
  29. local FLACHA = caverealms.config.flacha --0.04 --chance of constant flames
  30. local DM_TOP = caverealms.config.dm_top -- -4000 --level at which Dungeon Master Realms start to appear
  31. local DM_BOT = caverealms.config.dm_bot -- -5000 --level at which "" ends
  32. local DEEP_CAVE = caverealms.config.deep_cave -- -7000 --level at which deep cave biomes take over
  33. -- 2D noise for biome
  34. local np_biome = {
  35. offset = 0,
  36. scale = 1,
  37. spread = {x = 200, y = 200, z = 200},
  38. seed = 9130,
  39. octaves = 3,
  40. persist = 0.5
  41. }
  42. -- Stuff
  43. subterrain = {}
  44. local random = math.random
  45. -- Content IDs
  46. local c_air = minetest.get_content_id("air")
  47. local c_stone = minetest.get_content_id("default:stone")
  48. local c_water = minetest.get_content_id("default:water_source")
  49. local c_lava = minetest.get_content_id("default:lava_source")
  50. local c_ice = minetest.get_content_id("default:ice")
  51. local c_thinice = minetest.get_content_id("caverealms:thin_ice")
  52. local c_crystal = minetest.get_content_id("caverealms:glow_crystal")
  53. local c_gem1 = minetest.get_content_id("caverealms:glow_gem")
  54. local c_saltgem1 = minetest.get_content_id("caverealms:salt_gem")
  55. local c_spike1 = minetest.get_content_id("caverealms:spike")
  56. local c_moss = minetest.get_content_id("caverealms:stone_with_moss")
  57. local c_lichen = minetest.get_content_id("caverealms:stone_with_lichen")
  58. local c_algae = minetest.get_content_id("caverealms:stone_with_algae")
  59. local c_salt = minetest.get_content_id("caverealms:stone_with_salt")
  60. local c_hcobble = minetest.get_content_id("caverealms:hot_cobble")
  61. local c_gobsidian = minetest.get_content_id("caverealms:glow_obsidian")
  62. local c_gobsidian2 = minetest.get_content_id("caverealms:glow_obsidian_2")
  63. local c_coalblock = minetest.get_content_id("default:coalblock")
  64. local c_desand = minetest.get_content_id("default:desert_sand")
  65. local c_coaldust = minetest.get_content_id("caverealms:coal_dust")
  66. local c_fungus = minetest.get_content_id("caverealms:fungus")
  67. local c_mycena = minetest.get_content_id("caverealms:mycena")
  68. local c_worm = minetest.get_content_id("caverealms:glow_worm")
  69. local c_worm_green = minetest.get_content_id("caverealms:glow_worm_green")
  70. local c_fire_vine = minetest.get_content_id("caverealms:fire_vine")
  71. local c_iciu = minetest.get_content_id("caverealms:icicle_up")
  72. local c_icid = minetest.get_content_id("caverealms:icicle_down")
  73. local c_flame = minetest.get_content_id("fire:permanent_flame")
  74. -- On generated function
  75. minetest.register_on_generated(function(minp, maxp, seed)
  76. --if out of range of caverealms limits
  77. if minp.y > YMAX or maxp.y < YMIN then
  78. return --quit; otherwise, you'd have stalagmites all over the place
  79. end
  80. --easy reference to commonly used values
  81. local t1 = os.clock()
  82. local x1 = maxp.x
  83. local y1 = maxp.y
  84. local z1 = maxp.z
  85. local x0 = minp.x
  86. local y0 = minp.y
  87. local z0 = minp.z
  88. --print ("[caverealms] chunk minp ("..x0.." "..y0.." "..z0..")") --tell people you are generating a chunk
  89. local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
  90. local area = VoxelArea:new{MinEdge = emin, MaxEdge = emax}
  91. local data = vm:get_data()
  92. --mandatory values
  93. local sidelen = x1 - x0 + 1 --length of a mapblock
  94. local chulens = {x = sidelen, y = sidelen, z = sidelen} --table of chunk edges
  95. local chulens2D = {x = sidelen, y = sidelen, z = 1}
  96. local minposxyz = {x = x0, y = y0, z = z0} --bottom corner
  97. local minposxz = {x = x0, y = z0} --2D bottom corner
  98. --2D noise for biomes (will be 3D humidity/temp later)
  99. local nvals_biome = minetest.get_perlin_map(np_biome,
  100. chulens2D):get_2d_map_flat({x = x0 + 150, y = z0 + 50})
  101. local nixyz = 1 --3D node index
  102. local nixz = 1 --2D node index
  103. local nixyz2 = 1 --second 3D index for second loop
  104. local vi, ai, bi, bbi, bbbi, c_selected_worm, is_deep
  105. local biome, n_biome, gems, gidx, spikes, sidx
  106. for z = z0, z1 do -- for each xy plane progressing northwards
  107. --increment indices
  108. nixyz = nixyz + 1
  109. --decoration loop
  110. for y = y0, y1 do -- for each x row progressing upwards
  111. c_selected_worm = c_worm
  112. is_deep = false
  113. if y < DEEP_CAVE then
  114. is_deep = true
  115. end
  116. vi = area:index(x0, y, z)
  117. for x = x0, x1 do -- for each node do
  118. --determine biome
  119. biome = 0 --preliminary declaration
  120. n_biome = nvals_biome[nixz] --make an easier reference to the noise
  121. --compare noise values to determine a biome
  122. if n_biome <= -0.5 then
  123. if is_deep and n_biome <= -0.25 then
  124. biome = 8 --glow obsidian
  125. else
  126. biome = 2 --fungal
  127. c_selected_worm = c_worm_green
  128. end
  129. elseif n_biome < 0 then
  130. biome = 0 -- none
  131. elseif n_biome < 0.5 then
  132. if is_deep and n_biome <= 0.25 then
  133. biome = 7 --salt crystal
  134. else
  135. biome = 1 --moss
  136. end
  137. elseif n_biome < 0.65 then
  138. biome = 0
  139. elseif n_biome < 0.85 then
  140. if is_deep and n_biome <= 0.75 then
  141. biome = 9 --coal dust
  142. else
  143. biome = 3 --algae
  144. c_selected_worm = c_worm_green
  145. end
  146. else
  147. if is_deep and n_biome <= 0.95 then
  148. biome = 5 --deep glaciated
  149. else
  150. biome = 4 --glaciated
  151. end
  152. end
  153. --print(biome)
  154. if biome > 0 then
  155. if y <= DM_TOP and y >= DM_BOT then
  156. biome = 6 --DUNGEON MASTER'S LAIR
  157. c_selected_worm = c_fire_vine
  158. end
  159. --ceiling
  160. ai = area:index(x,y + 1,z) --above index
  161. if data[ai] == c_stone and data[vi] == c_air then --ceiling
  162. if random() < ICICHA and (biome == 4 or biome == 5) then
  163. data[vi] = c_icid
  164. end
  165. if random() < WORMCHA then
  166. data[vi] = c_selected_worm
  167. bi = area:index(x, y - 1, z)
  168. data[bi] = c_selected_worm
  169. if random(2) == 1 then
  170. bbi = area:index(x, y - 2, z)
  171. data[bbi] = c_selected_worm
  172. if random(2) ==1 then
  173. bbbi = area:index(x, y - 3, z)
  174. data[bbbi] = c_selected_worm
  175. end
  176. end
  177. end
  178. if random() < STALCHA then
  179. caverealms:stalactite(x, y, z, area, data)
  180. end
  181. if random() < CRYSTAL then
  182. caverealms:crystal_stalactite(x, y, z, area, data, biome)
  183. end
  184. end
  185. --ground
  186. bi = area:index(x, y - 1, z) --below index
  187. if data[bi] == c_stone and data[vi] == c_air then --ground
  188. ai = area:index(x, y + 1, z)
  189. --place floor material, add plants/decorations
  190. if biome == 1 then
  191. data[vi] = c_moss
  192. if random() < GEMCHA then
  193. data[ai] = c_gem1
  194. end
  195. elseif biome == 2 then
  196. data[vi] = c_lichen
  197. if random() < MUSHCHA then --mushrooms
  198. data[ai] = c_fungus
  199. end
  200. if random() < MYCCHA then --mycena mushrooms
  201. data[ai] = c_mycena
  202. end
  203. if random() < GIANTCHA then --giant mushrooms
  204. caverealms:giant_shroom(x, y, z, area, data)
  205. end
  206. elseif biome == 3 then
  207. data[vi] = c_algae
  208. elseif biome == 4 then
  209. data[vi] = c_thinice
  210. bi = area:index(x, y - 1, z)
  211. data[bi] = c_thinice
  212. if random() < ICICHA then --if glaciated, place icicles
  213. data[ai] = c_iciu
  214. end
  215. elseif biome == 5 then
  216. data[vi] = c_ice
  217. bi = area:index(x, y - 1, z)
  218. data[bi] = c_ice
  219. if random() < ICICHA then --if glaciated, place icicles
  220. data[ai] = c_iciu
  221. end
  222. elseif biome == 6 then
  223. data[vi] = c_hcobble
  224. if random() < FLACHA then --neverending flames
  225. data[ai] = c_flame
  226. end
  227. elseif biome == 7 then
  228. bi = area:index(x, y - 1, z)
  229. data[vi] = c_salt
  230. data[bi] = c_salt
  231. if random() < GEMCHA then
  232. data[ai] = c_saltgem1
  233. end
  234. if random() < STAGCHA then
  235. caverealms:salt_stalagmite(x, y, z, area, data)
  236. end
  237. elseif biome == 8 then
  238. bi = area:index(x, y - 1, z)
  239. if random() < 0.5 then
  240. data[vi] = c_gobsidian
  241. data[bi] = c_gobsidian
  242. else
  243. data[vi] = c_gobsidian2
  244. data[bi] = c_gobsidian2
  245. end
  246. if random() < FLACHA then --neverending flames
  247. data[ai] = c_flame
  248. end
  249. elseif biome == 9 then
  250. bi = area:index(x, y - 1, z)
  251. if random() < 0.05 then
  252. data[vi] = c_coalblock
  253. data[bi] = c_coalblock
  254. elseif random() < 0.15 then
  255. data[vi] = c_coaldust
  256. data[bi] = c_coaldust
  257. else
  258. data[vi] = c_desand
  259. data[bi] = c_desand
  260. end
  261. if random() < FLACHA * 0.75 then --neverending flames
  262. data[ai] = c_flame
  263. end
  264. if random() < GEMCHA then
  265. data[ai] = c_spike1
  266. end
  267. end
  268. if random() < STAGCHA then
  269. caverealms:stalagmite(x, y, z, area, data)
  270. end
  271. if random() < CRYSTAL then
  272. caverealms:crystal_stalagmite(x, y, z, area, data, biome)
  273. end
  274. end
  275. end
  276. nixyz2 = nixyz2 + 1
  277. nixz = nixz + 1
  278. vi = vi + 1
  279. end
  280. nixz = nixz - sidelen --shift the 2D index back
  281. end
  282. nixz = nixz + sidelen --shift the 2D index up a layer
  283. end
  284. --send data back to voxelmanip
  285. vm:set_data(data)
  286. --calc lighting
  287. vm:set_lighting({day = 0, night = 0})
  288. vm:calc_lighting()
  289. --write it to world
  290. vm:write_to_map(data)
  291. -- vm:update_map()
  292. --local chugent = math.ceil((os.clock() - t1) * 1000) --grab how long it took
  293. --print ("[caverealms] "..chugent.." ms") --tell people how long
  294. end)
  295. print("[caverealms] loaded!")