nodecore-cd2025/mods/nc_api/util_sound.lua
Aaron Suen 4a41aae4a8 Default all sounds to ephemeral
NodeCore was already using sounds this way, i.e. assuming
they can't meaningfully be managed (may not be heard by
players just entering the area) so might as well get the
supposed performance benefit.

Added an override to allow sounds to be marked as NOT
ephemeral just in case it's needed.
2020-04-05 21:18:30 -04:00

98 lines
2.7 KiB
Lua

-- LUALOCALS < ---------------------------------------------------------
local ItemStack, ipairs, math, minetest, nodecore, pairs, type, unpack,
vector
= ItemStack, ipairs, math, minetest, nodecore, pairs, type, unpack,
vector
local math_exp, math_random, math_sin, math_sqrt
= math.exp, math.random, math.sin, math.sqrt
-- LUALOCALS > ---------------------------------------------------------
local oldplay = minetest.sound_play
function minetest.sound_play(name, spec, ephem, ...)
if spec and type(spec) == "table" and spec.pitch == nil then
spec.pitch = math_exp((math_random() - 0.5) * (spec.pitchvary or 0.05))
end
if ephem == nil then ephem = not spec.not_ephemeral end
return oldplay(name, spec, ephem, ...)
end
function nodecore.windiness(y)
if y < 0 then return 0 end
if y > 512 then y = 512 end
return math_sqrt(y) * (1 + 0.5 * math_sin(nodecore.gametime / 5))
end
function nodecore.stack_sounds(pos, kind, stack)
stack = stack or nodecore.stack_get(pos)
stack = ItemStack(stack)
if stack:is_empty() then return end
local def = minetest.registered_items[stack:get_name()] or {}
if (not def.sounds) or (not def.sounds[kind]) then return end
local t = {}
for k, v in pairs(def.sounds[kind]) do t[k] = v end
t.pos = pos
return minetest.sound_play(t.name, t)
end
function nodecore.stack_sounds_delay(...)
local t = {...}
minetest.after(0, function()
nodecore.stack_sounds(unpack(t))
end)
end
local gains_base = {
footstep = 0.2,
dig = 0.5,
dug = 1,
place = 1,
place_failed = 0.2,
fall = 0.1
}
function nodecore.sounds(name, gains)
local t = {}
for k, v in pairs(gains_base) do
t[k] = {
name = name,
gain = (gains and gains[k] or 1) * v
}
end
return t
end
function nodecore.sound_play_except(name, def, pname)
if not pname then
return minetest.sound_play(name, def)
end
if type(pname) ~= "string" then
pname = pname:get_player_name()
end
for _, p in ipairs(minetest.get_connected_players()) do
local pn = p:get_player_name()
if pn ~= pname and ((not def.pos)
or (vector.distance(p:get_pos(), def.pos) <= 32)) then
def.to_player = pn
minetest.sound_play(name, def)
end
end
end
function nodecore.node_sound(pos, kind, opts)
local node = opts and opts.node or minetest.get_node(pos)
local def = minetest.registered_items[node.name] or {}
if def.groups and def.groups.visinv then
nodecore.stack_sounds(pos, kind)
end
if (not def.sounds) or (not def.sounds[kind]) then return end
local t = {}
for k, v in pairs(def.sounds[kind]) do t[k] = v end
t.pos = pos
return nodecore.sound_play_except(t.name, t, opts and opts.except)
end
function nodecore.set_loud(pos, node, opts)
minetest.set_node(pos, node)
opts = opts or {}
opts.node = node
return nodecore.node_sound(pos, "place", opts)
end