Aaron Suen 5e97fc3bcb Envsound consistency for multiple players.
Ensure players can't cause a blast of loud
wind or drip sounds to happen within the near
clipping boundaries of other nearby players
just because they're in the same general
area and played their sounds first in the tick.
2020-01-11 08:31:33 -05:00

70 lines
1.7 KiB
Lua

-- LUALOCALS < ---------------------------------------------------------
local math, minetest, nodecore, pairs, vector
= math, minetest, nodecore, pairs, vector
local math_exp, math_random
= math.exp, math.random
-- LUALOCALS > ---------------------------------------------------------
nodecore.amcoremod()
local function dsqr(a, b)
local v = vector.subtract(a, b)
return vector.dot(v, v)
end
local function check(pos, done, srcs)
local sp = {
x = pos.x + math_random() * 64 - 32,
y = pos.y + math_random() * 64 - 32,
z = pos.z + math_random() * 64 - 32,
}
if dsqr(sp, pos) > (32 * 32) then return end
for p in pairs(done) do
if dsqr(sp, p) < (32 * 32) then return end
end
for p in pairs(srcs) do
if dsqr(sp, p) < (4 * 4) then return end
end
if minetest.get_node(sp).name ~= "air" then return end
local light = minetest.get_node_light(sp, 0.5)
if light == 15 then
if sp.y <= 0 then return end
minetest.sound_play("nc_envsound_air", {
pos = sp,
gain = nodecore.windiness(sp.y) / 100
})
elseif light < 4 then
minetest.sound_play("nc_envsound_drip", {
pos = sp,
pitchvary = 0.4,
gain = math_exp(math_random()) / 5
})
end
done[pos] = true
end
local oldpos = {}
local function run()
minetest.after(math_random(), run)
local srcs = {}
for _, pl in pairs(minetest.get_connected_players()) do
if nodecore.player_visible(pl) then
local pname = pl:get_player_name()
local pos = pl:get_pos()
local op = oldpos[pname] or pos
oldpos[pname] = pos
pos = vector.add(pos, vector.multiply(vector.subtract(pos, op), 3))
srcs[#srcs + 1] = pos
end
end
local done = {}
for _, pos in pairs(srcs) do
check(pos, done, srcs)
end
end
run()