init.lua 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. --= Ambience lite by TenPlus1
  2. local max_frequency_all = 1000 -- larger number means more frequent sounds (100-2000)
  3. local SOUNDVOLUME = 1.0
  4. local ambiences
  5. -- override default water sounds
  6. minetest.override_item("default:water_source", { sounds = {} })
  7. minetest.override_item("default:water_flowing", { sounds = {} })
  8. minetest.override_item("default:river_water_source", { sounds = {} })
  9. minetest.override_item("default:river_water_flowing", { sounds = {} })
  10. -- music settings
  11. local music_handler = nil
  12. local MUSICVOLUME = 1
  13. local play_music = minetest.settings:get_bool("ambience_music") ~= false
  14. -- is playerplus running?
  15. local pplus = minetest.get_modpath("playerplus")
  16. -- sound sets (gain defaults to 0.3 unless specifically set)
  17. local night = {
  18. handler = {}, frequency = 40,
  19. {name = "hornedowl", length = 2},
  20. {name = "wolves", length = 4, gain = 0.4},
  21. {name = "cricket", length = 6},
  22. {name = "deer", length = 7},
  23. {name = "frog", length = 1},
  24. }
  25. local day = {
  26. handler = {}, frequency = 40,
  27. {name = "cardinal", length = 3},
  28. {name = "craw", length = 3},
  29. {name = "bluejay", length = 6},
  30. {name = "robin", length = 4},
  31. {name = "bird1", length = 11},
  32. {name = "bird2", length = 6},
  33. {name = "crestedlark", length = 6},
  34. {name = "peacock", length = 2},
  35. {name = "wind", length = 9},
  36. }
  37. local high_up = {
  38. handler = {}, frequency = 40,
  39. {name = "desertwind", length = 8},
  40. {name = "wind", length = 9},
  41. }
  42. local cave = {
  43. handler = {}, frequency = 60,
  44. {name = "drippingwater1", length = 1.5},
  45. {name = "drippingwater2", length = 1.5}
  46. }
  47. local beach = {
  48. handler = {}, frequency = 40,
  49. {name = "seagull", length = 4.5},
  50. {name = "beach", length = 13},
  51. {name = "gull", length = 1},
  52. {name = "beach_2", length = 6},
  53. }
  54. local desert = {
  55. handler = {}, frequency = 20,
  56. {name = "coyote", length = 2.5},
  57. {name = "wind", length = 9},
  58. {name = "desertwind", length = 8}
  59. }
  60. local flowing_water = {
  61. handler = {}, frequency = 1000,
  62. {name = "waterfall", length = 6}
  63. }
  64. local underwater = {
  65. handler = {}, frequency = 1000,
  66. {name = "scuba", length = 8}
  67. }
  68. local splash = {
  69. handler = {}, frequency = 1000,
  70. {name = "swim_splashing", length = 3},
  71. }
  72. local lava = {
  73. handler = {}, frequency = 1000,
  74. {name = "lava", length = 7}
  75. }
  76. local river = {
  77. handler = {}, frequency = 1000,
  78. {name = "river", length = 4, gain = 0.1}
  79. }
  80. local smallfire = {
  81. handler = {}, frequency = 1000,
  82. {name = "fire_small", length = 6, gain = 0.1}
  83. }
  84. local largefire = {
  85. handler = {}, frequency = 1000,
  86. {name = "fire_large", length = 8, gain = 0.4}
  87. }
  88. local jungle = {
  89. handler = {}, frequency = 200,
  90. {name = "jungle_day_1", length = 7},
  91. {name = "deer", length = 7},
  92. {name = "canadianloon2", length = 14},
  93. {name = "bird1", length = 11},
  94. {name = "peacock", length = 2},
  95. }
  96. local jungle_night = {
  97. handler = {}, frequency = 200,
  98. {name = "jungle_night_1", length = 4},
  99. {name = "jungle_night_2", length = 4},
  100. {name = "deer", length = 7},
  101. {name = "frog", length = 1},
  102. }
  103. local ice = {
  104. handler = {}, frequency = 250,
  105. {name = "icecrack", length = 23},
  106. {name = "desertwind", length = 8},
  107. {name = "wind", length = 9},
  108. }
  109. local radius = 6
  110. local num_fire, num_lava, num_water_flowing, num_water_source, num_air,
  111. num_desert, num_snow, num_jungletree, num_river, num_ice
  112. -- check where player is and which sounds are played
  113. local get_ambience = function(player)
  114. -- where am I?
  115. --local player_name = player:get_player_name()
  116. local pos = player:get_pos()
  117. -- what is around me?
  118. local nod_head, nod_feet
  119. -- is playerplus in use?
  120. if pplus then
  121. local name = player:get_player_name()
  122. nod_head = playerplus[name].nod_head
  123. nod_feet = playerplus[name].nod_feet
  124. else
  125. pos.y = pos.y + 1.4 -- head level
  126. nod_head = minetest.get_node(pos).name
  127. pos.y = pos.y - 1.2 -- foot level
  128. nod_feet = minetest.get_node(pos).name
  129. pos.y = pos.y - 0.2 -- reset pos
  130. end
  131. local tod = minetest.get_timeofday()
  132. -- play server or local music if available
  133. if play_music then
  134. -- print ("-- tod", tod, music_handler)
  135. if tod > 0.01 and tod < 0.02 then
  136. music_handler = nil
  137. end
  138. -- play at midnight
  139. if tod >= 0.0 and tod <= 0.01 and not music_handler then
  140. music_handler = minetest.sound_play("ambience_song", {
  141. to_player = player:get_player_name(),
  142. gain = MUSICVOLUME
  143. })
  144. end
  145. end
  146. --= START Ambiance
  147. -- head underwater
  148. if minetest.registered_nodes[nod_head]
  149. and minetest.registered_nodes[nod_head].groups.water then
  150. return {underwater = underwater}
  151. end
  152. -- wading through water
  153. if minetest.registered_nodes[nod_feet]
  154. and minetest.registered_nodes[nod_feet].groups.water then
  155. local control = player:get_player_control()
  156. if control.up or control.down or control.left or control.right then
  157. return {splash = splash}
  158. end
  159. end
  160. local ps, cn = minetest.find_nodes_in_area(
  161. {x = pos.x - radius, y = pos.y - radius, z = pos.z - radius},
  162. {x = pos.x + radius, y = pos.y + radius, z = pos.z + radius},
  163. {
  164. "fire:basic_flame", "fire:permanent_flame",
  165. "default:lava_flowing", "default:lava_source", "default:jungletree",
  166. "default:water_flowing", "default:water_source", "default:ice",
  167. "default:river_water_flowing",
  168. "default:desert_sand", "default:desert_stone", "default:snowblock"
  169. })
  170. num_fire = (cn["fire:basic_flame"] or 0) + (cn["fire:permanent_flame"] or 0)
  171. num_lava = (cn["default:lava_flowing"] or 0) + (cn["default:lava_source"] or 0)
  172. num_water_flowing = (cn["default:water_flowing"] or 0)
  173. num_water_source = (cn["default:water_source"] or 0)
  174. num_desert = (cn["default:desert_sand"] or 0) + (cn["default:desert_stone"] or 0)
  175. num_snow = (cn["default:snowblock"] or 0)
  176. num_jungletree = (cn["default:jungletree"] or 0)
  177. num_river = (cn["default:river_water_flowing"] or 0)
  178. num_ice = (cn["default:ice"] or 0)
  179. --[[
  180. print (
  181. "fr:" .. num_fire,
  182. "lv:" .. num_lava,
  183. "wf:" .. num_water_flowing,
  184. "ws:" .. num_water_source,
  185. "rv:" .. num_river,
  186. "ds:" .. num_desert,
  187. "sn:" .. num_snow,
  188. "ic:" .. num_ice,
  189. "jt:" .. num_jungletree
  190. )
  191. ]]
  192. -- is fire redo mod active?
  193. if fire and fire.mod and fire.mod == "redo" then
  194. if num_fire > 16 then
  195. return {largefire = largefire}, 0.4
  196. elseif num_fire > 8 then
  197. return {largefire = largefire}
  198. elseif num_fire > 3 then
  199. return {smallfire = smallfire}, 0.2
  200. elseif num_fire > 0 then
  201. return {smallfire = smallfire}
  202. end
  203. end
  204. -- lava
  205. if num_lava > 50 then
  206. return {lava = lava}, 0.5
  207. elseif num_lava > 5 then
  208. return {lava = lava}
  209. end
  210. -- flowing water
  211. if num_water_flowing > 50 then
  212. return {flowing_water = flowing_water}, 0.5
  213. elseif num_water_flowing > 20 then
  214. return {flowing_water = flowing_water}
  215. end
  216. -- flowing river
  217. if num_river > 20 then
  218. return {river = river}, 0.4
  219. elseif num_river > 5 then
  220. return {river = river}
  221. end
  222. -- sea level beach
  223. if pos.y < 7 and pos.y > 0
  224. and num_water_source > 100 then
  225. return {beach = beach}
  226. end
  227. -- ice flows
  228. if num_ice > 100 and num_snow > 100 then
  229. return {ice = ice}
  230. end
  231. -- desert
  232. if num_desert > 150 then
  233. return {desert = desert}
  234. end
  235. -- high up or surrounded by snow
  236. if pos.y > 60
  237. or num_snow > 150 then
  238. return {high_up = high_up}
  239. end
  240. -- underground
  241. if pos.y < -15 then
  242. return {cave = cave}
  243. end
  244. if tod > 0.2
  245. and tod < 0.8 then
  246. -- jungle day time
  247. if num_jungletree > 90 then
  248. return {jungle = jungle}
  249. end
  250. -- normal day time
  251. return {day = day}
  252. else
  253. -- jungle night time
  254. if num_jungletree > 90 then
  255. return {jungle_night = jungle_night}
  256. end
  257. -- normal night time
  258. return {night = night}
  259. end
  260. -- END Ambiance
  261. end
  262. -- play sound, set handler then delete handler when sound finished
  263. local play_sound = function(player_name, list, number, MORE_GAIN)
  264. if list.handler[player_name] == nil then
  265. local handler = minetest.sound_play(list[number].name, {
  266. to_player = player_name,
  267. gain = ((list[number].gain or 0.3) + (MORE_GAIN or 0)) * SOUNDVOLUME
  268. })
  269. if handler then
  270. list.handler[player_name] = handler
  271. minetest.after(list[number].length, function(args)
  272. local list = args[1]
  273. local player_name = args[2]
  274. if list.handler[player_name] then
  275. minetest.sound_stop(list.handler[player_name])
  276. list.handler[player_name] = nil
  277. end
  278. end, {list, player_name})
  279. end
  280. end
  281. end
  282. -- stop sound in still_playing
  283. local stop_sound = function (list, player_name)
  284. if list.handler[player_name] then
  285. minetest.sound_stop(list.handler[player_name])
  286. list.handler[player_name] = nil
  287. end
  288. end
  289. -- check sounds that are not in still_playing
  290. local still_playing = function(still_playing, player_name)
  291. if not still_playing.cave then stop_sound(cave, player_name) end
  292. if not still_playing.high_up then stop_sound(high_up, player_name) end
  293. if not still_playing.beach then stop_sound(beach, player_name) end
  294. if not still_playing.desert then stop_sound(desert, player_name) end
  295. if not still_playing.night then stop_sound(night, player_name) end
  296. if not still_playing.day then stop_sound(day, player_name) end
  297. if not still_playing.flowing_water then stop_sound(flowing_water, player_name) end
  298. if not still_playing.splash then stop_sound(splash, player_name) end
  299. if not still_playing.underwater then stop_sound(underwater, player_name) end
  300. if not still_playing.river then stop_sound(river, player_name) end
  301. if not still_playing.lava then stop_sound(lava, player_name) end
  302. if not still_playing.smallfire then stop_sound(smallfire, player_name) end
  303. if not still_playing.largefire then stop_sound(largefire, player_name) end
  304. if not still_playing.jungle then stop_sound(jungle, player_name) end
  305. if not still_playing.jungle_night then stop_sound(jungle_night, player_name) end
  306. if not still_playing.ice then stop_sound(ice, player_name) end
  307. end
  308. -- player routine
  309. local timer = 0
  310. minetest.register_globalstep(function(dtime)
  311. -- every 1 second
  312. timer = timer + dtime
  313. if timer < 1 then return end
  314. timer = 0
  315. local players = minetest.get_connected_players()
  316. local MORE_GAIN
  317. for n = 1, #players do
  318. local player_name = players[n]:get_player_name()
  319. --local t1 = os.clock()
  320. ambiences, MORE_GAIN = get_ambience(players[n])
  321. --print(string.format("elapsed time: %.4f\n", os.clock() - t1))
  322. still_playing(ambiences, player_name)
  323. for _,ambience in pairs(ambiences) do
  324. if math.random(1, 1000) <= ambience.frequency then
  325. play_sound(player_name, ambience, math.random(1, #ambience), MORE_GAIN)
  326. end
  327. end
  328. end
  329. end)
  330. -- set volume commands
  331. minetest.register_chatcommand("svol", {
  332. params = "<svol>",
  333. description = "set sound volume (0.1 to 1.0)",
  334. privs = {server = true},
  335. func = function(name, param)
  336. SOUNDVOLUME = tonumber(param) or SOUNDVOLUME
  337. if SOUNDVOLUME < 0.1 then SOUNDVOLUME = 0.1 end
  338. if SOUNDVOLUME > 1.0 then SOUNDVOLUME = 1.0 end
  339. return true, "Sound volume set to " .. SOUNDVOLUME
  340. end,
  341. })
  342. minetest.register_chatcommand("mvol", {
  343. params = "<mvol>",
  344. description = "set music volume (0.1 to 1.0)",
  345. privs = {server = true},
  346. func = function(name, param)
  347. MUSICVOLUME = tonumber(param) or MUSICVOLUME
  348. if MUSICVOLUME < 0.1 then MUSICVOLUME = 0.1 end
  349. if MUSICVOLUME > 1.0 then MUSICVOLUME = 1.0 end
  350. return true, "Music volume set to " .. MUSICVOLUME
  351. end,
  352. })