123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- -- Parameters
- -- Node search radius around player
- local radius = 8
- local allsounds = {
- ["env_sounds_water"] = {
- trigger = {"default:water_flowing", "default:river_water_flowing"},
- base_volume = 0.04,
- max_volume = 0.4,
- per_node = 0.004,
- },
- ["env_sounds_lava"] = {
- trigger = {"default:lava_source", "default:lava_flowing"},
- base_volume = 0,
- max_volume = 0.6,
- per_node = {
- ["default:lava_source"] = 0.008,
- ["default:lava_flowing"] = 0.002,
- },
- },
- }
- if minetest.settings:get_bool("river_source_sounds") then
- table.insert(allsounds["env_sounds_water"].trigger,
- "default:river_water_source")
- end
- -- Cache the union of all trigger nodes
- local cache_triggers = {}
- for sound, def in pairs(allsounds) do
- for _, name in ipairs(def.trigger) do
- table.insert(cache_triggers, name)
- end
- end
- -- Update sound for player
- local function update_sound(player)
- local player_name = player:get_player_name()
- local ppos = player:get_pos()
- ppos = vector.add(ppos, player:get_properties().eye_height)
- local areamin = vector.subtract(ppos, radius)
- local areamax = vector.add(ppos, radius)
- local pos = minetest.find_nodes_in_area(areamin, areamax, cache_triggers, true)
- if next(pos) == nil then -- If table empty
- return
- end
- for sound, def in pairs(allsounds) do
- -- Find average position
- local posav = {0, 0, 0}
- local count = 0
- for _, name in ipairs(def.trigger) do
- if pos[name] then
- for _, p in ipairs(pos[name]) do
- posav[1] = posav[1] + p.x
- posav[2] = posav[2] + p.y
- posav[3] = posav[3] + p.z
- end
- count = count + #pos[name]
- end
- end
- if count > 0 then
- posav = vector.new(posav[1] / count, posav[2] / count,
- posav[3] / count)
- -- Calculate gain
- local gain = def.base_volume
- if type(def.per_node) == 'table' then
- for name, multiplier in pairs(def.per_node) do
- if pos[name] then
- gain = gain + #pos[name] * multiplier
- end
- end
- else
- gain = gain + count * def.per_node
- end
- gain = math.min(gain, def.max_volume)
- minetest.sound_play(sound, {
- pos = posav,
- to_player = player_name,
- gain = gain,
- }, true)
- end
- end
- end
- -- Update sound when player joins
- 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)
|