init.lua 4.1 KB

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