using Content.Shared.Chat; using Content.Server.Administration.Logs; using Content.Server.Chat.Systems; using Content.Server.Speech.Components; using Content.Shared._DV.AACTablet; using Content.Shared.Database; using Content.Shared.IdentityManagement; using Robust.Shared.Prototypes; using Robust.Shared.Timing; namespace Content.Server._DV.AACTablet; public sealed class AACTabletSystem : EntitySystem { [Dependency] private readonly ChatSystem _chat = default!; [Dependency] private readonly IAdminLogManager _adminLogger = default!; [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; private readonly List _localisedPhrases = []; public const int MaxPhrases = 10; // no writing novels public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnSendPhrase); } private void OnSendPhrase(Entity ent, ref AACTabletSendPhraseMessage message) { if (ent.Comp.NextPhrase > _timing.CurTime || message.PhraseIds.Count > MaxPhrases) return; var senderName = Identity.Entity(message.Actor, EntityManager); var speakerName = Loc.GetString("speech-name-relay", ("speaker", Name(ent)), ("originalName", senderName)); _localisedPhrases.Clear(); foreach (var phraseProto in message.PhraseIds) { if (_prototype.Resolve(phraseProto, out var phrase)) { // Ensures each phrase is capitalised to maintain common AAC styling _localisedPhrases.Add(_chat.SanitizeMessageCapital(Loc.GetString(phrase.Text))); } } if (_localisedPhrases.Count <= 0) return; EnsureComp(ent).NameOverride = speakerName; // L5 — save the message for logging var messageToSend = string.Join(" ", _localisedPhrases); _chat.TrySendInGameICMessage(ent, messageToSend, InGameICChatType.Speak, hideChat: false, nameOverride: speakerName); // L5 — log AAC chat message _adminLogger.Add(LogType.Chat, LogImpact.Low, $"AAC tablet message from {ToPrettyString(message.Actor):user}: {messageToSend}"); var curTime = _timing.CurTime; ent.Comp.NextPhrase = curTime + ent.Comp.Cooldown; } }