1
0

SlurredSystem.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. using System.Text;
  2. using Content.Server.Speech.Components;
  3. using Content.Shared.Drunk;
  4. using Content.Shared.Speech.EntitySystems;
  5. using Content.Shared.StatusEffect;
  6. using Robust.Shared.Random;
  7. using Robust.Shared.Timing;
  8. namespace Content.Server.Speech.EntitySystems;
  9. public sealed class SlurredSystem : SharedSlurredSystem
  10. {
  11. [Dependency] private readonly StatusEffectsSystem _statusEffectsSystem = default!;
  12. [Dependency] private readonly IRobustRandom _random = default!;
  13. [Dependency] private readonly IGameTiming _timing = default!;
  14. [ValidatePrototypeId<StatusEffectPrototype>]
  15. private const string SlurKey = "SlurredSpeech";
  16. public override void Initialize()
  17. {
  18. SubscribeLocalEvent<SlurredAccentComponent, AccentGetEvent>(OnAccent);
  19. }
  20. public override void DoSlur(EntityUid uid, TimeSpan time, StatusEffectsComponent? status = null)
  21. {
  22. if (!Resolve(uid, ref status, false))
  23. return;
  24. if (!_statusEffectsSystem.HasStatusEffect(uid, SlurKey, status))
  25. _statusEffectsSystem.TryAddStatusEffect<SlurredAccentComponent>(uid, SlurKey, time, true, status);
  26. else
  27. _statusEffectsSystem.TryAddTime(uid, SlurKey, time, status);
  28. }
  29. /// <summary>
  30. /// Slur chance scales with "drunkeness", which is just measured using the time remaining on the status effect.
  31. /// </summary>
  32. private float GetProbabilityScale(EntityUid uid)
  33. {
  34. if (!_statusEffectsSystem.TryGetTime(uid, SharedDrunkSystem.DrunkKey, out var time))
  35. return 0;
  36. var curTime = _timing.CurTime;
  37. var timeLeft = (float) (time.Value.Item2 - curTime).TotalSeconds;
  38. return Math.Clamp((timeLeft - 80) / 1100, 0f, 1f);
  39. }
  40. private void OnAccent(EntityUid uid, SlurredAccentComponent component, AccentGetEvent args)
  41. {
  42. var scale = GetProbabilityScale(uid);
  43. args.Message = Accentuate(args.Message, scale);
  44. }
  45. private string Accentuate(string message, float scale)
  46. {
  47. var sb = new StringBuilder();
  48. // This is pretty much ported from TG.
  49. foreach (var character in message)
  50. {
  51. if (_random.Prob(scale / 3f))
  52. {
  53. var lower = char.ToLowerInvariant(character);
  54. var newString = lower switch
  55. {
  56. 'o' => "u",
  57. 's' => "ch",
  58. 'a' => "ah",
  59. 'u' => "oo",
  60. 'c' => "k",
  61. _ => $"{character}",
  62. };
  63. sb.Append(newString);
  64. }
  65. if (_random.Prob(scale / 20f))
  66. {
  67. if (character == ' ')
  68. {
  69. sb.Append(Loc.GetString("slur-accent-confused"));
  70. }
  71. else if (character == '.')
  72. {
  73. sb.Append(' ');
  74. sb.Append(Loc.GetString("slur-accent-burp"));
  75. }
  76. }
  77. if (!_random.Prob(scale * 3/20))
  78. {
  79. sb.Append(character);
  80. continue;
  81. }
  82. var next = _random.Next(1, 3) switch
  83. {
  84. 1 => "'",
  85. 2 => $"{character}{character}",
  86. _ => $"{character}{character}{character}",
  87. };
  88. sb.Append(next);
  89. }
  90. return sb.ToString();
  91. }
  92. }