hotsprings.lua 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. minetest.register_node("potions:hotspring_seed", {
  2. description = "Hotspring seed",
  3. drawtype = "node",
  4. tiles = {"default_mese.png"},
  5. groups = {cracky=3,},
  6. })
  7. minetest.register_node("potions:sulphur_deposit_1", {
  8. description = "Sulphur",
  9. paramtype = "light",
  10. paramtype2 = "facedir",
  11. drawtype = "nodebox",
  12. tiles = {"default_silver_sandstone.png^[colorize:yellow:140"},
  13. -- drops = {},
  14. node_box = {
  15. type = "fixed",
  16. fixed = {
  17. {-.3, -.5, -.3, -0.1, -.45, -0.1},
  18. {.3, -.5, .3, 0.1, -.45, 0.1,},
  19. {-.3, -.5, .3, -0.1, -.45, 0.1},
  20. },
  21. },
  22. groups = {cracky=3, geode_wall = 1 },
  23. })
  24. minetest.register_node("potions:fumarole", {
  25. description = "Fumarole",
  26. paramtype = "light",
  27. paramtype2 = "facedir",
  28. drawtype = "nodebox",
  29. tiles = {"default_stone.png^[colorize:black:10"},
  30. drop = 'default:cobble',
  31. damage_per_second = 3,
  32. node_box = {
  33. type = "fixed",
  34. fixed = {
  35. {-.4, -.5, -.4, 0.3, -.4, 0.3},
  36. {-.3+.05, -.4, -.3+.05, 0.2+.05, -.3, 0.2+.05},
  37. {-.2+.08, -.3, -.2+.08, 0.1+.08, -.2, 0.1+.08},
  38. },
  39. },
  40. groups = {cracky=3, },
  41. })
  42. minetest.register_abm({
  43. nodenames = "potions:fumarole",
  44. chance = 1,
  45. interval = 20,
  46. action = function(pos, node)
  47. pos.y = pos.y + 0
  48. minetest.add_particlespawner({
  49. amount = 20,
  50. time = 20,
  51. minpos = pos,
  52. maxpos = pos,
  53. minvel = {x=-0.1, y=.6, z=-0.1},
  54. maxvel = {x=0.1, y=1.6, z=0.1},
  55. minacc = {x=-0.1, y=.1, z=-0.1},
  56. maxacc = {x=0.1, y=.1, z=0.1},
  57. minexptime = 2.5,
  58. maxexptime = 4.5,
  59. minsize = 4.2,
  60. maxsize = 5.2,
  61. texture = "tnt_smoke.png",
  62. })
  63. end
  64. })
  65. minetest.register_node("potions:hotspring_water_source", {
  66. description = "Hotspring Water Source",
  67. drawtype = "liquid",
  68. tiles = {
  69. {
  70. name = "default_river_water_source_animated.png^[colorize:yellow:50",
  71. backface_culling = false,
  72. animation = {
  73. type = "vertical_frames",
  74. aspect_w = 16,
  75. aspect_h = 16,
  76. length = 2.0,
  77. },
  78. },
  79. {
  80. name = "default_river_water_source_animated.png^[colorize:yellow:50",
  81. backface_culling = true,
  82. animation = {
  83. type = "vertical_frames",
  84. aspect_w = 16,
  85. aspect_h = 16,
  86. length = 2.0,
  87. },
  88. },
  89. },
  90. alpha = 160,
  91. paramtype = "light",
  92. walkable = false,
  93. pointable = false,
  94. diggable = false,
  95. buildable_to = true,
  96. is_ground_content = false,
  97. drop = "",
  98. drowning = 1,
  99. liquidtype = "source",
  100. liquid_alternative_flowing = "potions:hotspring_water_flowing",
  101. liquid_alternative_source = "potions:hotspring_water_source",
  102. liquid_viscosity = 1,
  103. -- Not renewable to avoid horizontal spread of water sources in sloping
  104. -- rivers that can cause water to overflow riverbanks and cause floods.
  105. -- River water source is instead made renewable by the 'force renew'
  106. -- option used in the 'bucket' mod by the river water bucket.
  107. liquid_renewable = false,
  108. liquid_range = 2,
  109. damage_per_second = 1,
  110. post_effect_color = {a = 103, r = 60, g = 96, b = 90},
  111. groups = {water = 3, liquid = 3, cools_lava = 1},
  112. sounds = default.node_sound_water_defaults(),
  113. })
  114. minetest.register_node("potions:hotspring_water_flowing", {
  115. description = "Flowing Hotspring Water",
  116. drawtype = "flowingliquid",
  117. tiles = {"default_river_water.png^[colorize:yellow:50"},
  118. special_tiles = {
  119. {
  120. name = "default_river_water_flowing_animated.png^[colorize:yellow:50",
  121. backface_culling = false,
  122. animation = {
  123. type = "vertical_frames",
  124. aspect_w = 16,
  125. aspect_h = 16,
  126. length = 0.8,
  127. },
  128. },
  129. {
  130. name = "default_river_water_flowing_animated.png^[colorize:yellow:50",
  131. backface_culling = true,
  132. animation = {
  133. type = "vertical_frames",
  134. aspect_w = 16,
  135. aspect_h = 16,
  136. length = 0.8,
  137. },
  138. },
  139. },
  140. alpha = 160,
  141. paramtype = "light",
  142. paramtype2 = "flowingliquid",
  143. walkable = false,
  144. pointable = false,
  145. diggable = false,
  146. buildable_to = true,
  147. is_ground_content = false,
  148. drop = "",
  149. drowning = 1,
  150. liquidtype = "flowing",
  151. liquid_alternative_flowing = "potions:hotspring_water_flowing",
  152. liquid_alternative_source = "potions:hotspring_water_source",
  153. liquid_viscosity = 1,
  154. liquid_renewable = false,
  155. liquid_range = 2,
  156. damage_per_second = 1,
  157. post_effect_color = {a = 103, r = 60, g = 96, b = 90},
  158. groups = {water = 3, liquid = 3, not_in_creative_inventory = 1,
  159. cools_lava = 1},
  160. sounds = default.node_sound_water_defaults(),
  161. })
  162. minetest.register_node("potions:scalding_stone_1", {
  163. description = "Scalding Stone",
  164. tiles = {"default_stone.png^[colorize:orange:120"},
  165. groups = {cracky = 3, scalding_stone = 1},
  166. drop = 'default:cobble',
  167. damage_per_second = 1,
  168. sounds = default.node_sound_stone_defaults(),
  169. })
  170. minetest.register_node("potions:scalding_stone_2", {
  171. description = "Scalding Stone",
  172. tiles = {"default_stone.png^[colorize:yellow:80"},
  173. groups = {cracky = 3, scalding_stone = 1},
  174. drop = 'default:cobble',
  175. damage_per_second = 1,
  176. sounds = default.node_sound_stone_defaults(),
  177. })
  178. minetest.register_node("potions:scalding_stone_3", {
  179. description = "Scalding Stone",
  180. tiles = {"default_desert_stone.png^[colorize:orange:120"},
  181. groups = {cracky = 3, scalding_stone = 1},
  182. drop = 'default:cobble',
  183. damage_per_second = 1,
  184. sounds = default.node_sound_stone_defaults(),
  185. })
  186. minetest.register_node("potions:scalding_stone_4", {
  187. description = "Scalding Stone",
  188. tiles = {"default_desert_stone.png^[colorize:yellow:80"},
  189. groups = {cracky = 3, scalding_stone = 1},
  190. drop = 'default:cobble',
  191. damage_per_second = 1,
  192. sounds = default.node_sound_stone_defaults(),
  193. })
  194. minetest.register_node("potions:scalding_stone_5", {
  195. description = "Scalding Stone",
  196. tiles = {"default_stone.png^[colorize:red:80"},
  197. groups = {cracky = 3, scalding_stone = 1},
  198. drop = 'default:cobble',
  199. damage_per_second = 1,
  200. sounds = default.node_sound_stone_defaults(),
  201. })
  202. local scalding_stones = {
  203. "potions:scalding_stone_1",
  204. "potions:scalding_stone_2",
  205. "potions:scalding_stone_3",
  206. "potions:scalding_stone_4",
  207. "potions:scalding_stone_5",
  208. }
  209. local function dist3(a, b)
  210. local x = a.x - b.x
  211. local y = a.y - b.y
  212. local z = a.z - b.z
  213. return math.sqrt(x*x + y*y + z*z)
  214. end
  215. local function spawn_hotspring(pos, size)
  216. -- hotsprings don't spawn near forests
  217. if minetest.find_node_near(pos, 20, {"group:tree"}) then
  218. return
  219. end
  220. local r = size
  221. local r2 = math.ceil(r+1)
  222. for x = pos.x-r2,pos.x+r2,1 do
  223. for y = -r2,r2,1 do
  224. for z = pos.z-r2,pos.z+r2,1 do
  225. local p = {x=x, y=pos.y+y, z=z}
  226. local p_squash = {x=x, y=pos.y + (y*2), z=z}
  227. local d = dist3(p_squash, pos)
  228. d = d + math.random() * .5
  229. local dd = d - r
  230. local n = minetest.get_node(p)
  231. if n.name ~= "air" then
  232. if dd <= -.5 then
  233. minetest.set_node(p, {name = "potions:hotspring_water_source"})
  234. elseif dd < 1 then
  235. minetest.set_node(p, {name = scalding_stones[math.random(#scalding_stones)]})
  236. -- minetest.get_node_timer(p):start(1)
  237. elseif dd <= 1.8 then
  238. minetest.set_node(p, {name = "default:stone"})
  239. else
  240. -- minetest.set_node(p, {name = "default:stone"})
  241. end
  242. end
  243. end
  244. end
  245. end
  246. end
  247. minetest.register_abm({
  248. nodenames = "potions:hotspring_water_source",
  249. chance = 60,
  250. interval = 5,
  251. action = function(pos, node)
  252. minetest.add_particlespawner({
  253. amount = 1,
  254. time = 1,
  255. minpos = pos,
  256. maxpos = pos,
  257. minvel = {x=-0.1, y=.6, z=-0.1},
  258. maxvel = {x=0.1, y=1.6, z=0.1},
  259. minacc = {x=-0.1, y=.1, z=-0.1},
  260. maxacc = {x=0.1, y=.1, z=0.1},
  261. minexptime = 3.5,
  262. maxexptime = 6.5,
  263. minsize = 10.2,
  264. maxsize = 12.2,
  265. texture = "tnt_smoke.png",
  266. })
  267. end
  268. })
  269. local function random_pos(pos, dist)
  270. local p = {
  271. x=pos.x + math.random(-dist, dist),
  272. y=pos.y + dist,
  273. z=pos.z + math.random(-dist, dist),
  274. }
  275. while p.y > pos.y - dist do
  276. local n = minetest.get_node(p)
  277. if n.name ~= "air" and n.name ~= "ignore" then
  278. if n.name == "default:water_source" or n.name == "default:water_flowing" then
  279. return nil
  280. end
  281. return p
  282. end
  283. p.y = p.y - 1
  284. end
  285. return nil
  286. end
  287. minetest.register_abm({
  288. name = "potions:hotspring_tester",
  289. nodenames = "potions:hotspring_seed",
  290. chance = 1,
  291. interval = 5,
  292. action = function(pos, node)
  293. minetest.after(2, function()
  294. minetest.set_node(pos, {name="air"})
  295. -- spawn with greater frequency the farther we get from the origin
  296. local max_penalty = 20
  297. local ramp_dist = 10000
  298. local origind = math.sqrt(pos.x*pos.x + pos.z*pos.z)
  299. local penalty = math.min(max_penalty, max_penalty * (1 - (origind / ramp_dist)))
  300. -- random bail here
  301. if math.random(10 + penalty) > 1 then
  302. return
  303. end
  304. for i = 1,(math.random(3) + 1) do
  305. spawn_hotspring(random_pos(pos, 10), math.random(3) + 3)
  306. end
  307. for i = 1,(math.random(6) + 2) do
  308. spawn_hotspring(random_pos(pos, 20), math.random(2) + 1)
  309. end
  310. end)
  311. end
  312. })
  313. -- life dies near hotsprings
  314. minetest.register_abm({
  315. nodenames = "group:flora",
  316. neighbors = {"group:scalding_stone"},
  317. chance = 10,
  318. interval = 15,
  319. action = function(pos, node)
  320. minetest.set_node(pos, {name="air"})
  321. end
  322. })
  323. -- life dies near hotsprings
  324. minetest.register_abm({
  325. nodenames = "group:flora",
  326. neighbors = {"group:scalding_stone"},
  327. chance = 80,
  328. interval = 15,
  329. action = function(pos, node)
  330. local p = minetest.find_node_near(pos, 15, {"group:flora", "group:sapling", "group:leaves", "group:leafdecay"})
  331. if p then
  332. minetest.set_node(p, {name="air"})
  333. end
  334. end
  335. })
  336. -- minerals accumulate
  337. minetest.register_abm({
  338. nodenames = "group:scalding_stone",
  339. neighbors = {"air"},
  340. chance = 180,
  341. interval = 30,
  342. action = function(pos, node)
  343. -- TODO: place sulphur on sides too
  344. pos.y = pos.y + 1
  345. local n = minetest.get_node(pos)
  346. if n.name == "air" then
  347. minetest.set_node(pos, {name="potions:sulphur_deposit_1"})
  348. end
  349. end
  350. })
  351. -- water scalds stone
  352. minetest.register_abm({
  353. nodenames = {"group:stone", "group:dirt"},
  354. neighbors = {"potions:hotspring_water_source", "potions:hotspring_water_flowing"},
  355. chance = 80,
  356. interval = 10,
  357. action = function(pos, node)
  358. minetest.set_node(pos, {name=scalding_stones[math.random(#scalding_stones)]})
  359. end
  360. })
  361. -- stones scald dirt
  362. minetest.register_abm({
  363. nodenames = "group:soil",
  364. neighbors = {"group:scalding_stone"},
  365. chance = 80,
  366. interval = 10,
  367. action = function(pos, node)
  368. minetest.set_node(pos, {name="default:stone"})
  369. end
  370. })
  371. -- water melts snow
  372. minetest.register_abm({
  373. nodenames = {"default:snow", "default:snowblock"},
  374. neighbors = {"potions:hotspring_water_source", "potions:hotspring_water_flowing"},
  375. chance = 80,
  376. interval = 10,
  377. action = function(pos, node)
  378. minetest.set_node(pos, {name="air"})
  379. end
  380. })
  381. -- add hotspring seeds to mapgen
  382. minetest.register_decoration({
  383. name = "potions:hotspring_seed",
  384. deco_type = "simple",
  385. place_on = {"default:dirt_with_grass", "default:dirt_with_snow", "default:snowblock",
  386. "default:silver_sand", "default:sand", "default:desert_sand"
  387. },
  388. place_offset_y = 1,
  389. sidelen = 16,
  390. noise_params = {
  391. offset = -0.010,
  392. scale = 0.01,
  393. spread = {x = 200, y = 200, z = 200},
  394. seed = 65645647,
  395. octaves = 3,
  396. persist = 0.7,
  397. },
  398. biomes = {"grassland", "snowy_grassland", "tundra", "taiga", "desert", "cold_desert", "sandstone_desert"},
  399. y_max = 1000,
  400. y_min = 5,
  401. place_offset_y = 1,
  402. decoration = "potions:hotspring_seed",
  403. flags = "force_placement",
  404. })
  405. -- hotsprings boil rivers
  406. minetest.register_abm({
  407. nodenames = {"default:river_water_source"},
  408. neighbors = {"potions:hotspring_water_source", "potions:hotspring_water_flowing"},
  409. chance = 15,
  410. interval = 5,
  411. action = function(pos, node)
  412. -- only spread downhill
  413. local hw = minetest.find_nodes_in_area(
  414. {x=pos.x-1, y=pos.y, z=pos.z-1},
  415. {x=pos.x+1, y=pos.y+1, z=pos.z+1},
  416. {"potions:hotspring_water_source", "potions:hotspring_water_flowing"})
  417. if not hw or #hw == 0 then
  418. return
  419. end
  420. -- don't spread under rivers
  421. pos.y = pos.y + 1
  422. local n = minetest.get_node(pos)
  423. if n.name == "default:river_water_source" or n.name == "default:river_water_flowing" then
  424. return
  425. end
  426. pos.y = pos.y - 1
  427. minetest.set_node(pos, {name="potions:hotspring_water_source"})
  428. end
  429. })