Add option for character name colors in chat & move coloration to clientside (#24625)

* Adds option to disable character names in chat/speechbubbles

* Moved the coloring of names to clientside

* Move string functions to SharedChatSystem to avoid duplicate code in SpeechBubble.cs

* Changed to be put under Accessibility section

* Cache CVar
This commit is contained in:
SlamBamActionman
2024-02-11 07:38:55 +01:00
committed by GitHub
parent fabcc2b0d1
commit 247be5b5c7
9 changed files with 81 additions and 49 deletions

View File

@@ -15,10 +15,12 @@ using Content.Client.UserInterface.Systems.Gameplay;
using Content.Shared.Administration;
using Content.Shared.CCVar;
using Content.Shared.Chat;
using Content.Shared.Decals;
using Content.Shared.Damage.ForceSay;
using Content.Shared.Examine;
using Content.Shared.Input;
using Content.Shared.Radio;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Input;
using Robust.Client.Player;
@@ -27,9 +29,11 @@ using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controllers;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.Configuration;
using Robust.Shared.GameObjects.Components.Localization;
using Robust.Shared.Input.Binding;
using Robust.Shared.Map;
using Robust.Shared.Network;
using Robust.Shared.Prototypes;
using Robust.Shared.Replays;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
@@ -42,9 +46,11 @@ public sealed class ChatUIController : UIController
[Dependency] private readonly IChatManager _manager = default!;
[Dependency] private readonly IConfigurationManager _config = default!;
[Dependency] private readonly IEyeManager _eye = default!;
[Dependency] private readonly IEntityManager _ent = default!;
[Dependency] private readonly IInputManager _input = default!;
[Dependency] private readonly IClientNetManager _net = default!;
[Dependency] private readonly IPlayerManager _player = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IStateManager _state = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IReplayRecordingManager _replayRecording = default!;
@@ -55,6 +61,11 @@ public sealed class ChatUIController : UIController
[UISystemDependency] private readonly TypingIndicatorSystem? _typingIndicator = default;
[UISystemDependency] private readonly ChatSystem? _chatSys = default;
[ValidatePrototypeId<ColorPalettePrototype>]
private const string ChatNamePalette = "ChatNames";
private string[] _chatNameColors = default!;
private bool _chatNameColorsEnabled;
private ISawmill _sawmill = default!;
public static readonly Dictionary<char, ChatSelectChannel> PrefixToChannel = new()
@@ -168,6 +179,8 @@ public sealed class ChatUIController : UIController
_net.RegisterNetMessage<MsgChatMessage>(OnChatMessage);
_net.RegisterNetMessage<MsgDeleteChatMessagesBy>(OnDeleteChatMessagesBy);
SubscribeNetworkEvent<DamageForceSayEvent>(OnDamageForceSay);
_cfg.OnValueChanged(CCVars.ChatEnableColorName, (value) => { _chatNameColorsEnabled = value; });
_chatNameColorsEnabled = _cfg.GetCVar(CCVars.ChatEnableColorName);
_speechBubbleRoot = new LayoutContainer();
@@ -212,6 +225,13 @@ public sealed class ChatUIController : UIController
var gameplayStateLoad = UIManager.GetUIController<GameplayStateLoadController>();
gameplayStateLoad.OnScreenLoad += OnScreenLoad;
gameplayStateLoad.OnScreenUnload += OnScreenUnload;
var nameColors = _prototypeManager.Index<ColorPalettePrototype>(ChatNamePalette).Colors.Values.ToArray();
_chatNameColors = new string[nameColors.Length];
for (var i = 0; i < nameColors.Length; i++)
{
_chatNameColors[i] = nameColors[i].ToHex();
}
}
public void OnScreenLoad()
@@ -757,6 +777,14 @@ public sealed class ChatUIController : UIController
public void ProcessChatMessage(ChatMessage msg, bool speechBubble = true)
{
// color the name unless it's something like "the old man"
if ((msg.Channel == ChatChannel.Local || msg.Channel == ChatChannel.Whisper) && _chatNameColorsEnabled)
{
var grammar = _ent.GetComponentOrNull<GrammarComponent>(_ent.GetEntity(msg.SenderEntity));
if (grammar != null && grammar.ProperNoun == true)
msg.WrappedMessage = SharedChatSystem.InjectTagInsideTag(msg, "Name", "color", GetNameColor(SharedChatSystem.GetStringInsideTag(msg, "Name")));
}
// Log all incoming chat to repopulate when filter is un-toggled
if (!msg.HideChat)
{
@@ -845,6 +873,17 @@ public sealed class ChatUIController : UIController
}
}
/// <summary>
/// Returns the chat name color for a mob
/// </summary>
/// <param name="name">Name of the mob</param>
/// <returns>Hex value of the color</returns>
public string GetNameColor(string name)
{
var colorIdx = Math.Abs(name.GetHashCode() % _chatNameColors.Length);
return _chatNameColors[colorIdx];
}
private readonly record struct SpeechBubbleData(ChatMessage Message, SpeechBubble.SpeechType Type);
private sealed class SpeechBubbleQueueData