diff --git a/Content.Server/Chat/RainbowChatSystem.cs b/Content.Server/Chat/RainbowChatSystem.cs new file mode 100644 index 0000000000..eaa9c21b02 --- /dev/null +++ b/Content.Server/Chat/RainbowChatSystem.cs @@ -0,0 +1,51 @@ +using Content.Server.Chat.Systems; +using Content.Shared.Humanoid; + +namespace Content.Server.Chat; + +public sealed class RainbowChatSystem : EntitySystem +{ + public Dictionary NameToColor = new(); + + private const float MinSaturation = 0.22f; + private const float MaxSaturation = 0.30f; + private const float MinValue = 0.70f; + private const float MaxValue = 0.80f; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnHumanoidSpeak); + } + + private void OnHumanoidSpeak(EntityUid uid, HumanoidAppearanceComponent component, SetSpeakerColorEvent args) + { + var color = GetColor(args.Name); + args.Name = $"[color={color}]{args.Name}[/color]"; + } + + private string GetColor(string characterName) + { + if (NameToColor.TryGetValue(characterName, out var hexColor)) + return hexColor; + + return CreateCharacterHexColor(characterName); + } + + private string CreateCharacterHexColor(string characterName) + { + var random = new Random(characterName.GetHashCode()); + var h = GetRandomFloat(ref random,0f,1f); + var s = GetRandomFloat(ref random, MinSaturation, MaxSaturation); + var v = GetRandomFloat(ref random,MinValue, MaxValue); + + var color = Color.FromHsv(new Vector4(h, s, v, 1)).ToHex(); + NameToColor[characterName] = color; + return color; + } + + private float GetRandomFloat(ref Random random, float minimum, float maximum) + { + return (float)(random.NextDouble() * (maximum - minimum) + minimum); + } +} diff --git a/Content.Server/Chat/Systems/ChatSystem.cs b/Content.Server/Chat/Systems/ChatSystem.cs index 2520f77f51..65bee2190f 100644 --- a/Content.Server/Chat/Systems/ChatSystem.cs +++ b/Content.Server/Chat/Systems/ChatSystem.cs @@ -401,13 +401,15 @@ public sealed partial class ChatSystem : SharedChatSystem } name = FormattedMessage.EscapeText(name); - var speech = GetSpeechVerb(source, message); - var wrappedMessage = Loc.GetString(speech.Bold ? "chat-manager-entity-say-bold-wrap-message" : "chat-manager-entity-say-wrap-message", - ("entityName", name), - ("verb", Loc.GetString(_random.Pick(speech.SpeechVerbStrings))), - ("fontType", speech.FontId), - ("fontSize", speech.FontSize), - ("message", FormattedMessage.EscapeText(message))); + + //WD-EDIT + var colorEv = new SetSpeakerColorEvent(source, name); + RaiseLocalEvent(source, colorEv); + name = colorEv.Name; + //WD-EDIT + + var wrappedMessage = Loc.GetString("chat-manager-entity-say-wrap-message", + ("entityName", name), ("message", FormattedMessage.EscapeText(message))); SendInVoiceRange(ChatChannel.Local, message, wrappedMessage, source, range); @@ -928,6 +930,20 @@ public sealed class EntitySpokeEvent : EntityEventArgs } } +//WD-EDIT +public class SetSpeakerColorEvent +{ + public EntityUid Sender { get; set; } + public string Name { get; set; } + + public SetSpeakerColorEvent(EntityUid sender, string name) + { + Sender = sender; + Name = name; + } +} +//WD-EDIT + /// /// InGame IC chat is for chat that is specifically ingame (not lobby) but is also in character, i.e. speaking. ///