diff --git a/Content.Server/Radio/EntitySystems/RadioSystem.cs b/Content.Server/Radio/EntitySystems/RadioSystem.cs index 92e8139c75..8eccd4be69 100644 --- a/Content.Server/Radio/EntitySystems/RadioSystem.cs +++ b/Content.Server/Radio/EntitySystems/RadioSystem.cs @@ -10,6 +10,7 @@ using Content.Shared.Radio.Components; using Robust.Shared.Map; using Robust.Shared.Network; using Robust.Shared.Player; +using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Replays; using Robust.Shared.Utility; @@ -24,6 +25,7 @@ public sealed class RadioSystem : EntitySystem [Dependency] private readonly INetManager _netMan = default!; [Dependency] private readonly IReplayRecordingManager _replay = default!; [Dependency] private readonly IAdminLogManager _adminLogger = default!; + [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly ChatSystem _chat = default!; @@ -52,12 +54,20 @@ public sealed class RadioSystem : EntitySystem _netMan.ServerSendMessage(args.ChatMsg, actor.PlayerSession.ConnectedClient); } + /// + /// Send radio message to all active radio listeners + /// + public void SendRadioMessage(EntityUid messageSource, string message, ProtoId channel, EntityUid radioSource, bool escapeMarkup = true) + { + SendRadioMessage(messageSource, message, _prototype.Index(channel), radioSource, escapeMarkup: escapeMarkup); + } + /// /// Send radio message to all active radio listeners /// /// Entity that spoke the message /// Entity that picked up the message and will send it, e.g. headset - public void SendRadioMessage(EntityUid messageSource, string message, RadioChannelPrototype channel, EntityUid radioSource) + public void SendRadioMessage(EntityUid messageSource, string message, RadioChannelPrototype channel, EntityUid radioSource, bool escapeMarkup = true) { // TODO if radios ever garble / modify messages, feedback-prevention needs to be handled better than this. if (!_messages.Add(message)) @@ -70,6 +80,9 @@ public sealed class RadioSystem : EntitySystem name = FormattedMessage.EscapeText(name); var speech = _chat.GetSpeechVerb(messageSource, message); + var content = escapeMarkup + ? FormattedMessage.EscapeText(message) + : message; var wrappedMessage = Loc.GetString(speech.Bold ? "chat-radio-message-wrap-bold" : "chat-radio-message-wrap", ("color", channel.Color), @@ -78,7 +91,7 @@ public sealed class RadioSystem : EntitySystem ("verb", Loc.GetString(_random.Pick(speech.SpeechVerbStrings))), ("channel", $"\\[{channel.LocalizedName}\\]"), ("name", name), - ("message", FormattedMessage.EscapeText(message))); + ("message", content)); // most radios are relayed to chat, so lets parse the chat message beforehand var chat = new ChatMessage( diff --git a/Content.Server/Research/Components/ResearchConsoleComponent.cs b/Content.Server/Research/Components/ResearchConsoleComponent.cs index 038357ef8b..bdd620e9b0 100644 --- a/Content.Server/Research/Components/ResearchConsoleComponent.cs +++ b/Content.Server/Research/Components/ResearchConsoleComponent.cs @@ -1,8 +1,15 @@ +using Content.Shared.Radio; +using Robust.Shared.Prototypes; + namespace Content.Server.Research.Components; [RegisterComponent] public sealed partial class ResearchConsoleComponent : Component { - + /// + /// The radio channel that the unlock announcements are broadcast to. + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public ProtoId AnnouncementChannel = "Science"; } diff --git a/Content.Server/Research/Systems/ResearchSystem.Console.cs b/Content.Server/Research/Systems/ResearchSystem.Console.cs index 6da547999d..e802e2c7f9 100644 --- a/Content.Server/Research/Systems/ResearchSystem.Console.cs +++ b/Content.Server/Research/Systems/ResearchSystem.Console.cs @@ -3,6 +3,7 @@ using Content.Server.Research.Components; using Content.Server.UserInterface; using Content.Shared.Access.Components; using Content.Shared.Research.Components; +using Content.Shared.Research.Prototypes; namespace Content.Server.Research.Systems; @@ -25,6 +26,9 @@ public sealed partial class ResearchSystem if (!this.IsPowered(uid, EntityManager)) return; + if (!PrototypeManager.TryIndex(args.Id, out var technologyPrototype)) + return; + if (TryComp(uid, out var access) && !_accessReader.IsAllowed(ent, uid, access)) { _popup.PopupEntity(Loc.GetString("research-console-no-access-popup"), ent); @@ -34,6 +38,10 @@ public sealed partial class ResearchSystem if (!UnlockTechnology(uid, args.Id, ent)) return; + var message = Loc.GetString("research-console-unlock-technology-radio-broadcast", + ("technology", Loc.GetString(technologyPrototype.Name)), + ("amount", technologyPrototype.Cost)); + _radio.SendRadioMessage(uid, message, component.AnnouncementChannel, uid, escapeMarkup: false); SyncClientWithServer(uid); UpdateConsoleInterface(uid, component); } diff --git a/Content.Server/Research/Systems/ResearchSystem.cs b/Content.Server/Research/Systems/ResearchSystem.cs index e89b435800..f8c4d6902a 100644 --- a/Content.Server/Research/Systems/ResearchSystem.cs +++ b/Content.Server/Research/Systems/ResearchSystem.cs @@ -1,6 +1,7 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using Content.Server.Administration.Logs; +using Content.Server.Radio.EntitySystems; using Content.Shared.Access.Systems; using Content.Shared.Popups; using Content.Shared.Research.Components; @@ -19,6 +20,7 @@ namespace Content.Server.Research.Systems [Dependency] private readonly AccessReaderSystem _accessReader = default!; [Dependency] private readonly UserInterfaceSystem _uiSystem = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly RadioSystem _radio = default!; public override void Initialize() { diff --git a/Resources/Locale/en-US/research/components/research-console-component.ftl b/Resources/Locale/en-US/research/components/research-console-component.ftl index 196983efcd..33070480e5 100644 --- a/Resources/Locale/en-US/research/components/research-console-component.ftl +++ b/Resources/Locale/en-US/research/components/research-console-component.ftl @@ -18,3 +18,4 @@ research-console-prereqs-list-start = Requires: research-console-prereqs-list-entry = - [color=orchid]{$text}[/color] research-console-no-access-popup = No access! +research-console-unlock-technology-radio-broadcast = Unlocked [bold]{$technology}[/bold] for [bold]{$amount}[/bold] research. diff --git a/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml b/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml index d4cc456eda..24e828bf84 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml @@ -374,6 +374,9 @@ state: rd_key - type: ResearchClient - type: ResearchConsole + - type: ActiveRadio + channels: + - Science - type: TechnologyDatabase - type: ActivatableUI key: enum.ResearchConsoleUiKey.Key