Limit number of sounds and particles

This commit is contained in:
Wuzzy 2024-10-22 17:03:33 +02:00
parent 3ae18932cb
commit ede69b914a
4 changed files with 74 additions and 13 deletions

View File

@ -0,0 +1,55 @@
lzr_effects_limiter = {}
local active_effects = {}
local registered_effects = {}
lzr_effects_limiter.register_effect = function(effect_id, def)
registered_effects[effect_id] = {
duration = math.ceil(def.duration * 1000000),
max_count = def.max_count,
}
active_effects[effect_id] = {}
end
lzr_effects_limiter.add_effect = function(effect_id)
local time = minetest.get_us_time()
table.insert(active_effects[effect_id], time)
end
local remove_expired_effects = function(effect_id)
local time = minetest.get_us_time()
local effects = active_effects[effect_id]
if #effects == 0 then
return
end
local duration = registered_effects[effect_id].duration
local remove = {}
for e=1, #effects do
local effect_time = effects[e]
if time >= effect_time + duration then
table.insert(remove, e)
end
end
for r=1, #remove do
table.remove(active_effects[effect_id], r)
end
end
lzr_effects_limiter.can_add_effect = function(effect_id)
remove_expired_effects(effect_id)
if #active_effects[effect_id] > registered_effects[effect_id].max_count then
return false
else
return true
end
end
lzr_effects_limiter.add_effect_if_possible = function(effect_id)
if lzr_effects_limiter.can_add_effect(effect_id) then
lzr_effects_limiter.add_effect(effect_id)
return true
else
return false
end
end

View File

@ -0,0 +1,2 @@
name = lzr_effects_limiter
description = Functions to limit the number of simultaneous sounds and particles for better performance

View File

@ -323,6 +323,9 @@ local pick_n_of_m = function(n, m)
return ret
end
lzr_effects_limiter.register_effect("barricade_burn_or_break", { duration = 0.8, max_count = 20 })
lzr_effects_limiter.register_effect("bomb_explode", { duration = 0.3, max_count = 16 })
lzr_laser.burn_and_destroy = function(nodes_to_remove)
minetest.bulk_set_node(nodes_to_remove.barricades, {name="air"})
@ -340,10 +343,6 @@ lzr_laser.burn_and_destroy = function(nodes_to_remove)
vector.new(0,0,1),
}
-- Limit number of burn sounds to play at once to prevent
-- the sound library to run out of memory
local burn_sounds = 0
-- Burn up barricades. A burned-up barricade does:
-- * get destroyed
-- * create an audiovisual effect (fire and break sound)
@ -379,9 +378,11 @@ lzr_laser.burn_and_destroy = function(nodes_to_remove)
-- Play randomly-pitched break sound
if play_sounds_at == true or play_sounds_at[r] then
if lzr_effects_limiter.add_effect_if_possible("barricade_burn_or_break") then
local pitch = 1.0+math.random(-100, 100)*0.001 -- 0.9..1.1
minetest.sound_play({name="lzr_laser_barricade_break", gain=1.0}, {gain=1.0, pitch=pitch, pos=rpos}, true)
end
end
-- propagate fire to neighbors
for n=1, #neighbors_barricade do
@ -393,9 +394,10 @@ lzr_laser.burn_and_destroy = function(nodes_to_remove)
if minetest.get_item_group(node.name, "flammable") == 1 then
minetest.set_node(ppos, {name=def._lzr_active, param2=node.param2})
if def._lzr_active == "lzr_laser:barricade_on" then
if (play_sounds_at == true or play_sounds_at[r]) and burn_sounds < lzr_globals.MAX_DESTROY_SOUNDS_AT_ONCE then
if (play_sounds_at == true or play_sounds_at[r]) then
if lzr_effects_limiter.add_effect_if_possible("barricade_burn_or_break") then
minetest.sound_play({name="lzr_laser_quickburn", gain=1.0}, {pos=ppos}, true)
burn_sounds = burn_sounds + 1
end
end
table.insert(ignited_barricades, ppos)
end
@ -434,10 +436,12 @@ lzr_laser.burn_and_destroy = function(nodes_to_remove)
-- explosion effect (but not too many at once)
if bomb_effects_at == true or bomb_effects_at[r] then
if lzr_effects_limiter.add_effect_if_possible("bomb_explode") then
-- node table for particle
local bomb_node = { name = "lzr_laser:bomb_takable" }
lzr_laser.bomb_explosion_audiovisuals(rpos, bomb_node)
end
end
-- destroy nodes and deal player damage
lzr_laser.deal_bomb_damage(rpos)

View File

@ -1,2 +1,2 @@
name = lzr_laser
depends = lzr_globals, lzr_gamestate, lzr_sounds, lzr_util, lzr_triggers, lzr_slowdown, lzr_damage
depends = lzr_globals, lzr_gamestate, lzr_sounds, lzr_util, lzr_triggers, lzr_slowdown, lzr_damage, lzr_effects_limiter