From cbd5abb6987e5a264293f53f397e81960b589ece Mon Sep 17 00:00:00 2001 From: Kara Date: Fri, 17 Jun 2022 19:36:19 -0700 Subject: [PATCH] Mobster accents for rat king/servants (#8927) * basically perfect * oops * huh * new substitutions from retequizzle, rane, and olddancejacket + crown accent * fixes --- .../Components/MobsterAccentComponent.cs | 15 ++++ .../EntitySystems/MobsterAccentSystem.cs | 89 +++++++++++++++++++ Resources/Locale/en-US/accent/mobster.ftl | 8 ++ .../Entities/Clothing/Head/misc.yml | 6 +- .../Entities/Mobs/NPCs/regalrat.yml | 4 +- 5 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 Content.Server/Speech/Components/MobsterAccentComponent.cs create mode 100644 Content.Server/Speech/EntitySystems/MobsterAccentSystem.cs create mode 100644 Resources/Locale/en-US/accent/mobster.ftl diff --git a/Content.Server/Speech/Components/MobsterAccentComponent.cs b/Content.Server/Speech/Components/MobsterAccentComponent.cs new file mode 100644 index 0000000000..f67ea32792 --- /dev/null +++ b/Content.Server/Speech/Components/MobsterAccentComponent.cs @@ -0,0 +1,15 @@ +namespace Content.Server.Speech.Components; + +/// +/// Nyehh, my gabagool, see? +/// Etc etc. +/// +[RegisterComponent] +public sealed class MobsterAccentComponent : Component +{ + /// + /// Do you make all the rules? + /// + [DataField("isBoss")] + public bool IsBoss = true; +} diff --git a/Content.Server/Speech/EntitySystems/MobsterAccentSystem.cs b/Content.Server/Speech/EntitySystems/MobsterAccentSystem.cs new file mode 100644 index 0000000000..aeaf898fb1 --- /dev/null +++ b/Content.Server/Speech/EntitySystems/MobsterAccentSystem.cs @@ -0,0 +1,89 @@ +using System.Globalization; +using System.Text.RegularExpressions; +using Content.Server.Speech.Components; +using Robust.Shared.Random; + +namespace Content.Server.Speech.EntitySystems; + +public sealed class MobsterAccentSystem : EntitySystem +{ + [Dependency] private readonly IRobustRandom _random = default!; + + private static readonly Dictionary DirectReplacements = new() + { + { "let me", "lemme" }, + { "should", "oughta" }, + { "the", "da" }, + { "kill", "whack" }, + { "murder", "whack" }, + { "dead", "sleepin' with da fishies"}, + { "hey", "ey'o" }, + { "rules", "roolz" }, + { "you", "yous" }, + { "have to", "gotta" }, + { "here", "'ere" } + }; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnAccentGet); + } + + public string Accentuate(string message, MobsterAccentComponent component) + { + // Order: + // Do text manipulations first + // Then prefix/suffix funnyies + + var msg = message; + + foreach (var (first, replace) in DirectReplacements) + { + msg = msg.Replace(first, replace, true, CultureInfo.InvariantCulture); + } + + // thinking -> thinkin' + msg = Regex.Replace(msg, @"ing(?!\w)", "in'", RegexOptions.IgnoreCase); + + // or -> uh and ar -> ah in the middle of words (fuhget, tahget) + msg = Regex.Replace(msg, @"(?<=\w)or(?=\w)", "uh", RegexOptions.IgnoreCase); + msg = Regex.Replace(msg, @"(?<=\w)ar(?=\w)", "ah", RegexOptions.IgnoreCase); + + // Prefix + if (_random.Prob(0.15f)) + { + var pick = _random.Next(1, 2); + + // Reverse sanitize capital + msg = msg[0].ToString().ToLower() + msg.Remove(0, 1); + msg = Loc.GetString($"accent-mobster-prefix-{pick}") + " " + msg; + } + + // Sanitize capital again, in case we substituted a word that should be capitalized + msg = msg[0].ToString().ToUpper() + msg.Remove(0, 1); + + // Suffixes + if (_random.Prob(0.4f)) + { + if (component.IsBoss) + { + var pick = _random.Next(1, 4); + msg += Loc.GetString($"accent-mobster-suffix-boss-{pick}"); + } + else + { + var pick = _random.Next(1, 3); + msg += Loc.GetString($"accent-mobster-suffix-minion-{pick}"); + } + } + + return msg; + } + + private void OnAccentGet(EntityUid uid, MobsterAccentComponent component, AccentGetEvent args) + { + args.Message = Accentuate(args.Message, component); + } +} diff --git a/Resources/Locale/en-US/accent/mobster.ftl b/Resources/Locale/en-US/accent/mobster.ftl new file mode 100644 index 0000000000..9aca97971b --- /dev/null +++ b/Resources/Locale/en-US/accent/mobster.ftl @@ -0,0 +1,8 @@ +accent-mobster-prefix-1 = Nyehh, + +accent-mobster-suffix-boss-1 = , see? +accent-mobster-suffix-boss-2 = , fugeddaboutit. +accent-mobster-suffix-boss-3 = , capiche? + +accent-mobster-suffix-minion-1 = , yeah! +accent-mobster-suffix-minion-2 = , boss says! diff --git a/Resources/Prototypes/Entities/Clothing/Head/misc.yml b/Resources/Prototypes/Entities/Clothing/Head/misc.yml index cdbba6024d..f2324a861b 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/misc.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/misc.yml @@ -111,12 +111,12 @@ sprite: Clothing/Head/Misc/cone.rsi - type: Clothing sprite: Clothing/Head/Misc/cone.rsi - + - type: entity parent: ClothingHeadBase id: ClothingHeadHatFancyCrown name: fancy crown - description: It smells like dead rat. + description: It smells like dead rat. Lets you speak like one! components: - type: Sprite sprite: Clothing/Head/Misc/fancycrown.rsi @@ -124,6 +124,8 @@ sprite: Clothing/Head/Misc/fancycrown.rsi - type: MobPrice price: 3000 + - type: AddAccentClothing + accent: MobsterAccent - type: entity parent: ClothingHeadBase diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml b/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml index 74c798110c..ed6e564435 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml @@ -89,6 +89,7 @@ itemIconStyle: NoItem event: !type:RatKingDomainActionEvent hungerPerDomainUse: 50 + - type: MobsterAccent - type: Access #he's so baller he gets his own access. NT got nothing on him tags: - Maintenance @@ -192,4 +193,5 @@ - type: NoSlip - type: MobPrice price: 500 # rat wealth - + - type: MobsterAccent + isBoss: false