#nullable enable using System; using Content.Shared.Alert; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Shared.Interfaces.Timing; using Robust.Shared.IoC; using Robust.Shared.Maths; using Robust.Shared.Timing; namespace Content.Client.UserInterface.Controls { public class AlertControl : BaseButton { // shorter than default tooltip delay so user can more easily // see what alerts they have private const float CustomTooltipDelay = 0.5f; 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 IGameTiming _gameTiming; private readonly AnimatedTextureRect _icon; private readonly CooldownGraphic _cooldownGraphic; /// /// 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) { _gameTiming = IoCManager.Resolve(); TooltipDelay = CustomTooltipDelay; TooltipSupplier = SupplyTooltip; Alert = alert; _severity = severity; var specifier = alert.GetIcon(_severity); _icon = new AnimatedTextureRect { DisplayRect = {TextureScale = (2, 2)} }; _icon.SetFromSpriteSpecifier(specifier); Children.Add(_icon); _cooldownGraphic = new CooldownGraphic(); Children.Add(_cooldownGraphic); } private Control SupplyTooltip(Control? sender) { return new ActionAlertTooltip(Alert.Name, Alert.Description) {Cooldown = Cooldown}; } /// /// Change the alert severity, changing the displayed icon /// public void SetSeverity(short? severity) { if (_severity != severity) { _severity = severity; _icon.SetFromSpriteSpecifier(Alert.GetIcon(_severity)); } } protected override void FrameUpdate(FrameEventArgs args) { base.FrameUpdate(args); if (!Cooldown.HasValue) { _cooldownGraphic.Visible = false; _cooldownGraphic.Progress = 0; return; } var duration = Cooldown.Value.End - Cooldown.Value.Start; var curTime = _gameTiming.CurTime; var length = duration.TotalSeconds; var progress = (curTime - Cooldown.Value.Start).TotalSeconds / length; var ratio = (progress <= 1 ? (1 - progress) : (curTime - Cooldown.Value.End).TotalSeconds * -5); _cooldownGraphic.Progress = MathHelper.Clamp((float) ratio, -1, 1); _cooldownGraphic.Visible = ratio > -1f; } } }