using System; using Robust.Client.Graphics; using Robust.Client.UserInterface; using Robust.Shared.IoC; using Robust.Shared.Maths; using Robust.Shared.Prototypes; using Robust.Shared.Timing; namespace Content.Client.DoAfter.UI { public sealed class DoAfterBar : Control { private IGameTiming _gameTiming = default!; private readonly ShaderInstance _shader; /// /// Set from 0.0f to 1.0f to reflect bar progress /// public float Ratio { get => _ratio; set => _ratio = value; } private float _ratio = 1.0f; /// /// Flash red until removed /// public bool Cancelled { get => _cancelled; set { if (_cancelled == value) { return; } _cancelled = value; if (_cancelled) { _gameTiming = IoCManager.Resolve(); _lastFlash = _gameTiming.CurTime; } } } private bool _cancelled; /// /// Is the cancellation bar red? /// private bool _flash = true; /// /// Last time we swapped the flash. /// private TimeSpan _lastFlash; /// /// How long each cancellation bar flash lasts in seconds. /// private const float FlashTime = 0.125f; private const int XPixelDiff = 20 * DoAfterBarScale; public const byte DoAfterBarScale = 2; public DoAfterBar() { IoCManager.InjectDependencies(this); _shader = IoCManager.Resolve().Index("unshaded").Instance(); } protected override void FrameUpdate(FrameEventArgs args) { base.FrameUpdate(args); if (Cancelled) { if ((_gameTiming.CurTime - _lastFlash).TotalSeconds > FlashTime) { _lastFlash = _gameTiming.CurTime; _flash = !_flash; } } } protected override void Draw(DrawingHandleScreen handle) { base.Draw(handle); Color color; if (Cancelled) { if ((_gameTiming.CurTime - _lastFlash).TotalSeconds > FlashTime) { _lastFlash = _gameTiming.CurTime; _flash = !_flash; } color = new Color(1.0f, 0.0f, 0.0f, _flash ? 1.0f : 0.0f); } else { color = DoAfterHelpers.GetProgressColor(Ratio); } handle.UseShader(_shader); // If you want to make this less hard-coded be my guest var leftOffset = 2 * DoAfterBarScale; var box = new UIBox2i( leftOffset, -2 + 2 * DoAfterBarScale, leftOffset + (int) (XPixelDiff * Ratio * UIScale), -2); handle.DrawRect(box, color); } } public static class DoAfterHelpers { public static Color GetProgressColor(float progress) { if (progress >= 1.0f) { return new Color(0f, 1f, 0f); } // lerp var hue = (5f / 18f) * progress; return Color.FromHsv((hue, 1f, 0.75f, 1f)); } } }