using System.Collections.Generic; using Content.Shared.GameObjects.Components.Sound; using Content.Shared.Physics; using Robust.Client.GameObjects.EntitySystems; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.Network; using Robust.Shared.Interfaces.Random; using Robust.Shared.IoC; using Robust.Shared.Players; using Robust.Shared.Serialization; using Robust.Shared.Timers; using Robust.Shared.Utility; namespace Content.Client.GameObjects.Components.Sound { [RegisterComponent] public class LoopingSoundComponent : SharedLoopingSoundComponent { private readonly Dictionary _audioStreams = new Dictionary(); private AudioSystem _audioSystem; #pragma warning disable 649 [Dependency] private readonly IRobustRandom _random; #pragma warning restore 649 public override void StopAllSounds() { foreach (var kvp in _audioStreams) { kvp.Key.Play = false; kvp.Value.Stop(); } _audioStreams.Clear(); } public override void StopScheduledSound(string filename) { foreach (var kvp in _audioStreams) { if (kvp.Key.Filename != filename) continue; kvp.Key.Play = false; kvp.Value.Stop(); _audioStreams.Remove(kvp.Key); } } public override void AddScheduledSound(ScheduledSound schedule) { Play(schedule); } public void Play(ScheduledSound schedule) { if (!schedule.Play) return; Timer.Spawn((int) schedule.Delay + (_random.Next((int) schedule.RandomDelay)),() => { if (!schedule.Play) return; // We make sure this hasn't changed. if (_audioSystem == null) _audioSystem = EntitySystem.Get(); _audioStreams.Add(schedule,_audioSystem.Play(schedule.Filename, Owner, schedule.AudioParams)); if (schedule.Times == 0) return; if (schedule.Times > 0) schedule.Times--; Play(schedule); }); } public override void HandleNetworkMessage(ComponentMessage message, INetChannel channel, ICommonSession session = null) { base.HandleNetworkMessage(message, channel, session); switch (message) { case ScheduledSoundMessage msg: AddScheduledSound(msg.Schedule); break; case StopSoundScheduleMessage msg: StopScheduledSound(msg.Filename); break; case StopAllSoundsMessage _: StopAllSounds(); break; } } public override void Initialize() { base.Initialize(); if (EntitySystem.TryGet(out _audioSystem)) _audioSystem.OcclusionCollisionMask = (int) CollisionGroup.Impassable; } public override void ExposeData(ObjectSerializer serializer) { base.ExposeData(serializer); if (serializer.Writing) return; serializer.TryReadDataField("schedules", out List schedules); if (schedules == null) return; foreach (var schedule in schedules) { if (schedule == null) continue; AddScheduledSound(schedule); } } } }