diff --git a/init.lua b/init.lua index 1293c67..7985d4a 100644 --- a/init.lua +++ b/init.lua @@ -144,6 +144,122 @@ minetest.override_item("default:coalblock", { end, }) +-- +-- Sound +-- + +local flame_sound = minetest.setting_getbool("flame_sound") +if flame_sound == nil then + -- Enable if no setting present + flame_sound = true +end + +if flame_sound then + + local handles = {} + local timer = 0 + + -- Parameters + + local radius = 8 -- Flame node search radius around player + local cycle = 3 -- Cycle time for sound updates + + -- Update sound for player + + function fire.update_player_sound(player) + local player_name = player:get_player_name() + -- Search for flame nodes in radius around player + local ppos = player:getpos() + local areamin = vector.subtract(ppos, radius) + local areamax = vector.add(ppos, radius) + local fpos, num = minetest.find_nodes_in_area( + areamin, + areamax, + {"fire:basic_flame", "fire:permanent_flame"} + ) + -- Total number of flames in radius + local flames = (num["fire:basic_flame"] or 0) + + (num["fire:permanent_flame"] or 0) + -- Stop previous sound + if handles[player_name] then + minetest.sound_stop(handles[player_name]) + handles[player_name] = nil + end + -- If flames + if flames > 0 then + -- Find centre of flame positions + local fposmid = fpos[1] + -- If more than 1 flame + if #fpos > 1 then + local fposmin = areamax + local fposmax = areamin + for i = 1, #fpos do + local fposi = fpos[i] + if fposi.x > fposmax.x then + fposmax.x = fposi.x + end + if fposi.y > fposmax.y then + fposmax.y = fposi.y + end + if fposi.z > fposmax.z then + fposmax.z = fposi.z + end + if fposi.x < fposmin.x then + fposmin.x = fposi.x + end + if fposi.y < fposmin.y then + fposmin.y = fposi.y + end + if fposi.z < fposmin.z then + fposmin.z = fposi.z + end + end + fposmid = vector.divide(vector.add(fposmin, fposmax), 2) + end + -- Play sound + local handle = minetest.sound_play( + "fire_fire", + { + pos = fposmid, + to_player = player_name, + gain = math.min(0.06 * (1 + flames * 0.125), 0.18), + max_hear_distance = 32, + loop = true, -- In case of lag + } + ) + -- Store sound handle for this player + if handle then + handles[player_name] = handle + end + end + end + + -- Cycle for updating players sounds + + minetest.register_globalstep(function(dtime) + timer = timer + dtime + if timer < cycle then + return + end + + timer = 0 + local players = minetest.get_connected_players() + for n = 1, #players do + fire.update_player_sound(players[n]) + end + end) + + -- Stop sound and clear handle on player leave + + minetest.register_on_leaveplayer(function(player) + local player_name = player:get_player_name() + if handles[player_name] then + minetest.sound_stop(handles[player_name]) + handles[player_name] = nil + end + end) +end + -- Deprecated function kept temporarily to avoid crashes if mod fire nodes call it function fire.update_sounds_around(pos) @@ -205,10 +321,10 @@ else -- Fire enabled chance = 12, catch_up = false, action = function(pos, node, active_object_count, active_object_count_wider) - -- If there is water or stuff like that around node, don't ignite if fire.spread == false then return end + -- If there is water or stuff like that around node, don't ignite if minetest.find_node_near(pos, 1, {"group:puts_out_fire"}) then return end @@ -283,7 +399,7 @@ minetest.override_item("default:chest", { end, }) --- /fire [on/off]command to quickly stop flames spreading +-- /fire [on/off] command to quickly stop flames spreading minetest.register_chatcommand("fire", { params = "", diff --git a/sounds/fire_fire.1.ogg b/sounds/fire_fire.1.ogg new file mode 100644 index 0000000..cbfee4c Binary files /dev/null and b/sounds/fire_fire.1.ogg differ diff --git a/sounds/fire_fire.2.ogg b/sounds/fire_fire.2.ogg new file mode 100644 index 0000000..e8d0eb1 Binary files /dev/null and b/sounds/fire_fire.2.ogg differ diff --git a/sounds/fire_fire.3.ogg b/sounds/fire_fire.3.ogg new file mode 100644 index 0000000..5cad3d9 Binary files /dev/null and b/sounds/fire_fire.3.ogg differ diff --git a/sounds/fire_large.ogg b/sounds/fire_large.ogg new file mode 100644 index 0000000..fe78e62 Binary files /dev/null and b/sounds/fire_large.ogg differ diff --git a/sounds/fire_small.ogg b/sounds/fire_small.ogg new file mode 100644 index 0000000..5aac595 Binary files /dev/null and b/sounds/fire_small.ogg differ