diff --git a/README.md b/README.md index e756270..b3fbb97 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,9 @@ CC BY 3.0 CC0 * scifi_nodes_digicode.ogg https://freesound.org/people/benjaminharveydesign/sounds/315921/ +* scifi_nodes_ambience_fan.ogg https://freesound.org/people/itinerantmonk108/sounds/554430/ +* scifi_nodes_ambience_vent.ogg https://freesound.org/people/kentspublicdomain/sounds/324665/ +* scifi_nodes_ambience_engine.ogg https://freesound.org/people/firestorm185/sounds/423221/ # Contributors: diff --git a/ambience.lua b/ambience.lua new file mode 100644 index 0000000..8528839 --- /dev/null +++ b/ambience.lua @@ -0,0 +1,73 @@ + +-- currently playing sounds per mapblock +-- mapblock_pos[number] +local currently_playing = {} + +-- clear the currently playing tracker every few seconds +local function clear_currently_playing() + currently_playing = {} + minetest.after(5, clear_currently_playing) +end +minetest.after(5, clear_currently_playing) + +-- mapblock resolution +local function get_key(pos) + return minetest.pos_to_string(vector.round(vector.divide(pos, 16))) +end + +local function add_currently_playing(pos, value) + local key = get_key(pos) + local count = currently_playing[key] + if not count then + -- new entry + count = value + else + -- update entry + count = count + value + end + currently_playing[key] = count +end + +-- limit plaing sounds per mapblock +local function can_play(pos) + local count = currently_playing[get_key(pos)] + return not count or count < 25 +end + +-- register ambience sounds with node-timer +function scifi_nodes.register_ambience(nodename, soundname, opts) + assert(opts) + opts.interval = opts.interval or 60 + + local function play(pos) + minetest.sound_play(soundname ,{ + max_hear_distance = opts.max_hear_distance or 16, + pos = pos, + gain = opts.gain or 0.7 + }) + end + + minetest.override_item(nodename, { + on_timer = function(pos) + local timer = minetest.get_node_timer(pos) + + if not can_play(pos) then + -- too many sounds playing, recheck again soon + timer:start(1) + return + end + + -- increment usage count + add_currently_playing(pos, 1) + play(pos) + + -- restart timer + timer:start(opts.interval) + end, + on_construct = function(pos) + play(pos) + local timer = minetest.get_node_timer(pos) + timer:start(opts.interval) + end + }) +end diff --git a/init.lua b/init.lua index d664994..eec022a 100644 --- a/init.lua +++ b/init.lua @@ -20,6 +20,7 @@ if minetest.get_modpath("default") then dofile(MP.."/chest.lua") end +dofile(MP.."/ambience.lua") dofile(MP.."/plants.lua") dofile(MP.."/models.lua") dofile(MP.."/nodes.lua") diff --git a/nodes.json b/nodes.json index 4b23d5f..86b44d7 100644 --- a/nodes.json +++ b/nodes.json @@ -25,7 +25,12 @@ "texture_name": "white2" }, "engine": { - "description": "Engine" + "description": "Engine", + "ambience": { + "scifi_nodes_ambience_engine": { + "interval": 16.1 + } + } }, "wall": { "description": "metal wall" @@ -58,7 +63,12 @@ "description": "transparent vent", "texture_name": "vent2", "texture_modifier": "^[makealpha:33,33,33", - "drawtype": "glasslike" + "drawtype": "glasslike", + "ambience": { + "scifi_nodes_ambience_vent": { + "interval": 4.2 + } + } }, "stripes": { "description": "hazard stripes", @@ -261,7 +271,12 @@ "light": 5 }, "fan": { - "description": "Fan" + "description": "Fan", + "ambience": { + "scifi_nodes_ambience_fan": { + "interval": 7 + } + } }, "ppllght": { "description": "Purple wall light", diff --git a/nodes.lua b/nodes.lua index 38dfe9a..6b5b791 100644 --- a/nodes.lua +++ b/nodes.lua @@ -537,7 +537,8 @@ for name, def in pairs(nodes) do end -- register node - minetest.register_node("scifi_nodes:"..name, node_def) + local nodename = "scifi_nodes:" .. name + minetest.register_node(nodename , node_def) -- unified dyes registration if def.colorable and has_unifieddyes_mod then @@ -574,6 +575,12 @@ for name, def in pairs(nodes) do }) end + if def.ambience then + for soundname, opts in pairs(def.ambience) do + scifi_nodes.register_ambience(nodename, soundname, opts) + end + end + -- advtrains platform registration if has_advtrains_mod and def.advtrains_platform then advtrains.register_platform("scifi_nodes", "scifi_nodes:" .. name) diff --git a/sounds/scifi_nodes_ambience_engine.ogg b/sounds/scifi_nodes_ambience_engine.ogg new file mode 100644 index 0000000..ebf1acc Binary files /dev/null and b/sounds/scifi_nodes_ambience_engine.ogg differ diff --git a/sounds/scifi_nodes_ambience_fan.ogg b/sounds/scifi_nodes_ambience_fan.ogg new file mode 100644 index 0000000..c152927 Binary files /dev/null and b/sounds/scifi_nodes_ambience_fan.ogg differ diff --git a/sounds/scifi_nodes_ambience_vent.ogg b/sounds/scifi_nodes_ambience_vent.ogg new file mode 100644 index 0000000..941a4dd Binary files /dev/null and b/sounds/scifi_nodes_ambience_vent.ogg differ