Files
Delta-v/Content.Server/_DV/AACTablet/AACTabletSystem.cs
da885b1b1d PORT: AAC Tablet Radio Compatibility from Starcup (#5569)
* Allows the AAC to send messages over the radio

* Allows AAC names to be highlighted in chat

* Restores VoiceOverrideComponent to the AAC

* refactor: separate confluent code into new files

Signed-off-by: little-meow-meow <204685920+little-meow-meow@users.noreply.github.com>

* style fix

Signed-off-by: little-meow-meow <204685920+little-meow-meow@users.noreply.github.com>

* Ugh this took me too long to figure out

-Made so many changes to AACTabletBuiState, moved it under _DV: Made it compatible with Wizden #40293 which moved all radio comps and system to shared
-Had issues with having two AAC UI open so made it so one closes before another opens
-Trial and error with the UI window lol

* Reverted Refactor + Comment Clean up

Reverted 0873b66449 which split code between starcup namespace and removed starcup comments because it's editing _DV files.

Fix namespace error due to radio moving the share, seem to work just fine!

---------

Signed-off-by: little-meow-meow <204685920+little-meow-meow@users.noreply.github.com>
Co-authored-by: Oxdeception <9624-oxdeception@users.noreply.gitgud.io>
Co-authored-by: little-meow-meow <204685920+little-meow-meow@users.noreply.github.com>
Co-authored-by: Janet Blackquill <uhhadd@gmail.com>
2026-05-15 17:17:49 +00:00

106 lines
3.9 KiB
C#

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 Content.Shared.Radio.Components;
using Content.Shared.Radio;
using Robust.Server.GameObjects;
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!;
[Dependency] private readonly UserInterfaceSystem _userInterface = default!;
private readonly List<string> _localisedPhrases = [];
public const int MaxPhrases = 10; // no writing novels
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<AACTabletComponent, AACTabletSendPhraseMessage>(OnSendPhrase);
Subs.BuiEvents<AACTabletComponent>(AACTabletKey.Key, subs =>
{
subs.Event<BoundUIOpenedEvent>(OnBoundUIOpened);
});
}
private HashSet<ProtoId<RadioChannelPrototype>> GetAvailableChannels(EntityUid entity)
{
var channels = new HashSet<ProtoId<RadioChannelPrototype>>();
// Get all the intrinsic radio channels (IPCs, implants)
if (TryComp(entity, out ActiveRadioComponent? intrinsicRadio))
channels.UnionWith(intrinsicRadio.Channels);
// Get the user's headset channels, if any
if (TryComp(entity, out WearingHeadsetComponent? headset)
&& TryComp(headset.Headset, out ActiveRadioComponent? headsetRadio))
channels.UnionWith(headsetRadio.Channels);
return channels;
}
private void OnBoundUIOpened(Entity<AACTabletComponent> ent, ref BoundUIOpenedEvent args)
{
var state = new AACTabletBuiState(GetAvailableChannels(args.Actor));
_userInterface.SetUiState(args.Entity, AACTabletKey.Key, state);
}
private void OnSendPhrase(Entity<AACTabletComponent> 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<VoiceOverrideComponent>(ent).NameOverride = speakerName;
// Set the player's currently available channels before sending the message
EnsureComp(ent, out IntrinsicRadioTransmitterComponent transmitter);
transmitter.Channels = GetAvailableChannels(message.Actor);
// L5 — save the message for logging
var messageToSend = string.Join(" ", _localisedPhrases);
_chat.TrySendInGameICMessage(ent,
message.Prefix + 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;
}
}