init.lua 11 KB

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