-
Notifications
You must be signed in to change notification settings - Fork 198
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Cherry-picked commit cd4eda4 from space-wizards/space-station-14/master
- Loading branch information
Showing
8 changed files
with
168 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
namespace Content.Server.Speech.Components; | ||
|
||
/// <summary> | ||
/// Makes this entity speak like a parrot in all chat messages it sends. | ||
/// </summary> | ||
[RegisterComponent] | ||
public sealed partial class ParrotAccentComponent : Component | ||
{ | ||
/// <summary> | ||
/// Chance that a message will have a squawk sound added before the first character. | ||
/// If it fails, the message with have a squawk as a postfix instead. | ||
/// If the longest word is repeated, no pre- or postfix will be added. | ||
/// </summary> | ||
[DataField] | ||
public float SquawkPrefixChance = 0.5f; | ||
|
||
/// <summary> | ||
/// Chance that the longest word in the message will be repeated as an | ||
/// exclamation at the end of the final message. | ||
/// </summary> | ||
[DataField] | ||
public float LongestWordRepeatChance = 0.5f; | ||
|
||
/// <summary> | ||
/// The longest word must be at least this many characters long to be | ||
/// repeated. This prevents repeating short words, which can sound weird. | ||
/// ex: "How are you? AWWK! How!" - bad | ||
/// ex: "Look out, it's the captain! RAWWK! Captain!" - good | ||
/// </summary> | ||
[DataField] | ||
public float LongestWordMinLength = 5; | ||
|
||
/// <summary> | ||
/// Strings to use as squawking noises. | ||
/// </summary> | ||
public readonly string[] Squawks = [ | ||
"accent-parrot-squawk-1", | ||
"accent-parrot-squawk-2", | ||
"accent-parrot-squawk-3", | ||
"accent-parrot-squawk-4", | ||
"accent-parrot-squawk-5", | ||
"accent-parrot-squawk-6", | ||
"accent-parrot-squawk-7", | ||
"accent-parrot-squawk-8" | ||
]; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
using System.Linq; | ||
using System.Text.RegularExpressions; | ||
using Content.Server.Speech.Components; | ||
using Robust.Shared.Random; | ||
|
||
namespace Content.Server.Speech.EntitySystems; | ||
|
||
public sealed partial class ParrotAccentSystem : EntitySystem | ||
{ | ||
[Dependency] private readonly IRobustRandom _random = default!; | ||
|
||
public override void Initialize() | ||
{ | ||
base.Initialize(); | ||
|
||
SubscribeLocalEvent<ParrotAccentComponent, AccentGetEvent>(OnAccentGet); | ||
} | ||
|
||
private void OnAccentGet(Entity<ParrotAccentComponent> entity, ref AccentGetEvent args) | ||
{ | ||
args.Message = Accentuate(entity, args.Message); | ||
} | ||
|
||
public string Accentuate(Entity<ParrotAccentComponent> entity, string message) | ||
{ | ||
// Sometimes repeat the longest word at the end of the message, after a squawk! SQUAWK! Sometimes! | ||
if (_random.Prob(entity.Comp.LongestWordRepeatChance)) | ||
{ | ||
// Don't count non-alphanumeric characters as parts of words | ||
var cleaned = Regex.Replace(message, "[^A-Za-z0-9 -]", 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 >= entity.Comp.LongestWordMinLength) | ||
{ | ||
message = EnsurePunctuation(message); | ||
|
||
// Capitalize the first letter of the repeated word | ||
longest = string.Concat(longest[0].ToString().ToUpper(), longest.AsSpan(1)); | ||
|
||
message = string.Format("{0} {1} {2}!", message, GetRandomSquawk(entity), longest); | ||
return message; // No more changes, or it's too much | ||
} | ||
} | ||
|
||
if (_random.Prob(entity.Comp.SquawkPrefixChance)) | ||
{ | ||
// AWWK! Sometimes add a squawk at the begining of the message | ||
message = string.Format("{0} {1}", GetRandomSquawk(entity), message); | ||
} | ||
else | ||
{ | ||
// Otherwise add a squawk at the end of the message! RAWWK! | ||
message = EnsurePunctuation(message); | ||
message = string.Format("{0} {1}", message, GetRandomSquawk(entity)); | ||
} | ||
|
||
return message; | ||
} | ||
|
||
/// <summary> | ||
/// Adds a "!" to the end of the string, if there isn't already a sentence-ending punctuation mark. | ||
/// </summary> | ||
private string EnsurePunctuation(string message) | ||
{ | ||
if (!message.EndsWith('!') && !message.EndsWith('?') && !message.EndsWith('.')) | ||
return message + '!'; | ||
return message; | ||
} | ||
|
||
/// <summary> | ||
/// Returns a random, localized squawk sound. | ||
/// </summary> | ||
private string GetRandomSquawk(Entity<ParrotAccentComponent> entity) | ||
{ | ||
return Loc.GetString(_random.Pick(entity.Comp.Squawks)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
accent-parrot-squawk-1 = SQUAWK! | ||
accent-parrot-squawk-2 = SQUAAAWK! | ||
accent-parrot-squawk-3 = AWWK! | ||
accent-parrot-squawk-4 = AAWK! | ||
accent-parrot-squawk-5 = RAWWK! | ||
accent-parrot-squawk-6 = RAAAWK! | ||
accent-parrot-squawk-7 = BRAAWK! | ||
accent-parrot-squawk-8 = BRAWWK! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters