diff --git a/Content.Client/UserInterface/CooldownGraphic.cs b/Content.Client/UserInterface/CooldownGraphic.cs index bb0f1c39ce..4e1cd2f484 100644 --- a/Content.Client/UserInterface/CooldownGraphic.cs +++ b/Content.Client/UserInterface/CooldownGraphic.cs @@ -8,28 +8,49 @@ namespace Robust.Client.UserInterface.Controls { public class CooldownGraphic : Control { - public float Fraction { get; set; } + /// + /// Progress of the cooldown animation. + /// Possible values range from 1 to -1, where 1 to 0 is a depleting circle animation and 0 to -1 is a blink animation. + /// + public float Progress { get; set; } protected override void Draw(DrawingHandleScreen handle) { const int maxSegments = 64; const float segment = MathHelper.TwoPi / maxSegments; - var segments = (int)Math.Max(2, Math.Ceiling(maxSegments * Fraction)); // ensure that we always have at least 3 vertices - var max = MathHelper.TwoPi * Fraction; - var radius = (Math.Min(SizeBox.Height, SizeBox.Width) / 2) * 0.875f; // 28/32 = 0.875 - 2 pixels inwards from the edge - var ring_radius = (Math.Min(SizeBox.Height, SizeBox.Width) / 2) * 0.5625f; + var effective_fraction = Progress >= 0f ? Progress : 1f; // we want the full circle for the blink + + var segments = (int)Math.Max(2, Math.Ceiling(maxSegments * effective_fraction) + 1); // ensure that we always have at least 3 vertices, we also need one more segment + var max = MathHelper.TwoPi * effective_fraction; + var outer_radius = (Math.Min(SizeBox.Height, SizeBox.Width) / 2) * 0.875f; // 28/32 = 0.875 - 2 pixels inwards from the edge + var inner_radius = (Math.Min(SizeBox.Height, SizeBox.Width) / 2) * 0.5625f; // 18/32 = 0.5625 - 5 pixels thick Span vertices = stackalloc Vector2[segments * 2]; var center = PixelPosition + SizeBox.Center; for (int i = 0; i < segments; i++) { var angle = MathHelper.Pi + Math.Min(max, segment * i); - vertices[2*i] = center + new Vector2((float) Math.Sin(angle) * radius, (float) Math.Cos(angle) * radius); - vertices[2*i + 1] = center + new Vector2((float) Math.Sin(angle) * ring_radius, (float) Math.Cos(angle) * ring_radius); + vertices[2*i] = center + new Vector2((float) Math.Sin(angle) * outer_radius, (float) Math.Cos(angle) * outer_radius); + vertices[2*i + 1] = center + new Vector2((float) Math.Sin(angle) * inner_radius, (float) Math.Cos(angle) * inner_radius); } - handle.DrawPrimitives(DrawPrimitiveTopology.TriangleStrip, vertices, new Color(0.3f, 0.3f, 0.4f, 0.75f)); + Color draw_color; + + var fraction_lerp = 1f - Math.Abs(Progress); // for future bikeshedding purposes + + if (Progress >= 0f) + { + var hue = (5f / 18f) * fraction_lerp; + draw_color = Color.FromHsv((hue, 0.75f, 0.75f, 0.50f)); + } + else + { + var alpha = Math.Clamp(0.5f * fraction_lerp, 0f, 0.5f); + draw_color = new Color(1f, 1f, 1f, alpha); + } + + handle.DrawPrimitives(DrawPrimitiveTopology.TriangleStrip, vertices, draw_color); } } } diff --git a/Content.Client/UserInterface/ItemSlotManager.cs b/Content.Client/UserInterface/ItemSlotManager.cs index a1daa70ebe..69a7736b55 100644 --- a/Content.Client/UserInterface/ItemSlotManager.cs +++ b/Content.Client/UserInterface/ItemSlotManager.cs @@ -100,12 +100,12 @@ namespace Content.Client.UserInterface var end = cooldown.CooldownEnd.Value; var length = (end - start).TotalSeconds; - var progress = (_gameTiming.CurTime - start).TotalSeconds; - var ratio = 1 - (float)(progress / length).Clamp(0, 1); + var progress = (_gameTiming.CurTime - start).TotalSeconds / length; + var ratio = (progress <= 1 ? (1 - progress) : (_gameTiming.CurTime - end).TotalSeconds * -5); - cooldownDisplay.Fraction = ratio; + cooldownDisplay.Progress = (float)ratio.Clamp(-1, 1); - if (ratio > 0) + if (ratio > -1f) { cooldownDisplay.Visible = true; }