From 8e49256a5c28bac5d93d765c2efc4833e62bc165 Mon Sep 17 00:00:00 2001
From: Dean Herbert <pe@ppy.sh>
Date: Fri, 31 Jul 2020 09:03:29 +0900
Subject: [PATCH 01/12] Rename and split up statement to make more legible

---
 .../Drawables/Pieces/DefaultSpinnerDisc.cs     | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/DefaultSpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/DefaultSpinnerDisc.cs
index 2644f425a0..7f65a8c022 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/DefaultSpinnerDisc.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/DefaultSpinnerDisc.cs
@@ -29,7 +29,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
 
         private SpinnerTicks ticks;
 
-        private int completeTick;
+        private int wholeRotationCount;
+
         private SpinnerFill fill;
         private Container mainContainer;
         private SpinnerCentreLayer centre;
@@ -145,13 +146,24 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
             centre.FadeAccent(colour, duration);
         }
 
-        private bool updateCompleteTick() => completeTick != (completeTick = (int)(drawableSpinner.RotationTracker.CumulativeRotation / 360));
+        private bool checkNewRotationCount
+        {
+            get
+            {
+                int rotations = (int)(drawableSpinner.RotationTracker.CumulativeRotation / 360);
+
+                if (wholeRotationCount == rotations) return false;
+
+                wholeRotationCount = rotations;
+                return true;
+            }
+        }
 
         protected override void Update()
         {
             base.Update();
 
-            if (drawableSpinner.RotationTracker.Complete.Value && updateCompleteTick())
+            if (drawableSpinner.RotationTracker.Complete.Value && checkNewRotationCount)
             {
                 fill.FinishTransforms(false, nameof(Alpha));
                 fill

From cd570433f4aa1779d7bed92aac36e5fd368b6546 Mon Sep 17 00:00:00 2001
From: Dean Herbert <pe@ppy.sh>
Date: Fri, 31 Jul 2020 09:04:20 +0900
Subject: [PATCH 02/12] Move private methods to bottom of class

---
 .../Drawables/Pieces/DefaultSpinnerDisc.cs    | 39 ++++++++++---------
 1 file changed, 20 insertions(+), 19 deletions(-)

diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/DefaultSpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/DefaultSpinnerDisc.cs
index 7f65a8c022..81dea8d1c1 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/DefaultSpinnerDisc.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/DefaultSpinnerDisc.cs
@@ -96,6 +96,26 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
             drawableSpinner.State.BindValueChanged(updateStateTransforms, true);
         }
 
+        protected override void Update()
+        {
+            base.Update();
+
+            if (drawableSpinner.RotationTracker.Complete.Value && checkNewRotationCount)
+            {
+                fill.FinishTransforms(false, nameof(Alpha));
+                fill
+                    .FadeTo(tracking_alpha + 0.2f, 60, Easing.OutExpo)
+                    .Then()
+                    .FadeTo(tracking_alpha, 250, Easing.OutQuint);
+            }
+
+            const float initial_scale = 0.2f;
+            float targetScale = initial_scale + (1 - initial_scale) * drawableSpinner.Progress;
+
+            fill.Scale = new Vector2((float)Interpolation.Lerp(fill.Scale.X, targetScale, Math.Clamp(Math.Abs(Time.Elapsed) / 100, 0, 1)));
+            mainContainer.Rotation = drawableSpinner.RotationTracker.Rotation;
+        }
+
         private void updateStateTransforms(ValueChangedEvent<ArmedState> state)
         {
             centre.ScaleTo(0);
@@ -159,24 +179,5 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
             }
         }
 
-        protected override void Update()
-        {
-            base.Update();
-
-            if (drawableSpinner.RotationTracker.Complete.Value && checkNewRotationCount)
-            {
-                fill.FinishTransforms(false, nameof(Alpha));
-                fill
-                    .FadeTo(tracking_alpha + 0.2f, 60, Easing.OutExpo)
-                    .Then()
-                    .FadeTo(tracking_alpha, 250, Easing.OutQuint);
-            }
-
-            const float initial_scale = 0.2f;
-            float targetScale = initial_scale + (1 - initial_scale) * drawableSpinner.Progress;
-
-            fill.Scale = new Vector2((float)Interpolation.Lerp(fill.Scale.X, targetScale, Math.Clamp(Math.Abs(Time.Elapsed) / 100, 0, 1)));
-            mainContainer.Rotation = drawableSpinner.RotationTracker.Rotation;
-        }
     }
 }

From 86784e30ad4cea26f205370fc5c2781ce9802e6e Mon Sep 17 00:00:00 2001
From: Dean Herbert <pe@ppy.sh>
Date: Fri, 31 Jul 2020 09:54:30 +0900
Subject: [PATCH 03/12] Fix spacing

---
 .../Objects/Drawables/Pieces/DefaultSpinnerDisc.cs               | 1 -
 1 file changed, 1 deletion(-)

diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/DefaultSpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/DefaultSpinnerDisc.cs
index 81dea8d1c1..79bfeedd07 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/DefaultSpinnerDisc.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/DefaultSpinnerDisc.cs
@@ -178,6 +178,5 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
                 return true;
             }
         }
-
     }
 }

From fb74195d83be6b7361740e3584732a52c8795622 Mon Sep 17 00:00:00 2001
From: Dean Herbert <pe@ppy.sh>
Date: Fri, 31 Jul 2020 10:43:54 +0900
Subject: [PATCH 04/12] Move InputManager implementation to base skinnable test
 scene class

---
 .../OsuSkinnableTestScene.cs                      | 15 +++++++++++++++
 osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs    | 14 --------------
 osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs   |  2 --
 3 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/osu.Game.Rulesets.Osu.Tests/OsuSkinnableTestScene.cs b/osu.Game.Rulesets.Osu.Tests/OsuSkinnableTestScene.cs
index a0a38fc47b..cad98185ce 100644
--- a/osu.Game.Rulesets.Osu.Tests/OsuSkinnableTestScene.cs
+++ b/osu.Game.Rulesets.Osu.Tests/OsuSkinnableTestScene.cs
@@ -1,12 +1,27 @@
 // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
 // See the LICENCE file in the repository root for full licence text.
 
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
 using osu.Game.Tests.Visual;
 
 namespace osu.Game.Rulesets.Osu.Tests
 {
     public abstract class OsuSkinnableTestScene : SkinnableTestScene
     {
+        private Container content;
+
+        protected override Container<Drawable> Content
+        {
+            get
+            {
+                if (content == null)
+                    base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 }));
+
+                return content;
+            }
+        }
+
         protected override Ruleset CreateRulesetForSkinProvider() => new OsuRuleset();
     }
 }
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs
index a9404f665a..6a689a1f80 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs
@@ -3,7 +3,6 @@
 
 using System.Collections.Generic;
 using osu.Framework.Graphics;
-using osu.Framework.Graphics.Containers;
 using osu.Game.Audio;
 using osu.Game.Beatmaps;
 using osu.Game.Beatmaps.ControlPoints;
@@ -26,19 +25,6 @@ namespace osu.Game.Rulesets.Osu.Tests
     [TestFixture]
     public class TestSceneSlider : OsuSkinnableTestScene
     {
-        private Container content;
-
-        protected override Container<Drawable> Content
-        {
-            get
-            {
-                if (content == null)
-                    base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 }));
-
-                return content;
-            }
-        }
-
         private int depthIndex;
 
         public TestSceneSlider()
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs
index 65b338882e..b57561f3e1 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs
@@ -19,8 +19,6 @@ namespace osu.Game.Rulesets.Osu.Tests
 
         public TestSceneSpinner()
         {
-            //            base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 }));
-
             AddStep("Miss Big", () => SetContents(() => testSingle(2)));
             AddStep("Miss Medium", () => SetContents(() => testSingle(5)));
             AddStep("Miss Small", () => SetContents(() => testSingle(7)));

From 186b452331437ba41ef07d2559b1b28314d89933 Mon Sep 17 00:00:00 2001
From: Dean Herbert <pe@ppy.sh>
Date: Fri, 31 Jul 2020 14:48:56 +0900
Subject: [PATCH 05/12] Apply common multiplication refactor

---
 osu.Game.Rulesets.Osu/Skinning/LegacyNewStyleSpinner.cs | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyNewStyleSpinner.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyNewStyleSpinner.cs
index 618cb0e9ad..72bc3ddc9a 100644
--- a/osu.Game.Rulesets.Osu/Skinning/LegacyNewStyleSpinner.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/LegacyNewStyleSpinner.cs
@@ -93,8 +93,7 @@ namespace osu.Game.Rulesets.Osu.Skinning
             spinningMiddle.Rotation = discTop.Rotation = drawableSpinner.RotationTracker.Rotation;
             discBottom.Rotation = discTop.Rotation / 3;
 
-            Scale = new Vector2(final_scale * 0.8f
-                                + (float)Interpolation.ApplyEasing(Easing.Out, drawableSpinner.Progress) * (final_scale * 0.2f));
+            Scale = new Vector2(final_scale * (0.8f + (float)Interpolation.ApplyEasing(Easing.Out, drawableSpinner.Progress) * 0.2f));
         }
     }
 }

From b361761d869950fd802df2ae551e6819037233da Mon Sep 17 00:00:00 2001
From: smoogipoo <smoogipoo@smgi.me>
Date: Tue, 28 Jul 2020 22:08:10 +0900
Subject: [PATCH 06/12] Add position display in contracted score panels

---
 .../Online/Multiplayer/MultiplayerScore.cs    |  3 +-
 osu.Game/Scoring/ScoreInfo.cs                 |  7 ++++
 .../Contracted/ContractedPanelTopContent.cs   | 37 +++++++++++++++++++
 osu.Game/Screens/Ranking/ScorePanel.cs        |  1 +
 osu.Game/Tests/TestScoreInfo.cs               |  2 +
 5 files changed, 49 insertions(+), 1 deletion(-)
 create mode 100644 osu.Game/Screens/Ranking/Contracted/ContractedPanelTopContent.cs

diff --git a/osu.Game/Online/Multiplayer/MultiplayerScore.cs b/osu.Game/Online/Multiplayer/MultiplayerScore.cs
index 1793ba72ef..8191003aad 100644
--- a/osu.Game/Online/Multiplayer/MultiplayerScore.cs
+++ b/osu.Game/Online/Multiplayer/MultiplayerScore.cs
@@ -80,7 +80,8 @@ namespace osu.Game.Online.Multiplayer
                 Date = EndedAt,
                 Hash = string.Empty, // todo: temporary?
                 Rank = Rank,
-                Mods = Mods?.Select(m => m.ToMod(rulesetInstance)).ToArray() ?? Array.Empty<Mod>()
+                Mods = Mods?.Select(m => m.ToMod(rulesetInstance)).ToArray() ?? Array.Empty<Mod>(),
+                Position = Position,
             };
 
             return scoreInfo;
diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs
index 84c0d5b54e..efcf1737c9 100644
--- a/osu.Game/Scoring/ScoreInfo.cs
+++ b/osu.Game/Scoring/ScoreInfo.cs
@@ -179,6 +179,13 @@ namespace osu.Game.Scoring
         [JsonIgnore]
         public bool DeletePending { get; set; }
 
+        /// <summary>
+        /// The position of this score, starting at 1.
+        /// </summary>
+        [NotMapped]
+        [JsonProperty("position")]
+        public int? Position { get; set; }
+
         [Serializable]
         protected class DeserializedMod : IMod
         {
diff --git a/osu.Game/Screens/Ranking/Contracted/ContractedPanelTopContent.cs b/osu.Game/Screens/Ranking/Contracted/ContractedPanelTopContent.cs
new file mode 100644
index 0000000000..0935ee7fb2
--- /dev/null
+++ b/osu.Game/Screens/Ranking/Contracted/ContractedPanelTopContent.cs
@@ -0,0 +1,37 @@
+// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Game.Graphics;
+using osu.Game.Graphics.Sprites;
+using osu.Game.Scoring;
+
+namespace osu.Game.Screens.Ranking.Contracted
+{
+    public class ContractedPanelTopContent : CompositeDrawable
+    {
+        private readonly ScoreInfo score;
+
+        public ContractedPanelTopContent(ScoreInfo score)
+        {
+            this.score = score;
+
+            RelativeSizeAxes = Axes.Both;
+        }
+
+        [BackgroundDependencyLoader]
+        private void load()
+        {
+            InternalChild = new OsuSpriteText
+            {
+                Anchor = Anchor.TopCentre,
+                Origin = Anchor.TopCentre,
+                Y = 6,
+                Text = score.Position != null ? $"#{score.Position}" : string.Empty,
+                Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold)
+            };
+        }
+    }
+}
diff --git a/osu.Game/Screens/Ranking/ScorePanel.cs b/osu.Game/Screens/Ranking/ScorePanel.cs
index 5da432d5b2..b32da805e4 100644
--- a/osu.Game/Screens/Ranking/ScorePanel.cs
+++ b/osu.Game/Screens/Ranking/ScorePanel.cs
@@ -213,6 +213,7 @@ namespace osu.Game.Screens.Ranking
                     topLayerBackground.FadeColour(contracted_top_layer_colour, resize_duration, Easing.OutQuint);
                     middleLayerBackground.FadeColour(contracted_middle_layer_colour, resize_duration, Easing.OutQuint);
 
+                    topLayerContentContainer.Add(middleLayerContent = new ContractedPanelTopContent(Score).With(d => d.Alpha = 0));
                     middleLayerContentContainer.Add(topLayerContent = new ContractedPanelMiddleContent(Score).With(d => d.Alpha = 0));
                     break;
             }
diff --git a/osu.Game/Tests/TestScoreInfo.cs b/osu.Game/Tests/TestScoreInfo.cs
index 1193a29d70..31cced6ce4 100644
--- a/osu.Game/Tests/TestScoreInfo.cs
+++ b/osu.Game/Tests/TestScoreInfo.cs
@@ -37,6 +37,8 @@ namespace osu.Game.Tests
             Statistics[HitResult.Meh] = 50;
             Statistics[HitResult.Good] = 100;
             Statistics[HitResult.Great] = 300;
+
+            Position = 1;
         }
 
         private class TestModHardRock : ModHardRock

From 4f3795486d34f0db6e97a04b53ba23d5e1be8048 Mon Sep 17 00:00:00 2001
From: smoogipoo <smoogipoo@smgi.me>
Date: Fri, 31 Jul 2020 22:36:37 +0900
Subject: [PATCH 07/12] Post-process responses to populate positions

---
 .../TestSceneTimeshiftResultsScreen.cs        |  1 +
 .../Multi/Ranking/TimeshiftResultsScreen.cs   | 36 +++++++++++++++++++
 2 files changed, 37 insertions(+)

diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneTimeshiftResultsScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneTimeshiftResultsScreen.cs
index 628d08a314..03fd2b968c 100644
--- a/osu.Game.Tests/Visual/Multiplayer/TestSceneTimeshiftResultsScreen.cs
+++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneTimeshiftResultsScreen.cs
@@ -244,6 +244,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
                 EndedAt = userScore.Date,
                 Passed = userScore.Passed,
                 Rank = userScore.Rank,
+                Position = 200,
                 MaxCombo = userScore.MaxCombo,
                 TotalScore = userScore.TotalScore,
                 User = userScore.User,
diff --git a/osu.Game/Screens/Multi/Ranking/TimeshiftResultsScreen.cs b/osu.Game/Screens/Multi/Ranking/TimeshiftResultsScreen.cs
index e212bd4a82..232f368fb3 100644
--- a/osu.Game/Screens/Multi/Ranking/TimeshiftResultsScreen.cs
+++ b/osu.Game/Screens/Multi/Ranking/TimeshiftResultsScreen.cs
@@ -84,12 +84,18 @@ namespace osu.Game.Screens.Multi.Ranking
                 {
                     allScores.AddRange(userScore.ScoresAround.Higher.Scores);
                     higherScores = userScore.ScoresAround.Higher;
+
+                    Debug.Assert(userScore.Position != null);
+                    setPositions(higherScores, userScore.Position.Value, -1);
                 }
 
                 if (userScore.ScoresAround?.Lower != null)
                 {
                     allScores.AddRange(userScore.ScoresAround.Lower.Scores);
                     lowerScores = userScore.ScoresAround.Lower;
+
+                    Debug.Assert(userScore.Position != null);
+                    setPositions(lowerScores, userScore.Position.Value, 1);
                 }
 
                 performSuccessCallback(scoresCallback, allScores);
@@ -134,9 +140,15 @@ namespace osu.Game.Screens.Multi.Ranking
             indexReq.Success += r =>
             {
                 if (pivot == lowerScores)
+                {
                     lowerScores = r;
+                    setPositions(r, pivot, 1);
+                }
                 else
+                {
                     higherScores = r;
+                    setPositions(r, pivot, -1);
+                }
 
                 performSuccessCallback(scoresCallback, r.Scores, r);
             };
@@ -183,6 +195,30 @@ namespace osu.Game.Screens.Multi.Ranking
                 LeftSpinner.Hide();
         }
 
+        /// <summary>
+        /// Applies positions to all <see cref="MultiplayerScore"/>s from a given pivot.
+        /// </summary>
+        /// <param name="scores">The <see cref="MultiplayerScores"/> to set positions on.</param>
+        /// <param name="pivot">The pivot.</param>
+        /// <param name="increment">The amount to increment the pivot position by for each <see cref="MultiplayerScore"/> in <paramref name="scores"/>.</param>
+        private void setPositions([NotNull] MultiplayerScores scores, [CanBeNull] MultiplayerScores pivot, int increment)
+            => setPositions(scores, pivot?.Scores[^1].Position ?? 0, increment);
+
+        /// <summary>
+        /// Applies positions to all <see cref="MultiplayerScore"/>s from a given pivot.
+        /// </summary>
+        /// <param name="scores">The <see cref="MultiplayerScores"/> to set positions on.</param>
+        /// <param name="pivotPosition">The pivot position.</param>
+        /// <param name="increment">The amount to increment the pivot position by for each <see cref="MultiplayerScore"/> in <paramref name="scores"/>.</param>
+        private void setPositions([NotNull] MultiplayerScores scores, int pivotPosition, int increment)
+        {
+            foreach (var s in scores.Scores)
+            {
+                pivotPosition += increment;
+                s.Position = pivotPosition;
+            }
+        }
+
         private class PanelListLoadingSpinner : LoadingSpinner
         {
             private readonly ScorePanelList list;

From 308f8bf9bf1b5eb7a929d8f1a19c0746d908bbed Mon Sep 17 00:00:00 2001
From: smoogipoo <smoogipoo@smgi.me>
Date: Fri, 31 Jul 2020 23:11:42 +0900
Subject: [PATCH 08/12] Fix inverted naming

---
 osu.Game/Screens/Ranking/ScorePanel.cs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/osu.Game/Screens/Ranking/ScorePanel.cs b/osu.Game/Screens/Ranking/ScorePanel.cs
index ae55f6e0ae..1904da7094 100644
--- a/osu.Game/Screens/Ranking/ScorePanel.cs
+++ b/osu.Game/Screens/Ranking/ScorePanel.cs
@@ -203,8 +203,8 @@ namespace osu.Game.Screens.Ranking
                     topLayerBackground.FadeColour(expanded_top_layer_colour, resize_duration, Easing.OutQuint);
                     middleLayerBackground.FadeColour(expanded_middle_layer_colour, resize_duration, Easing.OutQuint);
 
-                    topLayerContentContainer.Add(middleLayerContent = new ExpandedPanelTopContent(Score.User).With(d => d.Alpha = 0));
-                    middleLayerContentContainer.Add(topLayerContent = new ExpandedPanelMiddleContent(Score).With(d => d.Alpha = 0));
+                    topLayerContentContainer.Add(topLayerContent = new ExpandedPanelTopContent(Score.User).With(d => d.Alpha = 0));
+                    middleLayerContentContainer.Add(middleLayerContent = new ExpandedPanelMiddleContent(Score).With(d => d.Alpha = 0));
                     break;
 
                 case PanelState.Contracted:
@@ -213,8 +213,8 @@ namespace osu.Game.Screens.Ranking
                     topLayerBackground.FadeColour(contracted_top_layer_colour, resize_duration, Easing.OutQuint);
                     middleLayerBackground.FadeColour(contracted_middle_layer_colour, resize_duration, Easing.OutQuint);
 
-                    topLayerContentContainer.Add(middleLayerContent = new ContractedPanelTopContent(Score).With(d => d.Alpha = 0));
-                    middleLayerContentContainer.Add(topLayerContent = new ContractedPanelMiddleContent(Score).With(d => d.Alpha = 0));
+                    topLayerContentContainer.Add(topLayerContent = new ContractedPanelTopContent(Score).With(d => d.Alpha = 0));
+                    middleLayerContentContainer.Add(middleLayerContent = new ContractedPanelMiddleContent(Score).With(d => d.Alpha = 0));
                     break;
             }
 

From 04b71a0c7c3fb0420dccfb645944d4687dd4588d Mon Sep 17 00:00:00 2001
From: smoogipoo <smoogipoo@smgi.me>
Date: Fri, 31 Jul 2020 23:16:55 +0900
Subject: [PATCH 09/12] Adjust xmldoc

---
 osu.Game/Screens/Multi/Ranking/TimeshiftResultsScreen.cs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/osu.Game/Screens/Multi/Ranking/TimeshiftResultsScreen.cs b/osu.Game/Screens/Multi/Ranking/TimeshiftResultsScreen.cs
index 232f368fb3..8da6a530a8 100644
--- a/osu.Game/Screens/Multi/Ranking/TimeshiftResultsScreen.cs
+++ b/osu.Game/Screens/Multi/Ranking/TimeshiftResultsScreen.cs
@@ -196,7 +196,7 @@ namespace osu.Game.Screens.Multi.Ranking
         }
 
         /// <summary>
-        /// Applies positions to all <see cref="MultiplayerScore"/>s from a given pivot.
+        /// Applies positions to all <see cref="MultiplayerScore"/>s referenced to a given pivot.
         /// </summary>
         /// <param name="scores">The <see cref="MultiplayerScores"/> to set positions on.</param>
         /// <param name="pivot">The pivot.</param>
@@ -205,7 +205,7 @@ namespace osu.Game.Screens.Multi.Ranking
             => setPositions(scores, pivot?.Scores[^1].Position ?? 0, increment);
 
         /// <summary>
-        /// Applies positions to all <see cref="MultiplayerScore"/>s from a given pivot.
+        /// Applies positions to all <see cref="MultiplayerScore"/>s referenced to a given pivot.
         /// </summary>
         /// <param name="scores">The <see cref="MultiplayerScores"/> to set positions on.</param>
         /// <param name="pivotPosition">The pivot position.</param>

From 9e244be4890aacc1ff0c1534fcd860817e507eae Mon Sep 17 00:00:00 2001
From: Dean Herbert <pe@ppy.sh>
Date: Sat, 1 Aug 2020 00:05:04 +0900
Subject: [PATCH 10/12] Use better conditional for choosing which spinner type
 to use

Co-authored-by: Dan Balasescu <smoogipoo@smgi.me>
---
 osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs
index 44f431d6f7..81d1d05b66 100644
--- a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs
@@ -104,9 +104,11 @@ namespace osu.Game.Rulesets.Osu.Skinning
                         };
 
                 case OsuSkinComponents.SpinnerBody:
-                    if (Source.GetTexture("spinner-top") != null)
+                    bool hasBackground = Source.GetTexture("spinner-background") != null;
+
+                    if (Source.GetTexture("spinner-top") != null && !hasBackground)
                         return new LegacyNewStyleSpinner();
-                    else if (Source.GetTexture("spinner-background") != null)
+                    else if (hasBackground)
                         return new LegacyOldStyleSpinner();
 
                     return null;

From bb01ee5be953d6a241830f8a08e3a029298f9e25 Mon Sep 17 00:00:00 2001
From: Dean Herbert <pe@ppy.sh>
Date: Sat, 1 Aug 2020 00:27:00 +0900
Subject: [PATCH 11/12] Fix trackign alpha not being applied

---
 .../Drawables/Pieces/DefaultSpinnerDisc.cs    | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/DefaultSpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/DefaultSpinnerDisc.cs
index 79bfeedd07..eba5d869c0 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/DefaultSpinnerDisc.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/DefaultSpinnerDisc.cs
@@ -100,13 +100,20 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
         {
             base.Update();
 
-            if (drawableSpinner.RotationTracker.Complete.Value && checkNewRotationCount)
+            if (drawableSpinner.RotationTracker.Complete.Value)
             {
-                fill.FinishTransforms(false, nameof(Alpha));
-                fill
-                    .FadeTo(tracking_alpha + 0.2f, 60, Easing.OutExpo)
-                    .Then()
-                    .FadeTo(tracking_alpha, 250, Easing.OutQuint);
+                if (checkNewRotationCount)
+                {
+                    fill.FinishTransforms(false, nameof(Alpha));
+                    fill
+                        .FadeTo(tracking_alpha + 0.2f, 60, Easing.OutExpo)
+                        .Then()
+                        .FadeTo(tracking_alpha, 250, Easing.OutQuint);
+                }
+            }
+            else
+            {
+                fill.Alpha = (float)Interpolation.Damp(fill.Alpha, drawableSpinner.RotationTracker.Tracking ? tracking_alpha : idle_alpha, 0.98f, (float)Clock.ElapsedFrameTime);
             }
 
             const float initial_scale = 0.2f;

From 180afff80515bc09a0833d1acb45a3bac243a958 Mon Sep 17 00:00:00 2001
From: Dean Herbert <pe@ppy.sh>
Date: Sat, 1 Aug 2020 00:39:04 +0900
Subject: [PATCH 12/12] Ensure damp is always positive exponent

---
 .../Objects/Drawables/Pieces/DefaultSpinnerDisc.cs              | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/DefaultSpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/DefaultSpinnerDisc.cs
index eba5d869c0..dfb692eba9 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/DefaultSpinnerDisc.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/DefaultSpinnerDisc.cs
@@ -113,7 +113,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
             }
             else
             {
-                fill.Alpha = (float)Interpolation.Damp(fill.Alpha, drawableSpinner.RotationTracker.Tracking ? tracking_alpha : idle_alpha, 0.98f, (float)Clock.ElapsedFrameTime);
+                fill.Alpha = (float)Interpolation.Damp(fill.Alpha, drawableSpinner.RotationTracker.Tracking ? tracking_alpha : idle_alpha, 0.98f, (float)Math.Abs(Clock.ElapsedFrameTime));
             }
 
             const float initial_scale = 0.2f;