mirror of
				https://codeberg.org/tenplus1/ambience.git
				synced 2025-11-04 09:35:30 +01:00 
			
		
		
		
	Compare commits
	
		
			10 Commits
		
	
	
		
			e317f727d0
			...
			a566fa9acc
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					a566fa9acc | ||
| 
						 | 
					6ad91b84db | ||
| 
						 | 
					e8c436685d | ||
| 
						 | 
					fe23993419 | ||
| 
						 | 
					82d5297666 | ||
| 
						 | 
					90660a7d8a | ||
| 
						 | 
					01ebd210df | ||
| 
						 | 
					0b7b1fd27d | ||
| 
						 | 
					bffbb1c822 | ||
| 
						 | 
					f4e73d592e | 
@@ -18,5 +18,7 @@ Based on Immersive Sounds .36 mod by Neuromancer and optimized to run on servers
 | 
			
		||||
- 1.3 - Added API for use with other mods, code rewrite
 | 
			
		||||
- 1.4 - Re-ordered water sets to come before fire and lava, day/night sounds play when leaves around and above ground
 | 
			
		||||
- 1.5 - Added 'flame_sound' and fire redo check, code tidy and tweak, added ephemeral flag for background sounds.
 | 
			
		||||
- 1.6 - Finding env_sounds disables water and lava sets, added 'ambience_water_move' flag to override water walking sounds, use eye level for head node.
 | 
			
		||||
- 1.7 - Music will play every 20-30 minutes if found, use '/mvol 0' to stop playing music or disable in-game.
 | 
			
		||||
 | 
			
		||||
Code license: MIT
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										131
									
								
								init.lua
									
									
									
									
									
								
							
							
						
						
									
										131
									
								
								init.lua
									
									
									
									
									
								
							@@ -1,15 +1,9 @@
 | 
			
		||||
 | 
			
		||||
ambience = {}
 | 
			
		||||
 | 
			
		||||
-- override default water sounds
 | 
			
		||||
minetest.override_item("default:water_source", { sounds = {} })
 | 
			
		||||
minetest.override_item("default:water_flowing", { sounds = {} })
 | 
			
		||||
minetest.override_item("default:river_water_source", { sounds = {} })
 | 
			
		||||
minetest.override_item("default:river_water_flowing", { sounds = {} })
 | 
			
		||||
 | 
			
		||||
-- settings
 | 
			
		||||
local SOUNDVOLUME = 1.0
 | 
			
		||||
local MUSICVOLUME = 1.0
 | 
			
		||||
local MUSICVOLUME = 0.6
 | 
			
		||||
local play_music = minetest.settings:get_bool("ambience_music") ~= false
 | 
			
		||||
local pplus = minetest.get_modpath("playerplus")
 | 
			
		||||
local radius = 6
 | 
			
		||||
@@ -19,8 +13,6 @@ local sound_set_order = {} -- needed because pairs loops randomly through tables
 | 
			
		||||
local set_nodes = {} -- all the nodes needed for sets
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- global functions
 | 
			
		||||
 | 
			
		||||
-- add set to list
 | 
			
		||||
ambience.add_set = function(set_name, def)
 | 
			
		||||
 | 
			
		||||
@@ -73,10 +65,7 @@ end
 | 
			
		||||
 | 
			
		||||
-- return set from list using name
 | 
			
		||||
ambience.get_set = function(set_name)
 | 
			
		||||
 | 
			
		||||
	if sound_sets[set_name] then
 | 
			
		||||
		return sound_sets[set_name]
 | 
			
		||||
	end
 | 
			
		||||
	return sound_sets[set_name]
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -100,39 +89,57 @@ ambience.del_set = function(set_name)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- setup table when player joins
 | 
			
		||||
minetest.register_on_joinplayer(function(player)
 | 
			
		||||
	playing[player:get_player_name()] = {music = -1}
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
-- remove table when player leaves
 | 
			
		||||
minetest.register_on_leaveplayer(function(player)
 | 
			
		||||
	playing[player:get_player_name()] = nil
 | 
			
		||||
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 server or local music if music enabled and music not already playing
 | 
			
		||||
	if play_music and MUSICVOLUME > 0 and playing[name].music < 0 then
 | 
			
		||||
 | 
			
		||||
		-- play at midnight
 | 
			
		||||
		if tod >= 0.0 and tod <= 0.01 then
 | 
			
		||||
		-- count backwards
 | 
			
		||||
		playing[name].music = playing[name].music -1
 | 
			
		||||
 | 
			
		||||
			if not playing[name].music then
 | 
			
		||||
		-- play music every 20 minutes
 | 
			
		||||
		if playing[name].music < -(60 * 20) then
 | 
			
		||||
 | 
			
		||||
				playing[name].music = minetest.sound_play("ambience_music", {
 | 
			
		||||
					to_player = player:get_player_name(),
 | 
			
		||||
					gain = MUSICVOLUME
 | 
			
		||||
				})
 | 
			
		||||
			end
 | 
			
		||||
			playing[name].music = minetest.sound_play("ambience_music", {
 | 
			
		||||
				to_player = name,
 | 
			
		||||
				gain = MUSICVOLUME
 | 
			
		||||
			})
 | 
			
		||||
 | 
			
		||||
		elseif tod > 0.1 and playing[name].music then
 | 
			
		||||
			-- reset music timer after 10 minutes
 | 
			
		||||
			minetest.after(60 * 10, function(name)
 | 
			
		||||
 | 
			
		||||
			playing[name].music = nil
 | 
			
		||||
				if playing[name] then
 | 
			
		||||
					playing[name].music = -1
 | 
			
		||||
				end
 | 
			
		||||
			end, name)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
--print("-- music count", playing[name].music)
 | 
			
		||||
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	-- get foot and head level nodes at player position
 | 
			
		||||
	local pos = player:get_pos() ; if not pos then return end
 | 
			
		||||
	local prop = player:get_properties()
 | 
			
		||||
 | 
			
		||||
	pos.y = pos.y + 1.4 -- head level
 | 
			
		||||
	pos.y = pos.y + prop.eye_height -- eye level
 | 
			
		||||
 | 
			
		||||
	local nod_head = pplus and name and playerplus[name]
 | 
			
		||||
			and playerplus[name].nod_head or minetest.get_node(pos).name
 | 
			
		||||
 | 
			
		||||
	pos.y = pos.y - 1.2 -- foot level
 | 
			
		||||
	pos.y = (pos.y - prop.eye_height) + 0.2 -- foot level
 | 
			
		||||
 | 
			
		||||
	local nod_feet = pplus and name and playerplus[name]
 | 
			
		||||
			and playerplus[name].nod_feet or minetest.get_node(pos).name
 | 
			
		||||
@@ -168,6 +175,8 @@ local get_ambience = function(player, tod, name)
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	return nil, nil -- ADDED
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -182,27 +191,24 @@ minetest.register_globalstep(function(dtime)
 | 
			
		||||
	if timer < 1 then return end
 | 
			
		||||
	timer = 0
 | 
			
		||||
 | 
			
		||||
	-- get list of players and set some variables
 | 
			
		||||
	local players = minetest.get_connected_players()
 | 
			
		||||
	local player_name, number, chance, ambience, handler, ok
 | 
			
		||||
	local tod = minetest.get_timeofday()
 | 
			
		||||
 | 
			
		||||
	-- loop through players
 | 
			
		||||
	for n = 1, #players do
 | 
			
		||||
	for _, player in ipairs(minetest.get_connected_players()) do
 | 
			
		||||
 | 
			
		||||
		player_name = players[n]:get_player_name()
 | 
			
		||||
		player_name = player:get_player_name()
 | 
			
		||||
 | 
			
		||||
--local t1 = os.clock()
 | 
			
		||||
 | 
			
		||||
		local set_name, MORE_GAIN = get_ambience(players[n], tod, player_name)
 | 
			
		||||
		local set_name, MORE_GAIN = get_ambience(player, tod, player_name)
 | 
			
		||||
 | 
			
		||||
--print(string.format("elapsed time: %.4f\n", os.clock() - t1))
 | 
			
		||||
 | 
			
		||||
		ok = true -- everything starts off ok
 | 
			
		||||
		ok = playing[player_name] -- everything starts off ok if player found
 | 
			
		||||
 | 
			
		||||
		-- are we playing something already?
 | 
			
		||||
		if playing[player_name]
 | 
			
		||||
		and playing[player_name].handler then
 | 
			
		||||
		if ok and playing[player_name].handler then
 | 
			
		||||
 | 
			
		||||
			-- stop current sound if another set active or gain changed
 | 
			
		||||
			if playing[player_name].set ~= set_name
 | 
			
		||||
@@ -213,8 +219,8 @@ minetest.register_globalstep(function(dtime)
 | 
			
		||||
				minetest.sound_stop(playing[player_name].handler)
 | 
			
		||||
 | 
			
		||||
				playing[player_name].set = nil
 | 
			
		||||
				playing[player_name].handler = nil
 | 
			
		||||
				playing[player_name].gain = nil
 | 
			
		||||
				playing[player_name].handler = nil
 | 
			
		||||
			else
 | 
			
		||||
				ok = false -- sound set still playing, skip new sound
 | 
			
		||||
			end
 | 
			
		||||
@@ -246,30 +252,29 @@ minetest.register_globalstep(function(dtime)
 | 
			
		||||
--print("-- current handler", handler)
 | 
			
		||||
 | 
			
		||||
				-- set what player is currently listening to
 | 
			
		||||
				playing[player_name] = {
 | 
			
		||||
					set = set_name, gain = MORE_GAIN, handler = handler
 | 
			
		||||
				}
 | 
			
		||||
				playing[player_name].set = set_name
 | 
			
		||||
				playing[player_name].gain = MORE_GAIN
 | 
			
		||||
				playing[player_name].handler = handler
 | 
			
		||||
 | 
			
		||||
				-- set timer to stop sound
 | 
			
		||||
				minetest.after(ambience.length, function()
 | 
			
		||||
 | 
			
		||||
--print("-- after", set_name, handler)
 | 
			
		||||
 | 
			
		||||
					-- make sure we are stopping same sound we started
 | 
			
		||||
					if playing[player_name]
 | 
			
		||||
					and playing[player_name].handler
 | 
			
		||||
					and playing[player_name].handler == handler then
 | 
			
		||||
				minetest.after(ambience.length, function(handler, player_name)
 | 
			
		||||
 | 
			
		||||
--print("-- timed stop", set_name, handler)
 | 
			
		||||
 | 
			
		||||
					if handler then
 | 
			
		||||
						minetest.sound_stop(handler)
 | 
			
		||||
 | 
			
		||||
						-- reset player variables and backup handler
 | 
			
		||||
						playing[player_name] = {
 | 
			
		||||
							set = nil, gain = nil, handler = nil
 | 
			
		||||
						}
 | 
			
		||||
					end
 | 
			
		||||
				end)
 | 
			
		||||
 | 
			
		||||
					-- reset variables if handlers match
 | 
			
		||||
					if playing[player_name]
 | 
			
		||||
					and playing[player_name].handler == handler then
 | 
			
		||||
 | 
			
		||||
--print("-- timed reset", handler, player_name)
 | 
			
		||||
 | 
			
		||||
						playing[player_name].set = nil
 | 
			
		||||
						playing[player_name].gain = nil
 | 
			
		||||
						playing[player_name].handler = nil
 | 
			
		||||
					end
 | 
			
		||||
				end, handler, player_name)
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
@@ -290,30 +295,34 @@ minetest.register_chatcommand("svol", {
 | 
			
		||||
		if SOUNDVOLUME > 1.0 then SOUNDVOLUME = 1.0 end
 | 
			
		||||
 | 
			
		||||
		return true, "Sound volume set to " .. SOUNDVOLUME
 | 
			
		||||
	end,
 | 
			
		||||
	end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- music volume command (0 stops music)
 | 
			
		||||
minetest.register_chatcommand("mvol", {
 | 
			
		||||
	params = "<mvol>",
 | 
			
		||||
	description = "set music volume (0.1 to 1.0)",
 | 
			
		||||
	description = "set music volume (0.1 to 1.0, 0 to stop music)",
 | 
			
		||||
	privs = {server = true},
 | 
			
		||||
 | 
			
		||||
	func = function(name, param)
 | 
			
		||||
 | 
			
		||||
		MUSICVOLUME = tonumber(param) or MUSICVOLUME
 | 
			
		||||
 | 
			
		||||
		-- ability to stop music just as it begins
 | 
			
		||||
		if MUSICVOLUME == 0 and playing[name].music then
 | 
			
		||||
		-- ability to stop music by setting volume to 0
 | 
			
		||||
		if MUSICVOLUME == 0 and playing[name].music
 | 
			
		||||
		and playing[name].music >= 0 then
 | 
			
		||||
 | 
			
		||||
			minetest.sound_stop(playing[name].music)
 | 
			
		||||
 | 
			
		||||
			playing[name].music = -1
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if MUSICVOLUME < 0.1 then MUSICVOLUME = 0.1 end
 | 
			
		||||
		if MUSICVOLUME < 0 then MUSICVOLUME = 0 end
 | 
			
		||||
		if MUSICVOLUME > 1.0 then MUSICVOLUME = 1.0 end
 | 
			
		||||
 | 
			
		||||
		return true, "Music volume set to " .. MUSICVOLUME
 | 
			
		||||
	end,
 | 
			
		||||
	end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,2 +1,5 @@
 | 
			
		||||
#    If enabled will play a random music file from ./minetest/sounds at midnight
 | 
			
		||||
ambience_music (Ambience music) bool true
 | 
			
		||||
 | 
			
		||||
#    If enabled then ambience will take over sounds when moving in water
 | 
			
		||||
ambience_water_move (Ambience water movement) bool true
 | 
			
		||||
 
 | 
			
		||||
@@ -25,14 +25,22 @@ ambience.add_set("underwater", {
 | 
			
		||||
	end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
-- Splashing sound plays when player walks inside water nodes
 | 
			
		||||
-- Splashing sound plays when player walks inside water nodes (if enabled)
 | 
			
		||||
 | 
			
		||||
if minetest.settings:get_bool("ambience_water_move") ~= false then
 | 
			
		||||
 | 
			
		||||
-- override default water sounds
 | 
			
		||||
minetest.override_item("default:water_source", { sounds = {} })
 | 
			
		||||
minetest.override_item("default:water_flowing", { sounds = {} })
 | 
			
		||||
minetest.override_item("default:river_water_source", { sounds = {} })
 | 
			
		||||
minetest.override_item("default:river_water_flowing", { sounds = {} })
 | 
			
		||||
 | 
			
		||||
ambience.add_set("splash", {
 | 
			
		||||
 | 
			
		||||
	frequency = 1000,
 | 
			
		||||
 | 
			
		||||
	sounds = {
 | 
			
		||||
		{name = "swim_splashing", length = 3},
 | 
			
		||||
		{name = "swim_splashing", length = 3}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	sound_check = function(def)
 | 
			
		||||
@@ -49,7 +57,9 @@ ambience.add_set("splash", {
 | 
			
		||||
	end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
-- check for env_sounds mod, if not found enable water flowing sounds
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- check for env_sounds mod, if not found enable water flowing and lava sounds
 | 
			
		||||
if not minetest.get_modpath("env_sounds") then
 | 
			
		||||
 | 
			
		||||
-- Water sound plays when near flowing water
 | 
			
		||||
@@ -102,6 +112,32 @@ ambience.add_set("river", {
 | 
			
		||||
	end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
-- Lava sound plays when near lava
 | 
			
		||||
 | 
			
		||||
ambience.add_set("lava", {
 | 
			
		||||
 | 
			
		||||
	frequency = 1000,
 | 
			
		||||
 | 
			
		||||
	sounds = {
 | 
			
		||||
		{name = "lava", length = 7}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	nodes = {"default:lava_source", "default:lava_flowing"},
 | 
			
		||||
 | 
			
		||||
	sound_check = function(def)
 | 
			
		||||
 | 
			
		||||
		local c = (def.totals["default:lava_source"] or 0)
 | 
			
		||||
			+ (def.totals["default:lava_flowing"] or 0)
 | 
			
		||||
 | 
			
		||||
		if c > 20 then
 | 
			
		||||
			return "lava", 0.5
 | 
			
		||||
 | 
			
		||||
		elseif c > 5 then
 | 
			
		||||
			return "lava"
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
else
 | 
			
		||||
	print ("[Ambience] found env_sounds, flowing water sounds disabled.")
 | 
			
		||||
end
 | 
			
		||||
@@ -170,32 +206,6 @@ ambience.add_set("largefire", {
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- Lava sound plays when near lava
 | 
			
		||||
 | 
			
		||||
ambience.add_set("lava", {
 | 
			
		||||
 | 
			
		||||
	frequency = 1000,
 | 
			
		||||
 | 
			
		||||
	sounds = {
 | 
			
		||||
		{name = "lava", length = 7}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	nodes = {"default:lava_source", "default:lava_flowing"},
 | 
			
		||||
 | 
			
		||||
	sound_check = function(def)
 | 
			
		||||
 | 
			
		||||
		local c = (def.totals["default:lava_source"] or 0)
 | 
			
		||||
			+ (def.totals["default:lava_flowing"] or 0)
 | 
			
		||||
 | 
			
		||||
		if c > 20 then
 | 
			
		||||
			return "lava", 0.5
 | 
			
		||||
 | 
			
		||||
		elseif c > 5 then
 | 
			
		||||
			return "lava"
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
-- Beach sounds play when below y-pos 6 and 150+ water source found
 | 
			
		||||
 | 
			
		||||
ambience.add_set("beach", {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user