From 0c5c9f0d15a2b1d4f97bc38a8a6167ad87d30401 Mon Sep 17 00:00:00 2001 From: Till Affeldt Date: Sat, 18 Apr 2020 17:24:59 +0200 Subject: [PATCH] Sound improvements --- ROADMAP.md | 1 + ca_effects/sound.lua | 49 +++++++++---------------------------- lib/influences.lua | 8 +++++++ lib/soundloop.lua | 57 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 38 deletions(-) create mode 100644 lib/soundloop.lua diff --git a/ROADMAP.md b/ROADMAP.md index b645b9e..a612687 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -18,6 +18,7 @@ - Make switches between effects more smooth - Adjust size of particle boxes based on player speed - Create conditions for time of day, annual progression, biome filters +- Generate wind based on speed and yaw instead of x and z values ## Future Plans & Ideas - Complete season system diff --git a/ca_effects/sound.lua b/ca_effects/sound.lua index 49db21c..9b37792 100644 --- a/ca_effects/sound.lua +++ b/ca_effects/sound.lua @@ -3,48 +3,21 @@ if not climate_mod.settings.sound then return end local EFFECT_NAME = "climate_api:sound" local FADE_DURATION = climate_api.LONG_CYCLE -local handles = {} -local removables = {} -local function end_sound(pname, weather, sound) - if removables[pname] == nil - or removables[pname][weather] == nil then return end - local handle = removables[pname][weather] - minetest.sound_stop(handle) - removables[pname][weather] = nil +local modpath = minetest.get_modpath(minetest.get_current_modname()) +local soundloop = dofile(modpath .. "/lib/soundloop.lua") + +local function start_sound(pname, sound) + return soundloop.play(pname, sound, FADE_DURATION) end -local function start_sound(pname, weather, sound) - local handle - if handles[pname] == nil then handles[pname] = {} end - if handles[pname][weather] ~= nil then return end - if removables[pname] == nil or removables[pname][weather] == nil then - handle = minetest.sound_play(sound.name, { - to_player = pname, - loop = true, - gain = 0 - }) - else - handle = removables[pname][weather] - removables[pname][weather] = nil - end - minetest.sound_fade(handle, sound.gain / FADE_DURATION, sound.gain) - handles[pname][weather] = handle -end - -local function stop_sound(pname, weather, sound) - if handles[pname] == nil or handles[pname][weather] == nil then return end - local handle = handles[pname][weather] - minetest.sound_fade(handle, -sound.gain / FADE_DURATION, 0) - if removables[pname] == nil then removables[pname] = {} end - removables[pname][weather] = handle - handles[pname][weather] = nil - minetest.after(FADE_DURATION, end_sound, pname, weather, sound) +local function stop_sound(pname, sound) + return soundloop.stop(pname, sound, FADE_DURATION) end local function start_effect(player_data) for playername, data in pairs(player_data) do for weather, value in pairs(data) do - start_sound(playername, weather, value) + start_sound(playername, value) end end end @@ -53,7 +26,7 @@ local function handle_effect(player_data, prev_data) for playername, data in pairs(player_data) do for weather, value in pairs(data) do if prev_data[playername][weather] == nil then - start_sound(playername, weather, value) + start_sound(playername, value) end end end @@ -61,7 +34,7 @@ local function handle_effect(player_data, prev_data) for playername, data in pairs(prev_data) do for weather, value in pairs(data) do if player_data[playername][weather] == nil then - stop_sound(playername, weather, value) + stop_sound(playername, value) end end end @@ -71,7 +44,7 @@ local function stop_effect(prev_data) minetest.log(dump2(prev_data, "stop_effect")) for playername, data in pairs(prev_data) do for weather, value in pairs(data) do - stop_sound(playername, weather, value) + stop_sound(playername, value) end end end diff --git a/lib/influences.lua b/lib/influences.lua index 87a3a6b..cbe3f9b 100644 --- a/lib/influences.lua +++ b/lib/influences.lua @@ -2,10 +2,18 @@ climate_api.register_influence("heat", function(pos) return climate_api.environment.get_heat(pos) end) +climate_api.register_influence("base_heat", function(pos) + return minetest.get_heat(pos) +end) + climate_api.register_influence("humidity", function(pos) return climate_api.environment.get_humidity(pos) end) +climate_api.register_influence("base_humidity", function(pos) + return minetest.get_humidity(pos) +end) + climate_api.register_influence("biome", function(pos) local data = minetest.get_biome_data(pos) local biome = minetest.get_biome_name(data.biome) diff --git a/lib/soundloop.lua b/lib/soundloop.lua new file mode 100644 index 0000000..697bb40 --- /dev/null +++ b/lib/soundloop.lua @@ -0,0 +1,57 @@ +local soundloop = {} +local sounds = {} + +local function parse_sound(sound) + if type(sound) == "string" then + return { name = sound, gain = 1, pitch = 1 } + end + if sound.gain == nil then sound.gain = 1 end + if sound.pitch == nil then sound.pitch = 1 end + return sound +end + +soundloop.play = function(player, sound, fade) + sound = parse_sound(sound) + if fade == nil then fade = 1 end + local step + local handle + local start_gain + if sounds[player] == nil then sounds[player] = {} end + if sounds[player][sound.name] == nil then + step = sound.gain / fade + start_gain = 0 + elseif sounds[player][sound.name] ~= sound.gain then + minetest.sound_stop(sounds[player][sound.name].handle) + start_gain = sounds[player][sound.name].gain + local change = sound.gain - start_gain + step = change / fade + else + return + end + handle = minetest.sound_play(sound.name, { + to_player = player, + loop = true, + gain = 0 + }) + sounds[player][sound.name] = { + gain = sound.gain, + handle = handle + } + minetest.sound_fade(handle, step, sound.gain) + return handle +end + +soundloop.stop = function(player, sound, fade) + sound = parse_sound(sound) + if sounds[player] == nil or sounds[player][sound.name] == nil then + return + end + if fade == nil then fade = 1 end + local handle = sounds[player][sound.name].handle + local step = -sounds[player][sound.name].gain / fade + minetest.sound_fade(handle, step, 0) + sounds[player][sound.name].gain = 0 + minetest.after(fade, minetest.sound_stop, handle) +end + +return soundloop \ No newline at end of file