using System.Numerics; using Content.Client.Actions.UI; using Content.Client.Cooldown; using Content.Shared.Alert; using Robust.Client.GameObjects; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Shared.Timing; using Robust.Shared.Utility; namespace Content.Client.UserInterface.Systems.Alerts.Controls { public sealed class AlertControl : BaseButton { [Dependency] private readonly IEntityManager _entityManager = default!; public AlertPrototype Alert { get; } /// /// Current cooldown displayed in this slot. Set to null to show no cooldown. /// public (TimeSpan Start, TimeSpan End)? Cooldown { get => _cooldown; set { _cooldown = value; if (SuppliedTooltip is ActionAlertTooltip actionAlertTooltip) { actionAlertTooltip.Cooldown = value; } } } private (TimeSpan Start, TimeSpan End)? _cooldown; private short? _severity; private readonly SpriteView _icon; private readonly CooldownGraphic _cooldownGraphic; private EntityUid _spriteViewEntity; /// /// Creates an alert control reflecting the indicated alert + state /// /// alert to display /// severity of alert, null if alert doesn't have severity levels public AlertControl(AlertPrototype alert, short? severity) { // Alerts will handle this. MuteSounds = true; IoCManager.InjectDependencies(this); TooltipSupplier = SupplyTooltip; Alert = alert; _severity = severity; _icon = new SpriteView { Scale = new Vector2(2, 2) }; SetupIcon(); Children.Add(_icon); _cooldownGraphic = new CooldownGraphic { MaxSize = new Vector2(64, 64) }; Children.Add(_cooldownGraphic); } private Control SupplyTooltip(Control? sender) { var msg = FormattedMessage.FromMarkupOrThrow(Loc.GetString(Alert.Name)); var desc = FormattedMessage.FromMarkupOrThrow(Loc.GetString(Alert.Description)); return new ActionAlertTooltip(msg, desc) {Cooldown = Cooldown}; } /// /// Change the alert severity, changing the displayed icon /// public void SetSeverity(short? severity) { if (_severity == severity) return; _severity = severity; if (!_entityManager.TryGetComponent(_spriteViewEntity, out var sprite)) return; var icon = Alert.GetIcon(_severity); if (sprite.LayerMapTryGet(AlertVisualLayers.Base, out var layer)) sprite.LayerSetSprite(layer, icon); } protected override void FrameUpdate(FrameEventArgs args) { base.FrameUpdate(args); UserInterfaceManager.GetUIController().UpdateAlertSpriteEntity(_spriteViewEntity, Alert); if (!Cooldown.HasValue) { _cooldownGraphic.Visible = false; _cooldownGraphic.Progress = 0; return; } _cooldownGraphic.FromTime(Cooldown.Value.Start, Cooldown.Value.End); } private void SetupIcon() { if (!_entityManager.Deleted(_spriteViewEntity)) _entityManager.QueueDeleteEntity(_spriteViewEntity); _spriteViewEntity = _entityManager.Spawn(Alert.AlertViewEntity); if (_entityManager.TryGetComponent(_spriteViewEntity, out var sprite)) { var icon = Alert.GetIcon(_severity); if (sprite.LayerMapTryGet(AlertVisualLayers.Base, out var layer)) sprite.LayerSetSprite(layer, icon); } _icon.SetEntity(_spriteViewEntity); } protected override void EnteredTree() { base.EnteredTree(); SetupIcon(); } protected override void ExitedTree() { base.ExitedTree(); if (!_entityManager.Deleted(_spriteViewEntity)) _entityManager.QueueDeleteEntity(_spriteViewEntity); } protected override void Dispose(bool disposing) { base.Dispose(disposing); if (!_entityManager.Deleted(_spriteViewEntity)) _entityManager.QueueDeleteEntity(_spriteViewEntity); } } public enum AlertVisualLayers : byte { Base } }