diff --git a/OpenRA.Game/GameRules/SoundInfo.cs b/OpenRA.Game/GameRules/SoundInfo.cs index 4c58646848..3ec00130a7 100644 --- a/OpenRA.Game/GameRules/SoundInfo.cs +++ b/OpenRA.Game/GameRules/SoundInfo.cs @@ -33,11 +33,11 @@ namespace OpenRA.GameRules { FieldLoader.Load(this, y); - VoicePools = Exts.Lazy(() => Voices.ToDictionary(a => a.Key, a => new SoundPool(1f, a.Value))); + VoicePools = Exts.Lazy(() => Voices.ToDictionary(a => a.Key, a => new SoundPool(1f, false, a.Value))); NotificationsPools = Exts.Lazy(() => ParseSoundPool(y, "Notifications")); } - Dictionary ParseSoundPool(MiniYaml y, string key) + static Dictionary ParseSoundPool(MiniYaml y, string key) { var ret = new Dictionary(); var classifiction = y.Nodes.First(x => x.Key == key); @@ -48,8 +48,13 @@ namespace OpenRA.GameRules if (volumeModifierNode != null) volumeModifier = FieldLoader.GetValue(volumeModifierNode.Key, volumeModifierNode.Value.Value); + var allowInterrupt = false; + var allowInterruptNode = t.Value.Nodes.FirstOrDefault(x => x.Key == "AllowInterrupt"); + if (allowInterruptNode != null) + allowInterrupt = FieldLoader.GetValue(allowInterruptNode.Key, allowInterruptNode.Value.Value); + var names = FieldLoader.GetValue(t.Key, t.Value.Value); - var sp = new SoundPool(volumeModifier, names); + var sp = new SoundPool(volumeModifier, allowInterrupt, names); ret.Add(t.Key, sp); } @@ -60,12 +65,14 @@ namespace OpenRA.GameRules public class SoundPool { public readonly float VolumeModifier; + public readonly bool AllowInterrupt; readonly string[] clips; readonly List liveclips = new List(); - public SoundPool(float volumeModifier, params string[] clips) + public SoundPool(float volumeModifier, bool allowInterrupt, params string[] clips) { VolumeModifier = volumeModifier; + AllowInterrupt = allowInterrupt; this.clips = clips; } diff --git a/OpenRA.Game/Sound/Sound.cs b/OpenRA.Game/Sound/Sound.cs index 7a61235b1d..d9772d5f21 100644 --- a/OpenRA.Game/Sound/Sound.cs +++ b/OpenRA.Game/Sound/Sound.cs @@ -45,6 +45,7 @@ namespace OpenRA ISound video; MusicInfo currentMusic; Dictionary currentSounds = new Dictionary(); + Dictionary currentNotifications = new Dictionary(); public bool DummyEngine { get; private set; } public Sound(IPlatform platform, SoundSettings soundSettings) @@ -390,16 +391,29 @@ namespace OpenRA if (!string.IsNullOrEmpty(name) && (p == null || p == p.World.LocalPlayer)) { + if (currentNotifications.ContainsKey(name) && !currentNotifications[name].Complete) + { + if (pool.AllowInterrupt) + soundEngine.StopSound(currentNotifications[name]); + else + return false; + } + else if (currentSounds.ContainsKey(id) && !currentSounds[id].Complete) + { + if (pool.AllowInterrupt) + soundEngine.StopSound(currentSounds[id]); + else + return false; + } + var sound = soundEngine.Play2D(sounds[name], false, relative, pos, InternalSoundVolume * volumeModifier * pool.VolumeModifier, attenuateVolume); - if (id != 0) - { - if (currentSounds.ContainsKey(id)) - soundEngine.StopSound(currentSounds[id]); + if (id != 0) currentSounds[id] = sound; - } + else + currentNotifications[name] = sound; } return true; diff --git a/mods/cnc/audio/notifications.yaml b/mods/cnc/audio/notifications.yaml index 57878440ad..1051c63d25 100644 --- a/mods/cnc/audio/notifications.yaml +++ b/mods/cnc/audio/notifications.yaml @@ -54,6 +54,7 @@ Sounds: Notifications: Appear: appear1 Beacon: bleep2 + AllowInterrupt: true Beepy2: beepy2 Beepy3: beepy3 Beepy6: beepy6 @@ -61,8 +62,11 @@ Sounds: CashTickUp: tone15 VolumeModifier: 0.33 ChatLine: scold1 + AllowInterrupt: true ClickDisabledSound: scold2 + AllowInterrupt: true ClickSound: button + AllowInterrupt: true Cloak: trans1 Clock: clock1 Construction: constru2 diff --git a/mods/d2k/audio/notifications.yaml b/mods/d2k/audio/notifications.yaml index 9256c95a9c..4e3b92ee29 100644 --- a/mods/d2k/audio/notifications.yaml +++ b/mods/d2k/audio/notifications.yaml @@ -70,9 +70,14 @@ Sounds: CashTickDown: CASHTIK1 LevelUp: SCORTIK1 ChatLine: CHAT1 + AllowInterrupt: true BuildPaletteOpen: BUTTON1 BuildPaletteClose: BUTTON1 TabClick: SIDEBAR1 + AllowInterrupt: true ClickSound: BUTTON1 + AllowInterrupt: true ClickDisabledSound: ENDLIST1 - Beacon: CHAT1 \ No newline at end of file + AllowInterrupt: true + Beacon: CHAT1 + AllowInterrupt: true diff --git a/mods/ra/audio/notifications.yaml b/mods/ra/audio/notifications.yaml index 5577da435c..312451a9e2 100644 --- a/mods/ra/audio/notifications.yaml +++ b/mods/ra/audio/notifications.yaml @@ -126,9 +126,12 @@ Sounds: DisablePower: bleep11 EnablePower: bleep12 ChatLine: rabeep1 + AllowInterrupt: true ClickSound: ramenu1 + AllowInterrupt: true ClickDisabledSound: Beacon: beepslct + AllowInterrupt: true AlertBuzzer: buzzy1 AlertBleep: bleep6 BaseSetup: bleep9 diff --git a/mods/ts/audio/sounds-generic.yaml b/mods/ts/audio/sounds-generic.yaml index 2fb28834f9..7ae0a3c422 100644 --- a/mods/ts/audio/sounds-generic.yaml +++ b/mods/ts/audio/sounds-generic.yaml @@ -2,6 +2,7 @@ Sounds: Notifications: Bargraph: bargraph Beacon: message1 + AllowInterrupt: true Bestbox: bestbox Blip: blip BuildPaletteClose: emblem @@ -13,8 +14,11 @@ Sounds: CashTickUp: credup1 VolumeModifier: 0.33 ChatLine: message1 + AllowInterrupt: true ClickDisabledSound: wrong1 + AllowInterrupt: true ClickSound: clicky1 + AllowInterrupt: true GameForming: gamefrm1 Gdiclose: gdiclose Gdiopen: gdiopen