1
0

SpeechNoiseSystem.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. using Robust.Shared.Audio;
  2. using Content.Server.Chat;
  3. using Content.Server.Chat.Systems;
  4. using Content.Shared.Speech;
  5. using Robust.Shared.Audio.Systems;
  6. using Robust.Shared.Player;
  7. using Robust.Shared.Prototypes;
  8. using Robust.Shared.Timing;
  9. using Robust.Shared.Random;
  10. namespace Content.Server.Speech
  11. {
  12. public sealed class SpeechSoundSystem : EntitySystem
  13. {
  14. [Dependency] private readonly IGameTiming _gameTiming = default!;
  15. [Dependency] private readonly IPrototypeManager _protoManager = default!;
  16. [Dependency] private readonly IRobustRandom _random = default!;
  17. [Dependency] private readonly SharedAudioSystem _audio = default!;
  18. public override void Initialize()
  19. {
  20. base.Initialize();
  21. SubscribeLocalEvent<SpeechComponent, EntitySpokeEvent>(OnEntitySpoke);
  22. }
  23. public SoundSpecifier? GetSpeechSound(Entity<SpeechComponent> ent, string message)
  24. {
  25. if (ent.Comp.SpeechSounds == null)
  26. return null;
  27. // Play speech sound
  28. SoundSpecifier? contextSound;
  29. var prototype = _protoManager.Index<SpeechSoundsPrototype>(ent.Comp.SpeechSounds);
  30. // Different sounds for ask/exclaim based on last character
  31. contextSound = message[^1] switch
  32. {
  33. '?' => prototype.AskSound,
  34. '!' => prototype.ExclaimSound,
  35. _ => prototype.SaySound
  36. };
  37. // Use exclaim sound if most characters are uppercase.
  38. int uppercaseCount = 0;
  39. for (int i = 0; i < message.Length; i++)
  40. {
  41. if (char.IsUpper(message[i]))
  42. uppercaseCount++;
  43. }
  44. if (uppercaseCount > (message.Length / 2))
  45. {
  46. contextSound = prototype.ExclaimSound;
  47. }
  48. var scale = (float) _random.NextGaussian(1, prototype.Variation);
  49. contextSound.Params = ent.Comp.AudioParams.WithPitchScale(scale);
  50. return contextSound;
  51. }
  52. private void OnEntitySpoke(EntityUid uid, SpeechComponent component, EntitySpokeEvent args)
  53. {
  54. if (component.SpeechSounds == null)
  55. return;
  56. var currentTime = _gameTiming.CurTime;
  57. var cooldown = TimeSpan.FromSeconds(component.SoundCooldownTime);
  58. // Ensure more than the cooldown time has passed since last speaking
  59. if (currentTime - component.LastTimeSoundPlayed < cooldown)
  60. return;
  61. var sound = GetSpeechSound((uid, component), args.Message);
  62. component.LastTimeSoundPlayed = currentTime;
  63. _audio.PlayPvs(sound, uid);
  64. }
  65. }
  66. }