Communications Console: The ECSining (#8374)
Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
This commit is contained in:
@@ -23,8 +23,7 @@ namespace Content.Client.Communications.UI
|
||||
|
||||
public string CurrentLevel { get; private set; } = default!;
|
||||
|
||||
public int Countdown => _expectedCountdownTime == null
|
||||
? 0 : Math.Max((int)_expectedCountdownTime.Value.Subtract(_gameTiming.CurTime).TotalSeconds, 0);
|
||||
public int Countdown => _expectedCountdownTime == null ? 0 : Math.Max((int)_expectedCountdownTime.Value.Subtract(_gameTiming.CurTime).TotalSeconds, 0);
|
||||
private TimeSpan? _expectedCountdownTime;
|
||||
|
||||
public CommunicationsConsoleBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
|
||||
|
||||
@@ -25,12 +25,12 @@ namespace Content.Client.Communications.UI
|
||||
SetSize = MinSize = (600, 400);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
Title = Loc.GetString("communicationsconsole-menu-title");
|
||||
Title = Loc.GetString("comms-console-menu-title");
|
||||
Owner = owner;
|
||||
|
||||
_messageInput = new LineEdit
|
||||
{
|
||||
PlaceHolder = Loc.GetString("communicationsconsole-menu-announcement-placeholder"),
|
||||
PlaceHolder = Loc.GetString("comms-console-menu-announcement-placeholder"),
|
||||
HorizontalExpand = true,
|
||||
SizeFlagsStretchRatio = 1
|
||||
};
|
||||
@@ -127,11 +127,11 @@ namespace Content.Client.Communications.UI
|
||||
if (!Owner.CountdownStarted)
|
||||
{
|
||||
_countdownLabel.SetMessage("");
|
||||
EmergencyShuttleButton.Text = Loc.GetString("communicationsconsole-menu-call-shuttle");
|
||||
EmergencyShuttleButton.Text = Loc.GetString("comms-console-menu-call-shuttle");
|
||||
return;
|
||||
}
|
||||
|
||||
EmergencyShuttleButton.Text = Loc.GetString("communicationsconsole-menu-recall-shuttle");
|
||||
EmergencyShuttleButton.Text = Loc.GetString("comms-console-menu-recall-shuttle");
|
||||
_countdownLabel.SetMessage($"Time remaining\n{Owner.Countdown.ToString()}s");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Server.Administration.Managers;
|
||||
using Content.Server.Chat;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.EUI;
|
||||
using Content.Shared.Administration;
|
||||
@@ -10,6 +11,7 @@ namespace Content.Server.Administration.UI
|
||||
{
|
||||
[Dependency] private readonly IAdminManager _adminManager = default!;
|
||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
||||
[Dependency] private readonly ChatSystem _chatSystem = default!;
|
||||
|
||||
public AdminAnnounceEui()
|
||||
{
|
||||
@@ -45,8 +47,9 @@ namespace Content.Server.Administration.UI
|
||||
case AdminAnnounceType.Server:
|
||||
_chatManager.DispatchServerAnnouncement(doAnnounce.Announcement);
|
||||
break;
|
||||
// TODO: Per-station announcement support
|
||||
case AdminAnnounceType.Station:
|
||||
_chatManager.DispatchStationAnnouncement(doAnnounce.Announcement, doAnnounce.Announcer, colorOverride: Color.Gold);
|
||||
_chatSystem.DispatchGlobalStationAnnouncement(doAnnounce.Announcement, doAnnounce.Announcer, colorOverride: Color.Gold);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,8 @@ public sealed class AlertLevelComponent : Component
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)] public bool IsLevelLocked = false;
|
||||
|
||||
[ViewVariables] public const float Delay = 300;
|
||||
[ViewVariables] public const float Delay = 30;
|
||||
|
||||
[ViewVariables] public float CurrentDelay = 0;
|
||||
[ViewVariables] public bool ActiveDelay;
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Administration.Logs;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Server.Chat;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared.AlertLevel;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
@@ -13,7 +10,7 @@ namespace Content.Server.AlertLevel;
|
||||
public sealed class AlertLevelSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
||||
[Dependency] private readonly ChatSystem _chatSystem = default!;
|
||||
[Dependency] private readonly StationSystem _stationSystem = default!;
|
||||
|
||||
// Until stations are a prototype, this is how it's going to have to be.
|
||||
@@ -52,7 +49,7 @@ public sealed class AlertLevelSystem : EntitySystem
|
||||
continue;
|
||||
}
|
||||
|
||||
alert.CurrentDelay--;
|
||||
alert.CurrentDelay -= time;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,11 +183,11 @@ public sealed class AlertLevelSystem : EntitySystem
|
||||
if (announce)
|
||||
{
|
||||
|
||||
_chatManager.DispatchStationAnnouncement(announcementFull, playDefaultSound: playDefault,
|
||||
_chatSystem.DispatchStationAnnouncement(station, announcementFull, playDefaultSound: playDefault,
|
||||
colorOverride: detail.Color, sender: stationName);
|
||||
}
|
||||
|
||||
RaiseLocalEvent(new AlertLevelChangedEvent(level));
|
||||
RaiseLocalEvent(new AlertLevelChangedEvent(station, level));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,10 +199,12 @@ public sealed class AlertLevelPrototypeReloadedEvent : EntityEventArgs
|
||||
|
||||
public sealed class AlertLevelChangedEvent : EntityEventArgs
|
||||
{
|
||||
public EntityUid Station { get; }
|
||||
public string AlertLevel { get; }
|
||||
|
||||
public AlertLevelChangedEvent(string alertLevel)
|
||||
public AlertLevelChangedEvent(EntityUid station, string alertLevel)
|
||||
{
|
||||
Station = station;
|
||||
AlertLevel = alertLevel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Content.Server.Administration;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.Chat;
|
||||
using Content.Shared.Administration;
|
||||
using Robust.Shared.Console;
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Content.Server.Announcements
|
||||
public string Help => $"{Command} <sender> <message> or {Command} <message> to send announcement as centcomm.";
|
||||
public void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
var chat = IoCManager.Resolve<IChatManager>();
|
||||
var chat = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ChatSystem>();
|
||||
|
||||
if (args.Length == 0)
|
||||
{
|
||||
@@ -23,12 +23,12 @@ namespace Content.Server.Announcements
|
||||
|
||||
if (args.Length == 1)
|
||||
{
|
||||
chat.DispatchStationAnnouncement(args[0], colorOverride: Color.Gold);
|
||||
chat.DispatchGlobalStationAnnouncement(args[0], colorOverride: Color.Gold);
|
||||
}
|
||||
else
|
||||
{
|
||||
var message = string.Join(' ', new ArraySegment<string>(args, 1, args.Length-1));
|
||||
chat.DispatchStationAnnouncement(message, args[0], colorOverride: Color.Gold);
|
||||
chat.DispatchGlobalStationAnnouncement(message, args[0], colorOverride: Color.Gold);
|
||||
}
|
||||
shell.WriteLine("Sent!");
|
||||
}
|
||||
|
||||
@@ -8,12 +8,15 @@ using Content.Server.Headset;
|
||||
using Content.Server.Players;
|
||||
using Content.Server.Popups;
|
||||
using Content.Server.Radio.EntitySystems;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared.ActionBlocker;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Chat;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Inventory;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Network;
|
||||
@@ -41,9 +44,11 @@ public sealed class ChatSystem : SharedChatSystem
|
||||
[Dependency] private readonly ListeningSystem _listener = default!;
|
||||
[Dependency] private readonly InventorySystem _inventory = default!;
|
||||
[Dependency] private readonly PopupSystem _popup = default!;
|
||||
[Dependency] private readonly StationSystem _stationSystem = default!;
|
||||
|
||||
private const int VoiceRange = 7; // how far voice goes in world units
|
||||
private const int WhisperRange = 2; // how far whisper goes in world units
|
||||
private const string AnnouncementSound = "/Audio/Announcements/announce.ogg";
|
||||
|
||||
private bool _loocEnabled = true;
|
||||
private readonly bool _adminLoocEnabled = true;
|
||||
@@ -140,6 +145,67 @@ public sealed class ChatSystem : SharedChatSystem
|
||||
}
|
||||
}
|
||||
|
||||
#region Announcements
|
||||
|
||||
/// <summary>
|
||||
/// Dispatches an announcement to all stations
|
||||
/// </summary>
|
||||
/// <param name="message">The contents of the message</param>
|
||||
/// <param name="sender">The sender (Communications Console in Communications Console Announcement)</param>
|
||||
/// <param name="playDefaultSound">Play the announcement sound</param>
|
||||
/// <param name="colorOverride">Optional color for the announcement message</param>
|
||||
public void DispatchGlobalStationAnnouncement(string message, string sender = "Central Command",
|
||||
bool playDefaultSound = true, Color? colorOverride = null)
|
||||
{
|
||||
var messageWrap = Loc.GetString("chat-manager-sender-announcement-wrap-message", ("sender", sender));
|
||||
_chatManager.ChatMessageToAll(ChatChannel.Radio, message, messageWrap);
|
||||
if (playDefaultSound)
|
||||
{
|
||||
SoundSystem.Play(Filter.Broadcast(), AnnouncementSound, AudioParams.Default.WithVolume(-2f));
|
||||
}
|
||||
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Global station announcement from {sender}: {message}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatches an announcement on a specific station
|
||||
/// </summary>
|
||||
/// <param name="source">The entity making the announcement (used to determine the station)</param>
|
||||
/// <param name="message">The contents of the message</param>
|
||||
/// <param name="sender">The sender (Communications Console in Communications Console Announcement)</param>
|
||||
/// <param name="playDefaultSound">Play the announcement sound</param>
|
||||
/// <param name="colorOverride">Optional color for the announcement message</param>
|
||||
public void DispatchStationAnnouncement(EntityUid source, string message, string sender = "Central Command", bool playDefaultSound = true, Color? colorOverride = null)
|
||||
{
|
||||
var messageWrap = Loc.GetString("chat-manager-sender-announcement-wrap-message", ("sender", sender));
|
||||
var station = _stationSystem.GetOwningStation(source);
|
||||
var filter = Filter.Empty();
|
||||
|
||||
if (station != null)
|
||||
{
|
||||
if (!EntityManager.TryGetComponent<StationDataComponent>(station, out var stationDataComp)) return;
|
||||
|
||||
foreach (var gridEnt in stationDataComp.Grids)
|
||||
{
|
||||
filter.AddInGrid(gridEnt);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
filter = Filter.Pvs(source, entityManager: EntityManager);
|
||||
}
|
||||
|
||||
_chatManager.ChatMessageToManyFiltered(filter, ChatChannel.Radio, message, messageWrap, source, true, colorOverride);
|
||||
|
||||
if (playDefaultSound)
|
||||
{
|
||||
SoundSystem.Play(filter, AnnouncementSound, AudioParams.Default.WithVolume(-2f));
|
||||
}
|
||||
|
||||
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Station Announcement on {station} from {sender}: {message}");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private API
|
||||
|
||||
private void SendEntitySpeak(EntityUid source, string message, bool hideChat = false)
|
||||
|
||||
@@ -3,13 +3,14 @@ using Content.Server.Administration.Logs;
|
||||
using Content.Server.Administration.Managers;
|
||||
using Content.Server.MoMMI;
|
||||
using Content.Server.Preferences.Managers;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared.Administration;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Chat;
|
||||
using Content.Shared.Database;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Utility;
|
||||
@@ -35,6 +36,10 @@ namespace Content.Server.Chat.Managers
|
||||
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
||||
[Dependency] private readonly IServerPreferencesManager _preferencesManager = default!;
|
||||
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
|
||||
private StationSystem _stationSystem = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum length a player-sent message can be sent
|
||||
@@ -46,6 +51,7 @@ namespace Content.Server.Chat.Managers
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
_stationSystem = _entityManager.EntitySysManager.GetEntitySystem<StationSystem>();
|
||||
_netManager.RegisterNetMessage<MsgChatMessage>();
|
||||
|
||||
_configurationManager.OnValueChanged(CCVars.OocEnabled, OnOocEnabledChanged, true);
|
||||
@@ -79,18 +85,6 @@ namespace Content.Server.Chat.Managers
|
||||
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Server announcement: {message}");
|
||||
}
|
||||
|
||||
public void DispatchStationAnnouncement(string message, string sender = "Central Command", bool playDefaultSound = true, Color? colorOverride = null)
|
||||
{
|
||||
var messageWrap = Loc.GetString("chat-manager-sender-announcement-wrap-message", ("sender", sender));
|
||||
ChatMessageToAll(ChatChannel.Radio, message, messageWrap, colorOverride);
|
||||
if (playDefaultSound)
|
||||
{
|
||||
SoundSystem.Play(Filter.Broadcast(), "/Audio/Announcements/announce.ogg", AudioParams.Default.WithVolume(-2f));
|
||||
}
|
||||
|
||||
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Station Announcement from {sender}: {message}");
|
||||
}
|
||||
|
||||
public void DispatchServerMessage(IPlayerSession player, string message)
|
||||
{
|
||||
var messageWrap = Loc.GetString("chat-manager-server-wrap-message");
|
||||
@@ -235,6 +229,20 @@ namespace Content.Server.Chat.Managers
|
||||
_netManager.ServerSendToMany(msg, clients);
|
||||
}
|
||||
|
||||
public void ChatMessageToManyFiltered(Filter filter, ChatChannel channel, string message, string messageWrap, EntityUid source,
|
||||
bool hideChat, Color? colorOverride = null)
|
||||
{
|
||||
if (!filter.Recipients.Any()) return;
|
||||
|
||||
var clients = new List<INetChannel>();
|
||||
foreach (var recipient in filter.Recipients)
|
||||
{
|
||||
clients.Add(recipient.ConnectedClient);
|
||||
}
|
||||
|
||||
ChatMessageToMany(channel, message, messageWrap, source, hideChat, clients);
|
||||
}
|
||||
|
||||
public void ChatMessageToAll(ChatChannel channel, string message, string messageWrap, Color? colorOverride = null)
|
||||
{
|
||||
var msg = new MsgChatMessage();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Content.Shared.Chat;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Player;
|
||||
|
||||
namespace Content.Server.Chat.Managers
|
||||
{
|
||||
@@ -15,16 +16,6 @@ namespace Content.Server.Chat.Managers
|
||||
/// <param name="colorOverride">Override the color of the message being sent.</param>
|
||||
void DispatchServerAnnouncement(string message, Color? colorOverride = null);
|
||||
|
||||
/// <summary>
|
||||
/// Station announcement to every player
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="playDefaultSound">If the default 'PA' sound should be played.</param>
|
||||
/// <param name="colorOverride">Override the color of the message being sent.</param>
|
||||
void DispatchStationAnnouncement(string message, string sender = "CentComm", bool playDefaultSound = true,
|
||||
Color? colorOverride = null);
|
||||
|
||||
void DispatchServerMessage(IPlayerSession player, string message);
|
||||
|
||||
void TrySendOOCMessage(IPlayerSession player, string message, OOCChatType type);
|
||||
@@ -36,6 +27,7 @@ namespace Content.Server.Chat.Managers
|
||||
INetChannel client);
|
||||
void ChatMessageToMany(ChatChannel channel, string message, string messageWrap, EntityUid source, bool hideChat,
|
||||
List<INetChannel> clients);
|
||||
void ChatMessageToManyFiltered(Filter filter, ChatChannel channel, string message, string messageWrap, EntityUid source, bool hideChat, Color? colorOverride);
|
||||
void ChatMessageToAll(ChatChannel channel, string message, string messageWrap, Color? colorOverride = null);
|
||||
|
||||
bool MessageCharacterLimit(IPlayerSession player, string message);
|
||||
|
||||
@@ -1,157 +1,59 @@
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Content.Server.Access.Systems;
|
||||
using Content.Server.AlertLevel;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Server.RoundEnd;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Server.UserInterface;
|
||||
using Content.Shared.Communications;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Timing;
|
||||
using Timer = Robust.Shared.Timing.Timer;
|
||||
|
||||
namespace Content.Server.Communications
|
||||
{
|
||||
// TODO: ECS
|
||||
[RegisterComponent]
|
||||
public sealed class CommunicationsConsoleComponent : SharedCommunicationsConsoleComponent, IEntityEventSubscriber
|
||||
public sealed class CommunicationsConsoleComponent : SharedCommunicationsConsoleComponent
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entities = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
[Dependency] private readonly IEntitySystemManager _sysMan = default!;
|
||||
/// <summary>
|
||||
/// Remaining cooldown between making announcements.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public float AnnouncementCooldownRemaining;
|
||||
|
||||
private bool Powered => !_entities.TryGetComponent(Owner, out ApcPowerReceiverComponent? receiver) || receiver.Powered;
|
||||
/// <summary>
|
||||
/// Has the UI already been refreshed after the announcement
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public bool AlreadyRefreshed = false;
|
||||
|
||||
private RoundEndSystem RoundEndSystem => EntitySystem.Get<RoundEndSystem>();
|
||||
private AlertLevelSystem AlertLevelSystem => EntitySystem.Get<AlertLevelSystem>();
|
||||
private StationSystem StationSystem => EntitySystem.Get<StationSystem>();
|
||||
/// <summary>
|
||||
/// Fluent ID for the announcement title
|
||||
/// If a Fluent ID isn't found, just uses the raw string
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("title", required: true)]
|
||||
public string AnnouncementDisplayName = "comms-console-announcement-title-station";
|
||||
|
||||
[ViewVariables] private BoundUserInterface? UserInterface => Owner.GetUIOrNull(CommunicationsConsoleUiKey.Key);
|
||||
/// <summary>
|
||||
/// Announcement color
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("color")]
|
||||
public Color AnnouncementColor = Color.Gold;
|
||||
|
||||
public TimeSpan LastAnnounceTime { get; private set; } = TimeSpan.Zero;
|
||||
public TimeSpan AnnounceCooldown { get; } = TimeSpan.FromSeconds(90);
|
||||
private CancellationTokenSource _announceCooldownEndedTokenSource = new();
|
||||
/// <summary>
|
||||
/// Time in seconds between announcement delays on a per-console basis
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("delay")]
|
||||
public int DelayBetweenAnnouncements = 90;
|
||||
|
||||
protected override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
/// <summary>
|
||||
/// Can call or recall the shuttle
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("canShuttle")]
|
||||
public bool CanCallShuttle = true;
|
||||
|
||||
if (UserInterface != null)
|
||||
{
|
||||
UserInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
||||
}
|
||||
/// <summary>
|
||||
/// Announce on all grids (for nukies)
|
||||
/// </summary>
|
||||
[DataField("global")]
|
||||
public bool AnnounceGlobal = false;
|
||||
|
||||
_entityManager.EventBus.SubscribeEvent<RoundEndSystemChangedEvent>(EventSource.Local, this, (s) => UpdateBoundInterface());
|
||||
_entityManager.EventBus.SubscribeEvent<AlertLevelChangedEvent>(EventSource.Local, this, _ => UpdateBoundInterface());
|
||||
_entityManager.EventBus.SubscribeEvent<AlertLevelDelayFinishedEvent>(EventSource.Local, this, _ => UpdateBoundInterface());
|
||||
}
|
||||
|
||||
protected override void Startup()
|
||||
{
|
||||
base.Startup();
|
||||
|
||||
UpdateBoundInterface();
|
||||
}
|
||||
|
||||
private void UpdateBoundInterface()
|
||||
{
|
||||
if (!Deleted)
|
||||
{
|
||||
var system = RoundEndSystem;
|
||||
|
||||
List<string>? levels = null;
|
||||
string currentLevel = default!;
|
||||
float currentDelay = 0;
|
||||
var stationUid = StationSystem.GetOwningStation(Owner);
|
||||
if (stationUid != null)
|
||||
{
|
||||
if (_entityManager.TryGetComponent(stationUid.Value, out AlertLevelComponent? alerts)
|
||||
&& alerts.AlertLevels != null)
|
||||
{
|
||||
if (alerts.IsSelectable)
|
||||
{
|
||||
levels = new();
|
||||
foreach (var (id, detail) in alerts.AlertLevels.Levels)
|
||||
{
|
||||
if (detail.Selectable)
|
||||
{
|
||||
levels.Add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentLevel = alerts.CurrentLevel;
|
||||
currentDelay = AlertLevelSystem.GetAlertLevelDelay(stationUid.Value, alerts);
|
||||
}
|
||||
}
|
||||
|
||||
UserInterface?.SetState(new CommunicationsConsoleInterfaceState(CanAnnounce(), system.CanCall(), levels, currentLevel, currentDelay, system.ExpectedCountdownEnd));
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanAnnounce()
|
||||
{
|
||||
if (LastAnnounceTime == TimeSpan.Zero)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return _gameTiming.CurTime >= LastAnnounceTime + AnnounceCooldown;
|
||||
}
|
||||
|
||||
protected override void OnRemove()
|
||||
{
|
||||
_entityManager.EventBus.UnsubscribeEvent<RoundEndSystemChangedEvent>(EventSource.Local, this);
|
||||
base.OnRemove();
|
||||
}
|
||||
|
||||
private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage obj)
|
||||
{
|
||||
switch (obj.Message)
|
||||
{
|
||||
case CommunicationsConsoleCallEmergencyShuttleMessage _:
|
||||
RoundEndSystem.RequestRoundEnd(obj.Session.AttachedEntity);
|
||||
break;
|
||||
|
||||
case CommunicationsConsoleRecallEmergencyShuttleMessage _:
|
||||
RoundEndSystem.CancelRoundEndCountdown(obj.Session.AttachedEntity);
|
||||
break;
|
||||
case CommunicationsConsoleAnnounceMessage msg:
|
||||
if (!CanAnnounce())
|
||||
{
|
||||
return;
|
||||
}
|
||||
_announceCooldownEndedTokenSource.Cancel();
|
||||
_announceCooldownEndedTokenSource = new CancellationTokenSource();
|
||||
LastAnnounceTime = _gameTiming.CurTime;
|
||||
Timer.Spawn(AnnounceCooldown, UpdateBoundInterface, _announceCooldownEndedTokenSource.Token);
|
||||
UpdateBoundInterface();
|
||||
|
||||
var message = msg.Message.Length <= 256 ? msg.Message.Trim() : $"{msg.Message.Trim().Substring(0, 256)}...";
|
||||
var sys = _sysMan.GetEntitySystem<IdCardSystem>();
|
||||
|
||||
var author = "Unknown";
|
||||
if (obj.Session.AttachedEntity is {Valid: true} mob && sys.TryFindIdCard(mob, out var id))
|
||||
{
|
||||
author = $"{id.FullName} ({CultureInfo.CurrentCulture.TextInfo.ToTitleCase(id.JobTitle ?? string.Empty)})".Trim();
|
||||
}
|
||||
|
||||
message += $"\nSent by {author}";
|
||||
_chatManager.DispatchStationAnnouncement(message, "Communications Console", colorOverride: Color.Gold);
|
||||
break;
|
||||
case CommunicationsConsoleSelectAlertLevelMessage alertMsg:
|
||||
var stationUid = StationSystem.GetOwningStation(Owner);
|
||||
if (stationUid != null)
|
||||
{
|
||||
AlertLevelSystem.SetLevel(stationUid.Value, alertMsg.Level, true, true);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
public BoundUserInterface? UserInterface => Owner.GetUIOrNull(CommunicationsConsoleUiKey.Key);
|
||||
}
|
||||
}
|
||||
|
||||
233
Content.Server/Communications/CommunicationsConsoleSystem.cs
Normal file
233
Content.Server/Communications/CommunicationsConsoleSystem.cs
Normal file
@@ -0,0 +1,233 @@
|
||||
using System.Globalization;
|
||||
using Content.Server.Access.Systems;
|
||||
using Content.Server.AlertLevel;
|
||||
using Content.Server.Chat;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.Popups;
|
||||
using Content.Server.RoundEnd;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared.Access.Components;
|
||||
using Content.Shared.Access.Systems;
|
||||
using Content.Shared.Communications;
|
||||
using Robust.Shared.Player;
|
||||
|
||||
namespace Content.Server.Communications
|
||||
{
|
||||
public sealed class CommunicationsConsoleSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly RoundEndSystem _roundEndSystem = default!;
|
||||
[Dependency] private readonly AlertLevelSystem _alertLevelSystem = default!;
|
||||
[Dependency] private readonly StationSystem _stationSystem = default!;
|
||||
[Dependency] private readonly IdCardSystem _idCardSystem = default!;
|
||||
[Dependency] private readonly AccessReaderSystem _accessReaderSystem = default!;
|
||||
[Dependency] private readonly PopupSystem _popupSystem = default!;
|
||||
[Dependency] private readonly ChatSystem _chatSystem = default!;
|
||||
|
||||
private const int MaxMessageLength = 256;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
// All events that refresh the BUI
|
||||
SubscribeLocalEvent<AlertLevelChangedEvent>(OnAlertLevelChanged);
|
||||
SubscribeLocalEvent<CommunicationsConsoleComponent, ComponentInit>((_, comp, _) => UpdateBoundUserInterface(comp));
|
||||
SubscribeLocalEvent<RoundEndSystemChangedEvent>(_ => OnGenericBroadcastEvent());
|
||||
SubscribeLocalEvent<AlertLevelDelayFinishedEvent>(_ => OnGenericBroadcastEvent());
|
||||
|
||||
// Messages from the BUI
|
||||
SubscribeLocalEvent<CommunicationsConsoleComponent, CommunicationsConsoleSelectAlertLevelMessage>(OnSelectAlertLevelMessage);
|
||||
SubscribeLocalEvent<CommunicationsConsoleComponent, CommunicationsConsoleAnnounceMessage>(OnAnnounceMessage);
|
||||
SubscribeLocalEvent<CommunicationsConsoleComponent, CommunicationsConsoleCallEmergencyShuttleMessage>(OnCallShuttleMessage);
|
||||
SubscribeLocalEvent<CommunicationsConsoleComponent, CommunicationsConsoleRecallEmergencyShuttleMessage>(OnRecallShuttleMessage);
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
foreach (var comp in EntityQuery<CommunicationsConsoleComponent>())
|
||||
{
|
||||
// TODO: Find a less ass way of refreshing the UI
|
||||
if (comp.AlreadyRefreshed) continue;
|
||||
if (comp.AnnouncementCooldownRemaining <= 0f)
|
||||
{
|
||||
UpdateBoundUserInterface(comp);
|
||||
comp.AlreadyRefreshed = true;
|
||||
continue;
|
||||
}
|
||||
comp.AnnouncementCooldownRemaining -= frameTime;
|
||||
}
|
||||
|
||||
base.Update(frameTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the UI of every comms console.
|
||||
/// </summary>
|
||||
private void OnGenericBroadcastEvent()
|
||||
{
|
||||
foreach (var comp in EntityQuery<CommunicationsConsoleComponent>())
|
||||
{
|
||||
UpdateBoundUserInterface(comp);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates all comms consoles belonging to the station that the alert level was set on
|
||||
/// </summary>
|
||||
/// <param name="args">Alert level changed event arguments</param>
|
||||
private void OnAlertLevelChanged(AlertLevelChangedEvent args)
|
||||
{
|
||||
foreach (var comp in EntityQuery<CommunicationsConsoleComponent>())
|
||||
{
|
||||
var entStation = _stationSystem.GetOwningStation(comp.Owner);
|
||||
if (args.Station == entStation)
|
||||
{
|
||||
UpdateBoundUserInterface(comp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateBoundUserInterface(CommunicationsConsoleComponent comp)
|
||||
{
|
||||
var uid = comp.Owner;
|
||||
|
||||
var stationUid = _stationSystem.GetOwningStation(uid);
|
||||
List<string>? levels = null;
|
||||
string currentLevel = default!;
|
||||
float currentDelay = 0;
|
||||
|
||||
if (stationUid != null)
|
||||
{
|
||||
if (TryComp(stationUid.Value, out AlertLevelComponent? alertComp) &&
|
||||
alertComp.AlertLevels != null)
|
||||
{
|
||||
if (alertComp.IsSelectable)
|
||||
{
|
||||
levels = new();
|
||||
foreach (var (id, detail) in alertComp.AlertLevels.Levels)
|
||||
{
|
||||
if (detail.Selectable)
|
||||
{
|
||||
levels.Add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentLevel = alertComp.CurrentLevel;
|
||||
currentDelay = _alertLevelSystem.GetAlertLevelDelay(stationUid.Value, alertComp);
|
||||
}
|
||||
}
|
||||
|
||||
comp.UserInterface?.SetState(
|
||||
new CommunicationsConsoleInterfaceState(
|
||||
CanAnnounce(comp),
|
||||
CanCall(comp),
|
||||
levels,
|
||||
currentLevel,
|
||||
currentDelay,
|
||||
_roundEndSystem.ExpectedCountdownEnd
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private bool CanAnnounce(CommunicationsConsoleComponent comp)
|
||||
{
|
||||
return comp.AnnouncementCooldownRemaining <= 0f;
|
||||
}
|
||||
|
||||
private bool CanUse(EntityUid user, EntityUid console)
|
||||
{
|
||||
if (TryComp<AccessReaderComponent>(console, out var accessReaderComponent) && accessReaderComponent.Enabled)
|
||||
{
|
||||
return _accessReaderSystem.IsAllowed(user, accessReaderComponent);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool CanCall(CommunicationsConsoleComponent comp)
|
||||
{
|
||||
return comp.CanCallShuttle && _roundEndSystem.CanCall();
|
||||
}
|
||||
|
||||
private void OnSelectAlertLevelMessage(EntityUid uid, CommunicationsConsoleComponent comp, CommunicationsConsoleSelectAlertLevelMessage message)
|
||||
{
|
||||
if (message.Session.AttachedEntity is not {Valid: true} mob) return;
|
||||
if (!CanUse(mob, uid))
|
||||
{
|
||||
_popupSystem.PopupCursor(Loc.GetString("comms-console-permission-denied"), Filter.Entities(mob));
|
||||
return;
|
||||
}
|
||||
|
||||
var stationUid = _stationSystem.GetOwningStation(uid);
|
||||
if (stationUid != null)
|
||||
{
|
||||
_alertLevelSystem.SetLevel(stationUid.Value, message.Level, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnAnnounceMessage(EntityUid uid, CommunicationsConsoleComponent comp,
|
||||
CommunicationsConsoleAnnounceMessage message)
|
||||
{
|
||||
var msg = message.Message.Length <= MaxMessageLength ? message.Message.Trim() : $"{message.Message.Trim().Substring(0, MaxMessageLength)}...";
|
||||
var author = Loc.GetString("comms-console-announcement-unknown-sender");
|
||||
if (message.Session.AttachedEntity is {Valid: true} mob)
|
||||
{
|
||||
if (!CanAnnounce(comp))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CanUse(mob, uid))
|
||||
{
|
||||
_popupSystem.PopupEntity(Loc.GetString("comms-console-permission-denied"), uid, Filter.Entities(mob));
|
||||
return;
|
||||
}
|
||||
|
||||
if (_idCardSystem.TryFindIdCard(mob, out var id))
|
||||
{
|
||||
author = $"{id.FullName} ({CultureInfo.CurrentCulture.TextInfo.ToTitleCase(id.JobTitle ?? string.Empty)})".Trim();
|
||||
}
|
||||
}
|
||||
|
||||
comp.AnnouncementCooldownRemaining = comp.DelayBetweenAnnouncements;
|
||||
comp.AlreadyRefreshed = false;
|
||||
UpdateBoundUserInterface(comp);
|
||||
|
||||
// allow admemes with vv
|
||||
Loc.TryGetString(comp.AnnouncementDisplayName, out var title);
|
||||
title ??= comp.AnnouncementDisplayName;
|
||||
|
||||
msg += "\n" + Loc.GetString("comms-console-announcement-sent-by") + " " + author;
|
||||
if (comp.AnnounceGlobal)
|
||||
{
|
||||
_chatSystem.DispatchGlobalStationAnnouncement(msg, title, colorOverride: comp.AnnouncementColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
_chatSystem.DispatchStationAnnouncement(uid, msg, title, colorOverride: comp.AnnouncementColor);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCallShuttleMessage(EntityUid uid, CommunicationsConsoleComponent comp, CommunicationsConsoleCallEmergencyShuttleMessage message)
|
||||
{
|
||||
if (!comp.CanCallShuttle) return;
|
||||
if (message.Session.AttachedEntity is not {Valid: true} mob) return;
|
||||
if (!CanUse(mob, uid))
|
||||
{
|
||||
_popupSystem.PopupEntity(Loc.GetString("comms-console-permission-denied"), uid, Filter.Entities(mob));
|
||||
return;
|
||||
}
|
||||
_roundEndSystem.RequestRoundEnd(uid);
|
||||
}
|
||||
|
||||
private void OnRecallShuttleMessage(EntityUid uid, CommunicationsConsoleComponent comp, CommunicationsConsoleRecallEmergencyShuttleMessage message)
|
||||
{
|
||||
if (!comp.CanCallShuttle) return;
|
||||
if (message.Session.AttachedEntity is not {Valid: true} mob) return;
|
||||
if (!CanUse(mob, uid))
|
||||
{
|
||||
_popupSystem.PopupEntity(Loc.GetString("comms-console-permission-denied"), uid, Filter.Entities(mob));
|
||||
return;
|
||||
}
|
||||
_roundEndSystem.CancelRoundEndCountdown(uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -474,7 +474,7 @@ namespace Content.Server.GameTicking
|
||||
if (!proto.GamePresets.Contains(Preset.ID)) continue;
|
||||
|
||||
if (proto.Message != null)
|
||||
_chatManager.DispatchStationAnnouncement(Loc.GetString(proto.Message), playDefaultSound: false);
|
||||
_chatSystem.DispatchGlobalStationAnnouncement(Loc.GetString(proto.Message), playDefaultSound: true);
|
||||
|
||||
if (proto.Sound != null)
|
||||
SoundSystem.Play(Filter.Broadcast(), proto.Sound.GetSound());
|
||||
|
||||
@@ -157,7 +157,8 @@ namespace Content.Server.GameTicking
|
||||
|
||||
if (lateJoin)
|
||||
{
|
||||
_chatManager.DispatchStationAnnouncement(Loc.GetString(
|
||||
_chatSystem.DispatchStationAnnouncement(station,
|
||||
Loc.GetString(
|
||||
"latejoin-arrival-announcement",
|
||||
("character", character.Name),
|
||||
("job", CultureInfo.CurrentCulture.TextInfo.ToTitleCase(job.Name))
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Server.Administration.Logs;
|
||||
using Content.Server.Administration.Managers;
|
||||
using Content.Server.Chat;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.Database;
|
||||
using Content.Server.Ghost;
|
||||
@@ -114,6 +115,7 @@ namespace Content.Server.GameTicking
|
||||
[Dependency] private readonly DamageableSystem _damageable = default!;
|
||||
[Dependency] private readonly GhostSystem _ghosts = default!;
|
||||
[Dependency] private readonly RoleBanManager _roleBanManager = default!;
|
||||
[Dependency] private readonly ChatSystem _chatSystem = default!;
|
||||
[Dependency] private readonly ServerUpdateManager _serverUpdates = default!;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.Chat;
|
||||
using Content.Server.Communications;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared.GameTicking;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
@@ -12,7 +13,8 @@ namespace Content.Server.Nuke
|
||||
public sealed class NukeCodeSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly IChatManager _chat = default!;
|
||||
[Dependency] private readonly ChatSystem _chatSystem = default!;
|
||||
[Dependency] private readonly StationSystem _stationSystem = default!;
|
||||
|
||||
private const int CodeLength = 6;
|
||||
public string Code { get; private set; } = default!;
|
||||
@@ -73,10 +75,11 @@ namespace Content.Server.Nuke
|
||||
wasSent = true;
|
||||
}
|
||||
|
||||
// TODO: Allow selecting a station for nuke codes
|
||||
if (wasSent)
|
||||
{
|
||||
var msg = Loc.GetString("nuke-component-announcement-send-codes");
|
||||
_chat.DispatchStationAnnouncement(msg, colorOverride: Color.Red);
|
||||
_chatSystem.DispatchGlobalStationAnnouncement(msg, colorOverride: Color.Red);
|
||||
}
|
||||
|
||||
return wasSent;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Server.AlertLevel;
|
||||
using Content.Server.Chat;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.Coordinates.Helpers;
|
||||
using Content.Server.Explosion.EntitySystems;
|
||||
@@ -24,7 +25,7 @@ namespace Content.Server.Nuke
|
||||
[Dependency] private readonly ExplosionSystem _explosions = default!;
|
||||
[Dependency] private readonly AlertLevelSystem _alertLevel = default!;
|
||||
[Dependency] private readonly StationSystem _stationSystem = default!;
|
||||
[Dependency] private readonly IChatManager _chat = default!;
|
||||
[Dependency] private readonly ChatSystem _chatSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -340,7 +341,7 @@ namespace Content.Server.Nuke
|
||||
var announcement = Loc.GetString("nuke-component-announcement-armed",
|
||||
("time", (int) component.RemainingTime));
|
||||
var sender = Loc.GetString("nuke-component-announcement-sender");
|
||||
_chat.DispatchStationAnnouncement(announcement, sender, false, Color.Red);
|
||||
_chatSystem.DispatchStationAnnouncement(uid, announcement, sender, false, Color.Red);
|
||||
|
||||
// todo: move it to announcements system
|
||||
SoundSystem.Play(Filter.Broadcast(), component.ArmSound.GetSound());
|
||||
@@ -369,7 +370,7 @@ namespace Content.Server.Nuke
|
||||
// warn a crew
|
||||
var announcement = Loc.GetString("nuke-component-announcement-unarmed");
|
||||
var sender = Loc.GetString("nuke-component-announcement-sender");
|
||||
_chat.DispatchStationAnnouncement(announcement, sender, false);
|
||||
_chatSystem.DispatchStationAnnouncement(uid, announcement, sender, false);
|
||||
|
||||
// todo: move it to announcements system
|
||||
SoundSystem.Play(Filter.Broadcast(), component.DisarmSound.GetSound());
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Content.Server.Chat;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Shared.Roles;
|
||||
|
||||
@@ -31,18 +32,26 @@ namespace Content.Server.Roles
|
||||
|
||||
if (Mind.TryGetSession(out var session))
|
||||
{
|
||||
var chat = IoCManager.Resolve<IChatManager>();
|
||||
chat.DispatchServerMessage(session, Loc.GetString("job-greet-introduce-job-name", ("jobName", Name)));
|
||||
var chatMgr = IoCManager.Resolve<IChatManager>();
|
||||
var chatSys = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ChatSystem>();
|
||||
chatMgr.DispatchServerMessage(session, Loc.GetString("job-greet-introduce-job-name", ("jobName", Name)));
|
||||
|
||||
if(Prototype.RequireAdminNotify)
|
||||
chat.DispatchServerMessage(session, Loc.GetString("job-greet-important-disconnect-admin-notify"));
|
||||
chatMgr.DispatchServerMessage(session, Loc.GetString("job-greet-important-disconnect-admin-notify"));
|
||||
|
||||
chat.DispatchServerMessage(session, Loc.GetString("job-greet-supervisors-warning", ("jobName", Name), ("supervisors", Prototype.Supervisors)));
|
||||
chatMgr.DispatchServerMessage(session, Loc.GetString("job-greet-supervisors-warning", ("jobName", Name), ("supervisors", Prototype.Supervisors)));
|
||||
|
||||
if(Prototype.JoinNotifyCrew && Mind.CharacterName != null)
|
||||
chat.DispatchStationAnnouncement(Loc.GetString("job-greet-join-notify-crew", ("jobName", Name), ("characterName", Mind.CharacterName)),
|
||||
{
|
||||
if (Mind.OwnedEntity != null)
|
||||
{
|
||||
chatSys.DispatchStationAnnouncement(Mind.OwnedEntity.Value,
|
||||
Loc.GetString("job-greet-join-notify-crew", ("jobName", Name),
|
||||
("characterName", Mind.CharacterName)),
|
||||
Loc.GetString("job-greet-join-notify-crew-announcer"), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Threading;
|
||||
using Content.Server.Administration.Logs;
|
||||
using Content.Server.Chat;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Shared.Database;
|
||||
@@ -15,6 +16,7 @@ namespace Content.Server.RoundEnd
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
||||
[Dependency] private readonly ChatSystem _chatSystem = default!;
|
||||
[Dependency] private readonly GameTicker _gameTicker = default!;
|
||||
|
||||
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
||||
@@ -80,7 +82,7 @@ namespace Content.Server.RoundEnd
|
||||
_adminLogger.Add(LogType.ShuttleCalled, LogImpact.High, $"Shuttle called");
|
||||
}
|
||||
|
||||
_chatManager.DispatchStationAnnouncement(Loc.GetString("round-end-system-shuttle-called-announcement",("minutes", countdownTime.Minutes)), Loc.GetString("Station"), false, Color.Gold);
|
||||
_chatSystem.DispatchGlobalStationAnnouncement(Loc.GetString("round-end-system-shuttle-called-announcement",("minutes", countdownTime.Minutes)), Loc.GetString("Station"), false, Color.Gold);
|
||||
|
||||
SoundSystem.Play(Filter.Broadcast(), "/Audio/Announcements/shuttlecalled.ogg");
|
||||
|
||||
@@ -109,7 +111,7 @@ namespace Content.Server.RoundEnd
|
||||
_adminLogger.Add(LogType.ShuttleRecalled, LogImpact.High, $"Shuttle recalled");
|
||||
}
|
||||
|
||||
_chatManager.DispatchStationAnnouncement(Loc.GetString("round-end-system-shuttle-recalled-announcement"),
|
||||
_chatSystem.DispatchGlobalStationAnnouncement(Loc.GetString("round-end-system-shuttle-recalled-announcement"),
|
||||
Loc.GetString("Station"), false, colorOverride: Color.Gold);
|
||||
|
||||
SoundSystem.Play(Filter.Broadcast(), "/Audio/Announcements/shuttlerecalled.ogg");
|
||||
|
||||
14
Content.Server/Salvage/SalvageGridComponent.cs
Normal file
14
Content.Server/Salvage/SalvageGridComponent.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace Content.Server.Salvage
|
||||
{
|
||||
/// <summary>
|
||||
/// A grid spawned by a salvage magnet.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed class SalvageGridComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The magnet that spawned this grid.
|
||||
/// </summary>
|
||||
public SalvageMagnetComponent? SpawnerMagnet;
|
||||
}
|
||||
}
|
||||
@@ -12,24 +12,28 @@ using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Utility;
|
||||
using System.Linq;
|
||||
using Content.Server.Chat;
|
||||
using Content.Server.Station.Systems;
|
||||
|
||||
namespace Content.Server.Salvage
|
||||
{
|
||||
public sealed class SalvageSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
||||
[Dependency] private readonly IMapLoader _mapLoader = default!;
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
||||
[Dependency] private readonly StationSystem _stationSystem = default!;
|
||||
[Dependency] private readonly ChatSystem _chatSystem = default!;
|
||||
|
||||
private static readonly TimeSpan AttachingTime = TimeSpan.FromSeconds(30);
|
||||
private static readonly TimeSpan HoldTime = TimeSpan.FromMinutes(4);
|
||||
private static readonly TimeSpan DetachingTime = TimeSpan.FromSeconds(30);
|
||||
private static readonly TimeSpan CooldownTime = TimeSpan.FromMinutes(1);
|
||||
|
||||
// TODO: This is probably not compatible with multi-station
|
||||
private readonly Dictionary<GridId, SalvageGridState> _salvageGridStates = new();
|
||||
|
||||
public override void Initialize()
|
||||
@@ -58,7 +62,9 @@ namespace Content.Server.Salvage
|
||||
// If we ever want to give magnets names, and announce them individually, we would need to loop this, before removing it.
|
||||
if (_salvageGridStates.Remove(ev.GridId))
|
||||
{
|
||||
Report("salvage-system-announcement-spawn-magnet-lost");
|
||||
var gridUid = _mapManager.GetGridEuid(ev.GridId);
|
||||
if (EntityManager.TryGetComponent<SalvageGridComponent>(gridUid, out var salvComp) && salvComp.SpawnerMagnet != null)
|
||||
Report(salvComp.SpawnerMagnet.Owner, "salvage-system-announcement-spawn-magnet-lost");
|
||||
// For the very unlikely possibility that the salvage magnet was on a salvage, we will not return here
|
||||
}
|
||||
foreach(var gridState in _salvageGridStates)
|
||||
@@ -85,16 +91,16 @@ namespace Content.Server.Salvage
|
||||
return;
|
||||
}
|
||||
salvageGridState.ActiveMagnets.Remove(component);
|
||||
Report("salvage-system-announcement-spawn-magnet-lost");
|
||||
Report(uid, "salvage-system-announcement-spawn-magnet-lost");
|
||||
if (component.AttachedEntity.HasValue)
|
||||
{
|
||||
SafeDeleteSalvage(component.AttachedEntity.Value);
|
||||
component.AttachedEntity = null;
|
||||
Report("salvage-system-announcement-lost");
|
||||
Report(uid, "salvage-system-announcement-lost");
|
||||
}
|
||||
else if (component.MagnetState is { StateType: MagnetStateType.Attaching })
|
||||
{
|
||||
Report("salvage-system-announcement-spawn-no-debris-available");
|
||||
Report(uid, "salvage-system-announcement-spawn-no-debris-available");
|
||||
}
|
||||
component.MagnetState = MagnetState.Inactive;
|
||||
}
|
||||
@@ -157,7 +163,7 @@ namespace Content.Server.Salvage
|
||||
}
|
||||
gridState.ActiveMagnets.Add(component);
|
||||
component.MagnetState = new MagnetState(MagnetStateType.Attaching, gridState.CurrentTime + AttachingTime);
|
||||
Report("salvage-system-report-activate-success");
|
||||
Report(component.Owner, "salvage-system-report-activate-success");
|
||||
break;
|
||||
case MagnetStateType.Attaching:
|
||||
case MagnetStateType.Holding:
|
||||
@@ -260,7 +266,7 @@ namespace Content.Server.Salvage
|
||||
|
||||
if (map == null)
|
||||
{
|
||||
Report("salvage-system-announcement-spawn-no-debris-available");
|
||||
Report(component.Owner, "salvage-system-announcement-spawn-no-debris-available");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -272,22 +278,24 @@ namespace Content.Server.Salvage
|
||||
var (_, gridId) = _mapLoader.LoadBlueprint(spl.MapId, map.MapPath.ToString(), opts);
|
||||
if (gridId == null)
|
||||
{
|
||||
Report("salvage-system-announcement-spawn-debris-disintegrated");
|
||||
Report(component.Owner, "salvage-system-announcement-spawn-debris-disintegrated");
|
||||
return false;
|
||||
}
|
||||
var salvageEntityId = _mapManager.GetGridEuid(gridId.Value);
|
||||
component.AttachedEntity = salvageEntityId;
|
||||
var gridcomp = EntityManager.EnsureComponent<SalvageGridComponent>(salvageEntityId);
|
||||
gridcomp.SpawnerMagnet = component;
|
||||
|
||||
var pulledTransform = EntityManager.GetComponent<TransformComponent>(salvageEntityId);
|
||||
pulledTransform.WorldRotation = spAngle;
|
||||
|
||||
Report("salvage-system-announcement-arrived", ("timeLeft", HoldTime.TotalSeconds));
|
||||
Report(component.Owner, "salvage-system-announcement-arrived", ("timeLeft", HoldTime.TotalSeconds));
|
||||
return true;
|
||||
}
|
||||
private void Report(string messageKey) =>
|
||||
_chatManager.DispatchStationAnnouncement(Loc.GetString(messageKey), Loc.GetString("salvage-system-announcement-source"), colorOverride: Color.Orange, playDefaultSound: false);
|
||||
private void Report(string messageKey, params (string, object)[] args) =>
|
||||
_chatManager.DispatchStationAnnouncement(Loc.GetString(messageKey, args), Loc.GetString("salvage-system-announcement-source"), colorOverride: Color.Orange, playDefaultSound: false);
|
||||
private void Report(EntityUid source, string messageKey) =>
|
||||
_chatSystem.DispatchStationAnnouncement(source, Loc.GetString(messageKey), Loc.GetString("salvage-system-announcement-source"), colorOverride: Color.Orange, playDefaultSound: false);
|
||||
private void Report(EntityUid source, string messageKey, params (string, object)[] args) =>
|
||||
_chatSystem.DispatchStationAnnouncement(source, Loc.GetString(messageKey, args), Loc.GetString("salvage-system-announcement-source"), colorOverride: Color.Orange, playDefaultSound: false);
|
||||
|
||||
private void Transition(SalvageMagnetComponent magnet, TimeSpan currentTime)
|
||||
{
|
||||
@@ -304,7 +312,7 @@ namespace Content.Server.Salvage
|
||||
}
|
||||
break;
|
||||
case MagnetStateType.Holding:
|
||||
Report("salvage-system-announcement-losing", ("timeLeft", DetachingTime.TotalSeconds));
|
||||
Report(magnet.Owner, "salvage-system-announcement-losing", ("timeLeft", DetachingTime.TotalSeconds));
|
||||
magnet.MagnetState = new MagnetState(MagnetStateType.Detaching, currentTime + DetachingTime);
|
||||
break;
|
||||
case MagnetStateType.Detaching:
|
||||
@@ -316,7 +324,7 @@ namespace Content.Server.Salvage
|
||||
{
|
||||
Logger.ErrorS("salvage", "Salvage detaching was expecting attached entity but it was null");
|
||||
}
|
||||
Report("salvage-system-announcement-lost");
|
||||
Report(magnet.Owner, "salvage-system-announcement-lost");
|
||||
magnet.MagnetState = new MagnetState(MagnetStateType.CoolingDown, currentTime + CooldownTime);
|
||||
break;
|
||||
case MagnetStateType.CoolingDown:
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Chat;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.Station.Components;
|
||||
@@ -23,6 +24,7 @@ public sealed class StationSystem : EntitySystem
|
||||
[Dependency] private readonly ILogManager _logManager = default!;
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly ChatSystem _chatSystem = default!;
|
||||
[Dependency] private readonly GameTicker _gameTicker = default!;
|
||||
|
||||
private ISawmill _sawmill = default!;
|
||||
@@ -268,7 +270,7 @@ public sealed class StationSystem : EntitySystem
|
||||
|
||||
if (loud)
|
||||
{
|
||||
_chatManager.DispatchStationAnnouncement($"The station {oldName} has been renamed to {name}.");
|
||||
_chatSystem.DispatchStationAnnouncement(station, $"The station {oldName} has been renamed to {name}.");
|
||||
}
|
||||
|
||||
RaiseLocalEvent(station, new StationRenamedEvent(oldName, name));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.Chat;
|
||||
using Content.Server.Disease.Components;
|
||||
using Content.Server.Disease;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared.Disease;
|
||||
using Content.Shared.MobState.Components;
|
||||
using Content.Shared.Sound;
|
||||
@@ -17,7 +18,6 @@ public sealed class DiseaseOutbreak : StationEvent
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Disease prototypes I decided were not too deadly for a random event
|
||||
@@ -36,6 +36,7 @@ public sealed class DiseaseOutbreak : StationEvent
|
||||
|
||||
public override SoundSpecifier? StartAudio => new SoundPathSpecifier("/Audio/Announcements/outbreak7.ogg");
|
||||
protected override float EndAfter => 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Finds 2-5 random, alive entities that can host diseases
|
||||
/// and gives them a randomly selected disease.
|
||||
@@ -44,6 +45,7 @@ public sealed class DiseaseOutbreak : StationEvent
|
||||
public override void Startup()
|
||||
{
|
||||
base.Startup();
|
||||
HashSet<EntityUid> stationsToNotify = new();
|
||||
List<DiseaseCarrierComponent> aliveList = new();
|
||||
foreach (var (carrier, mobState) in _entityManager.EntityQuery<DiseaseCarrierComponent, MobStateComponent>())
|
||||
{
|
||||
@@ -61,15 +63,25 @@ public sealed class DiseaseOutbreak : StationEvent
|
||||
return;
|
||||
|
||||
var diseaseSystem = EntitySystem.Get<DiseaseSystem>();
|
||||
/// Now we give it to people in the list of living disease carriers earlier
|
||||
var stationSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<StationSystem>();
|
||||
var chatSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ChatSystem>();
|
||||
// Now we give it to people in the list of living disease carriers earlier
|
||||
foreach (var target in aliveList)
|
||||
{
|
||||
if (toInfect-- == 0)
|
||||
break;
|
||||
|
||||
diseaseSystem.TryAddDisease(target.Owner, disease, target);
|
||||
|
||||
var station = stationSystem.GetOwningStation(target.Owner);
|
||||
if(station == null) continue;
|
||||
stationsToNotify.Add((EntityUid) station);
|
||||
}
|
||||
_chatManager.DispatchStationAnnouncement(Loc.GetString("station-event-disease-outbreak-announcement"),
|
||||
|
||||
foreach (var station in stationsToNotify)
|
||||
{
|
||||
chatSystem.DispatchStationAnnouncement(station, Loc.GetString("station-event-disease-outbreak-announcement"),
|
||||
playDefaultSound: false, colorOverride: Color.YellowGreen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.Chat;
|
||||
using Content.Server.Ghost.Roles.Components;
|
||||
using Content.Server.Mind.Commands;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
@@ -11,7 +12,6 @@ public sealed class RandomSentience : StationEvent
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
||||
|
||||
public override string Name => "RandomSentience";
|
||||
|
||||
@@ -22,6 +22,7 @@ public sealed class RandomSentience : StationEvent
|
||||
public override void Startup()
|
||||
{
|
||||
base.Startup();
|
||||
HashSet<EntityUid> stationsToNotify = new();
|
||||
|
||||
var targetList = _entityManager.EntityQuery<SentienceTargetComponent>().ToList();
|
||||
_random.Shuffle(targetList);
|
||||
@@ -49,7 +50,19 @@ public sealed class RandomSentience : StationEvent
|
||||
var kind1 = groupList.Count > 0 ? groupList[0] : "???";
|
||||
var kind2 = groupList.Count > 1 ? groupList[1] : "???";
|
||||
var kind3 = groupList.Count > 2 ? groupList[2] : "???";
|
||||
_chatManager.DispatchStationAnnouncement(
|
||||
|
||||
var stationSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<StationSystem>();
|
||||
var chatSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ChatSystem>();
|
||||
foreach (var target in targetList)
|
||||
{
|
||||
var station = stationSystem.GetOwningStation(target.Owner);
|
||||
if(station == null) continue;
|
||||
stationsToNotify.Add((EntityUid) station);
|
||||
}
|
||||
foreach (var station in stationsToNotify)
|
||||
{
|
||||
chatSystem.DispatchStationAnnouncement(
|
||||
(EntityUid) station,
|
||||
Loc.GetString("station-event-random-sentience-announcement",
|
||||
("kind1", kind1), ("kind2", kind2), ("kind3", kind3), ("amount", groupList.Count),
|
||||
("data", Loc.GetString($"random-sentience-event-data-{_random.Next(1, 6)}")),
|
||||
@@ -58,4 +71,5 @@ public sealed class RandomSentience : StationEvent
|
||||
colorOverride: Color.Gold
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Server.Administration.Logs;
|
||||
using Content.Server.Atmos.EntitySystems;
|
||||
using Content.Server.Chat;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.Station.Components;
|
||||
@@ -140,8 +141,8 @@ namespace Content.Server.StationEvents.Events
|
||||
|
||||
if (StartAnnouncement != null)
|
||||
{
|
||||
var chatManager = IoCManager.Resolve<IChatManager>();
|
||||
chatManager.DispatchStationAnnouncement(StartAnnouncement, playDefaultSound: false, colorOverride: Color.Gold);
|
||||
var chatSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ChatSystem>();
|
||||
chatSystem.DispatchGlobalStationAnnouncement(StartAnnouncement, playDefaultSound: false, colorOverride: Color.Gold);
|
||||
}
|
||||
|
||||
if (StartAudio != null)
|
||||
@@ -163,8 +164,8 @@ namespace Content.Server.StationEvents.Events
|
||||
|
||||
if (EndAnnouncement != null)
|
||||
{
|
||||
var chatManager = IoCManager.Resolve<IChatManager>();
|
||||
chatManager.DispatchStationAnnouncement(EndAnnouncement, playDefaultSound: false, colorOverride: Color.Gold);
|
||||
var chatSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ChatSystem>();
|
||||
chatSystem.DispatchGlobalStationAnnouncement(EndAnnouncement, playDefaultSound: false, colorOverride: Color.Gold);
|
||||
}
|
||||
|
||||
if (EndAudio != null)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Content.Server.Chat;
|
||||
using Robust.Shared.Random;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.Disease.Zombie.Components;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared.MobState.Components;
|
||||
using Content.Shared.Sound;
|
||||
|
||||
@@ -13,7 +14,6 @@ namespace Content.Server.StationEvents.Events
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
||||
|
||||
public override string Name => "ZombieOutbreak";
|
||||
public override int EarliestStart => 50;
|
||||
@@ -31,6 +31,7 @@ namespace Content.Server.StationEvents.Events
|
||||
public override void Startup()
|
||||
{
|
||||
base.Startup();
|
||||
HashSet<EntityUid> stationsToNotify = new();
|
||||
List<MobStateComponent> deadList = new();
|
||||
foreach (var mobState in _entityManager.EntityQuery<MobStateComponent>())
|
||||
{
|
||||
@@ -41,16 +42,25 @@ namespace Content.Server.StationEvents.Events
|
||||
|
||||
var toInfect = _random.Next(1, 3);
|
||||
|
||||
/// Now we give it to people in the list of dead entities earlier.
|
||||
// Now we give it to people in the list of dead entities earlier.
|
||||
var stationSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<StationSystem>();
|
||||
var chatSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ChatSystem>();
|
||||
foreach (var target in deadList)
|
||||
{
|
||||
if (toInfect-- == 0)
|
||||
break;
|
||||
|
||||
_entityManager.EnsureComponent<DiseaseZombieComponent>(target.Owner);
|
||||
|
||||
var station = stationSystem.GetOwningStation(target.Owner);
|
||||
if(station == null) continue;
|
||||
stationsToNotify.Add((EntityUid) station);
|
||||
}
|
||||
_chatManager.DispatchStationAnnouncement(Loc.GetString("station-event-zombie-outbreak-announcement"),
|
||||
foreach (var station in stationsToNotify)
|
||||
{
|
||||
chatSystem.DispatchStationAnnouncement((EntityUid) station, Loc.GetString("station-event-zombie-outbreak-announcement"),
|
||||
playDefaultSound: false, colorOverride: Color.DarkMagenta);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,11 @@ namespace Content.Shared.Administration
|
||||
Station,
|
||||
Server,
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class AdminAnnounceEuiState : EuiStateBase {}
|
||||
public sealed class AdminAnnounceEuiState : EuiStateBase
|
||||
{
|
||||
}
|
||||
|
||||
public static class AdminAnnounceEuiMsg
|
||||
{
|
||||
|
||||
@@ -1,4 +1,17 @@
|
||||
communicationsconsole-menu-title = Communications Console
|
||||
communicationsconsole-menu-announcement-placeholder = Announcement
|
||||
communicationsconsole-menu-call-shuttle = Call emergency shuttle
|
||||
communicationsconsole-menu-recall-shuttle = Recall emergency shuttle
|
||||
# User interface
|
||||
comms-console-menu-title = Communications Console
|
||||
comms-console-menu-announcement-placeholder = Announcement
|
||||
comms-console-menu-call-shuttle = Call emergency shuttle
|
||||
comms-console-menu-recall-shuttle = Recall emergency shuttle
|
||||
|
||||
# Popup
|
||||
comms-console-permission-denied = Permission denied
|
||||
|
||||
# Placeholder values
|
||||
comms-console-announcement-sent-by = Sent by
|
||||
comms-console-announcement-unknown-sender = Unknown
|
||||
|
||||
# Comms console variant titles
|
||||
comms-console-announcement-title-station = Communications Console
|
||||
comms-console-announcement-title-centcom = Central Command
|
||||
comms-console-announcement-title-nukie = Syndicate Nuclear Operative
|
||||
|
||||
@@ -97,6 +97,8 @@
|
||||
event: !type:ToggleIntrinsicUIEvent
|
||||
- type: SolarControlConsole # look ma i AM the computer!
|
||||
- type: CommunicationsConsole
|
||||
title: communicationsconsole-announcement-title-centcom
|
||||
color: "#228b22"
|
||||
- type: RadarConsole
|
||||
- type: CargoConsole
|
||||
- type: CargoOrderDatabase
|
||||
|
||||
@@ -146,6 +146,15 @@
|
||||
- type: ComputerBoard
|
||||
prototype: ComputerComms
|
||||
|
||||
- type: entity
|
||||
parent: BaseComputerCircuitboard
|
||||
id: SyndicateCommsComputerCircuitboard
|
||||
name: syndicate communications computer board
|
||||
description: A computer printed circuit board for a syndicate communications console
|
||||
components:
|
||||
- type: ComputerBoard
|
||||
prototype: SyndicateComputerComms
|
||||
|
||||
- type: entity
|
||||
parent: BaseComputerCircuitboard
|
||||
id: RadarConsoleCircuitboard
|
||||
|
||||
@@ -278,7 +278,10 @@
|
||||
- type: ComputerVisualizer
|
||||
key: generic_key
|
||||
screen: comm
|
||||
- type: AccessReader
|
||||
access: [[ "Command" ]]
|
||||
- type: CommunicationsConsole
|
||||
title: comms-console-announcement-title-station
|
||||
- type: ActivatableUI
|
||||
key: enum.CommunicationsConsoleUiKey.Key
|
||||
- type: ActivatableUIRequiresPower
|
||||
@@ -293,6 +296,31 @@
|
||||
energy: 1.6
|
||||
color: "#3c5eb5"
|
||||
|
||||
- type: entity
|
||||
parent: ComputerComms
|
||||
id: SyndicateComputerComms
|
||||
name: syndicate communications computer
|
||||
description: This can be used for various important functions. Still under development.
|
||||
components:
|
||||
- type: Appearance
|
||||
visuals:
|
||||
- type: ComputerVisualizer
|
||||
key: syndie_key
|
||||
screen: comm_syndie
|
||||
- type: AccessReader
|
||||
access: [[ "NuclearOperative" ]]
|
||||
- type: CommunicationsConsole
|
||||
title: comms-console-announcement-title-nukie
|
||||
color: "#ff0000"
|
||||
canShuttle: false
|
||||
global: true #announce to everyone they're about to fuck shit up
|
||||
- type: Computer
|
||||
board: SyndicateCommsComputerCircuitboard
|
||||
- type: PointLight
|
||||
radius: 1.5
|
||||
energy: 1.6
|
||||
color: "#f71713"
|
||||
|
||||
- type: entity
|
||||
parent: ComputerBase
|
||||
id: ComputerSolarControl
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 9.3 KiB |
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"version": 1,
|
||||
"license": "CC-BY-SA-3.0",
|
||||
"copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/bd6873fd4dd6a61d7e46f1d75cd4d90f64c40894",
|
||||
"copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/bd6873fd4dd6a61d7e46f1d75cd4d90f64c40894. comm_syndie made by Veritius, based on comm.",
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
@@ -305,6 +305,28 @@
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "comm_syndie",
|
||||
"directions": 4,
|
||||
"delays": [
|
||||
[
|
||||
0.1,
|
||||
0.1
|
||||
],
|
||||
[
|
||||
0.1,
|
||||
0.1
|
||||
],
|
||||
[
|
||||
0.1,
|
||||
0.1
|
||||
],
|
||||
[
|
||||
0.1,
|
||||
0.1
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "command",
|
||||
"directions": 4,
|
||||
|
||||
Reference in New Issue
Block a user