diff --git a/Content.Server/Chat/Systems/ChatSystem.cs b/Content.Server/Chat/Systems/ChatSystem.cs
index cd48b6de716..d2ed6e04346 100644
--- a/Content.Server/Chat/Systems/ChatSystem.cs
+++ b/Content.Server/Chat/Systems/ChatSystem.cs
@@ -241,6 +241,17 @@ public void TrySendInGameICMessage(
if (string.IsNullOrEmpty(message))
return;
+ // Check if the message is in sign language
+ if (desiredType == InGameICChatType.Speak || desiredType == InGameICChatType.Whisper)
+ {
+ var language = languageOverride ?? _language.GetLanguage(source);
+ if (language.SignLanguage ?? false)
+ {
+ SendEntityEmote(source, message, range, nameOverride, ignoreActionBlocker, signLanguage: true, languageOverride: languageOverride);
+ return;
+ }
+ }
+
// This message may have a radio prefix, and should then be whispered to the resolved radio channel
if (checkRadioPrefix)
{
@@ -576,7 +587,9 @@ private void SendEntityEmote(
bool hideLog = false,
bool checkEmote = true,
bool ignoreActionBlocker = false,
- NetUserId? author = null
+ NetUserId? author = null,
+ LanguagePrototype? languageOverride = null,
+ bool? signLanguage = false
)
{
if (!_actionBlocker.CanEmote(source) && !ignoreActionBlocker)
@@ -586,15 +599,32 @@ private void SendEntityEmote(
var ent = Identity.Entity(source, EntityManager);
string name = FormattedMessage.EscapeText(nameOverride ?? Name(ent));
+ var language = languageOverride ?? _language.GetLanguage(source);
+
// Emotes use Identity.Name, since it doesn't actually involve your voice at all.
- var wrappedMessage = Loc.GetString("chat-manager-entity-me-wrap-message",
- ("entityName", name),
- ("entity", ent),
- ("message", FormattedMessage.RemoveMarkup(action)));
+ var wrappedMessage = "";
+ var obfuscatedWrappedMessage = "";
+ if (signLanguage == true)
+ {
+ wrappedMessage = Loc.GetString("entity-signlanguage-message",
+ ("entityName", name),
+ ("message", FormattedMessage.EscapeText(action)));
+
+ obfuscatedWrappedMessage = Loc.GetString(_language.ObfuscateSpeech(action, language),
+ ("entityName", name));
+ }
+ else
+ {
+ wrappedMessage = Loc.GetString("chat-manager-entity-me-wrap-message",
+ ("entityName", name),
+ ("entity", ent),
+ ("message", FormattedMessage.RemoveMarkup(action)));
+
+ }
if (checkEmote)
TryEmoteChatInput(source, action);
- SendInVoiceRange(ChatChannel.Emotes, name, action, wrappedMessage, obfuscated: "", obfuscatedWrappedMessage: "", source, range, author);
+ SendInVoiceRange(ChatChannel.Emotes, name, action, wrappedMessage, obfuscated: "", obfuscatedWrappedMessage, source, range, author, signLanguage: true);
if (!hideLog)
if (name != Name(source))
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Emote from {ToPrettyString(source):user} as {name}: {action}");
@@ -749,7 +779,7 @@ private MessageRangeCheckResult MessageRangeCheck(ICommonSession session, ICChat
///
/// Sends a chat message to the given players in range of the source entity.
///
- private void SendInVoiceRange(ChatChannel channel, string name, string message, string wrappedMessage, string obfuscated, string obfuscatedWrappedMessage, EntityUid source, ChatTransmitRange range, NetUserId? author = null, LanguagePrototype? languageOverride = null)
+ private void SendInVoiceRange(ChatChannel channel, string name, string message, string wrappedMessage, string obfuscated, string obfuscatedWrappedMessage, EntityUid source, ChatTransmitRange range, NetUserId? author = null, LanguagePrototype? languageOverride = null, bool? signLanguage = false)
{
var language = languageOverride ?? _language.GetLanguage(source);
foreach (var (session, data) in GetRecipients(source, VoiceRange))
@@ -762,9 +792,17 @@ private void SendInVoiceRange(ChatChannel channel, string name, string message,
continue;
EntityUid listener = session.AttachedEntity.Value;
+ // Quickly Checking if the Emote is a real one or Sign Language.
+ var notSignLanguage = false;
+ if (channel == ChatChannel.Emotes)
+ {
+ notSignLanguage = true;
+ if (signLanguage == true)
+ notSignLanguage = false;
+ }
// If the channel does not support languages, or the entity can understand the message, send the original message, otherwise send the obfuscated version
- if (channel == ChatChannel.LOOC || channel == ChatChannel.Emotes || _language.CanUnderstand(listener, language.ID))
+ if (channel == ChatChannel.LOOC || notSignLanguage || _language.CanUnderstand(listener, language.ID))
{
_chatManager.ChatMessageToOne(channel, message, wrappedMessage, source, entHideChat, session.Channel, author: author);
}
diff --git a/Content.Shared/Language/LanguagePrototype.cs b/Content.Shared/Language/LanguagePrototype.cs
index be54b45aa1f..79c17daccd8 100644
--- a/Content.Shared/Language/LanguagePrototype.cs
+++ b/Content.Shared/Language/LanguagePrototype.cs
@@ -16,7 +16,13 @@ public sealed class LanguagePrototype : IPrototype
[DataField("fontSize")]
public int? FontSize;
-
+
+ ///
+ /// If true, will mark the language as a SignLanguage and will be handled as such.
+ ///
+ [DataField("signLanguage")]
+ public bool? SignLanguage;
+
///
/// Obfuscation method used by this language. By default, uses
///
diff --git a/Resources/Locale/en-US/language/languages.ftl b/Resources/Locale/en-US/language/languages.ftl
index 69c5d0a4a76..209daf92de8 100644
--- a/Resources/Locale/en-US/language/languages.ftl
+++ b/Resources/Locale/en-US/language/languages.ftl
@@ -4,6 +4,9 @@ language-Universal-description = What are you?
language-GalacticCommon-name = Galactic common
language-GalacticCommon-description = The standard Galatic language, most commonly used for inter-species communications and legal work.
+language-SignLanguage-name = Sign Language
+language-SignLanguage-description = The standard Galactic sign language, used by those that are unable to speak Galactic Common or at all.
+
language-Bubblish-name = Bubblish
language-Bubblish-description = The language of Slimes. Being a mixture of bubbling noises and pops it's very difficult to speak for humans without the use of mechanical aids.
diff --git a/Resources/Locale/en-US/language/sign-language.ftl b/Resources/Locale/en-US/language/sign-language.ftl
new file mode 100644
index 00000000000..f4548f995c5
--- /dev/null
+++ b/Resources/Locale/en-US/language/sign-language.ftl
@@ -0,0 +1,4 @@
+entity-signlanguage-message = [italic]{$entityName} signs "[BubbleContent]{$message}[/BubbleContent]"[/italic]
+
+language-signlanguage-1 = [italic]{$entityName} signs something.[/italic]
+language-signlanguage-2 = [italic]{$entityName} makes weird hand gestures.[/italic]
diff --git a/Resources/Prototypes/Language/languages.yml b/Resources/Prototypes/Language/languages.yml
index 048fdc6f24c..bec1884fe5c 100644
--- a/Resources/Prototypes/Language/languages.yml
+++ b/Resources/Prototypes/Language/languages.yml
@@ -35,6 +35,15 @@
- nah
- wah
+- type: language
+ id: SignLanguage
+ signLanguage: true
+ obfuscation:
+ !type:ReplacementObfuscation
+ replacement:
+ - "language-signlanguage-1"
+ - "language-signlanguage-2"
+
# Spoken by slimes.
- type: language
id: Bubblish