Station alert levels (#8226)

This commit is contained in:
Flipp Syder
2022-05-17 21:05:31 -07:00
committed by GitHub
parent 2697bbf8c7
commit dcdda39048
21 changed files with 566 additions and 2 deletions

View 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()));
}
}
}

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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();