using System.Linq; using System.Text.RegularExpressions; using Content.Shared.Random.Helpers; using Content.Shared.Speech.Components; using Robust.Shared.Random; using Robust.Shared.Timing; namespace Content.Shared.Speech.EntitySystems; public sealed partial class ParrotAccentSystem : RelayAccentSystem { private static readonly Regex WordCleanupRegex = new("[^A-Za-z0-9 -]"); [Dependency] private IGameTiming _timing = default!; public override string Accentuate(string message, Entity? ent = null) { if (ent == null) return message; var random = SharedRandomExtensions.PredictedRandom(_timing, GetNetEntity(ent.Value)); // Sometimes repeat the longest word at the end of the message, after a squawk! SQUAWK! Sometimes! if (random.Prob(ent.Value.Comp.LongestWordRepeatChance)) { // Don't count non-alphanumeric characters as parts of words var cleaned = WordCleanupRegex.Replace(message, string.Empty); // Split on whitespace and favor words towards the end of the message var words = cleaned.Split(null).Reverse(); // Find longest word var longest = words.MaxBy(word => word.Length); if (longest?.Length >= ent.Value.Comp.LongestWordMinLength) { message = EnsurePunctuation(message); // Capitalize the first letter of the repeated word longest = string.Concat(longest[0].ToString().ToUpper(), longest.AsSpan(1)); message = $"{message} {GetRandomSquawk(ent.Value)} {longest}!"; return message; // No more changes, or it's too much } } if (random.Prob(ent.Value.Comp.SquawkPrefixChance)) { // AWWK! Sometimes add a squawk at the beginning of the message message = $"{GetRandomSquawk(ent.Value)} {message}"; } else { // Otherwise add a squawk at the end of the message! RAWWK! message = EnsurePunctuation(message); message = $"{message} {GetRandomSquawk(ent.Value)}"; } return message; } /// /// Adds a "!" to the end of the string, if there isn't already a sentence-ending punctuation mark. /// private string EnsurePunctuation(string message) { return message.EndsWith('!') || message.EndsWith('?') || message.EndsWith('.') ? message : message + '!'; } /// /// Returns a random, localized squawk sound. /// private string GetRandomSquawk(Entity ent) { var random = SharedRandomExtensions.PredictedRandom(_timing, GetNetEntity(ent)); return Loc.GetString(random.Pick(ent.Comp.Squawks)); } }