minetest/mods/env_sounds/init.lua
paramat 95fb14aa8e Add initial environmental sounds mod with flowing water sounds
default:river_water_source can also create sound if desired as
rivers are considered to be flowing water.
A simple mod for now, with the intention to later use new engine
environmental sound features if/when they appear.
2019-09-10 00:14:45 +01:00

121 lines
2.6 KiB
Lua

-- Parameters
local radius = 8 -- Water node search radius around player
-- End of parameters
local handles = {}
local river_source_sounds = minetest.settings:get_bool("river_source_sounds")
-- Update sound for player
local function update_sound(player)
local player_name = player:get_player_name()
-- Search for water nodes in radius around player
local ppos = player:getpos()
local areamin = vector.subtract(ppos, radius)
local areamax = vector.add(ppos, radius)
local wpos, num
if river_source_sounds then
wpos, num = minetest.find_nodes_in_area(
areamin,
areamax,
{
"default:water_flowing",
"default:river_water_source",
"default:river_water_flowing"
}
)
else
wpos, num = minetest.find_nodes_in_area(
areamin,
areamax,
{
"default:water_flowing",
"default:river_water_flowing"
}
)
end
-- Total number of waters in radius
local waters = (num["default:water_flowing"] or 0) +
(num["default:river_water_source"] or 0) +
(num["default:river_water_flowing"] or 0)
-- If waters
if waters > 0 then
-- Find centre of water positions
local wposmid = wpos[1]
-- If more than 1 water
if #wpos > 1 then
local wposmin = areamax
local wposmax = areamin
for i = 1, #wpos do
local wposi = wpos[i]
if wposi.x > wposmax.x then
wposmax.x = wposi.x
end
if wposi.y > wposmax.y then
wposmax.y = wposi.y
end
if wposi.z > wposmax.z then
wposmax.z = wposi.z
end
if wposi.x < wposmin.x then
wposmin.x = wposi.x
end
if wposi.y < wposmin.y then
wposmin.y = wposi.y
end
if wposi.z < wposmin.z then
wposmin.z = wposi.z
end
end
wposmid = vector.divide(vector.add(wposmin, wposmax), 2)
end
-- Play sound
local handle = minetest.sound_play(
"env_sounds_water",
{
pos = wposmid,
to_player = player_name,
gain = math.min(0.04 + waters * 0.004, 0.4),
max_hear_distance = 32,
}
)
-- Store sound handle for this player
if handle then
handles[player_name] = handle
end
end
end
-- Update sound 'on joinplayer'
minetest.register_on_joinplayer(function(player)
update_sound(player)
end)
-- Cyclic sound update
local function cyclic_update()
for _, player in pairs(minetest.get_connected_players()) do
update_sound(player)
end
minetest.after(3.5, cyclic_update)
end
minetest.after(0, cyclic_update)
-- Stop sound and clear handle on player leave
minetest.register_on_leaveplayer(function(player)
local player_name = player:get_player_name()
if handles[player_name] then
minetest.sound_stop(handles[player_name])
handles[player_name] = nil
end
end)