init.lua 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. -- This file is reloadable.
  2. ambiance = ambiance or {}
  3. ambiance.players = ambiance.players or {}
  4. ambiance.environment_cache = ambiance.environment_cache or {}
  5. ambiance.modpath = minetest.get_modpath("ambiance")
  6. dofile(ambiance.modpath .. "/data.lua")
  7. dofile(ambiance.modpath .. "/utility.lua")
  8. dofile(ambiance.modpath .. "/scuba.lua")
  9. dofile(ambiance.modpath .. "/particles.lua")
  10. dofile(ambiance.modpath .. "/beacon.lua")
  11. dofile(ambiance.modpath .. "/treesounds.lua")
  12. dofile(ambiance.modpath .. "/gate.lua")
  13. -- Modifiable parameters.
  14. ambiance.server_step = 1
  15. local step_timer = 0
  16. local step_total = ambiance.server_step
  17. ambiance.globalstep = function(dtime)
  18. step_timer = step_timer + dtime
  19. if step_timer < step_total then
  20. return
  21. end
  22. step_timer = 0
  23. -- Get current time of day.
  24. local curtime = minetest.get_timeofday()
  25. local rand = math.random
  26. -- For all sounds, check if anyone can hear them. If yes, play sound to players that can hear.
  27. local allsounds = ambiance.allsounds
  28. for k, v in ipairs(allsounds) do
  29. v.timer = v.timer - step_total
  30. if v.timer <= 0 then
  31. -- Timer has expired, fire sound (if possible).
  32. -- Also reset the timer so the sound can fire again.
  33. v.timer = rand(v.mintime, v.maxtime)
  34. -- Can this sound play at the current time of day?
  35. if ambiance.check_time(v.time, curtime) then
  36. -- Scan through all players. The following checks must be done per-player.
  37. for name, pdata in pairs(ambiance.players) do
  38. local player = minetest.get_player_by_name(name)
  39. if player and player:is_player() then
  40. local pos = utility.get_foot_pos(player:get_pos())
  41. -- Is player in this sounds's Y layer?
  42. if pos.y >= v.miny and pos.y <= v.maxy then
  43. -- Don't play sound if player is underwater (muted sounds).
  44. -- Note: player's underwater status is modified by the scuba code.
  45. local underwater = ambiance.players[name].underwater
  46. if underwater == nil then
  47. local nospawn = false
  48. -- If have perlin object, then check if sound can spawn in this location.
  49. if v.perlin and v.noise_threshold then
  50. local noise = v.perlin:get_3d(pos)
  51. if noise < v.noise_threshold then
  52. nospawn = true
  53. end
  54. end
  55. if not nospawn then
  56. -- Only play sound if sound can be played indoors or out-of-doors.
  57. -- If sound doesn't care whether indoors or out-of-doors, then play it.
  58. local indoors
  59. if v.indoors ~= nil then
  60. -- Randomize position a bit in case player is just standing under an overhang.
  61. pos.x = rand(pos.x - 1, pos.x + 1)
  62. pos.y = rand(pos.y - 1, pos.y + 1)
  63. pos.z = rand(pos.z - 1, pos.z + 1)
  64. indoors = ambiance.check_indoors(name, pos)
  65. end
  66. if v.indoors == indoors then
  67. -- Play sound to current player!
  68. -- If multiple players can hear, the sound will be played at the same time to all of them.
  69. local gain = rand(v.mingain*100.0, v.maxgain*100.0)/100.0
  70. -- Clamp gain!
  71. if gain < 0.0 then gain = 0.0 end
  72. if gain > 2.0 then gain = 2.0 end
  73. minetest.sound_play(v.name, {to_player=name, gain=gain})
  74. end
  75. end
  76. end
  77. end
  78. end
  79. end
  80. end
  81. end
  82. end
  83. end
  84. -- Register our handlers only once.
  85. if not ambiance.registered then
  86. -- Store data per-player.
  87. minetest.register_on_joinplayer(function(player)
  88. local pname = player:get_player_name()
  89. ambiance.players[pname] = {}
  90. end)
  91. minetest.register_on_leaveplayer(function(player)
  92. ambiance.players[player:get_player_name()] = nil
  93. end)
  94. minetest.register_globalstep(function(...) return ambiance.globalstep(...) end)
  95. minetest.register_globalstep(function(...) return ambiance.globalstep_scuba(...) end)
  96. ambiance.registered = true
  97. end
  98. -- Register everything as reloadable.
  99. if minetest.get_modpath("reload") then
  100. local c = "ambiance:core"
  101. local f = ambiance.modpath .. "/init.lua"
  102. if not reload.file_registered(c) then
  103. reload.register_file(c, f, false)
  104. end
  105. end