Station alert levels (#8226)
This commit is contained in:
46
Content.Client/AlertLevel/AlertLevelDisplaySystem.cs
Normal file
46
Content.Client/AlertLevel/AlertLevelDisplaySystem.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System.Linq;
|
||||
using Content.Shared.AlertLevel;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.AlertLevel;
|
||||
|
||||
public sealed class AlertLevelDisplaySystem : EntitySystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<AlertLevelDisplayComponent, AppearanceChangeEvent>(OnAppearanceChange);
|
||||
}
|
||||
|
||||
private void OnAppearanceChange(EntityUid uid, AlertLevelDisplayComponent component, ref AppearanceChangeEvent args)
|
||||
{
|
||||
if (args.Sprite == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!args.Sprite.LayerMapTryGet(AlertLevelDisplay.Layer, out _))
|
||||
{
|
||||
var layer = args.Sprite.AddLayer(new RSI.StateId(component.AlertVisuals.Values.First()));
|
||||
args.Sprite.LayerMapSet(AlertLevelDisplay.Layer, layer);
|
||||
}
|
||||
|
||||
if (!args.AppearanceData.TryGetValue(AlertLevelDisplay.CurrentLevel, out var level))
|
||||
{
|
||||
args.Sprite.LayerSetState(AlertLevelDisplay.Layer, new RSI.StateId(component.AlertVisuals.Values.First()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (component.AlertVisuals.TryGetValue((string) level, out var visual))
|
||||
{
|
||||
args.Sprite.LayerSetState(AlertLevelDisplay.Layer, new RSI.StateId(visual));
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Sprite.LayerSetState(AlertLevelDisplay.Layer, new RSI.StateId(component.AlertVisuals.Values.First()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,10 @@ namespace Content.Client.Communications.UI
|
||||
|
||||
public bool CountdownStarted { get; private set; }
|
||||
|
||||
public bool AlertLevelSelectable { get; private set; }
|
||||
|
||||
public string CurrentLevel { get; private set; } = default!;
|
||||
|
||||
public int Countdown => _expectedCountdownTime == null
|
||||
? 0 : Math.Max((int)_expectedCountdownTime.Value.Subtract(_gameTiming.CurTime).TotalSeconds, 0);
|
||||
private TimeSpan? _expectedCountdownTime;
|
||||
@@ -36,6 +40,15 @@ namespace Content.Client.Communications.UI
|
||||
_menu.OpenCentered();
|
||||
}
|
||||
|
||||
public void AlertLevelSelected(string level)
|
||||
{
|
||||
if (AlertLevelSelectable)
|
||||
{
|
||||
CurrentLevel = level;
|
||||
SendMessage(new CommunicationsConsoleSelectAlertLevelMessage(level));
|
||||
}
|
||||
}
|
||||
|
||||
public void EmergencyShuttleButtonPressed()
|
||||
{
|
||||
if (CountdownStarted)
|
||||
@@ -71,10 +84,14 @@ namespace Content.Client.Communications.UI
|
||||
CanCall = commsState.CanCall;
|
||||
_expectedCountdownTime = commsState.ExpectedCountdownEnd;
|
||||
CountdownStarted = commsState.CountdownStarted;
|
||||
AlertLevelSelectable = commsState.AlertLevels != null && !float.IsNaN(commsState.CurrentAlertDelay) && commsState.CurrentAlertDelay <= 0;
|
||||
CurrentLevel = commsState.CurrentAlert;
|
||||
|
||||
if (_menu != null)
|
||||
{
|
||||
_menu.UpdateCountdown();
|
||||
_menu.UpdateAlertLevels(commsState.AlertLevels, CurrentLevel);
|
||||
_menu.AlertLevelButton.Disabled = !AlertLevelSelectable;
|
||||
_menu.EmergencyShuttleButton.Disabled = !CanCall;
|
||||
_menu.AnnounceButton.Disabled = !CanAnnounce;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace Content.Client.Communications.UI
|
||||
public readonly Button AnnounceButton;
|
||||
public readonly Button EmergencyShuttleButton;
|
||||
private readonly RichTextLabel _countdownLabel;
|
||||
public readonly OptionButton AlertLevelButton;
|
||||
|
||||
public CommunicationsConsoleMenu(CommunicationsConsoleBoundUserInterface owner)
|
||||
{
|
||||
@@ -38,6 +39,17 @@ namespace Content.Client.Communications.UI
|
||||
AnnounceButton.OnPressed += (_) => Owner.AnnounceButtonPressed(_messageInput.Text.Trim());
|
||||
AnnounceButton.Disabled = !owner.CanAnnounce;
|
||||
|
||||
AlertLevelButton = new OptionButton();
|
||||
AlertLevelButton.OnItemSelected += args =>
|
||||
{
|
||||
var metadata = AlertLevelButton.GetItemMetadata(args.Id);
|
||||
if (metadata != null && metadata is string cast)
|
||||
{
|
||||
Owner.AlertLevelSelected(cast);
|
||||
}
|
||||
};
|
||||
AlertLevelButton.Disabled = !owner.AlertLevelSelectable;
|
||||
|
||||
_countdownLabel = new RichTextLabel(){MinSize = new Vector2(0, 200)};
|
||||
EmergencyShuttleButton = new Button();
|
||||
EmergencyShuttleButton.OnPressed += (_) => Owner.EmergencyShuttleButtonPressed();
|
||||
@@ -52,6 +64,7 @@ namespace Content.Client.Communications.UI
|
||||
vbox.AddChild(_messageInput);
|
||||
vbox.AddChild(new Control(){MinSize = new Vector2(0,10), HorizontalExpand = true});
|
||||
vbox.AddChild(AnnounceButton);
|
||||
vbox.AddChild(AlertLevelButton);
|
||||
vbox.AddChild(new Control(){MinSize = new Vector2(0,10), HorizontalExpand = true});
|
||||
vbox.AddChild(_countdownLabel);
|
||||
vbox.AddChild(EmergencyShuttleButton);
|
||||
@@ -72,6 +85,34 @@ namespace Content.Client.Communications.UI
|
||||
Timer.SpawnRepeating(1000, UpdateCountdown, _timerCancelTokenSource.Token);
|
||||
}
|
||||
|
||||
// The current alert could make levels unselectable, so we need to ensure that the UI reacts properly.
|
||||
// If the current alert is unselectable, the only item in the alerts list will be
|
||||
// the current alert. Otherwise, it will be the list of alerts, with the current alert
|
||||
// selected.
|
||||
public void UpdateAlertLevels(List<string>? alerts, string currentAlert)
|
||||
{
|
||||
AlertLevelButton.Clear();
|
||||
|
||||
if (alerts == null)
|
||||
{
|
||||
AlertLevelButton.AddItem(Loc.GetString($"alert-level-{currentAlert}"));
|
||||
AlertLevelButton.SetItemMetadata(AlertLevelButton.ItemCount - 1, currentAlert);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var alert in alerts)
|
||||
{
|
||||
AlertLevelButton.AddItem(Loc.GetString($"alert-level-{alert}"));
|
||||
AlertLevelButton.SetItemMetadata(AlertLevelButton.ItemCount - 1, alert);
|
||||
|
||||
if (alert == currentAlert)
|
||||
{
|
||||
AlertLevelButton.Select(AlertLevelButton.ItemCount - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateCountdown()
|
||||
{
|
||||
if (!Owner.CountdownStarted)
|
||||
|
||||
@@ -106,6 +106,7 @@ namespace Content.Client.Entry
|
||||
prototypes.RegisterIgnore("instantSpell");
|
||||
prototypes.RegisterIgnore("roundAnnouncement");
|
||||
prototypes.RegisterIgnore("wireLayout");
|
||||
prototypes.RegisterIgnore("alertLevels");
|
||||
prototypes.RegisterIgnore("nukeopsRole");
|
||||
|
||||
ClientContentIoC.Register();
|
||||
|
||||
Reference in New Issue
Block a user