]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Fancy speech bubbles - Names over speech bubbles, and 1:1 chat parity for emotes...
authordeathride58 <deathride58@users.noreply.github.com>
Mon, 4 Dec 2023 23:10:49 +0000 (18:10 -0500)
committerGitHub <noreply@github.com>
Mon, 4 Dec 2023 23:10:49 +0000 (16:10 -0700)
Content.Client/Chat/UI/SpeechBubble.cs
Content.Client/Options/UI/Tabs/GraphicsTab.xaml
Content.Client/Options/UI/Tabs/GraphicsTab.xaml.cs
Content.Client/UserInterface/Systems/Chat/ChatUIController.cs
Content.Shared/CCVar/CCVars.cs
Resources/Locale/en-US/chat/managers/chat-manager.ftl
Resources/Locale/en-US/escape-menu/ui/options-menu.ftl

index 46a9f0539213bd2ee4516783de2d3237df265167..4c8b44999407175f5d2e23779ef8afa5cff99da0 100644 (file)
@@ -1,8 +1,11 @@
 using System.Numerics;
 using Content.Client.Chat.Managers;
+using Content.Shared.CCVar;
+using Content.Shared.Chat;
 using Robust.Client.Graphics;
 using Robust.Client.UserInterface;
 using Robust.Client.UserInterface.Controls;
+using Robust.Shared.Configuration;
 using Robust.Shared.Timing;
 using Robust.Shared.Utility;
 
@@ -10,6 +13,10 @@ namespace Content.Client.Chat.UI
 {
     public abstract class SpeechBubble : Control
     {
+        [Dependency] private readonly IEyeManager _eyeManager = default!;
+        [Dependency] private readonly IEntityManager _entityManager = default!;
+        [Dependency] protected readonly IConfigurationManager ConfigManager = default!;
+
         public enum SpeechType : byte
         {
             Emote,
@@ -34,10 +41,12 @@ namespace Content.Client.Chat.UI
         /// </summary>
         private const float EntityVerticalOffset = 0.5f;
 
-        private readonly IEyeManager _eyeManager;
+        /// <summary>
+        ///     The default maximum width for speech bubbles.
+        /// </summary>
+        public const float SpeechMaxWidth = 256;
+
         private readonly EntityUid _senderEntity;
-        private readonly IChatManager _chatManager;
-        private readonly IEntityManager _entityManager;
 
         private float _timeLeft = TotalTime;
 
@@ -49,38 +58,36 @@ namespace Content.Client.Chat.UI
         // man down
         public event Action<EntityUid, SpeechBubble>? OnDied;
 
-        public static SpeechBubble CreateSpeechBubble(SpeechType type, string text, EntityUid senderEntity, IEyeManager eyeManager, IChatManager chatManager, IEntityManager entityManager)
+        public static SpeechBubble CreateSpeechBubble(SpeechType type, ChatMessage message, EntityUid senderEntity)
         {
             switch (type)
             {
                 case SpeechType.Emote:
-                    return new TextSpeechBubble(text, senderEntity, eyeManager, chatManager, entityManager, "emoteBox");
+                    return new TextSpeechBubble(message, senderEntity, "emoteBox");
 
                 case SpeechType.Say:
-                    return new TextSpeechBubble(text, senderEntity, eyeManager, chatManager, entityManager, "sayBox");
+                    return new FancyTextSpeechBubble(message, senderEntity, "sayBox");
 
                 case SpeechType.Whisper:
-                    return new TextSpeechBubble(text, senderEntity, eyeManager, chatManager, entityManager, "whisperBox");
+                    return new FancyTextSpeechBubble(message, senderEntity, "whisperBox");
 
                 case SpeechType.Looc:
-                    return new TextSpeechBubble(text, senderEntity, eyeManager, chatManager, entityManager, "emoteBox", Color.FromHex("#48d1cc"));
+                    return new TextSpeechBubble(message, senderEntity, "emoteBox", Color.FromHex("#48d1cc"));
 
                 default:
                     throw new ArgumentOutOfRangeException();
             }
         }
 
-        public SpeechBubble(string text, EntityUid senderEntity, IEyeManager eyeManager, IChatManager chatManager, IEntityManager entityManager, string speechStyleClass, Color? fontColor = null)
+        public SpeechBubble(ChatMessage message, EntityUid senderEntity, string speechStyleClass, Color? fontColor = null)
         {
-            _chatManager = chatManager;
+            IoCManager.InjectDependencies(this);
             _senderEntity = senderEntity;
-            _eyeManager = eyeManager;
-            _entityManager = entityManager;
 
             // Use text clipping so new messages don't overlap old ones being pushed up.
             RectClipContent = true;
 
-            var bubble = BuildBubble(text, speechStyleClass, fontColor);
+            var bubble = BuildBubble(message, speechStyleClass, fontColor);
 
             AddChild(bubble);
 
@@ -91,7 +98,7 @@ namespace Content.Client.Chat.UI
             _verticalOffsetAchieved = -ContentSize.Y;
         }
 
-        protected abstract Control BuildBubble(string text, string speechStyleClass, Color? fontColor = null);
+        protected abstract Control BuildBubble(ChatMessage message, string speechStyleClass, Color? fontColor = null);
 
         protected override void FrameUpdate(FrameEventArgs args)
         {
@@ -165,33 +172,47 @@ namespace Content.Client.Chat.UI
                 _timeLeft = FadeTime;
             }
         }
+
+        protected FormattedMessage FormatSpeech(string message, Color? fontColor = null)
+        {
+            var msg = new FormattedMessage();
+            if (fontColor != null)
+                msg.PushColor(fontColor.Value);
+            msg.AddMarkup(message);
+            return msg;
+        }
+
+        protected string ExtractSpeechSubstring(ChatMessage message, string tag)
+        {
+            var rawmsg = message.WrappedMessage;
+            var tagStart = rawmsg.IndexOf($"[{tag}]");
+            var tagEnd = rawmsg.IndexOf($"[/{tag}]");
+            tagStart += tag.Length + 2;
+            return rawmsg.Substring(tagStart, tagEnd - tagStart);
+        }
+
+        protected FormattedMessage ExtractAndFormatSpeechSubstring(ChatMessage message, string tag, Color? fontColor = null)
+        {
+            return FormatSpeech(ExtractSpeechSubstring(message, tag), fontColor);
+        }
+
     }
 
     public sealed class TextSpeechBubble : SpeechBubble
     {
-        public TextSpeechBubble(string text, EntityUid senderEntity, IEyeManager eyeManager, IChatManager chatManager, IEntityManager entityManager, string speechStyleClass, Color? fontColor = null)
-            : base(text, senderEntity, eyeManager, chatManager, entityManager, speechStyleClass, fontColor)
+        public TextSpeechBubble(ChatMessage message, EntityUid senderEntity, string speechStyleClass, Color? fontColor = null)
+            : base(message, senderEntity, speechStyleClass, fontColor)
         {
         }
 
-        protected override Control BuildBubble(string text, string speechStyleClass, Color? fontColor = null)
+        protected override Control BuildBubble(ChatMessage message, string speechStyleClass, Color? fontColor = null)
         {
             var label = new RichTextLabel
             {
-                MaxWidth = 256,
+                MaxWidth = SpeechMaxWidth,
             };
 
-            if (fontColor != null)
-            {
-                var msg = new FormattedMessage();
-                msg.PushColor(fontColor.Value);
-                msg.AddMarkup(text);
-                label.SetMessage(msg);
-            }
-            else
-            {
-                label.SetMessage(text);
-            }
+            label.SetMessage(FormatSpeech(message.WrappedMessage, fontColor));
 
             var panel = new PanelContainer
             {
@@ -203,4 +224,76 @@ namespace Content.Client.Chat.UI
             return panel;
         }
     }
+
+    public sealed class FancyTextSpeechBubble : SpeechBubble
+    {
+
+        public FancyTextSpeechBubble(ChatMessage message, EntityUid senderEntity, string speechStyleClass, Color? fontColor = null)
+            : base(message, senderEntity, speechStyleClass, fontColor)
+        {
+        }
+
+        protected override Control BuildBubble(ChatMessage message, string speechStyleClass, Color? fontColor = null)
+        {
+            if (!ConfigManager.GetCVar(CCVars.ChatEnableFancyBubbles))
+            {
+                var label = new RichTextLabel
+                {
+                    MaxWidth = SpeechMaxWidth
+                };
+
+                label.SetMessage(ExtractAndFormatSpeechSubstring(message, "BubbleContent", fontColor));
+
+                var unfanciedPanel = new PanelContainer
+                {
+                    StyleClasses = { "speechBox", speechStyleClass },
+                    Children = { label },
+                    ModulateSelfOverride = Color.White.WithAlpha(0.75f)
+                };
+                return unfanciedPanel;
+            }
+
+            var bubbleHeader = new RichTextLabel
+            {
+                Margin = new Thickness(1, 1, 1, 1)
+            };
+
+            var bubbleContent = new RichTextLabel
+            {
+                MaxWidth = SpeechMaxWidth,
+                Margin = new Thickness(2, 6, 2, 2)
+            };
+
+            //We'll be honest. *Yes* this is hacky. Doing this in a cleaner way would require a bottom-up refactor of how saycode handles sending chat messages. -Myr
+            bubbleHeader.SetMessage(ExtractAndFormatSpeechSubstring(message, "BubbleHeader", fontColor));
+            bubbleContent.SetMessage(ExtractAndFormatSpeechSubstring(message, "BubbleContent", fontColor));
+
+            //As for below: Some day this could probably be converted to xaml. But that is not today. -Myr
+            var mainPanel = new PanelContainer
+            {
+                StyleClasses = { "speechBox", speechStyleClass },
+                Children = { bubbleContent },
+                ModulateSelfOverride = Color.White.WithAlpha(0.75f),
+                HorizontalAlignment = HAlignment.Center,
+                VerticalAlignment = VAlignment.Bottom,
+                Margin = new Thickness(4, 14, 4, 2)
+            };
+
+            var headerPanel = new PanelContainer
+            {
+                StyleClasses = { "speechBox", speechStyleClass },
+                Children = { bubbleHeader },
+                ModulateSelfOverride = Color.White.WithAlpha(ConfigManager.GetCVar(CCVars.ChatFancyNameBackground) ? 0.75f : 0f),
+                HorizontalAlignment = HAlignment.Center,
+                VerticalAlignment = VAlignment.Top
+            };
+
+            var panel = new PanelContainer
+            {
+                Children = { mainPanel, headerPanel }
+            };
+
+            return panel;
+        }
+    }
 }
index f759c78eca89017df10d83ab581a62aee24b6b6a..3de59cf5dcc93b67654dbc80fb1208b19c641ea7 100644 (file)
@@ -23,6 +23,8 @@
             <CheckBox Name="ShowHeldItemCheckBox" Text="{Loc 'ui-options-show-held-item'}" />
             <CheckBox Name="ShowCombatModeIndicatorsCheckBox" Text="{Loc 'ui-options-show-combat-mode-indicators'}" />
             <CheckBox Name="ShowLoocAboveHeadCheckBox" Text="{Loc 'ui-options-show-looc-on-head'}" />
+            <CheckBox Name="FancySpeechBubblesCheckBox" Text="{Loc 'ui-options-fancy-speech'}" />
+            <CheckBox Name="FancyNameBackgroundsCheckBox" Text="{Loc 'ui-options-fancy-name-background'}" />
             <BoxContainer Orientation="Horizontal">
                 <CheckBox Name="ViewportStretchCheckBox" Text="{Loc 'ui-options-vp-stretch'}" />
                 <BoxContainer Name="ViewportScaleBox" Orientation="Horizontal">
index e64838ba752e1a7f6c4293b52dc1aa4bcd121a34..9d7e5006518d70d2700641b84668e450c612c282 100644 (file)
@@ -104,6 +104,8 @@ namespace Content.Client.Options.UI.Tabs
             ShowHeldItemCheckBox.OnToggled += OnCheckBoxToggled;
             ShowCombatModeIndicatorsCheckBox.OnToggled += OnCheckBoxToggled;
             ShowLoocAboveHeadCheckBox.OnToggled += OnCheckBoxToggled;
+            FancySpeechBubblesCheckBox.OnToggled += OnCheckBoxToggled;
+            FancyNameBackgroundsCheckBox.OnToggled += OnCheckBoxToggled;
             IntegerScalingCheckBox.OnToggled += OnCheckBoxToggled;
             ViewportLowResCheckBox.OnToggled += OnCheckBoxToggled;
             ParallaxLowQualityCheckBox.OnToggled += OnCheckBoxToggled;
@@ -123,6 +125,8 @@ namespace Content.Client.Options.UI.Tabs
             ShowHeldItemCheckBox.Pressed = _cfg.GetCVar(CCVars.HudHeldItemShow);
             ShowCombatModeIndicatorsCheckBox.Pressed = _cfg.GetCVar(CCVars.CombatModeIndicatorsPointShow);
             ShowLoocAboveHeadCheckBox.Pressed = _cfg.GetCVar(CCVars.LoocAboveHeadShow);
+            FancySpeechBubblesCheckBox.Pressed = _cfg.GetCVar(CCVars.ChatEnableFancyBubbles);
+            FancyNameBackgroundsCheckBox.Pressed = _cfg.GetCVar(CCVars.ChatFancyNameBackground);
             ViewportWidthSlider.Value = _cfg.GetCVar(CCVars.ViewportWidth);
 
             _cfg.OnValueChanged(CCVars.ViewportMinimumWidth, _ => UpdateViewportWidthRange());
@@ -171,6 +175,8 @@ namespace Content.Client.Options.UI.Tabs
             _cfg.SetCVar(CCVars.HudHeldItemShow, ShowHeldItemCheckBox.Pressed);
             _cfg.SetCVar(CCVars.CombatModeIndicatorsPointShow, ShowCombatModeIndicatorsCheckBox.Pressed);
             _cfg.SetCVar(CCVars.LoocAboveHeadShow, ShowLoocAboveHeadCheckBox.Pressed);
+            _cfg.SetCVar(CCVars.ChatEnableFancyBubbles, FancySpeechBubblesCheckBox.Pressed);
+            _cfg.SetCVar(CCVars.ChatFancyNameBackground, FancyNameBackgroundsCheckBox.Pressed);
             _cfg.SetCVar(CCVars.HudFpsCounterVisible, FpsCounterCheckBox.Pressed);
             _cfg.SetCVar(CCVars.ViewportWidth, (int) ViewportWidthSlider.Value);
 
@@ -209,6 +215,8 @@ namespace Content.Client.Options.UI.Tabs
             var isShowHeldItemSame = ShowHeldItemCheckBox.Pressed == _cfg.GetCVar(CCVars.HudHeldItemShow);
             var isCombatModeIndicatorsSame = ShowCombatModeIndicatorsCheckBox.Pressed == _cfg.GetCVar(CCVars.CombatModeIndicatorsPointShow);
             var isLoocShowSame = ShowLoocAboveHeadCheckBox.Pressed == _cfg.GetCVar(CCVars.LoocAboveHeadShow);
+            var isFancyChatSame = FancySpeechBubblesCheckBox.Pressed == _cfg.GetCVar(CCVars.ChatEnableFancyBubbles);
+            var isFancyBackgroundSame = FancyNameBackgroundsCheckBox.Pressed == _cfg.GetCVar(CCVars.ChatFancyNameBackground);
             var isFpsCounterVisibleSame = FpsCounterCheckBox.Pressed == _cfg.GetCVar(CCVars.HudFpsCounterVisible);
             var isWidthSame = (int) ViewportWidthSlider.Value == _cfg.GetCVar(CCVars.ViewportWidth);
             var isLayoutSame = HudLayoutOption.SelectedMetadata is string opt && opt == _cfg.GetCVar(CCVars.UILayout);
@@ -226,6 +234,8 @@ namespace Content.Client.Options.UI.Tabs
                                    isShowHeldItemSame &&
                                    isCombatModeIndicatorsSame &&
                                    isLoocShowSame &&
+                                   isFancyChatSame &&
+                                   isFancyBackgroundSame &&
                                    isFpsCounterVisibleSame &&
                                    isWidthSame &&
                                    isLayoutSame;
index 2d90b371c3c69fa8544cb1fdaf7e2f7279232517..e5393944169449602c3c7239cfbcfc0366352ec3 100644 (file)
@@ -369,7 +369,7 @@ public sealed class ChatUIController : UIController
         UpdateChannelPermissions();
     }
 
-    private void AddSpeechBubble(ChatMessage msg, SpeechBubble.SpeechType speechType, string? prefixText = null, string? prefixEndText = null)
+    private void AddSpeechBubble(ChatMessage msg, SpeechBubble.SpeechType speechType)
     {
         var ent = EntityManager.GetEntity(msg.SenderEntity);
 
@@ -379,22 +379,13 @@ public sealed class ChatUIController : UIController
             return;
         }
 
-        // Kind of shitty way to add prefixes but hey it works!
-        string Message = prefixText + msg.Message + prefixEndText;
-
-        // msg.Message should be the string that a user sent over text, without any added markup.
-        var messages = SplitMessage(Message);
-
-        foreach (var message in messages)
-        {
-            EnqueueSpeechBubble(ent, message, speechType);
-        }
+        EnqueueSpeechBubble(ent, msg, speechType);
     }
 
     private void CreateSpeechBubble(EntityUid entity, SpeechBubbleData speechData)
     {
         var bubble =
-            SpeechBubble.CreateSpeechBubble(speechData.Type, speechData.Message, entity, _eye, _manager, EntityManager);
+            SpeechBubble.CreateSpeechBubble(speechData.Type, speechData.Message, entity);
 
         bubble.OnDied += SpeechBubbleDied;
 
@@ -428,7 +419,7 @@ public sealed class ChatUIController : UIController
         RemoveSpeechBubble(entity, bubble);
     }
 
-    private void EnqueueSpeechBubble(EntityUid entity, string contents, SpeechBubble.SpeechType speechType)
+    private void EnqueueSpeechBubble(EntityUid entity, ChatMessage message, SpeechBubble.SpeechType speechType)
     {
         // Don't enqueue speech bubbles for other maps. TODO: Support multiple viewports/maps?
         if (EntityManager.GetComponent<TransformComponent>(entity).MapID != _eye.CurrentMap)
@@ -440,7 +431,7 @@ public sealed class ChatUIController : UIController
             _queuedSpeechBubbles.Add(entity, queueData);
         }
 
-        queueData.MessageQueue.Enqueue(new SpeechBubbleData(contents, speechType));
+        queueData.MessageQueue.Enqueue(new SpeechBubbleData(message, speechType));
     }
 
     public void RemoveSpeechBubble(EntityUid entityUid, SpeechBubble bubble)
@@ -568,7 +559,7 @@ public sealed class ChatUIController : UIController
 
             var msg = queueData.MessageQueue.Dequeue();
 
-            queueData.TimeLeft += BubbleDelayBase + msg.Message.Length * BubbleDelayFactor;
+            queueData.TimeLeft += BubbleDelayBase + msg.Message.Message.Length * BubbleDelayFactor;
 
             // We keep the queue around while it has 0 items. This allows us to keep the timer.
             // When the timer hits 0 and there's no messages left, THEN we can clear it up.
@@ -621,52 +612,6 @@ public sealed class ChatUIController : UIController
         }
     }
 
-    private List<string> SplitMessage(string msg)
-    {
-        // Split message into words separated by spaces.
-        var words = msg.Split(' ');
-        var messages = new List<string>();
-        var currentBuffer = new List<string>();
-
-        // Really shoddy way to approximate word length.
-        // Yes, I am aware of all the crimes here.
-        // TODO: Improve this to use actual glyph width etc..
-        var currentWordLength = 0;
-        foreach (var word in words)
-        {
-            // +1 for the space.
-            currentWordLength += word.Length + 1;
-
-            if (currentWordLength > SingleBubbleCharLimit)
-            {
-                // Too long for the current speech bubble, flush it.
-                messages.Add(string.Join(" ", currentBuffer));
-                currentBuffer.Clear();
-
-                currentWordLength = word.Length;
-
-                if (currentWordLength > SingleBubbleCharLimit)
-                {
-                    // Word is STILL too long.
-                    // Truncate it with an ellipse.
-                    messages.Add($"{word.Substring(0, SingleBubbleCharLimit - 3)}...");
-                    currentWordLength = 0;
-                    continue;
-                }
-            }
-
-            currentBuffer.Add(word);
-        }
-
-        if (currentBuffer.Count != 0)
-        {
-            // Don't forget the last bubble.
-            messages.Add(string.Join(" ", currentBuffer));
-        }
-
-        return messages;
-    }
-
     public ChatSelectChannel MapLocalIfGhost(ChatSelectChannel channel)
     {
         if (channel == ChatSelectChannel.Local && _ghost is {IsGhost: true})
@@ -849,11 +794,7 @@ public sealed class ChatUIController : UIController
 
             case ChatChannel.LOOC:
                 if (_cfg.GetCVar(CCVars.LoocAboveHeadShow))
-                {
-                    const string prefixText = "(LOOC: ";
-                    const string prefixEndText = ")";
-                    AddSpeechBubble(msg, SpeechBubble.SpeechType.Looc, prefixText, prefixEndText);
-                }
+                    AddSpeechBubble(msg, SpeechBubble.SpeechType.Looc);
                 break;
         }
     }
@@ -896,7 +837,7 @@ public sealed class ChatUIController : UIController
         }
     }
 
-    private readonly record struct SpeechBubbleData(string Message, SpeechBubble.SpeechType Type);
+    private readonly record struct SpeechBubbleData(ChatMessage Message, SpeechBubble.SpeechType Type);
 
     private sealed class SpeechBubbleQueueData
     {
index 999ef21e256fd174da360aff8d05ecea8e890c21..5b03816f261af0f4a4d460f7a478ecb01cb58d80 100644 (file)
@@ -1476,6 +1476,12 @@ namespace Content.Shared.CCVar
         public static readonly CVarDef<bool> ChatShowTypingIndicator =
             CVarDef.Create("chat.show_typing_indicator", true, CVar.CLIENTONLY);
 
+        public static readonly CVarDef<bool> ChatEnableFancyBubbles =
+            CVarDef.Create("chat.enable_fancy_bubbles", true, CVar.CLIENTONLY | CVar.ARCHIVE, "Toggles displaying fancy speech bubbles, which display the speaking character's name.");
+
+        public static readonly CVarDef<bool> ChatFancyNameBackground =
+            CVarDef.Create("chat.fancy_name_background", false, CVar.CLIENTONLY | CVar.ARCHIVE, "Toggles displaying a background under the speaking character's name.");
+
         /// <summary>
         /// A message broadcast to each player that joins the lobby.
         /// May be changed by admins ingame through use of the "set-motd" command.
index 2690a6dfdb2e2934bf208898f2275c91dc806695..0c817479a24cb9f7fc0cbcef3fc6a1f26e3f394b 100644 (file)
@@ -21,11 +21,11 @@ chat-manager-whisper-headset-on-message = You can't whisper on the radio!
 chat-manager-server-wrap-message = [bold]{$message}[/bold]
 chat-manager-sender-announcement-wrap-message = [font size=14][bold]{$sender} Announcement:[/font][font size=12]
                                                 {$message}[/bold][/font]
-chat-manager-entity-say-wrap-message = [bold]{$entityName}[/bold] {$verb}, [font={$fontType} size={$fontSize}]"{$message}"[/font]
-chat-manager-entity-say-bold-wrap-message = [bold]{$entityName}[/bold] {$verb}, [font={$fontType} size={$fontSize}][bold]"{$message}"[/bold][/font]
+chat-manager-entity-say-wrap-message = [BubbleHeader][bold]{$entityName}[/bold][/BubbleHeader] {$verb}, [font={$fontType} size={$fontSize}]"[BubbleContent]{$message}[/BubbleContent]"[/font]
+chat-manager-entity-say-bold-wrap-message = [BubbleHeader][bold]{$entityName}[/bold][/BubbleHeader] {$verb}, [font={$fontType} size={$fontSize}]"[BubbleContent][bold]{$message}[/bold][/BubbleContent]"[/font]
 
-chat-manager-entity-whisper-wrap-message = [font size=11][italic]{$entityName} whispers, "{$message}"[/italic][/font]
-chat-manager-entity-whisper-unknown-wrap-message = [font size=11][italic]Someone whispers, "{$message}"[/italic][/font]
+chat-manager-entity-whisper-wrap-message = [font size=11][italic][BubbleHeader]{$entityName}[/BubbleHeader] whispers,"[BubbleContent]{$message}[/BubbleContent]"[/italic][/font]
+chat-manager-entity-whisper-unknown-wrap-message = [font size=11][italic][BubbleHeader]Someone[/BubbleHeader] whispers, "[BubbleContent]{$message}[/BubbleContent]"[/italic][/font]
 
 # THE() is not used here because the entity and its name can technically be disconnected if a nameOverride is passed...
 chat-manager-entity-me-wrap-message = [italic]{ PROPER($entity) ->
index 7c541e0257e793b067dca76415e50fe0fe7bcb2f..da9edc6f75b0d24d256c92d2ca33deb712cdc807 100644 (file)
@@ -30,6 +30,8 @@ ui-options-volume-percent = { TOSTRING($volume, "P0") }
 ui-options-show-held-item = Show held item next to cursor?
 ui-options-show-combat-mode-indicators = Show combat mode indicators with cursor?
 ui-options-show-looc-on-head = Show LOOC chat above characters head?
+ui-options-fancy-speech = Show names in speech bubbles?
+ui-options-fancy-name-background = Add background to speech bubble names?
 ui-options-vsync = VSync
 ui-options-fullscreen = Fullscreen
 ui-options-lighting-label = Lighting Quality: