From 3657e3a58066a800621b6bb34d150e7805fa8662 Mon Sep 17 00:00:00 2001 From: TenPlus1 Date: Thu, 30 Aug 2018 15:09:48 +0100 Subject: [PATCH] Redone code, added API to add sound sets --- README.md | 1 + api.txt | 90 ++++++++ init.lua | 559 ++++++++++++++++++-------------------------------- soundsets.lua | 342 ++++++++++++++++++++++++++++++ 4 files changed, 636 insertions(+), 356 deletions(-) create mode 100644 api.txt create mode 100644 soundsets.lua diff --git a/README.md b/README.md index 65b04a4..d656f20 100644 --- a/README.md +++ b/README.md @@ -15,5 +15,6 @@ Based on Immersive Sounds .36 mod by Neuromancer and optimized to run on servers - 1.0 - Added icecrack sound when walking on snow/ice flows, also tidied code - 1.1 - Using newer functions, Minetest 0.4.16 and above needed to run - 1.2 - Added PlayerPlus compatibility, removed fire sounds, added volume changes +- 1.3 - Added API for use with other mods, code rewrite Code license: MIT diff --git a/api.txt b/api.txt new file mode 100644 index 0000000..50584a9 --- /dev/null +++ b/api.txt @@ -0,0 +1,90 @@ + +Ambience Lite API +================= + +This short guide will show you how to add sound sets into ambience mod for the +api to use and play sounds accordingly. Please note that the order they are +added will affect sound checks, so high priority sets first. + + +Function Usage +============== + + +Adding Sound Set +---------------- + +ambience.add_set(set_name, def) + 'set_name' contains the name of the sound set to add + 'def' contains the following: + 'frequency' how often the sound set is played (1 to 1000) higher is more + 'nodes' contains a table of nodes needed for checks + 'sound_check(def)' function to check if sounds can be played, def contains: + 'player' player userdata + 'pos' position of player + 'tod' time of day + 'totals' totals for each node e.g. def.totals["default:sand"] + 'positions' position data for every node found + 'head_node' name of node at player head level + 'feet_node' nameof node at player foot level + +This will let you add a set or sounds with the frequency it's used and check +function for it to play. + +e.g. + +ambience.add_set("windy", { + frequency = 500, + nodes = {"default:sand"}, + sounds = { + {name = "wind", length = 9, gain = 0.3}, + {name = "desertwind", length = 8, gain = 0.3}, + }, + sound_check = function(def) + local number = totals["default:sand"] or 0 -- yep, can also be nil + if number > 20 then + return "windy", 0.2 -- return set to play and optional gain volume + end + end, +}) + + +Getting Sound Set +----------------- + +ambience.get_set(set_name) + +This returns a table containing all of the set information like example above. + +e.g. + +local myset = ambience.get_set("windy") -- returns everything inside {} above. + + +Deleting Sound Set +------------------ + +ambience.del_set(set_name) + +This will remove a sound set from the list. + +e.g. + +ambience.del_set("windy") + + +Additional Commands +=================== + +Two volume commands have been added to set sound and music volume: + +/svol (0.1 to 1.0) +/mvol (0.1 to 1.0) -- 0 can be used to stop music from playing when it begins + + +Music +===== + +Music can be stored in the sounds folder either on server or locally and so long +as it is named 'ambience_music.1', 'ambience_music.2' etc. then it will select +a song randomly at midnight and play player. diff --git a/init.lua b/init.lua index baa8f86..2c92714 100644 --- a/init.lua +++ b/init.lua @@ -1,9 +1,5 @@ ---= Ambience lite by TenPlus1 - -local max_frequency_all = 1000 -- larger number means more frequent sounds (100-2000) -local SOUNDVOLUME = 1.0 -local ambiences +ambience = {} -- override default water sounds minetest.override_item("default:water_source", { sounds = {} }) @@ -11,385 +7,166 @@ minetest.override_item("default:water_flowing", { sounds = {} }) minetest.override_item("default:river_water_source", { sounds = {} }) minetest.override_item("default:river_water_flowing", { sounds = {} }) --- music settings -local music_handler = nil -local MUSICVOLUME = 1 +-- settings +local SOUNDVOLUME = 1.0 +local MUSICVOLUME = 1.0 local play_music = minetest.settings:get_bool("ambience_music") ~= false - --- is playerplus running? local pplus = minetest.get_modpath("playerplus") - --- sound sets (gain defaults to 0.3 unless specifically set) - -local night = { - handler = {}, frequency = 40, - {name = "hornedowl", length = 2}, - {name = "wolves", length = 4, gain = 0.4}, - {name = "cricket", length = 6}, - {name = "deer", length = 7}, - {name = "frog", length = 1}, -} - -local day = { - handler = {}, frequency = 40, - {name = "cardinal", length = 3}, - {name = "craw", length = 3}, - {name = "bluejay", length = 6}, - {name = "robin", length = 4}, - {name = "bird1", length = 11}, - {name = "bird2", length = 6}, - {name = "crestedlark", length = 6}, - {name = "peacock", length = 2}, - {name = "wind", length = 9}, -} - -local high_up = { - handler = {}, frequency = 40, - {name = "desertwind", length = 8}, - {name = "wind", length = 9}, -} - -local cave = { - handler = {}, frequency = 60, - {name = "drippingwater1", length = 1.5}, - {name = "drippingwater2", length = 1.5} -} - -local beach = { - handler = {}, frequency = 40, - {name = "seagull", length = 4.5}, - {name = "beach", length = 13}, - {name = "gull", length = 1}, - {name = "beach_2", length = 6}, -} - -local desert = { - handler = {}, frequency = 20, - {name = "coyote", length = 2.5}, - {name = "wind", length = 9}, - {name = "desertwind", length = 8} -} - -local flowing_water = { - handler = {}, frequency = 1000, - {name = "waterfall", length = 6} -} - -local underwater = { - handler = {}, frequency = 1000, - {name = "scuba", length = 8} -} - -local splash = { - handler = {}, frequency = 1000, - {name = "swim_splashing", length = 3}, -} - -local lava = { - handler = {}, frequency = 1000, - {name = "lava", length = 7} -} - -local river = { - handler = {}, frequency = 1000, - {name = "river", length = 4, gain = 0.1} -} - -local smallfire = { - handler = {}, frequency = 1000, - {name = "fire_small", length = 6, gain = 0.1} -} - -local largefire = { - handler = {}, frequency = 1000, - {name = "fire_large", length = 8, gain = 0.4} -} - -local jungle = { - handler = {}, frequency = 200, - {name = "jungle_day_1", length = 7}, - {name = "deer", length = 7}, - {name = "canadianloon2", length = 14}, - {name = "bird1", length = 11}, - {name = "peacock", length = 2}, -} - -local jungle_night = { - handler = {}, frequency = 200, - {name = "jungle_night_1", length = 4}, - {name = "jungle_night_2", length = 4}, - {name = "deer", length = 7}, - {name = "frog", length = 1}, -} - -local ice = { - handler = {}, frequency = 250, - {name = "icecrack", length = 23}, - {name = "desertwind", length = 8}, - {name = "wind", length = 9}, -} - local radius = 6 -local num_fire, num_lava, num_water_flowing, num_water_source, num_air, - num_desert, num_snow, num_jungletree, num_river, num_ice +local playing = {} +local sound_sets = {} -- all the sounds and their settings +local sound_set_order = {} -- needed because pairs loops randomly through tables +local set_nodes = {} -- all the nodes needed for sets --- check where player is and which sounds are played -local get_ambience = function(player) - -- where am I? - --local player_name = player:get_player_name() - local pos = player:get_pos() +-- global functions +ambience.add_set = function(set_name, def) - -- what is around me? - local nod_head, nod_feet + if set_name and def then - -- is playerplus in use? - if pplus then + sound_sets[set_name] = { + frequency = def.frequency or 50, + sounds = def.sounds, + sound_check = def.sound_check, + nodes = def.nodes, + } - local name = player:get_player_name() + -- add set name to the sound_set_order table + local can_add = true - nod_head = playerplus[name].nod_head - nod_feet = playerplus[name].nod_feet - else + for i = 1, #sound_set_order do - pos.y = pos.y + 1.4 -- head level - nod_head = minetest.get_node(pos).name - - pos.y = pos.y - 1.2 -- foot level - nod_feet = minetest.get_node(pos).name - - pos.y = pos.y - 0.2 -- reset pos - end - - local tod = minetest.get_timeofday() - - -- play server or local music if available - if play_music then - --- print ("-- tod", tod, music_handler) - - if tod > 0.01 and tod < 0.02 then - music_handler = nil + if sound_set_order[i] == set_name then + can_add = false + end end - -- play at midnight - if tod >= 0.0 and tod <= 0.01 and not music_handler then - - music_handler = minetest.sound_play("ambience_music", { - to_player = player:get_player_name(), - gain = MUSICVOLUME - }) - end - end - ---= START Ambiance - - -- head underwater - if minetest.registered_nodes[nod_head] - and minetest.registered_nodes[nod_head].groups.water then - return {underwater = underwater} - end - - -- wading through water - if minetest.registered_nodes[nod_feet] - and minetest.registered_nodes[nod_feet].groups.water then - - local control = player:get_player_control() - - if control.up or control.down or control.left or control.right then - return {splash = splash} - end - end - - local ps, cn = minetest.find_nodes_in_area( - {x = pos.x - radius, y = pos.y - radius, z = pos.z - radius}, - {x = pos.x + radius, y = pos.y + radius, z = pos.z + radius}, - { - "fire:basic_flame", "fire:permanent_flame", - "default:lava_flowing", "default:lava_source", "default:jungletree", - "default:water_flowing", "default:water_source", "default:ice", - "default:river_water_flowing", - "default:desert_sand", "default:desert_stone", "default:snowblock" - }) - - num_fire = (cn["fire:basic_flame"] or 0) + (cn["fire:permanent_flame"] or 0) - num_lava = (cn["default:lava_flowing"] or 0) + (cn["default:lava_source"] or 0) - num_water_flowing = (cn["default:water_flowing"] or 0) - num_water_source = (cn["default:water_source"] or 0) - num_desert = (cn["default:desert_sand"] or 0) + (cn["default:desert_stone"] or 0) - num_snow = (cn["default:snowblock"] or 0) - num_jungletree = (cn["default:jungletree"] or 0) - num_river = (cn["default:river_water_flowing"] or 0) - num_ice = (cn["default:ice"] or 0) ---[[ -print ( - "fr:" .. num_fire, - "lv:" .. num_lava, - "wf:" .. num_water_flowing, - "ws:" .. num_water_source, - "rv:" .. num_river, - "ds:" .. num_desert, - "sn:" .. num_snow, - "ic:" .. num_ice, - "jt:" .. num_jungletree -) -]] - -- is fire redo mod active? - if fire and fire.mod and fire.mod == "redo" then - - if num_fire > 16 then - return {largefire = largefire}, 0.4 - - elseif num_fire > 8 then - return {largefire = largefire} - - elseif num_fire > 3 then - return {smallfire = smallfire}, 0.2 - - elseif num_fire > 0 then - return {smallfire = smallfire} - end - end - - -- lava - if num_lava > 50 then - return {lava = lava}, 0.5 - elseif num_lava > 5 then - return {lava = lava} - end - - -- flowing water - if num_water_flowing > 50 then - return {flowing_water = flowing_water}, 0.5 - elseif num_water_flowing > 20 then - return {flowing_water = flowing_water} - end - - -- flowing river - if num_river > 20 then - return {river = river}, 0.4 - elseif num_river > 5 then - return {river = river} - end - - -- sea level beach - if pos.y < 7 and pos.y > 0 - and num_water_source > 100 then - return {beach = beach} - end - - -- ice flows - if num_ice > 100 and num_snow > 100 then - return {ice = ice} - end - - -- desert - if num_desert > 150 then - return {desert = desert} - end - - -- high up or surrounded by snow - if pos.y > 60 - or num_snow > 150 then - return {high_up = high_up} - end - - -- underground - if pos.y < -15 then - return {cave = cave} - end - - if tod > 0.2 - and tod < 0.8 then - - -- jungle day time - if num_jungletree > 90 then - return {jungle = jungle} + if can_add then + table.insert(sound_set_order, set_name) end - -- normal day time - return {day = day} - else + -- add any missing nodes to the set_nodes table + if def.nodes then - -- jungle night time - if num_jungletree > 90 then - return {jungle_night = jungle_night} - end + for i = 1, #def.nodes do - -- normal night time - return {night = night} - end + can_add = def.nodes[i] - -- END Ambiance -end + for j = 1, #set_nodes do --- play sound, set handler then delete handler when sound finished -local play_sound = function(player_name, list, number, MORE_GAIN) - - if list.handler[player_name] == nil then - - local handler = minetest.sound_play(list[number].name, { - to_player = player_name, - gain = ((list[number].gain or 0.3) + (MORE_GAIN or 0)) * SOUNDVOLUME - }) - - if handler then - - list.handler[player_name] = handler - - minetest.after(list[number].length, function(args) - - local list = args[1] - local player_name = args[2] - - if list.handler[player_name] then - - minetest.sound_stop(list.handler[player_name]) - - list.handler[player_name] = nil + if def.nodes[i] == set_nodes[j] then + can_add = false + end end - end, {list, player_name}) + if can_add then + table.insert(set_nodes, can_add) + end + end end end end --- stop sound in still_playing -local stop_sound = function (list, player_name) - if list.handler[player_name] then +ambience.get_set = function(set_name) - minetest.sound_stop(list.handler[player_name]) - - list.handler[player_name] = nil + if sound_sets[set_name] then + return sound_sets[set_name] end end --- check sounds that are not in still_playing -local still_playing = function(still_playing, player_name) - if not still_playing.cave then stop_sound(cave, player_name) end - if not still_playing.high_up then stop_sound(high_up, player_name) end - if not still_playing.beach then stop_sound(beach, player_name) end - if not still_playing.desert then stop_sound(desert, player_name) end - if not still_playing.night then stop_sound(night, player_name) end - if not still_playing.day then stop_sound(day, player_name) end - if not still_playing.flowing_water then stop_sound(flowing_water, player_name) end - if not still_playing.splash then stop_sound(splash, player_name) end - if not still_playing.underwater then stop_sound(underwater, player_name) end - if not still_playing.river then stop_sound(river, player_name) end - if not still_playing.lava then stop_sound(lava, player_name) end - if not still_playing.smallfire then stop_sound(smallfire, player_name) end - if not still_playing.largefire then stop_sound(largefire, player_name) end - if not still_playing.jungle then stop_sound(jungle, player_name) end - if not still_playing.jungle_night then stop_sound(jungle_night, player_name) end - if not still_playing.ice then stop_sound(ice, player_name) end +ambience.del_set = function(set_name) + + sound_sets[set_name] = nil + + local can_del = false + + for i = 1, #sound_set_order do + + if sound_set_order[i] == set_name then + can_del = i + end + end + + if can_del then + table.remove(sound_set_order, can_del) + end +end + + +-- plays music and selects sound set +local get_ambience = function(player, tod, name) + + -- play server or local music if available + if play_music and playing[name] then + + -- play at midnight + if tod >= 0.0 and tod <= 0.01 then + + if not playing[name].music then + + playing[name].music = minetest.sound_play("ambience_music", { + to_player = player:get_player_name(), + gain = MUSICVOLUME + }) + end + + elseif tod > 0.1 and playing[name].music then + + playing[name].music = nil + end + end + + + -- get foot and head level nodes at player position + local pos = player:get_pos() + + pos.y = pos.y + 1.4 -- head level + + local nod_head = pplus and playerplus[name].nod_head or minetest.get_node(pos).name + + pos.y = pos.y - 1.2 -- foot level + + local nod_feet = pplus and playerplus[name].nod_feet or minetest.get_node(pos).name + + pos.y = pos.y - 0.2 -- reset pos + + + -- get all set nodes around player + local ps, cn = minetest.find_nodes_in_area( + {x = pos.x - radius, y = pos.y - radius, z = pos.z - radius}, + {x = pos.x + radius, y = pos.y + radius, z = pos.z + radius}, set_nodes) + + -- loop through sets in order and play appropriate sound + for n = 1, #sound_set_order do + + local set = sound_sets[ sound_set_order[n] ] + + if set and set.sound_check then + + local set_name, gain = set.sound_check({ + player = player, + pos = pos, + tod = tod, + totals = cn, + positions = ps, + head_node = nod_head, + feet_node = nod_feet + }) + + if set_name then + return set_name, gain + end + end + end end --- player routine local timer = 0 +local random = math.random +-- player routine minetest.register_globalstep(function(dtime) -- every 1 second @@ -398,30 +175,87 @@ minetest.register_globalstep(function(dtime) timer = 0 local players = minetest.get_connected_players() - local MORE_GAIN + local player_name, number, chance, ambience, handler + local tod = minetest.get_timeofday() for n = 1, #players do - local player_name = players[n]:get_player_name() + player_name = players[n]:get_player_name() --local t1 = os.clock() - ambiences, MORE_GAIN = get_ambience(players[n]) + local set_name, MORE_GAIN = get_ambience(players[n], tod, player_name) --print(string.format("elapsed time: %.4f\n", os.clock() - t1)) - still_playing(ambiences, player_name) + if set_name then - for _,ambience in pairs(ambiences) do + -- stop sound if another set active + if playing[player_name] + and playing[player_name].handler then - if math.random(1, 1000) <= ambience.frequency then + if playing[player_name].sound ~= set_name + or (playing[player_name].sound == set_name + and playing[player_name].gain ~= MORE_GAIN) then - play_sound(player_name, ambience, math.random(1, #ambience), MORE_GAIN) + minetest.sound_stop(playing[player_name].handler) + + playing[player_name].sound = nil + playing[player_name].handler = nil + playing[player_name].gain = nil + else + return + end + end + + -- choose random sound from set + number = random(1, #sound_sets[set_name].sounds) + ambience = sound_sets[set_name].sounds[number] + + math.randomseed(tod + number) + + chance = random(1, 1000) + + if chance < sound_sets[set_name].frequency then + + handler = minetest.sound_play(ambience.name, { + to_player = player_name, + gain = ((ambience.gain or 0.3) + (MORE_GAIN or 0)) * SOUNDVOLUME + }) + +--print ("playing... " .. ambience.name .. " (" .. chance .. " < " +-- .. sound_sets[set_name].frequency .. ") @ ", MORE_GAIN) + + if handler then + + playing[player_name] = playing[player_name] or {} + playing[player_name].handler = handler + playing[player_name].sound = set_name + playing[player_name].gain = MORE_GAIN + + minetest.after(ambience.length, function(args) + + local player_name = args[2] + + if playing[player_name] + and playing[player_name].handler + and playing[player_name].sound == set_name then + + minetest.sound_stop(playing[player_name].handler) + + playing[player_name].sound = nil + playing[player_name].handler = nil + playing[player_name].gain = nil + end + + end, {ambience, player_name}) + end end end end end) + -- set volume commands minetest.register_chatcommand("svol", { params = "", @@ -439,6 +273,7 @@ minetest.register_chatcommand("svol", { end, }) + minetest.register_chatcommand("mvol", { params = "", description = "set music volume (0.1 to 1.0)", @@ -448,9 +283,21 @@ minetest.register_chatcommand("mvol", { MUSICVOLUME = tonumber(param) or MUSICVOLUME + -- ability to stop music just as it begins + if MUSICVOLUME == 0 and playing[name].music then + minetest.sound_stop(playing[name].music) + end + if MUSICVOLUME < 0.1 then MUSICVOLUME = 0.1 end if MUSICVOLUME > 1.0 then MUSICVOLUME = 1.0 end return true, "Music volume set to " .. MUSICVOLUME end, }) + + +-- load default sound sets +dofile(minetest.get_modpath("ambience") .. "/soundsets.lua") + + +print("[MOD] Ambience Lite loaded") diff --git a/soundsets.lua b/soundsets.lua new file mode 100644 index 0000000..4a54953 --- /dev/null +++ b/soundsets.lua @@ -0,0 +1,342 @@ +--[[ + Default Sound Sets + ------------------ + + Order is very important when adding a sound set so it will play a certain + set of sounds before any another. +--]] + +-- Underwater sounds play when player head is submerged + +ambience.add_set("underwater", { + frequency = 1000, + sounds = { + {name = "scuba", length = 8} + }, + sound_check = function(def) + + if minetest.registered_nodes[def.head_node] + and minetest.registered_nodes[def.head_node].groups.water then + return "underwater" + end + end, +}) + +-- Splashing sound plays when player walks inside water nodes + +ambience.add_set("splash", { + frequency = 1000, + sounds = { + {name = "swim_splashing", length = 3}, + }, + sound_check = function(def) + + if minetest.registered_nodes[def.feet_node] + and minetest.registered_nodes[def.feet_node].groups.water then + + local control = def.player:get_player_control() + + if control.up or control.down or control.left or control.right then + return "splash" + end + end + end, +}) + +-- Small fire sound plays when near flame, will get louder if more than 3 + +ambience.add_set("smallfire", { + frequency = 1000, + sounds = { + {name = "fire_small", length = 6, gain = 0.1} + }, + sound_check = function(def) + + if fire and fire.mod and fire.mod == "redo" then + + local c = (def.totals["fire:basic_flame"] or 0) + + (def.totals["fire:permanent_flame"] or 0) + + if c > 3 and c < 9 then + return "smallfire", 0.2 + + elseif c > 0 and c < 4 then + return "smallfire" + end + end + end, + nodes = {"fire:basic_flame", "fire:permanent_flame"} +}) + +-- Large fire sound plays when near flames, will get louder if more than 16 + +ambience.add_set("largefire", { + frequency = 1000, + sounds = { + {name = "fire_large", length = 8, gain = 0.4} + }, + sound_check = function(def) + + if fire and fire.mod and fire.mod == "redo" then + + local c = (def.totals["fire:basic_flame"] or 0) + + (def.totals["fire:permanent_flame"] or 0) + + if c > 16 then + return "largefire", 0.4 + + elseif c > 8 then + return "largefire" + end + end + end, + nodes = {"fire:basic_flame", "fire:permanent_flame"} +}) + +-- Lava sound plays when near lava, will get louder if more than 50 + +ambience.add_set("lava", { + frequency = 1000, + sounds = { + {name = "lava", length = 7} + }, + sound_check = function(def) + + local c = (def.totals["default:lava_source"] or 0) + + (def.totals["default:lava_flowing"] or 0) + + if c > 50 then + return "lava", 0.5 + + elseif c > 5 then + return "lava" + end + end, + nodes = {"default:lava_source", "default:lava_flowing"} +}) + +-- Water sound plays when near flowing water, will get louder if more than 50 + +ambience.add_set("flowing_water", { + frequency = 1000, + sounds = { + {name = "waterfall", length = 6} + }, + sound_check = function(def) + + local c = (def.totals["default:water_flowing"] or 0) + + if c > 50 then + return "flowing_water", 0.5 + + elseif c > 20 then + return "flowing_water" + end + end, + nodes = {"default:water_flowing"} +}) + +-- River sound plays when near flowing river, will get louder if more than 20 + +ambience.add_set("river", { + frequency = 1000, + sounds = { + {name = "river", length = 4, gain = 0.1} + }, + sound_check = function(def) + + local c = (def.totals["default:river_water_flowing"] or 0) + + if c > 20 then + return "river", 0.4 + + elseif c > 5 then + return "river" + end + end, + nodes = {"default:river_water_flowing"} +}) + +-- Beach sounds play when around 0-7 player Y position and 150+ water source found + +ambience.add_set("beach", { + frequency = 40, + sounds = { + {name = "seagull", length = 4.5}, + {name = "beach", length = 13}, + {name = "gull", length = 1}, + {name = "beach_2", length = 6}, + }, + sound_check = function(def) + + local c = (def.totals["default:water_source"] or 0) + + if def.pos.y < 7 and def.pos.y > 0 + and c > 150 then + return "beach" + end + end, + nodes = {"default:water_source"} +}) + +-- Ice sounds play when 100 or more ice are nearby + +ambience.add_set("ice", { + frequency = 250, + sounds = { + {name = "icecrack", length = 23}, + {name = "desertwind", length = 8}, + {name = "wind", length = 9}, + }, + sound_check = function(def) + + local c = (def.totals["default:ice"] or 0) + + if c > 100 then + return "ice" + end + end, + nodes = {"default:ice"}, +}) + +-- Desert sounds play when near 150+ desert sand or stone + +ambience.add_set("desert", { + frequency = 20, + sounds = { + {name = "coyote", length = 2.5}, + {name = "wind", length = 9}, + {name = "desertwind", length = 8} + }, + sound_check = function(def) + + local c = (def.totals["default:desert_sand"] or 0) + + (def.totals["default:desert_stone"] or 0) + + if c > 150 then + return "desert" + end + end, + nodes = {"default:desert_sand", "default:desert_stone"} +}) + +-- Winds play when player is above 60 Y position and near 150+ snow blocks + +ambience.add_set("high_up", { + frequency = 40, + sounds = { + {name = "desertwind", length = 8}, + {name = "wind", length = 9}, + }, + sound_check = function(def) + + local c = (def.totals["default:snowblock"] or 0) + + if def.pos.y > 60 + or c > 150 then + return "high_up" + end + end, + nodes = {"default:snowblock"} +}) + +-- Cave sounds play when below player position Y -25 + +ambience.add_set("cave", { + frequency = 60, + sounds = { + {name = "drippingwater1", length = 1.5}, + {name = "drippingwater2", length = 1.5} + }, + sound_check = function(def) + + if def.pos.y < -25 then + return "cave" + end + end, +}) + +-- Jungle sounds play during daytime and when around 90 jungletree trunks + +ambience.add_set("jungle", { + frequency = 200, + sounds = { + {name = "jungle_day_1", length = 7}, + {name = "deer", length = 7}, + {name = "canadianloon2", length = 14}, + {name = "bird1", length = 11}, + {name = "peacock", length = 2}, + }, + sound_check = function(def) + + local c = (def.totals["default:jungletree"] or 0) + + if def.tod > 0.2 and def.tod < 0.8 and c > 90 then + return "jungle" + end + end, + nodes = {"default:jungletree"} +}) + +-- Jungle sounds play during nighttime and when around 90 jungletree trunks + +ambience.add_set("jungle_night", { + frequency = 200, + sounds = { + {name = "jungle_night_1", length = 4}, + {name = "jungle_night_2", length = 4}, + {name = "deer", length = 7}, + {name = "frog", length = 1}, + }, + sound_check = function(def) + + local c = (def.totals["default:jungletree"] or 0) + + if (def.tod < 0.2 or def.tod > 0.8) and c > 90 then + return "jungle" + end + end, + nodes = {"default:jungletree"} +}) + +-- Nighttime sounds play at night (default sounds near end of list) + +ambience.add_set("night", { + frequency = 40, + sounds = { + {name = "hornedowl", length = 2}, + {name = "wolves", length = 4, gain = 0.4}, + {name = "cricket", length = 6}, + {name = "deer", length = 7}, + {name = "frog", length = 1}, + }, + sound_check = function(def) + + if def.tod < 0.2 or def.tod > 0.8 then + return "night" + end + end, +}) + +-- Daytime sounds play during day (default sounds near end of list) + +ambience.add_set("day", { + frequency = 40, + sounds = { + {name = "cardinal", length = 3}, + {name = "craw", length = 3}, + {name = "bluejay", length = 6}, + {name = "robin", length = 4}, + {name = "bird1", length = 11}, + {name = "bird2", length = 6}, + {name = "crestedlark", length = 6}, + {name = "peacock", length = 2}, + {name = "wind", length = 9}, + }, + sound_check = function(def) + + if def.tod > 0.2 and def.tod < 0.8 then + return "day" + end + end, +})