From d773eb2c22c804e97977298fb57bc3cd265a7530 Mon Sep 17 00:00:00 2001 From: mcendu Date: Wed, 5 Feb 2020 14:05:12 +0800 Subject: [PATCH 01/77] refactor rotation logic to use explicit delta value --- .../Objects/Drawables/Pieces/SpinnerDisc.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs index e3dd2b1b4f..91e49e0264 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs @@ -98,6 +98,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces bool validAndTracking = tracking && spinner.StartTime <= Time.Current && spinner.EndTime > Time.Current; + var delta = thisAngle - lastAngle; + if (validAndTracking) { if (!rotationTransferred) @@ -106,13 +108,19 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces rotationTransferred = true; } - if (thisAngle - lastAngle > 180) + if (delta > 180) + { lastAngle += 360; - else if (lastAngle - thisAngle > 180) + delta -= 360; + } + else if (-delta > 180) + { lastAngle -= 360; + delta += 360; + } - currentRotation += thisAngle - lastAngle; - RotationAbsolute += Math.Abs(thisAngle - lastAngle) * Math.Sign(Clock.ElapsedFrameTime); + currentRotation += delta; + RotationAbsolute += Math.Abs(delta) * Math.Sign(Clock.ElapsedFrameTime); } lastAngle = thisAngle; From 9f79713fb3a7b14e4f502d96b9b5bf9e417342cc Mon Sep 17 00:00:00 2001 From: mcendu Date: Wed, 5 Feb 2020 14:23:59 +0800 Subject: [PATCH 02/77] move rotation logic to its own method --- .../Objects/Drawables/Pieces/SpinnerDisc.cs | 49 ++++++++++--------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs index 91e49e0264..58132635ca 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs @@ -96,32 +96,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces var thisAngle = -MathUtils.RadiansToDegrees(MathF.Atan2(mousePosition.X - DrawSize.X / 2, mousePosition.Y - DrawSize.Y / 2)); - bool validAndTracking = tracking && spinner.StartTime <= Time.Current && spinner.EndTime > Time.Current; - var delta = thisAngle - lastAngle; + bool validAndTracking = tracking && spinner.StartTime <= Time.Current && spinner.EndTime > Time.Current; + if (validAndTracking) - { - if (!rotationTransferred) - { - currentRotation = Rotation * 2; - rotationTransferred = true; - } - - if (delta > 180) - { - lastAngle += 360; - delta -= 360; - } - else if (-delta > 180) - { - lastAngle -= 360; - delta += 360; - } - - currentRotation += delta; - RotationAbsolute += Math.Abs(delta) * Math.Sign(Clock.ElapsedFrameTime); - } + Rotate(delta); lastAngle = thisAngle; @@ -136,5 +116,28 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces this.RotateTo(currentRotation / 2, validAndTracking ? 500 : 1500, Easing.OutExpo); } + + public void Rotate(float angle) + { + if (!rotationTransferred) + { + currentRotation = Rotation * 2; + rotationTransferred = true; + } + + if (angle > 180) + { + lastAngle += 360; + angle -= 360; + } + else if (-angle > 180) + { + lastAngle -= 360; + angle += 360; + } + + currentRotation += angle; + RotationAbsolute += Math.Abs(angle) * Math.Sign(Clock.ElapsedFrameTime); + } } } From 25a930c43877007279a2503e34b4fa7702860f21 Mon Sep 17 00:00:00 2001 From: mcendu Date: Sat, 8 Feb 2020 08:59:35 +0800 Subject: [PATCH 03/77] Implement OsuModSpunOut --- osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs | 17 ++++++++++++++- .../Objects/Drawables/DrawableSpinner.cs | 2 +- .../Objects/Drawables/Pieces/SpinnerDisc.cs | 21 ++++++++++++------- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs index 1cdcddbd33..1ef53542a8 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs @@ -2,13 +2,17 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Osu.Objects.Drawables; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModSpunOut : Mod + public class OsuModSpunOut : Mod, IApplicableToDrawableHitObjects { public override string Name => "Spun Out"; public override string Acronym => "SO"; @@ -18,5 +22,16 @@ namespace osu.Game.Rulesets.Osu.Mods public override double ScoreMultiplier => 0.9; public override bool Ranked => true; public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(OsuModAutopilot) }; + + public void ApplyToDrawableHitObjects(IEnumerable drawables) + { + foreach (var hitObject in drawables) + { + if (hitObject is DrawableSpinner spinner) + { + spinner.Disc.AutoSpin = true; + } + } + } } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index de11ab6419..b5265babd9 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -177,7 +177,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void Update() { Disc.Tracking = OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false; - if (!SpmCounter.IsPresent && Disc.Tracking) + if (!SpmCounter.IsPresent && (Disc.Tracking || Disc.AutoSpin)) SpmCounter.FadeIn(HitObject.TimeFadeIn); base.Update(); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs index 58132635ca..e042a3791d 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs @@ -73,6 +73,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces } } + public bool AutoSpin { get; set; } = false; + protected override bool OnMouseMove(MouseMoveEvent e) { mousePosition = Parent.ToLocalSpace(e.ScreenSpaceMousePosition); @@ -94,16 +96,21 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { base.Update(); - var thisAngle = -MathUtils.RadiansToDegrees(MathF.Atan2(mousePosition.X - DrawSize.X / 2, mousePosition.Y - DrawSize.Y / 2)); + bool valid = spinner.StartTime <= Time.Current && spinner.EndTime > Time.Current; - var delta = thisAngle - lastAngle; + if (valid && AutoSpin) + Rotate(6f); + else + { + var thisAngle = -MathUtils.RadiansToDegrees(MathF.Atan2(mousePosition.X - DrawSize.X / 2, mousePosition.Y - DrawSize.Y / 2)); - bool validAndTracking = tracking && spinner.StartTime <= Time.Current && spinner.EndTime > Time.Current; + var delta = thisAngle - lastAngle; - if (validAndTracking) - Rotate(delta); + if (valid && tracking) + Rotate(delta); - lastAngle = thisAngle; + lastAngle = thisAngle; + } if (Complete && updateCompleteTick()) { @@ -114,7 +121,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces .FadeTo(tracking_alpha, 250, Easing.OutQuint); } - this.RotateTo(currentRotation / 2, validAndTracking ? 500 : 1500, Easing.OutExpo); + this.RotateTo(currentRotation / 2, 500, Easing.OutExpo); } public void Rotate(float angle) From 0dee6ceab74a3826c2705d55e50921f58d38dc52 Mon Sep 17 00:00:00 2001 From: mcendu Date: Sat, 8 Feb 2020 09:06:29 +0800 Subject: [PATCH 04/77] Remove unnecessary using --- osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs index 1ef53542a8..f1a1e47118 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables; From 4d9232a895ad4dd12e43cc0c9fc0b519a62091a2 Mon Sep 17 00:00:00 2001 From: mcendu Date: Sat, 8 Feb 2020 09:51:32 +0800 Subject: [PATCH 05/77] Move autospin logic to mods --- osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs | 24 +++++++++++++++++-- .../Objects/Drawables/DrawableSpinner.cs | 2 +- .../Objects/Drawables/Pieces/SpinnerDisc.cs | 21 ++++++---------- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs index f1a1e47118..07c10966d3 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs @@ -3,15 +3,18 @@ using System; using System.Collections.Generic; +using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables; +using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; +using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModSpunOut : Mod, IApplicableToDrawableHitObjects + public class OsuModSpunOut : Mod, IApplicableToDrawableHitObjects, IUpdatableByPlayfield { public override string Name => "Spun Out"; public override string Acronym => "SO"; @@ -22,15 +25,32 @@ namespace osu.Game.Rulesets.Osu.Mods public override bool Ranked => true; public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(OsuModAutopilot) }; + private double lastFrameTime; + private double frameDelay; + public void ApplyToDrawableHitObjects(IEnumerable drawables) { foreach (var hitObject in drawables) { if (hitObject is DrawableSpinner spinner) { - spinner.Disc.AutoSpin = true; + spinner.Disc.Trackable = false; + spinner.Disc.OnUpdate += d => + { + if (d is SpinnerDisc s) + { + if (s.Valid) + s.Rotate((float)frameDelay); + } + }; } } } + + public void Update(Playfield playfield) + { + frameDelay = playfield.Time.Current - lastFrameTime; + lastFrameTime = playfield.Time.Current; + } } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index b5265babd9..2930134d4f 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -177,7 +177,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void Update() { Disc.Tracking = OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false; - if (!SpmCounter.IsPresent && (Disc.Tracking || Disc.AutoSpin)) + if (!SpmCounter.IsPresent && (Disc.Tracking || !Disc.Trackable)) SpmCounter.FadeIn(HitObject.TimeFadeIn); base.Update(); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs index e042a3791d..9a9d915cfe 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs @@ -73,7 +73,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces } } - public bool AutoSpin { get; set; } = false; + public bool Valid => spinner.StartTime <= Time.Current && spinner.EndTime > Time.Current; + public bool Trackable { get; set; } protected override bool OnMouseMove(MouseMoveEvent e) { @@ -95,22 +96,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces protected override void Update() { base.Update(); + var thisAngle = -MathUtils.RadiansToDegrees(MathF.Atan2(mousePosition.X - DrawSize.X / 2, mousePosition.Y - DrawSize.Y / 2)); - bool valid = spinner.StartTime <= Time.Current && spinner.EndTime > Time.Current; + var delta = thisAngle - lastAngle; - if (valid && AutoSpin) - Rotate(6f); - else - { - var thisAngle = -MathUtils.RadiansToDegrees(MathF.Atan2(mousePosition.X - DrawSize.X / 2, mousePosition.Y - DrawSize.Y / 2)); + if (Valid && tracking && Trackable) + Rotate(delta); - var delta = thisAngle - lastAngle; - - if (valid && tracking) - Rotate(delta); - - lastAngle = thisAngle; - } + lastAngle = thisAngle; if (Complete && updateCompleteTick()) { From ca09ae6849b94cdc2ef15c4b770212d1f8a92138 Mon Sep 17 00:00:00 2001 From: mcendu Date: Sat, 8 Feb 2020 09:53:20 +0800 Subject: [PATCH 06/77] fix formatting --- osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs index 07c10966d3..c74e4e3e70 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs @@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Osu.Mods if (d is SpinnerDisc s) { if (s.Valid) - s.Rotate((float)frameDelay); + s.Rotate((float)frameDelay); } }; } From 204c2f0bde7cbd36563842d0f4831a65d2308fcc Mon Sep 17 00:00:00 2001 From: mcendu Date: Sat, 8 Feb 2020 10:16:04 +0800 Subject: [PATCH 07/77] add tests --- osu.Game.Rulesets.Osu.Tests/Class1.cs | 23 +++++++++++++++++++++ osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs | 1 - 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Rulesets.Osu.Tests/Class1.cs diff --git a/osu.Game.Rulesets.Osu.Tests/Class1.cs b/osu.Game.Rulesets.Osu.Tests/Class1.cs new file mode 100644 index 0000000000..402c14fa64 --- /dev/null +++ b/osu.Game.Rulesets.Osu.Tests/Class1.cs @@ -0,0 +1,23 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using osu.Game.Rulesets.Osu.Mods; + +namespace osu.Game.Rulesets.Osu.Tests +{ + [TestFixture] + public class TestSceneSpinnerSpunOut : TestSceneSpinner + { + public override IReadOnlyList RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(OsuModSpunOut) }).ToList(); + + [SetUp] + public void SetUp() => Schedule(() => + { + SelectedMods.Value = new[] { new OsuModHidden() }; + }); + } +} diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs index c74e4e3e70..eb49742db6 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Rulesets.Mods; From 715608c7985c2366905751be856b3984b6cf94cd Mon Sep 17 00:00:00 2001 From: mcendu Date: Sat, 8 Feb 2020 10:49:49 +0800 Subject: [PATCH 08/77] Fix test applying incorrect mod --- .../{Class1.cs => TestSceneSpinnerSpunOut.cs} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename osu.Game.Rulesets.Osu.Tests/{Class1.cs => TestSceneSpinnerSpunOut.cs} (90%) diff --git a/osu.Game.Rulesets.Osu.Tests/Class1.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerSpunOut.cs similarity index 90% rename from osu.Game.Rulesets.Osu.Tests/Class1.cs rename to osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerSpunOut.cs index 402c14fa64..a6c09691c7 100644 --- a/osu.Game.Rulesets.Osu.Tests/Class1.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerSpunOut.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Osu.Tests [SetUp] public void SetUp() => Schedule(() => { - SelectedMods.Value = new[] { new OsuModHidden() }; + SelectedMods.Value = new[] { new OsuModSpunOut() }; }); } } From efa95ecebb66fe587c6c2e9862c384586b29dbf9 Mon Sep 17 00:00:00 2001 From: mcendu Date: Sat, 8 Feb 2020 10:52:59 +0800 Subject: [PATCH 09/77] fix spinner unspinnable --- osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs index 9a9d915cfe..4e2758b3d5 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs @@ -74,7 +74,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces } public bool Valid => spinner.StartTime <= Time.Current && spinner.EndTime > Time.Current; - public bool Trackable { get; set; } + public bool Trackable { get; set; } = true; protected override bool OnMouseMove(MouseMoveEvent e) { From fbdf07dc201c87140c00be1121d227d003c3dd1e Mon Sep 17 00:00:00 2001 From: mcendu Date: Sat, 8 Feb 2020 11:06:37 +0800 Subject: [PATCH 10/77] Correct speed of spun out --- osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs index eb49742db6..16fc7646c2 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Osu.Mods if (d is SpinnerDisc s) { if (s.Valid) - s.Rotate((float)frameDelay); + s.Rotate(180 / MathF.PI * ((float)frameDelay) / 40); } }; } From d821b6a15aee2f2d0d7559828a6a04752546ddba Mon Sep 17 00:00:00 2001 From: mcendu Date: Sat, 8 Feb 2020 11:16:48 +0800 Subject: [PATCH 11/77] make frameDelay a float --- osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs index 16fc7646c2..1832910e71 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(OsuModAutopilot) }; private double lastFrameTime; - private double frameDelay; + private float frameDelay; public void ApplyToDrawableHitObjects(IEnumerable drawables) { @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Osu.Mods if (d is SpinnerDisc s) { if (s.Valid) - s.Rotate(180 / MathF.PI * ((float)frameDelay) / 40); + s.Rotate(180 / MathF.PI * frameDelay / 40); } }; } @@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Osu.Mods public void Update(Playfield playfield) { - frameDelay = playfield.Time.Current - lastFrameTime; + frameDelay = (float)(playfield.Time.Current - lastFrameTime); lastFrameTime = playfield.Time.Current; } } From 2d672159317783629f3e5334621fc7341942531e Mon Sep 17 00:00:00 2001 From: mcendu Date: Sat, 8 Feb 2020 12:07:21 +0800 Subject: [PATCH 12/77] make target practice subject of unimplemented mod test --- .../Visual/UserInterface/TestSceneModSelectOverlay.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs index 12ee4ceb2e..1e18e18631 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs @@ -97,7 +97,7 @@ namespace osu.Game.Tests.Visual.UserInterface var doubleTimeMod = harderMods.OfType().FirstOrDefault(m => m.Mods.Any(a => a is OsuModDoubleTime)); - var spunOutMod = easierMods.FirstOrDefault(m => m is OsuModSpunOut); + var targetMod = easierMods.FirstOrDefault(m => m is OsuModTarget); var easy = easierMods.FirstOrDefault(m => m is OsuModEasy); var hardRock = harderMods.FirstOrDefault(m => m is OsuModHardRock); @@ -109,7 +109,7 @@ namespace osu.Game.Tests.Visual.UserInterface testMultiplierTextColour(noFailMod, () => modSelect.LowMultiplierColour); testMultiplierTextColour(hiddenMod, () => modSelect.HighMultiplierColour); - testUnimplementedMod(spunOutMod); + testUnimplementedMod(targetMod); } [Test] From a4637a24a6c6d57a23f18db87ac954577ff9e1c3 Mon Sep 17 00:00:00 2001 From: mcendu Date: Sat, 8 Feb 2020 12:08:44 +0800 Subject: [PATCH 13/77] fix test scene crash --- .../Visual/UserInterface/TestSceneModSelectOverlay.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs index 1e18e18631..034324aadd 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs @@ -91,13 +91,14 @@ namespace osu.Game.Tests.Visual.UserInterface var easierMods = osu.GetModsFor(ModType.DifficultyReduction); var harderMods = osu.GetModsFor(ModType.DifficultyIncrease); + var conversionMods = osu.GetModsFor(ModType.Conversion); var noFailMod = osu.GetModsFor(ModType.DifficultyReduction).FirstOrDefault(m => m is OsuModNoFail); var hiddenMod = harderMods.FirstOrDefault(m => m is OsuModHidden); var doubleTimeMod = harderMods.OfType().FirstOrDefault(m => m.Mods.Any(a => a is OsuModDoubleTime)); - var targetMod = easierMods.FirstOrDefault(m => m is OsuModTarget); + var targetMod = conversionMods.FirstOrDefault(m => m is OsuModTarget); var easy = easierMods.FirstOrDefault(m => m is OsuModEasy); var hardRock = harderMods.FirstOrDefault(m => m is OsuModHardRock); From 8e20e641f440d4a2dff2c49b60816b0021a1cd55 Mon Sep 17 00:00:00 2001 From: mcendu Date: Sun, 9 Feb 2020 13:33:43 +0800 Subject: [PATCH 14/77] move spun out to automation --- osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs index b794f5e22e..c4890afe36 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override string Name => "Spun Out"; public override string Acronym => "SO"; public override IconUsage? Icon => OsuIcon.ModSpunout; - public override ModType Type => ModType.DifficultyReduction; + public override ModType Type => ModType.Automation; public override string Description => @"Spinners will be automatically completed."; public override double ScoreMultiplier => 0.9; public override bool Ranked => true; From 83c67dc155518d1a9b2432432e0a4f250c370544 Mon Sep 17 00:00:00 2001 From: mcendu Date: Sun, 9 Feb 2020 13:34:35 +0800 Subject: [PATCH 15/77] move spun out to automation --- osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 148869f5e8..ed73a54815 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -113,7 +113,6 @@ namespace osu.Game.Rulesets.Osu new OsuModEasy(), new OsuModNoFail(), new MultiMod(new OsuModHalfTime(), new OsuModDaycore()), - new OsuModSpunOut(), }; case ModType.DifficultyIncrease: @@ -139,6 +138,7 @@ namespace osu.Game.Rulesets.Osu new MultiMod(new OsuModAutoplay(), new OsuModCinema()), new OsuModRelax(), new OsuModAutopilot(), + new OsuModSpunOut(), }; case ModType.Fun: From c9520b299a40cd23d228dd62b38c87a1ee3b9632 Mon Sep 17 00:00:00 2001 From: mcendu Date: Sun, 9 Feb 2020 13:35:36 +0800 Subject: [PATCH 16/77] replace if check with variable decl --- osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs index c4890afe36..6a2610ae05 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs @@ -36,11 +36,10 @@ namespace osu.Game.Rulesets.Osu.Mods spinner.Disc.Trackable = false; spinner.Disc.OnUpdate += d => { - if (d is SpinnerDisc s) - { - if (s.Valid) - s.Rotate(180 / MathF.PI * frameDelay / 40); - } + var s = d as SpinnerDisc; + + if (s.Valid) + s.Rotate(180 / MathF.PI * frameDelay / 40); }; } } From d314b38699d1211d034cc896a478b809d8aa15e5 Mon Sep 17 00:00:00 2001 From: mcendu Date: Sun, 9 Feb 2020 13:46:06 +0800 Subject: [PATCH 17/77] rename trackable to enabled and cleanup code --- osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs | 2 +- .../Objects/Drawables/DrawableSpinner.cs | 2 +- .../Objects/Drawables/Pieces/SpinnerDisc.cs | 9 +++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs index 6a2610ae05..e02ded979f 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Osu.Mods { if (hitObject is DrawableSpinner spinner) { - spinner.Disc.Trackable = false; + spinner.Disc.Enabled = false; spinner.Disc.OnUpdate += d => { var s = d as SpinnerDisc; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 2930134d4f..de11ab6419 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -177,7 +177,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void Update() { Disc.Tracking = OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false; - if (!SpmCounter.IsPresent && (Disc.Tracking || !Disc.Trackable)) + if (!SpmCounter.IsPresent && Disc.Tracking) SpmCounter.FadeIn(HitObject.TimeFadeIn); base.Update(); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs index 4e2758b3d5..b062fc5afa 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs @@ -50,9 +50,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces get => tracking; set { - if (value == tracking) return; + if ((Enabled && value) == tracking) return; - tracking = value; + tracking = Enabled && value; background.FadeTo(tracking ? tracking_alpha : idle_alpha, 100); } @@ -74,7 +74,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces } public bool Valid => spinner.StartTime <= Time.Current && spinner.EndTime > Time.Current; - public bool Trackable { get; set; } = true; + + public bool Enabled { get; set; } = true; protected override bool OnMouseMove(MouseMoveEvent e) { @@ -100,7 +101,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces var delta = thisAngle - lastAngle; - if (Valid && tracking && Trackable) + if (Valid && tracking) Rotate(delta); lastAngle = thisAngle; From 68873830aadfde6495812766820c3b9b78dc94d3 Mon Sep 17 00:00:00 2001 From: mcendu Date: Sun, 9 Feb 2020 13:49:08 +0800 Subject: [PATCH 18/77] make spm counter show up automatically with spun out --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index de11ab6419..752bd7be85 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -177,7 +177,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void Update() { Disc.Tracking = OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false; - if (!SpmCounter.IsPresent && Disc.Tracking) + if (!SpmCounter.IsPresent && (Disc.Tracking || !Disc.Enabled)) SpmCounter.FadeIn(HitObject.TimeFadeIn); base.Update(); From 596f4f7d2e6c62c7a4c3fa43ce161c5b71c388d8 Mon Sep 17 00:00:00 2001 From: mcendu Date: Sun, 9 Feb 2020 14:54:46 +0800 Subject: [PATCH 19/77] use spinner's clock to drive spinner --- osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs index e02ded979f..084be40672 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs @@ -13,7 +13,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModSpunOut : Mod, IApplicableToDrawableHitObjects, IUpdatableByPlayfield + public class OsuModSpunOut : Mod, IApplicableToDrawableHitObjects { public override string Name => "Spun Out"; public override string Acronym => "SO"; @@ -24,9 +24,6 @@ namespace osu.Game.Rulesets.Osu.Mods public override bool Ranked => true; public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(OsuModAutopilot) }; - private double lastFrameTime; - private float frameDelay; - public void ApplyToDrawableHitObjects(IEnumerable drawables) { foreach (var hitObject in drawables) @@ -39,16 +36,10 @@ namespace osu.Game.Rulesets.Osu.Mods var s = d as SpinnerDisc; if (s.Valid) - s.Rotate(180 / MathF.PI * frameDelay / 40); + s.Rotate(180 / MathF.PI * (float)s.Clock.ElapsedFrameTime / 40); }; } } } - - public void Update(Playfield playfield) - { - frameDelay = (float)(playfield.Time.Current - lastFrameTime); - lastFrameTime = playfield.Time.Current; - } } } From e78d94d4692d02ed5843e5f23882c660e23099d1 Mon Sep 17 00:00:00 2001 From: mcendu Date: Sun, 9 Feb 2020 14:56:47 +0800 Subject: [PATCH 20/77] return to use if for casting --- osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs index 084be40672..2c1d1362a6 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs @@ -33,9 +33,7 @@ namespace osu.Game.Rulesets.Osu.Mods spinner.Disc.Enabled = false; spinner.Disc.OnUpdate += d => { - var s = d as SpinnerDisc; - - if (s.Valid) + if (d is SpinnerDisc s && s.Valid) s.Rotate(180 / MathF.PI * (float)s.Clock.ElapsedFrameTime / 40); }; } From 10a1948720b15e8de61149ff7abfcad89d5eca8d Mon Sep 17 00:00:00 2001 From: mcendu Date: Sun, 9 Feb 2020 16:19:21 +0800 Subject: [PATCH 21/77] remove using directive --- osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs index 2c1d1362a6..d56e39b588 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs @@ -9,7 +9,6 @@ using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; -using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu.Mods { From 9aa5db88d4baed09dcda72005845cf2dad27e9f0 Mon Sep 17 00:00:00 2001 From: mcendu Date: Mon, 10 Feb 2020 14:14:04 +0800 Subject: [PATCH 22/77] move auto fade in to mod --- osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs | 13 +++++++++---- .../Objects/Drawables/DrawableSpinner.cs | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs index d56e39b588..670f4a2cd8 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs @@ -3,12 +3,12 @@ using System; using System.Collections.Generic; +using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables; -using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; namespace osu.Game.Rulesets.Osu.Mods { @@ -30,10 +30,15 @@ namespace osu.Game.Rulesets.Osu.Mods if (hitObject is DrawableSpinner spinner) { spinner.Disc.Enabled = false; - spinner.Disc.OnUpdate += d => + spinner.OnUpdate += d => { - if (d is SpinnerDisc s && s.Valid) - s.Rotate(180 / MathF.PI * (float)s.Clock.ElapsedFrameTime / 40); + if (d is DrawableSpinner s) + { + if (s.Disc.Valid) + s.Disc.Rotate(180 / MathF.PI * (float)s.Clock.ElapsedFrameTime / 40); + if (!s.SpmCounter.IsPresent) + s.SpmCounter.FadeIn(s.HitObject.TimeFadeIn); + } }; } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 752bd7be85..de11ab6419 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -177,7 +177,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void Update() { Disc.Tracking = OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false; - if (!SpmCounter.IsPresent && (Disc.Tracking || !Disc.Enabled)) + if (!SpmCounter.IsPresent && Disc.Tracking) SpmCounter.FadeIn(HitObject.TimeFadeIn); base.Update(); From 403c03841d1d3497dfda7ffc3af8f2fb72d2daba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 10 Feb 2020 21:39:45 +0100 Subject: [PATCH 23/77] Decouple test scene & add assertions --- .../TestSceneSpinnerSpunOut.cs | 51 ++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerSpunOut.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerSpunOut.cs index a6c09691c7..e406f9ddff 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerSpunOut.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerSpunOut.cs @@ -5,19 +5,66 @@ using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; +using osu.Framework.Graphics; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; +using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Osu.Objects.Drawables; +using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; +using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Osu.Tests { [TestFixture] - public class TestSceneSpinnerSpunOut : TestSceneSpinner + public class TestSceneSpinnerSpunOut : OsuTestScene { - public override IReadOnlyList RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(OsuModSpunOut) }).ToList(); + public override IReadOnlyList RequiredTypes => new[] + { + typeof(SpinnerDisc), + typeof(DrawableSpinner), + typeof(DrawableOsuHitObject), + typeof(OsuModSpunOut) + }; [SetUp] public void SetUp() => Schedule(() => { SelectedMods.Value = new[] { new OsuModSpunOut() }; }); + + [Test] + public void TestSpunOut() + { + DrawableSpinner spinner = null; + + AddStep("create spinner", () => spinner = createSpinner()); + + AddUntilStep("wait for end", () => Time.Current > spinner.LifetimeEnd); + + AddAssert("spinner is completed", () => spinner.Progress >= 1); + } + + private DrawableSpinner createSpinner() + { + var spinner = new Spinner + { + StartTime = Time.Current + 500, + EndTime = Time.Current + 2500 + }; + spinner.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + + var drawableSpinner = new DrawableSpinner(spinner) + { + Anchor = Anchor.Centre + }; + + foreach (var mod in SelectedMods.Value.OfType()) + mod.ApplyToDrawableHitObjects(new[] { drawableSpinner }); + + Add(drawableSpinner); + return drawableSpinner; + } } } From 686040d8ad7926ad515fcb1bfcf586ca8b1d5d04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 10 Feb 2020 21:42:34 +0100 Subject: [PATCH 24/77] Extract auto-spin logic to method --- osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs | 22 +++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs index 670f4a2cd8..37ef001223 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs @@ -30,18 +30,20 @@ namespace osu.Game.Rulesets.Osu.Mods if (hitObject is DrawableSpinner spinner) { spinner.Disc.Enabled = false; - spinner.OnUpdate += d => - { - if (d is DrawableSpinner s) - { - if (s.Disc.Valid) - s.Disc.Rotate(180 / MathF.PI * (float)s.Clock.ElapsedFrameTime / 40); - if (!s.SpmCounter.IsPresent) - s.SpmCounter.FadeIn(s.HitObject.TimeFadeIn); - } - }; + spinner.OnUpdate += autoSpin; } } } + + private void autoSpin(Drawable drawable) + { + if (drawable is DrawableSpinner spinner) + { + if (spinner.Disc.Valid) + spinner.Disc.Rotate(180 / MathF.PI * (float)spinner.Clock.ElapsedFrameTime / 40); + if (!spinner.SpmCounter.IsPresent) + spinner.SpmCounter.FadeIn(spinner.HitObject.TimeFadeIn); + } + } } } From b6378c7ae22ef88365a604a34289f574d6decae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=9CNate?= Date: Sun, 16 Feb 2020 17:50:52 +0800 Subject: [PATCH 25/77] fix speed * Original /40 is due to documentation error. Co-Authored-By: clayton --- osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs index 37ef001223..30b9c84538 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs @@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Osu.Mods if (drawable is DrawableSpinner spinner) { if (spinner.Disc.Valid) - spinner.Disc.Rotate(180 / MathF.PI * (float)spinner.Clock.ElapsedFrameTime / 40); + spinner.Disc.Rotate(180 / MathF.PI * (float)spinner.Clock.ElapsedFrameTime * 0.03f); if (!spinner.SpmCounter.IsPresent) spinner.SpmCounter.FadeIn(spinner.HitObject.TimeFadeIn); } From e2ea92e21f7d3a6fad4459a8cfdaadbbcfead410 Mon Sep 17 00:00:00 2001 From: mcendu Date: Wed, 4 Mar 2020 13:51:12 +0800 Subject: [PATCH 26/77] Use framework method to convert rad to deg --- osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs index 30b9c84538..49c4e7fa45 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; +using osu.Framework.Utils; using osu.Game.Graphics; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Drawables; @@ -40,7 +41,7 @@ namespace osu.Game.Rulesets.Osu.Mods if (drawable is DrawableSpinner spinner) { if (spinner.Disc.Valid) - spinner.Disc.Rotate(180 / MathF.PI * (float)spinner.Clock.ElapsedFrameTime * 0.03f); + spinner.Disc.Rotate(MathUtils.RadiansToDegrees((float)spinner.Clock.ElapsedFrameTime * 0.03f)); if (!spinner.SpmCounter.IsPresent) spinner.SpmCounter.FadeIn(spinner.HitObject.TimeFadeIn); } From e59d7fee26728e6c281d03bf67ee004c127973de Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Wed, 18 Mar 2020 23:42:14 -0400 Subject: [PATCH 27/77] fix comment grammar --- osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs index 2083671072..c3d1e4c857 100644 --- a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs @@ -79,7 +79,7 @@ namespace osu.Game.Rulesets.Mods /// /// Transfer a setting from to a configuration bindable. - /// Only performs the transfer if the user it not currently overriding.. + /// Only performs the transfer if the user is not currently overriding. /// protected void TransferSetting(BindableNumber bindable, T beatmapDefault) where T : struct, IComparable, IConvertible, IEquatable From 18bf7c913b1b73f444f09ca16d2f43334d696404 Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Wed, 18 Mar 2020 23:43:26 -0400 Subject: [PATCH 28/77] show mod settings in ModIcon tooltip --- .../Mods/CatchModDifficultyAdjust.cs | 5 +++++ osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs | 5 +++++ osu.Game/Rulesets/Mods/Mod.cs | 11 +++++++++++ osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs | 3 +++ osu.Game/Rulesets/Mods/ModDoubleTime.cs | 2 ++ osu.Game/Rulesets/Mods/ModEasy.cs | 2 ++ osu.Game/Rulesets/Mods/ModHalfTime.cs | 2 ++ osu.Game/Rulesets/Mods/ModTimeRamp.cs | 2 ++ osu.Game/Rulesets/UI/ModIcon.cs | 2 +- 9 files changed, 33 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs index e2465d727e..8ea39c8676 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs @@ -30,6 +30,11 @@ namespace osu.Game.Rulesets.Catch.Mods Value = 5, }; + public override string IconTooltip => ($"{Name} ({(CircleSize.IsDefault ? "" : $"CS {CircleSize.Value.ToString()}, ")}" + + $"{(DrainRate.IsDefault ? "" : $"HP {DrainRate.Value.ToString()}, ")}" + + $"{(OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value.ToString()}, ")}" + + $"{(ApproachRate.IsDefault ? "" : $"AR {ApproachRate.Value.ToString()}")}").TrimEnd(new char[] { ',', ' ' }) + ")"; + protected override void TransferSettings(BeatmapDifficulty difficulty) { base.TransferSettings(difficulty); diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs index 75de6896a3..c3e1321dac 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs @@ -30,6 +30,11 @@ namespace osu.Game.Rulesets.Osu.Mods Value = 5, }; + public override string IconTooltip => ($"{Name} ({(CircleSize.IsDefault ? "" : $"CS {CircleSize.Value.ToString()}, ")}" + + $"{(DrainRate.IsDefault ? "" : $"HP {DrainRate.Value.ToString()}, ")}" + + $"{(OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value.ToString()}, ")}" + + $"{(ApproachRate.IsDefault ? "" : $"AR {ApproachRate.Value.ToString()}")}").TrimEnd(new char[] { ',', ' ' }) + ")"; + protected override void TransferSettings(BeatmapDifficulty difficulty) { base.TransferSettings(difficulty); diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index 46c0c1da07..b70ddc6d46 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -5,6 +5,7 @@ using System; using Newtonsoft.Json; using osu.Framework.Graphics.Sprites; using osu.Game.IO.Serialization; +using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Mods { @@ -42,6 +43,16 @@ namespace osu.Game.Rulesets.Mods [JsonIgnore] public virtual string Description => string.Empty; + /// + /// The tooltip to display for this mod when used in a . + /// + /// + /// Differs from , as the value of attributes (AR, CS, etc) changeable via the mod + /// are displayed in the tooltip. + /// + [JsonIgnore] + public virtual string IconTooltip => Name; + /// /// The score multiplier of this mod. /// diff --git a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs index c3d1e4c857..4072e6a6af 100644 --- a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs @@ -52,6 +52,9 @@ namespace osu.Game.Rulesets.Mods Value = 5, }; + public override string IconTooltip => $"{Name} ({(DrainRate.IsDefault ? $"HP {DrainRate.Value.ToString()}, " : "")}" + + $"{(OverallDifficulty.IsDefault ? $"OD {OverallDifficulty.Value.ToString()}, " : "")})"; + private BeatmapDifficulty difficulty; public void ReadFromDifficulty(BeatmapDifficulty difficulty) diff --git a/osu.Game/Rulesets/Mods/ModDoubleTime.cs b/osu.Game/Rulesets/Mods/ModDoubleTime.cs index 152657da33..4f7d82418d 100644 --- a/osu.Game/Rulesets/Mods/ModDoubleTime.cs +++ b/osu.Game/Rulesets/Mods/ModDoubleTime.cs @@ -30,5 +30,7 @@ namespace osu.Game.Rulesets.Mods Value = 1.5, Precision = 0.01, }; + + public override string IconTooltip => $"{Name}{(SpeedChange.IsDefault ? "" : $" ({SpeedChange.Value}x)")}"; } } diff --git a/osu.Game/Rulesets/Mods/ModEasy.cs b/osu.Game/Rulesets/Mods/ModEasy.cs index b56be95dfe..2ec4e9610b 100644 --- a/osu.Game/Rulesets/Mods/ModEasy.cs +++ b/osu.Game/Rulesets/Mods/ModEasy.cs @@ -28,6 +28,8 @@ namespace osu.Game.Rulesets.Mods MaxValue = 10 }; + public override string IconTooltip => $"{Name}{(Retries.IsDefault ? "" : $" ({Retries.Value} lives)")}"; + private int retries; private BindableNumber health; diff --git a/osu.Game/Rulesets/Mods/ModHalfTime.cs b/osu.Game/Rulesets/Mods/ModHalfTime.cs index 203b88951c..14133bddcd 100644 --- a/osu.Game/Rulesets/Mods/ModHalfTime.cs +++ b/osu.Game/Rulesets/Mods/ModHalfTime.cs @@ -30,5 +30,7 @@ namespace osu.Game.Rulesets.Mods Value = 0.75, Precision = 0.01, }; + + public override string IconTooltip => $"{Name}{(SpeedChange.IsDefault ? "" : $" ({SpeedChange.Value}x)")}"; } } diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index 9e63142b42..9cb97dfc35 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -26,6 +26,8 @@ namespace osu.Game.Rulesets.Mods [SettingSource("Final rate", "The final speed to ramp to")] public abstract BindableNumber FinalRate { get; } + public override string IconTooltip => $"{Name} ({InitialRate.Value}x to {FinalRate.Value}x)"; + private double finalRateTime; private double beginRampTime; diff --git a/osu.Game/Rulesets/UI/ModIcon.cs b/osu.Game/Rulesets/UI/ModIcon.cs index 3edab0745d..3cd1b0820d 100644 --- a/osu.Game/Rulesets/UI/ModIcon.cs +++ b/osu.Game/Rulesets/UI/ModIcon.cs @@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.UI type = mod.Type; - TooltipText = mod.Name; + TooltipText = mod.IconTooltip; Size = new Vector2(size); From 7a0a633ef9320fbd2c519f7630999306fcce6ce5 Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Thu, 19 Mar 2020 00:06:55 -0400 Subject: [PATCH 29/77] don't use ToString, proper indent level --- osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs | 8 ++++---- osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs index 8ea39c8676..661c59332f 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs @@ -30,10 +30,10 @@ namespace osu.Game.Rulesets.Catch.Mods Value = 5, }; - public override string IconTooltip => ($"{Name} ({(CircleSize.IsDefault ? "" : $"CS {CircleSize.Value.ToString()}, ")}" + - $"{(DrainRate.IsDefault ? "" : $"HP {DrainRate.Value.ToString()}, ")}" + - $"{(OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value.ToString()}, ")}" + - $"{(ApproachRate.IsDefault ? "" : $"AR {ApproachRate.Value.ToString()}")}").TrimEnd(new char[] { ',', ' ' }) + ")"; + public override string IconTooltip => ($"{Name} ({(CircleSize.IsDefault ? "" : $"CS {CircleSize.Value}, ")}" + + $"{(DrainRate.IsDefault ? "" : $"HP {DrainRate.Value}, ")}" + + $"{(OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value}, ")}" + + $"{(ApproachRate.IsDefault ? "" : $"AR {ApproachRate.Value}")}").TrimEnd(new char[] { ',', ' ' }) + ")"; protected override void TransferSettings(BeatmapDifficulty difficulty) { diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs index c3e1321dac..477028dbbe 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs @@ -30,10 +30,10 @@ namespace osu.Game.Rulesets.Osu.Mods Value = 5, }; - public override string IconTooltip => ($"{Name} ({(CircleSize.IsDefault ? "" : $"CS {CircleSize.Value.ToString()}, ")}" + - $"{(DrainRate.IsDefault ? "" : $"HP {DrainRate.Value.ToString()}, ")}" + - $"{(OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value.ToString()}, ")}" + - $"{(ApproachRate.IsDefault ? "" : $"AR {ApproachRate.Value.ToString()}")}").TrimEnd(new char[] { ',', ' ' }) + ")"; + public override string IconTooltip => ($"{Name} ({(CircleSize.IsDefault ? "" : $"CS {CircleSize.Value}, ")}" + + $"{(DrainRate.IsDefault ? "" : $"HP {DrainRate.Value}, ")}" + + $"{(OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value}, ")}" + + $"{(ApproachRate.IsDefault ? "" : $"AR {ApproachRate.Value}")}").TrimEnd(new char[] { ',', ' ' }) + ")"; protected override void TransferSettings(BeatmapDifficulty difficulty) { From 5a6d8f1932715d9fc7479d8cb5614e0b2efe4025 Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Fri, 20 Mar 2020 12:47:17 -0400 Subject: [PATCH 30/77] use SettingSource to define IconTooltip format --- .../Mods/CatchModDifficultyAdjust.cs | 9 ++--- .../Mods/OsuModDifficultyAdjust.cs | 9 ++--- .../Configuration/SettingSourceAttribute.cs | 11 +++++- osu.Game/Rulesets/Mods/Mod.cs | 34 ++++++++++++++++++- osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs | 7 ++-- osu.Game/Rulesets/Mods/ModDoubleTime.cs | 4 +-- osu.Game/Rulesets/Mods/ModEasy.cs | 4 +-- osu.Game/Rulesets/Mods/ModHalfTime.cs | 4 +-- 8 files changed, 52 insertions(+), 30 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs index 661c59332f..e4298dc008 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs @@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Catch.Mods { public class CatchModDifficultyAdjust : ModDifficultyAdjust { - [SettingSource("Circle Size", "Override a beatmap's set CS.", FIRST_SETTING_ORDER - 1)] + [SettingSource("Circle Size", "Override a beatmap's set CS.", "CS {0}", FIRST_SETTING_ORDER - 1)] public BindableNumber CircleSize { get; } = new BindableFloat { Precision = 0.1f, @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Catch.Mods Value = 5, }; - [SettingSource("Approach Rate", "Override a beatmap's set AR.", LAST_SETTING_ORDER + 1)] + [SettingSource("Approach Rate", "Override a beatmap's set AR.", "AR {0}", LAST_SETTING_ORDER + 1)] public BindableNumber ApproachRate { get; } = new BindableFloat { Precision = 0.1f, @@ -30,11 +30,6 @@ namespace osu.Game.Rulesets.Catch.Mods Value = 5, }; - public override string IconTooltip => ($"{Name} ({(CircleSize.IsDefault ? "" : $"CS {CircleSize.Value}, ")}" + - $"{(DrainRate.IsDefault ? "" : $"HP {DrainRate.Value}, ")}" + - $"{(OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value}, ")}" + - $"{(ApproachRate.IsDefault ? "" : $"AR {ApproachRate.Value}")}").TrimEnd(new char[] { ',', ' ' }) + ")"; - protected override void TransferSettings(BeatmapDifficulty difficulty) { base.TransferSettings(difficulty); diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs index 477028dbbe..91707ea328 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs @@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Osu.Mods { public class OsuModDifficultyAdjust : ModDifficultyAdjust { - [SettingSource("Circle Size", "Override a beatmap's set CS.", FIRST_SETTING_ORDER - 1)] + [SettingSource("Circle Size", "Override a beatmap's set CS.", "CS {0}", FIRST_SETTING_ORDER - 1)] public BindableNumber CircleSize { get; } = new BindableFloat { Precision = 0.1f, @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Osu.Mods Value = 5, }; - [SettingSource("Approach Rate", "Override a beatmap's set AR.", LAST_SETTING_ORDER + 1)] + [SettingSource("Approach Rate", "Override a beatmap's set AR.", "AR {0}", LAST_SETTING_ORDER + 1)] public BindableNumber ApproachRate { get; } = new BindableFloat { Precision = 0.1f, @@ -30,11 +30,6 @@ namespace osu.Game.Rulesets.Osu.Mods Value = 5, }; - public override string IconTooltip => ($"{Name} ({(CircleSize.IsDefault ? "" : $"CS {CircleSize.Value}, ")}" + - $"{(DrainRate.IsDefault ? "" : $"HP {DrainRate.Value}, ")}" + - $"{(OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value}, ")}" + - $"{(ApproachRate.IsDefault ? "" : $"AR {ApproachRate.Value}")}").TrimEnd(new char[] { ',', ' ' }) + ")"; - protected override void TransferSettings(BeatmapDifficulty difficulty) { base.TransferSettings(difficulty); diff --git a/osu.Game/Configuration/SettingSourceAttribute.cs b/osu.Game/Configuration/SettingSourceAttribute.cs index fe487cb1d0..1a79dc7335 100644 --- a/osu.Game/Configuration/SettingSourceAttribute.cs +++ b/osu.Game/Configuration/SettingSourceAttribute.cs @@ -30,17 +30,26 @@ namespace osu.Game.Configuration public int? OrderPosition { get; } + public string TooltipText { get; } + public SettingSourceAttribute(string label, string description = null) { Label = label ?? string.Empty; Description = description ?? string.Empty; } - public SettingSourceAttribute(string label, string description, int orderPosition) + public SettingSourceAttribute(string label, string description, string tooltipText, int orderPosition) : this(label, description) { OrderPosition = orderPosition; + TooltipText = tooltipText; } + + public SettingSourceAttribute(string label, string description, string tooltipText) : this(label, description) + { + TooltipText = tooltipText; + } + } public static class SettingSourceExtensions diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index b70ddc6d46..860e768350 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -2,8 +2,12 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; +using System.Linq; using Newtonsoft.Json; +using osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; +using osu.Game.Configuration; using osu.Game.IO.Serialization; using osu.Game.Rulesets.UI; @@ -51,7 +55,35 @@ namespace osu.Game.Rulesets.Mods /// are displayed in the tooltip. /// [JsonIgnore] - public virtual string IconTooltip => Name; + public virtual string IconTooltip + { + get + { + List attributes = new List(); + foreach ((SettingSourceAttribute attr, System.Reflection.PropertyInfo property) in this.GetOrderedSettingsSourceProperties()) + { + // use TooltipText from SettingSource if available, but fall back to Label, which has to be provided + string tooltipText = attr.TooltipText ?? attr.Label + " {0}"; + object bindableObj = property.GetValue(this); + if (bindableObj is BindableInt bindableInt && !bindableInt.IsDefault) + { + attributes.Add(string.Format(tooltipText, bindableInt.Value)); + continue; + } + if (bindableObj is BindableFloat bindableFloat && !bindableFloat.IsDefault) + { + attributes.Add(string.Format(tooltipText, bindableFloat.Value)); + continue; + } + if (bindableObj is BindableDouble bindableDouble && !bindableDouble.IsDefault) + { + attributes.Add(string.Format(tooltipText, bindableDouble.Value)); + continue; + } + } + return $"{Name}{(attributes.Any() ? $" ({string.Join(", ", attributes)})" : "")}"; + } + } /// /// The score multiplier of this mod. diff --git a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs index 4072e6a6af..8188e36b64 100644 --- a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Mods protected const int LAST_SETTING_ORDER = 2; - [SettingSource("HP Drain", "Override a beatmap's set HP.", FIRST_SETTING_ORDER)] + [SettingSource("HP Drain", "Override a beatmap's set HP.", "HP {0}", FIRST_SETTING_ORDER)] public BindableNumber DrainRate { get; } = new BindableFloat { Precision = 0.1f, @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Mods Value = 5, }; - [SettingSource("Accuracy", "Override a beatmap's set OD.", LAST_SETTING_ORDER)] + [SettingSource("Accuracy", "Override a beatmap's set OD.", "OD {0}", LAST_SETTING_ORDER)] public BindableNumber OverallDifficulty { get; } = new BindableFloat { Precision = 0.1f, @@ -52,9 +52,6 @@ namespace osu.Game.Rulesets.Mods Value = 5, }; - public override string IconTooltip => $"{Name} ({(DrainRate.IsDefault ? $"HP {DrainRate.Value.ToString()}, " : "")}" + - $"{(OverallDifficulty.IsDefault ? $"OD {OverallDifficulty.Value.ToString()}, " : "")})"; - private BeatmapDifficulty difficulty; public void ReadFromDifficulty(BeatmapDifficulty difficulty) diff --git a/osu.Game/Rulesets/Mods/ModDoubleTime.cs b/osu.Game/Rulesets/Mods/ModDoubleTime.cs index 4f7d82418d..fe027b9da0 100644 --- a/osu.Game/Rulesets/Mods/ModDoubleTime.cs +++ b/osu.Game/Rulesets/Mods/ModDoubleTime.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Mods public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ModHalfTime)).ToArray(); - [SettingSource("Speed increase", "The actual increase to apply")] + [SettingSource("Speed increase", "The actual increase to apply", "{0}x")] public override BindableNumber SpeedChange { get; } = new BindableDouble { MinValue = 1.01, @@ -30,7 +30,5 @@ namespace osu.Game.Rulesets.Mods Value = 1.5, Precision = 0.01, }; - - public override string IconTooltip => $"{Name}{(SpeedChange.IsDefault ? "" : $" ({SpeedChange.Value}x)")}"; } } diff --git a/osu.Game/Rulesets/Mods/ModEasy.cs b/osu.Game/Rulesets/Mods/ModEasy.cs index 2ec4e9610b..c92c7297c3 100644 --- a/osu.Game/Rulesets/Mods/ModEasy.cs +++ b/osu.Game/Rulesets/Mods/ModEasy.cs @@ -21,15 +21,13 @@ namespace osu.Game.Rulesets.Mods public override bool Ranked => true; public override Type[] IncompatibleMods => new[] { typeof(ModHardRock), typeof(ModDifficultyAdjust) }; - [SettingSource("Extra Lives", "Number of extra lives")] + [SettingSource("Extra Lives", "Number of extra lives", "{0} lives")] public Bindable Retries { get; } = new BindableInt(2) { MinValue = 0, MaxValue = 10 }; - public override string IconTooltip => $"{Name}{(Retries.IsDefault ? "" : $" ({Retries.Value} lives)")}"; - private int retries; private BindableNumber health; diff --git a/osu.Game/Rulesets/Mods/ModHalfTime.cs b/osu.Game/Rulesets/Mods/ModHalfTime.cs index 14133bddcd..7c1f4b8e12 100644 --- a/osu.Game/Rulesets/Mods/ModHalfTime.cs +++ b/osu.Game/Rulesets/Mods/ModHalfTime.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Mods public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ModDoubleTime)).ToArray(); - [SettingSource("Speed decrease", "The actual decrease to apply")] + [SettingSource("Speed decrease", "The actual decrease to apply", "{0}x")] public override BindableNumber SpeedChange { get; } = new BindableDouble { MinValue = 0.5, @@ -30,7 +30,5 @@ namespace osu.Game.Rulesets.Mods Value = 0.75, Precision = 0.01, }; - - public override string IconTooltip => $"{Name}{(SpeedChange.IsDefault ? "" : $" ({SpeedChange.Value}x)")}"; } } From 9dc814681195f864192436ba0a9f8197a726108b Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Fri, 20 Mar 2020 13:21:44 -0400 Subject: [PATCH 31/77] fix style issues --- osu.Game/Configuration/SettingSourceAttribute.cs | 4 ++-- osu.Game/Rulesets/Mods/Mod.cs | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Configuration/SettingSourceAttribute.cs b/osu.Game/Configuration/SettingSourceAttribute.cs index 1a79dc7335..fb0daf9217 100644 --- a/osu.Game/Configuration/SettingSourceAttribute.cs +++ b/osu.Game/Configuration/SettingSourceAttribute.cs @@ -45,11 +45,11 @@ namespace osu.Game.Configuration TooltipText = tooltipText; } - public SettingSourceAttribute(string label, string description, string tooltipText) : this(label, description) + public SettingSourceAttribute(string label, string description, string tooltipText) + : this(label, description) { TooltipText = tooltipText; } - } public static class SettingSourceExtensions diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index 860e768350..69fd45767b 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -60,25 +60,28 @@ namespace osu.Game.Rulesets.Mods get { List attributes = new List(); + foreach ((SettingSourceAttribute attr, System.Reflection.PropertyInfo property) in this.GetOrderedSettingsSourceProperties()) { // use TooltipText from SettingSource if available, but fall back to Label, which has to be provided string tooltipText = attr.TooltipText ?? attr.Label + " {0}"; object bindableObj = property.GetValue(this); + if (bindableObj is BindableInt bindableInt && !bindableInt.IsDefault) { attributes.Add(string.Format(tooltipText, bindableInt.Value)); continue; } + if (bindableObj is BindableFloat bindableFloat && !bindableFloat.IsDefault) { attributes.Add(string.Format(tooltipText, bindableFloat.Value)); continue; } + if (bindableObj is BindableDouble bindableDouble && !bindableDouble.IsDefault) { attributes.Add(string.Format(tooltipText, bindableDouble.Value)); - continue; } } return $"{Name}{(attributes.Any() ? $" ({string.Join(", ", attributes)})" : "")}"; From 9e3bff3b97503c6e4f2a89fa5ea1c8a01f3767bf Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Fri, 20 Mar 2020 13:36:16 -0400 Subject: [PATCH 32/77] oops, missed a newline --- osu.Game/Rulesets/Mods/Mod.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index 69fd45767b..f3b7fed96a 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -84,6 +84,7 @@ namespace osu.Game.Rulesets.Mods attributes.Add(string.Format(tooltipText, bindableDouble.Value)); } } + return $"{Name}{(attributes.Any() ? $" ({string.Join(", ", attributes)})" : "")}"; } } From 3d955921302cbe8e449640bdb0488b528654fd7c Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Fri, 20 Mar 2020 14:37:31 -0400 Subject: [PATCH 33/77] use var for list declaration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Bartłomiej Dach --- osu.Game/Rulesets/Mods/Mod.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index f3b7fed96a..b4faf55734 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -59,7 +59,7 @@ namespace osu.Game.Rulesets.Mods { get { - List attributes = new List(); + var attributes = new List(); foreach ((SettingSourceAttribute attr, System.Reflection.PropertyInfo property) in this.GetOrderedSettingsSourceProperties()) { From 7bdbdd25f8b3955b9c0a8f2dcb897a722073f958 Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Fri, 20 Mar 2020 16:05:12 -0400 Subject: [PATCH 34/77] Revert "use SettingSource to define IconTooltip format" This reverts commit 5a6d8f1932715d9fc7479d8cb5614e0b2efe4025. --- .../Mods/CatchModDifficultyAdjust.cs | 9 ++++- .../Mods/OsuModDifficultyAdjust.cs | 9 ++++- .../Configuration/SettingSourceAttribute.cs | 11 +----- osu.Game/Rulesets/Mods/Mod.cs | 38 +------------------ osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs | 7 +++- osu.Game/Rulesets/Mods/ModDoubleTime.cs | 4 +- osu.Game/Rulesets/Mods/ModEasy.cs | 4 +- osu.Game/Rulesets/Mods/ModHalfTime.cs | 4 +- 8 files changed, 30 insertions(+), 56 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs index e4298dc008..661c59332f 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs @@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Catch.Mods { public class CatchModDifficultyAdjust : ModDifficultyAdjust { - [SettingSource("Circle Size", "Override a beatmap's set CS.", "CS {0}", FIRST_SETTING_ORDER - 1)] + [SettingSource("Circle Size", "Override a beatmap's set CS.", FIRST_SETTING_ORDER - 1)] public BindableNumber CircleSize { get; } = new BindableFloat { Precision = 0.1f, @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Catch.Mods Value = 5, }; - [SettingSource("Approach Rate", "Override a beatmap's set AR.", "AR {0}", LAST_SETTING_ORDER + 1)] + [SettingSource("Approach Rate", "Override a beatmap's set AR.", LAST_SETTING_ORDER + 1)] public BindableNumber ApproachRate { get; } = new BindableFloat { Precision = 0.1f, @@ -30,6 +30,11 @@ namespace osu.Game.Rulesets.Catch.Mods Value = 5, }; + public override string IconTooltip => ($"{Name} ({(CircleSize.IsDefault ? "" : $"CS {CircleSize.Value}, ")}" + + $"{(DrainRate.IsDefault ? "" : $"HP {DrainRate.Value}, ")}" + + $"{(OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value}, ")}" + + $"{(ApproachRate.IsDefault ? "" : $"AR {ApproachRate.Value}")}").TrimEnd(new char[] { ',', ' ' }) + ")"; + protected override void TransferSettings(BeatmapDifficulty difficulty) { base.TransferSettings(difficulty); diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs index 91707ea328..477028dbbe 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs @@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Osu.Mods { public class OsuModDifficultyAdjust : ModDifficultyAdjust { - [SettingSource("Circle Size", "Override a beatmap's set CS.", "CS {0}", FIRST_SETTING_ORDER - 1)] + [SettingSource("Circle Size", "Override a beatmap's set CS.", FIRST_SETTING_ORDER - 1)] public BindableNumber CircleSize { get; } = new BindableFloat { Precision = 0.1f, @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Osu.Mods Value = 5, }; - [SettingSource("Approach Rate", "Override a beatmap's set AR.", "AR {0}", LAST_SETTING_ORDER + 1)] + [SettingSource("Approach Rate", "Override a beatmap's set AR.", LAST_SETTING_ORDER + 1)] public BindableNumber ApproachRate { get; } = new BindableFloat { Precision = 0.1f, @@ -30,6 +30,11 @@ namespace osu.Game.Rulesets.Osu.Mods Value = 5, }; + public override string IconTooltip => ($"{Name} ({(CircleSize.IsDefault ? "" : $"CS {CircleSize.Value}, ")}" + + $"{(DrainRate.IsDefault ? "" : $"HP {DrainRate.Value}, ")}" + + $"{(OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value}, ")}" + + $"{(ApproachRate.IsDefault ? "" : $"AR {ApproachRate.Value}")}").TrimEnd(new char[] { ',', ' ' }) + ")"; + protected override void TransferSettings(BeatmapDifficulty difficulty) { base.TransferSettings(difficulty); diff --git a/osu.Game/Configuration/SettingSourceAttribute.cs b/osu.Game/Configuration/SettingSourceAttribute.cs index fb0daf9217..fe487cb1d0 100644 --- a/osu.Game/Configuration/SettingSourceAttribute.cs +++ b/osu.Game/Configuration/SettingSourceAttribute.cs @@ -30,25 +30,16 @@ namespace osu.Game.Configuration public int? OrderPosition { get; } - public string TooltipText { get; } - public SettingSourceAttribute(string label, string description = null) { Label = label ?? string.Empty; Description = description ?? string.Empty; } - public SettingSourceAttribute(string label, string description, string tooltipText, int orderPosition) + public SettingSourceAttribute(string label, string description, int orderPosition) : this(label, description) { OrderPosition = orderPosition; - TooltipText = tooltipText; - } - - public SettingSourceAttribute(string label, string description, string tooltipText) - : this(label, description) - { - TooltipText = tooltipText; } } diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index b4faf55734..b70ddc6d46 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -2,12 +2,8 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; -using System.Linq; using Newtonsoft.Json; -using osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; -using osu.Game.Configuration; using osu.Game.IO.Serialization; using osu.Game.Rulesets.UI; @@ -55,39 +51,7 @@ namespace osu.Game.Rulesets.Mods /// are displayed in the tooltip. /// [JsonIgnore] - public virtual string IconTooltip - { - get - { - var attributes = new List(); - - foreach ((SettingSourceAttribute attr, System.Reflection.PropertyInfo property) in this.GetOrderedSettingsSourceProperties()) - { - // use TooltipText from SettingSource if available, but fall back to Label, which has to be provided - string tooltipText = attr.TooltipText ?? attr.Label + " {0}"; - object bindableObj = property.GetValue(this); - - if (bindableObj is BindableInt bindableInt && !bindableInt.IsDefault) - { - attributes.Add(string.Format(tooltipText, bindableInt.Value)); - continue; - } - - if (bindableObj is BindableFloat bindableFloat && !bindableFloat.IsDefault) - { - attributes.Add(string.Format(tooltipText, bindableFloat.Value)); - continue; - } - - if (bindableObj is BindableDouble bindableDouble && !bindableDouble.IsDefault) - { - attributes.Add(string.Format(tooltipText, bindableDouble.Value)); - } - } - - return $"{Name}{(attributes.Any() ? $" ({string.Join(", ", attributes)})" : "")}"; - } - } + public virtual string IconTooltip => Name; /// /// The score multiplier of this mod. diff --git a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs index 8188e36b64..4072e6a6af 100644 --- a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Mods protected const int LAST_SETTING_ORDER = 2; - [SettingSource("HP Drain", "Override a beatmap's set HP.", "HP {0}", FIRST_SETTING_ORDER)] + [SettingSource("HP Drain", "Override a beatmap's set HP.", FIRST_SETTING_ORDER)] public BindableNumber DrainRate { get; } = new BindableFloat { Precision = 0.1f, @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Mods Value = 5, }; - [SettingSource("Accuracy", "Override a beatmap's set OD.", "OD {0}", LAST_SETTING_ORDER)] + [SettingSource("Accuracy", "Override a beatmap's set OD.", LAST_SETTING_ORDER)] public BindableNumber OverallDifficulty { get; } = new BindableFloat { Precision = 0.1f, @@ -52,6 +52,9 @@ namespace osu.Game.Rulesets.Mods Value = 5, }; + public override string IconTooltip => $"{Name} ({(DrainRate.IsDefault ? $"HP {DrainRate.Value.ToString()}, " : "")}" + + $"{(OverallDifficulty.IsDefault ? $"OD {OverallDifficulty.Value.ToString()}, " : "")})"; + private BeatmapDifficulty difficulty; public void ReadFromDifficulty(BeatmapDifficulty difficulty) diff --git a/osu.Game/Rulesets/Mods/ModDoubleTime.cs b/osu.Game/Rulesets/Mods/ModDoubleTime.cs index fe027b9da0..4f7d82418d 100644 --- a/osu.Game/Rulesets/Mods/ModDoubleTime.cs +++ b/osu.Game/Rulesets/Mods/ModDoubleTime.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Mods public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ModHalfTime)).ToArray(); - [SettingSource("Speed increase", "The actual increase to apply", "{0}x")] + [SettingSource("Speed increase", "The actual increase to apply")] public override BindableNumber SpeedChange { get; } = new BindableDouble { MinValue = 1.01, @@ -30,5 +30,7 @@ namespace osu.Game.Rulesets.Mods Value = 1.5, Precision = 0.01, }; + + public override string IconTooltip => $"{Name}{(SpeedChange.IsDefault ? "" : $" ({SpeedChange.Value}x)")}"; } } diff --git a/osu.Game/Rulesets/Mods/ModEasy.cs b/osu.Game/Rulesets/Mods/ModEasy.cs index c92c7297c3..2ec4e9610b 100644 --- a/osu.Game/Rulesets/Mods/ModEasy.cs +++ b/osu.Game/Rulesets/Mods/ModEasy.cs @@ -21,13 +21,15 @@ namespace osu.Game.Rulesets.Mods public override bool Ranked => true; public override Type[] IncompatibleMods => new[] { typeof(ModHardRock), typeof(ModDifficultyAdjust) }; - [SettingSource("Extra Lives", "Number of extra lives", "{0} lives")] + [SettingSource("Extra Lives", "Number of extra lives")] public Bindable Retries { get; } = new BindableInt(2) { MinValue = 0, MaxValue = 10 }; + public override string IconTooltip => $"{Name}{(Retries.IsDefault ? "" : $" ({Retries.Value} lives)")}"; + private int retries; private BindableNumber health; diff --git a/osu.Game/Rulesets/Mods/ModHalfTime.cs b/osu.Game/Rulesets/Mods/ModHalfTime.cs index 7c1f4b8e12..14133bddcd 100644 --- a/osu.Game/Rulesets/Mods/ModHalfTime.cs +++ b/osu.Game/Rulesets/Mods/ModHalfTime.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Mods public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ModDoubleTime)).ToArray(); - [SettingSource("Speed decrease", "The actual decrease to apply", "{0}x")] + [SettingSource("Speed decrease", "The actual decrease to apply")] public override BindableNumber SpeedChange { get; } = new BindableDouble { MinValue = 0.5, @@ -30,5 +30,7 @@ namespace osu.Game.Rulesets.Mods Value = 0.75, Precision = 0.01, }; + + public override string IconTooltip => $"{Name}{(SpeedChange.IsDefault ? "" : $" ({SpeedChange.Value}x)")}"; } } From cda1efef0bde4d9ee692cb8d7747aea63b502e58 Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Fri, 20 Mar 2020 16:34:36 -0400 Subject: [PATCH 35/77] move overridability to SettingDescription method --- .../Mods/CatchModDifficultyAdjust.cs | 20 +++++++++++++++---- .../Mods/OsuModDifficultyAdjust.cs | 20 +++++++++++++++---- osu.Game/Rulesets/Mods/Mod.cs | 18 ++++++++++++++++- osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs | 16 +++++++++++++-- osu.Game/Rulesets/Mods/ModDoubleTime.cs | 2 +- osu.Game/Rulesets/Mods/ModEasy.cs | 2 +- osu.Game/Rulesets/Mods/ModHalfTime.cs | 2 +- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 2 +- 8 files changed, 67 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs index 661c59332f..ee05dd1560 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Configuration; @@ -30,10 +31,21 @@ namespace osu.Game.Rulesets.Catch.Mods Value = 5, }; - public override string IconTooltip => ($"{Name} ({(CircleSize.IsDefault ? "" : $"CS {CircleSize.Value}, ")}" + - $"{(DrainRate.IsDefault ? "" : $"HP {DrainRate.Value}, ")}" + - $"{(OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value}, ")}" + - $"{(ApproachRate.IsDefault ? "" : $"AR {ApproachRate.Value}")}").TrimEnd(new char[] { ',', ' ' }) + ")"; + public override string SettingDescription + { + get + { + string circleSize = CircleSize.IsDefault ? "" : $"CS {CircleSize.Value.ToString()}"; + string drainRate = DrainRate.IsDefault ? "" : $"HP {DrainRate.Value.ToString()}"; + string overallDifficulty = OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value.ToString()}"; + string approachRate = ApproachRate.IsDefault ? "" : $"AR {ApproachRate.Value.ToString()}"; + + string[] settings = new string[] { circleSize, drainRate, overallDifficulty, approachRate }; + // filter out empty strings so we don't have orphaned commas + settings = Array.FindAll(settings, s => !string.IsNullOrEmpty(s)); + return string.Join(", ", settings); + } + } protected override void TransferSettings(BeatmapDifficulty difficulty) { diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs index 477028dbbe..520e5a6726 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Configuration; @@ -30,10 +31,21 @@ namespace osu.Game.Rulesets.Osu.Mods Value = 5, }; - public override string IconTooltip => ($"{Name} ({(CircleSize.IsDefault ? "" : $"CS {CircleSize.Value}, ")}" + - $"{(DrainRate.IsDefault ? "" : $"HP {DrainRate.Value}, ")}" + - $"{(OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value}, ")}" + - $"{(ApproachRate.IsDefault ? "" : $"AR {ApproachRate.Value}")}").TrimEnd(new char[] { ',', ' ' }) + ")"; + public override string SettingDescription + { + get + { + string circleSize = CircleSize.IsDefault ? "" : $"CS {CircleSize.Value.ToString()}"; + string drainRate = DrainRate.IsDefault ? "" : $"HP {DrainRate.Value.ToString()}"; + string overallDifficulty = OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value.ToString()}"; + string approachRate = ApproachRate.IsDefault ? "" : $"AR {ApproachRate.Value.ToString()}"; + + string[] settings = new string[] { circleSize, drainRate, overallDifficulty, approachRate }; + // filter out empty strings so we don't have orphaned commas + settings = Array.FindAll(settings, s => !string.IsNullOrEmpty(s)); + return string.Join(", ", settings); + } + } protected override void TransferSettings(BeatmapDifficulty difficulty) { diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index b70ddc6d46..231b95f974 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -51,7 +51,23 @@ namespace osu.Game.Rulesets.Mods /// are displayed in the tooltip. /// [JsonIgnore] - public virtual string IconTooltip => Name; + public string IconTooltip + { + get + { + string settingDescription = string.IsNullOrEmpty(SettingDescription) ? "" : $" ({SettingDescription})"; + return $"{Name}{settingDescription}"; + } + } + + /// + /// The description of editable settings of a mod to use in the . + /// + /// + /// Parentheses are added to the tooltip, surrounding the value of this property. If this property is string.Empty, + /// the tooltip will not have parentheses. + /// + public virtual string SettingDescription => string.Empty; /// /// The score multiplier of this mod. diff --git a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs index 4072e6a6af..a5024d6988 100644 --- a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics.Sprites; using System; using System.Collections.Generic; using osu.Game.Configuration; +using System.Linq; namespace osu.Game.Rulesets.Mods { @@ -52,8 +53,19 @@ namespace osu.Game.Rulesets.Mods Value = 5, }; - public override string IconTooltip => $"{Name} ({(DrainRate.IsDefault ? $"HP {DrainRate.Value.ToString()}, " : "")}" + - $"{(OverallDifficulty.IsDefault ? $"OD {OverallDifficulty.Value.ToString()}, " : "")})"; + public override string SettingDescription + { + get + { + string drainRate = DrainRate.IsDefault ? "" : $"HP {DrainRate.Value.ToString()}"; + string overallDifficulty = OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value.ToString()}"; + + string[] settings = new string[] { drainRate, overallDifficulty }; + // filter out empty strings so we don't have orphaned commas + settings = Array.FindAll(settings, s => !string.IsNullOrEmpty(s)); + return string.Join(", ", settings); + } + } private BeatmapDifficulty difficulty; diff --git a/osu.Game/Rulesets/Mods/ModDoubleTime.cs b/osu.Game/Rulesets/Mods/ModDoubleTime.cs index 4f7d82418d..1730c98c7f 100644 --- a/osu.Game/Rulesets/Mods/ModDoubleTime.cs +++ b/osu.Game/Rulesets/Mods/ModDoubleTime.cs @@ -31,6 +31,6 @@ namespace osu.Game.Rulesets.Mods Precision = 0.01, }; - public override string IconTooltip => $"{Name}{(SpeedChange.IsDefault ? "" : $" ({SpeedChange.Value}x)")}"; + public override string SettingDescription => SpeedChange.IsDefault ? "" : $" ({SpeedChange.Value}x)"; } } diff --git a/osu.Game/Rulesets/Mods/ModEasy.cs b/osu.Game/Rulesets/Mods/ModEasy.cs index 2ec4e9610b..4433a28a95 100644 --- a/osu.Game/Rulesets/Mods/ModEasy.cs +++ b/osu.Game/Rulesets/Mods/ModEasy.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Mods MaxValue = 10 }; - public override string IconTooltip => $"{Name}{(Retries.IsDefault ? "" : $" ({Retries.Value} lives)")}"; + public override string SettingDescription => Retries.IsDefault ? "" : $" ({Retries.Value} lives)"; private int retries; diff --git a/osu.Game/Rulesets/Mods/ModHalfTime.cs b/osu.Game/Rulesets/Mods/ModHalfTime.cs index 14133bddcd..5f99748a87 100644 --- a/osu.Game/Rulesets/Mods/ModHalfTime.cs +++ b/osu.Game/Rulesets/Mods/ModHalfTime.cs @@ -31,6 +31,6 @@ namespace osu.Game.Rulesets.Mods Precision = 0.01, }; - public override string IconTooltip => $"{Name}{(SpeedChange.IsDefault ? "" : $" ({SpeedChange.Value}x)")}"; + public override string SettingDescription => SpeedChange.IsDefault ? "" : $" ({SpeedChange.Value}x)"; } } diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index 9cb97dfc35..7b4c1370ac 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Mods [SettingSource("Final rate", "The final speed to ramp to")] public abstract BindableNumber FinalRate { get; } - public override string IconTooltip => $"{Name} ({InitialRate.Value}x to {FinalRate.Value}x)"; + public override string SettingDescription => $"{InitialRate.Value} to {FinalRate.Value}"; private double finalRateTime; private double beginRampTime; From 6a63ba1bb826235cdca903ccdc855188d4e3d584 Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Fri, 20 Mar 2020 16:42:35 -0400 Subject: [PATCH 36/77] use humanizer for ModEasy lives setting --- osu.Game/Rulesets/Mods/ModEasy.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModEasy.cs b/osu.Game/Rulesets/Mods/ModEasy.cs index 4433a28a95..a1dd6c088d 100644 --- a/osu.Game/Rulesets/Mods/ModEasy.cs +++ b/osu.Game/Rulesets/Mods/ModEasy.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using Humanizer; using osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; using osu.Game.Beatmaps; @@ -28,7 +29,7 @@ namespace osu.Game.Rulesets.Mods MaxValue = 10 }; - public override string SettingDescription => Retries.IsDefault ? "" : $" ({Retries.Value} lives)"; + public override string SettingDescription => Retries.IsDefault ? "" : $"{"lives".ToQuantity(Retries.Value)}"; private int retries; From 55568ee6a5cae8ce8494eae518f8fc14562f64bf Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Fri, 20 Mar 2020 16:44:38 -0400 Subject: [PATCH 37/77] remove extra parentheses --- osu.Game/Rulesets/Mods/ModDoubleTime.cs | 2 +- osu.Game/Rulesets/Mods/ModHalfTime.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModDoubleTime.cs b/osu.Game/Rulesets/Mods/ModDoubleTime.cs index 1730c98c7f..05a8dbfa56 100644 --- a/osu.Game/Rulesets/Mods/ModDoubleTime.cs +++ b/osu.Game/Rulesets/Mods/ModDoubleTime.cs @@ -31,6 +31,6 @@ namespace osu.Game.Rulesets.Mods Precision = 0.01, }; - public override string SettingDescription => SpeedChange.IsDefault ? "" : $" ({SpeedChange.Value}x)"; + public override string SettingDescription => SpeedChange.IsDefault ? "" : $"{SpeedChange.Value}x"; } } diff --git a/osu.Game/Rulesets/Mods/ModHalfTime.cs b/osu.Game/Rulesets/Mods/ModHalfTime.cs index 5f99748a87..5252ce8d89 100644 --- a/osu.Game/Rulesets/Mods/ModHalfTime.cs +++ b/osu.Game/Rulesets/Mods/ModHalfTime.cs @@ -31,6 +31,6 @@ namespace osu.Game.Rulesets.Mods Precision = 0.01, }; - public override string SettingDescription => SpeedChange.IsDefault ? "" : $" ({SpeedChange.Value}x)"; + public override string SettingDescription => SpeedChange.IsDefault ? "" : $"{SpeedChange.Value}x"; } } From e84b40f8ed86507a16a162d5b1ce6ee1e66821ff Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Fri, 20 Mar 2020 16:53:40 -0400 Subject: [PATCH 38/77] remove unnecessary ToString calls --- osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs | 8 ++++---- osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs index ee05dd1560..3ebe8c6f6f 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs @@ -35,10 +35,10 @@ namespace osu.Game.Rulesets.Catch.Mods { get { - string circleSize = CircleSize.IsDefault ? "" : $"CS {CircleSize.Value.ToString()}"; - string drainRate = DrainRate.IsDefault ? "" : $"HP {DrainRate.Value.ToString()}"; - string overallDifficulty = OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value.ToString()}"; - string approachRate = ApproachRate.IsDefault ? "" : $"AR {ApproachRate.Value.ToString()}"; + string circleSize = CircleSize.IsDefault ? "" : $"CS {CircleSize.Value}"; + string drainRate = DrainRate.IsDefault ? "" : $"HP {DrainRate.Value}"; + string overallDifficulty = OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value}"; + string approachRate = ApproachRate.IsDefault ? "" : $"AR {ApproachRate.Value}"; string[] settings = new string[] { circleSize, drainRate, overallDifficulty, approachRate }; // filter out empty strings so we don't have orphaned commas diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs index 520e5a6726..d63239755b 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs @@ -35,10 +35,10 @@ namespace osu.Game.Rulesets.Osu.Mods { get { - string circleSize = CircleSize.IsDefault ? "" : $"CS {CircleSize.Value.ToString()}"; - string drainRate = DrainRate.IsDefault ? "" : $"HP {DrainRate.Value.ToString()}"; - string overallDifficulty = OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value.ToString()}"; - string approachRate = ApproachRate.IsDefault ? "" : $"AR {ApproachRate.Value.ToString()}"; + string circleSize = CircleSize.IsDefault ? "" : $"CS {CircleSize.Value}"; + string drainRate = DrainRate.IsDefault ? "" : $"HP {DrainRate.Value}"; + string overallDifficulty = OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value}"; + string approachRate = ApproachRate.IsDefault ? "" : $"AR {ApproachRate.Value}"; string[] settings = new string[] { circleSize, drainRate, overallDifficulty, approachRate }; // filter out empty strings so we don't have orphaned commas From ac202ba7ea963d43b2e5a7054dbfd285edf2a48b Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Fri, 20 Mar 2020 16:57:37 -0400 Subject: [PATCH 39/77] remove unused using directive --- osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs index a5024d6988..f50c2cf001 100644 --- a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs @@ -7,7 +7,6 @@ using osu.Framework.Graphics.Sprites; using System; using System.Collections.Generic; using osu.Game.Configuration; -using System.Linq; namespace osu.Game.Rulesets.Mods { @@ -60,7 +59,7 @@ namespace osu.Game.Rulesets.Mods string drainRate = DrainRate.IsDefault ? "" : $"HP {DrainRate.Value.ToString()}"; string overallDifficulty = OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value.ToString()}"; - string[] settings = new string[] { drainRate, overallDifficulty }; + string[] settings = { drainRate, overallDifficulty }; // filter out empty strings so we don't have orphaned commas settings = Array.FindAll(settings, s => !string.IsNullOrEmpty(s)); return string.Join(", ", settings); From a440d156205ea6503cfed552bb782dad9e6cba41 Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Fri, 20 Mar 2020 16:58:02 -0400 Subject: [PATCH 40/77] simplify array initializationstatement --- osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs | 2 +- osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs index 3ebe8c6f6f..6d0025b236 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs @@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Catch.Mods string overallDifficulty = OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value}"; string approachRate = ApproachRate.IsDefault ? "" : $"AR {ApproachRate.Value}"; - string[] settings = new string[] { circleSize, drainRate, overallDifficulty, approachRate }; + string[] settings = { circleSize, drainRate, overallDifficulty, approachRate }; // filter out empty strings so we don't have orphaned commas settings = Array.FindAll(settings, s => !string.IsNullOrEmpty(s)); return string.Join(", ", settings); diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs index d63239755b..307fe3da4a 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs @@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Osu.Mods string overallDifficulty = OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value}"; string approachRate = ApproachRate.IsDefault ? "" : $"AR {ApproachRate.Value}"; - string[] settings = new string[] { circleSize, drainRate, overallDifficulty, approachRate }; + string[] settings = { circleSize, drainRate, overallDifficulty, approachRate }; // filter out empty strings so we don't have orphaned commas settings = Array.FindAll(settings, s => !string.IsNullOrEmpty(s)); return string.Join(", ", settings); From eab705a9b690e9bdac340edae616895aef3465f1 Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Fri, 20 Mar 2020 17:00:36 -0400 Subject: [PATCH 41/77] remove another ToString statement --- osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs index f50c2cf001..4a8313b1f1 100644 --- a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs @@ -57,7 +57,7 @@ namespace osu.Game.Rulesets.Mods get { string drainRate = DrainRate.IsDefault ? "" : $"HP {DrainRate.Value.ToString()}"; - string overallDifficulty = OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value.ToString()}"; + string overallDifficulty = OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value}"; string[] settings = { drainRate, overallDifficulty }; // filter out empty strings so we don't have orphaned commas From 4907fb8fd1e966c1940936b74712c9bf672b3184 Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Fri, 20 Mar 2020 17:04:22 -0400 Subject: [PATCH 42/77] remove another ToString statement --- osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs index 4a8313b1f1..f8341e6cdb 100644 --- a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs @@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Mods { get { - string drainRate = DrainRate.IsDefault ? "" : $"HP {DrainRate.Value.ToString()}"; + string drainRate = DrainRate.IsDefault ? "" : $"HP {DrainRate.Value}"; string overallDifficulty = OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value}"; string[] settings = { drainRate, overallDifficulty }; From 63e9b2a299cf6496ec535315a4787ad9327cb044 Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Sun, 22 Mar 2020 18:49:45 -0400 Subject: [PATCH 43/77] use string.Empty, use base SettingDescription for [Osu/Catch]ModDifficultyAdjust --- .../Mods/CatchModDifficultyAdjust.cs | 17 ++++++------ .../Mods/OsuModDifficultyAdjust.cs | 17 ++++++------ osu.Game/Rulesets/Mods/Mod.cs | 26 ++++++++++++++++++- osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs | 14 +++++----- osu.Game/Rulesets/Mods/ModDoubleTime.cs | 2 +- osu.Game/Rulesets/Mods/ModEasy.cs | 2 +- osu.Game/Rulesets/Mods/ModHalfTime.cs | 2 +- 7 files changed, 54 insertions(+), 26 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs index 6d0025b236..a60b35739e 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Linq; using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Configuration; @@ -35,15 +36,15 @@ namespace osu.Game.Rulesets.Catch.Mods { get { - string circleSize = CircleSize.IsDefault ? "" : $"CS {CircleSize.Value}"; - string drainRate = DrainRate.IsDefault ? "" : $"HP {DrainRate.Value}"; - string overallDifficulty = OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value}"; - string approachRate = ApproachRate.IsDefault ? "" : $"AR {ApproachRate.Value}"; + string circleSize = CircleSize.IsDefault ? string.Empty : $"CS {CircleSize.Value}"; + string approachRate = ApproachRate.IsDefault ? string.Empty : $"AR {ApproachRate.Value}"; - string[] settings = { circleSize, drainRate, overallDifficulty, approachRate }; - // filter out empty strings so we don't have orphaned commas - settings = Array.FindAll(settings, s => !string.IsNullOrEmpty(s)); - return string.Join(", ", settings); + return string.Join(", ", new[] + { + circleSize, + base.SettingDescription, + approachRate + }.Where(s => !string.IsNullOrEmpty(s))); } } diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs index 307fe3da4a..18492828f0 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Linq; using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Configuration; @@ -35,15 +36,15 @@ namespace osu.Game.Rulesets.Osu.Mods { get { - string circleSize = CircleSize.IsDefault ? "" : $"CS {CircleSize.Value}"; - string drainRate = DrainRate.IsDefault ? "" : $"HP {DrainRate.Value}"; - string overallDifficulty = OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value}"; - string approachRate = ApproachRate.IsDefault ? "" : $"AR {ApproachRate.Value}"; + string circleSize = CircleSize.IsDefault ? string.Empty : $"CS {CircleSize.Value}"; + string approachRate = ApproachRate.IsDefault ? string.Empty : $"AR {ApproachRate.Value}"; - string[] settings = { circleSize, drainRate, overallDifficulty, approachRate }; - // filter out empty strings so we don't have orphaned commas - settings = Array.FindAll(settings, s => !string.IsNullOrEmpty(s)); - return string.Join(", ", settings); + return string.Join(", ", new[] + { + circleSize, + base.SettingDescription, + approachRate + }.Where(s => !string.IsNullOrEmpty(s))); } } diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index 231b95f974..95e8ff86eb 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -2,8 +2,13 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; using Newtonsoft.Json; +using osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; +using osu.Game.Configuration; using osu.Game.IO.Serialization; using osu.Game.Rulesets.UI; @@ -67,7 +72,26 @@ namespace osu.Game.Rulesets.Mods /// Parentheses are added to the tooltip, surrounding the value of this property. If this property is string.Empty, /// the tooltip will not have parentheses. /// - public virtual string SettingDescription => string.Empty; + public virtual string SettingDescription + { + get + { + var tooltipTexts = new List(); + + foreach ((SettingSourceAttribute attr, PropertyInfo property) in this.GetOrderedSettingsSourceProperties()) + { + object bindableObj = property.GetValue(this); + bool? settingIsDefault = (bindableObj as IHasDefaultValue)?.IsDefault; + string tooltipText = settingIsDefault == true ? string.Empty : attr.Label + " " + bindableObj.ToString(); + tooltipTexts.Add(tooltipText); + } + + // filter out empty strings so we don't have orphaned commas + //tooltipTexts = tooltipTexts.Where(s => !string.IsNullOrEmpty(s)).ToList(); + string joinedTooltipText = string.Join(", ", tooltipTexts); + return $"{Name}{joinedTooltipText}"; + } + } /// /// The score multiplier of this mod. diff --git a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs index f8341e6cdb..1baf9f7057 100644 --- a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics.Sprites; using System; using System.Collections.Generic; using osu.Game.Configuration; +using System.Linq; namespace osu.Game.Rulesets.Mods { @@ -56,13 +57,14 @@ namespace osu.Game.Rulesets.Mods { get { - string drainRate = DrainRate.IsDefault ? "" : $"HP {DrainRate.Value}"; - string overallDifficulty = OverallDifficulty.IsDefault ? "" : $"OD {OverallDifficulty.Value}"; + string drainRate = DrainRate.IsDefault ? string.Empty : $"HP {DrainRate.Value}"; + string overallDifficulty = OverallDifficulty.IsDefault ? string.Empty : $"OD {OverallDifficulty.Value}"; - string[] settings = { drainRate, overallDifficulty }; - // filter out empty strings so we don't have orphaned commas - settings = Array.FindAll(settings, s => !string.IsNullOrEmpty(s)); - return string.Join(", ", settings); + return string.Join(", ", new[] + { + drainRate, + overallDifficulty + }.Where(s => !string.IsNullOrEmpty(s))); } } diff --git a/osu.Game/Rulesets/Mods/ModDoubleTime.cs b/osu.Game/Rulesets/Mods/ModDoubleTime.cs index 05a8dbfa56..7d86190134 100644 --- a/osu.Game/Rulesets/Mods/ModDoubleTime.cs +++ b/osu.Game/Rulesets/Mods/ModDoubleTime.cs @@ -31,6 +31,6 @@ namespace osu.Game.Rulesets.Mods Precision = 0.01, }; - public override string SettingDescription => SpeedChange.IsDefault ? "" : $"{SpeedChange.Value}x"; + public override string SettingDescription => SpeedChange.IsDefault ? string.Empty : $"{SpeedChange.Value}x"; } } diff --git a/osu.Game/Rulesets/Mods/ModEasy.cs b/osu.Game/Rulesets/Mods/ModEasy.cs index a1dd6c088d..c1c4124b98 100644 --- a/osu.Game/Rulesets/Mods/ModEasy.cs +++ b/osu.Game/Rulesets/Mods/ModEasy.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Mods MaxValue = 10 }; - public override string SettingDescription => Retries.IsDefault ? "" : $"{"lives".ToQuantity(Retries.Value)}"; + public override string SettingDescription => Retries.IsDefault ? string.Empty : $"{"lives".ToQuantity(Retries.Value)}"; private int retries; diff --git a/osu.Game/Rulesets/Mods/ModHalfTime.cs b/osu.Game/Rulesets/Mods/ModHalfTime.cs index 5252ce8d89..ec215369a3 100644 --- a/osu.Game/Rulesets/Mods/ModHalfTime.cs +++ b/osu.Game/Rulesets/Mods/ModHalfTime.cs @@ -31,6 +31,6 @@ namespace osu.Game.Rulesets.Mods Precision = 0.01, }; - public override string SettingDescription => SpeedChange.IsDefault ? "" : $"{SpeedChange.Value}x"; + public override string SettingDescription => SpeedChange.IsDefault ? string.Empty : $"{SpeedChange.Value}x"; } } From 67667b3d22c0f0e389cd0717c1ed717704dfb11c Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Sun, 22 Mar 2020 21:22:46 -0400 Subject: [PATCH 44/77] enforce precision for ModDifficultyAdjust and derived classes --- osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs | 4 ++-- osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs | 4 ++-- osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs index a60b35739e..6288d498bd 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs @@ -36,8 +36,8 @@ namespace osu.Game.Rulesets.Catch.Mods { get { - string circleSize = CircleSize.IsDefault ? string.Empty : $"CS {CircleSize.Value}"; - string approachRate = ApproachRate.IsDefault ? string.Empty : $"AR {ApproachRate.Value}"; + string circleSize = CircleSize.IsDefault ? string.Empty : $"CS {CircleSize.Value:0.#}"; + string approachRate = ApproachRate.IsDefault ? string.Empty : $"AR {ApproachRate.Value:0.#}"; return string.Join(", ", new[] { diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs index 18492828f0..4830b29c4e 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs @@ -36,8 +36,8 @@ namespace osu.Game.Rulesets.Osu.Mods { get { - string circleSize = CircleSize.IsDefault ? string.Empty : $"CS {CircleSize.Value}"; - string approachRate = ApproachRate.IsDefault ? string.Empty : $"AR {ApproachRate.Value}"; + string circleSize = CircleSize.IsDefault ? string.Empty : $"CS {CircleSize.Value:0.#}"; + string approachRate = ApproachRate.IsDefault ? string.Empty : $"AR {ApproachRate.Value:0.#}"; return string.Join(", ", new[] { diff --git a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs index 1baf9f7057..06616c7b24 100644 --- a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs @@ -57,8 +57,8 @@ namespace osu.Game.Rulesets.Mods { get { - string drainRate = DrainRate.IsDefault ? string.Empty : $"HP {DrainRate.Value}"; - string overallDifficulty = OverallDifficulty.IsDefault ? string.Empty : $"OD {OverallDifficulty.Value}"; + string drainRate = DrainRate.IsDefault ? string.Empty : $"HP {DrainRate.Value:0.#}"; + string overallDifficulty = OverallDifficulty.IsDefault ? string.Empty : $"OD {OverallDifficulty.Value:0.#}"; return string.Join(", ", new[] { From cb6e6025567179280b52d2e58aa099af6b2ef5d9 Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Sun, 22 Mar 2020 22:06:35 -0400 Subject: [PATCH 45/77] enforce single signficiant digit precision for other mods --- osu.Game/Rulesets/Mods/ModDoubleTime.cs | 2 +- osu.Game/Rulesets/Mods/ModHalfTime.cs | 2 +- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModDoubleTime.cs b/osu.Game/Rulesets/Mods/ModDoubleTime.cs index 7d86190134..105c19dec7 100644 --- a/osu.Game/Rulesets/Mods/ModDoubleTime.cs +++ b/osu.Game/Rulesets/Mods/ModDoubleTime.cs @@ -31,6 +31,6 @@ namespace osu.Game.Rulesets.Mods Precision = 0.01, }; - public override string SettingDescription => SpeedChange.IsDefault ? string.Empty : $"{SpeedChange.Value}x"; + public override string SettingDescription => SpeedChange.IsDefault ? string.Empty : $"{SpeedChange.Value:0.#}x"; } } diff --git a/osu.Game/Rulesets/Mods/ModHalfTime.cs b/osu.Game/Rulesets/Mods/ModHalfTime.cs index ec215369a3..32e16e0914 100644 --- a/osu.Game/Rulesets/Mods/ModHalfTime.cs +++ b/osu.Game/Rulesets/Mods/ModHalfTime.cs @@ -31,6 +31,6 @@ namespace osu.Game.Rulesets.Mods Precision = 0.01, }; - public override string SettingDescription => SpeedChange.IsDefault ? string.Empty : $"{SpeedChange.Value}x"; + public override string SettingDescription => SpeedChange.IsDefault ? string.Empty : $"{SpeedChange.Value:0.#}x"; } } diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index 7b4c1370ac..01b49faa75 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Mods [SettingSource("Final rate", "The final speed to ramp to")] public abstract BindableNumber FinalRate { get; } - public override string SettingDescription => $"{InitialRate.Value} to {FinalRate.Value}"; + public override string SettingDescription => $"{InitialRate.Value:0.#} to {FinalRate.Value:0.#}"; private double finalRateTime; private double beginRampTime; From ea87afd5775c8f4220d642d093f0fe664b1a0d3e Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Sun, 22 Mar 2020 22:06:54 -0400 Subject: [PATCH 46/77] use string.Empty in IconTooltip --- osu.Game/Rulesets/Mods/Mod.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index 95e8ff86eb..23ad48ac5a 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -60,7 +60,7 @@ namespace osu.Game.Rulesets.Mods { get { - string settingDescription = string.IsNullOrEmpty(SettingDescription) ? "" : $" ({SettingDescription})"; + string settingDescription = string.IsNullOrEmpty(SettingDescription) ? string.Empty : $" ({SettingDescription})"; return $"{Name}{settingDescription}"; } } From 98b8f828103c037ae54ecbeb07c9a398289ae335 Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Sun, 22 Mar 2020 22:07:09 -0400 Subject: [PATCH 47/77] simplify SettingDescription default definition --- osu.Game/Rulesets/Mods/Mod.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index 23ad48ac5a..5944717c13 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -86,10 +86,8 @@ namespace osu.Game.Rulesets.Mods tooltipTexts.Add(tooltipText); } - // filter out empty strings so we don't have orphaned commas - //tooltipTexts = tooltipTexts.Where(s => !string.IsNullOrEmpty(s)).ToList(); - string joinedTooltipText = string.Join(", ", tooltipTexts); - return $"{Name}{joinedTooltipText}"; + string joinedTooltipText = string.Join(", ", tooltipTexts.Where(s => !string.IsNullOrEmpty(s))); + return $"{joinedTooltipText}"; } } From afe7397d891237271902caa4b3f31f8b189b770b Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Sun, 22 Mar 2020 22:50:52 -0400 Subject: [PATCH 48/77] remove unnecessary using statements --- osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs | 1 - osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs index 6288d498bd..c465048da3 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using System.Linq; using osu.Framework.Bindables; using osu.Game.Beatmaps; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs index 4830b29c4e..fab4638fb7 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using System.Linq; using osu.Framework.Bindables; using osu.Game.Beatmaps; From 889608a408e854e30ffd2177aa9d3f079cc71717 Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Sun, 22 Mar 2020 22:51:29 -0400 Subject: [PATCH 49/77] remove redundant ToString call --- osu.Game/Rulesets/Mods/Mod.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index 5944717c13..f712fdc3be 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -82,7 +82,7 @@ namespace osu.Game.Rulesets.Mods { object bindableObj = property.GetValue(this); bool? settingIsDefault = (bindableObj as IHasDefaultValue)?.IsDefault; - string tooltipText = settingIsDefault == true ? string.Empty : attr.Label + " " + bindableObj.ToString(); + string tooltipText = settingIsDefault == true ? string.Empty : attr.Label + " " + bindableObj; tooltipTexts.Add(tooltipText); } From 1da590c63f6b77b68471e564e1210b2109f304aa Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Sun, 22 Mar 2020 22:54:21 -0400 Subject: [PATCH 50/77] use N1 format instead of 0.# --- osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs | 4 ++-- osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs | 4 ++-- osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs | 4 ++-- osu.Game/Rulesets/Mods/ModDoubleTime.cs | 2 +- osu.Game/Rulesets/Mods/ModHalfTime.cs | 2 +- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs index c465048da3..acdd0a420c 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs @@ -35,8 +35,8 @@ namespace osu.Game.Rulesets.Catch.Mods { get { - string circleSize = CircleSize.IsDefault ? string.Empty : $"CS {CircleSize.Value:0.#}"; - string approachRate = ApproachRate.IsDefault ? string.Empty : $"AR {ApproachRate.Value:0.#}"; + string circleSize = CircleSize.IsDefault ? string.Empty : $"CS {CircleSize.Value:N1}"; + string approachRate = ApproachRate.IsDefault ? string.Empty : $"AR {ApproachRate.Value:N1}"; return string.Join(", ", new[] { diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs index fab4638fb7..8228161008 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs @@ -35,8 +35,8 @@ namespace osu.Game.Rulesets.Osu.Mods { get { - string circleSize = CircleSize.IsDefault ? string.Empty : $"CS {CircleSize.Value:0.#}"; - string approachRate = ApproachRate.IsDefault ? string.Empty : $"AR {ApproachRate.Value:0.#}"; + string circleSize = CircleSize.IsDefault ? string.Empty : $"CS {CircleSize.Value:N1}"; + string approachRate = ApproachRate.IsDefault ? string.Empty : $"AR {ApproachRate.Value:N1}"; return string.Join(", ", new[] { diff --git a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs index 06616c7b24..c3a8efdd66 100644 --- a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs @@ -57,8 +57,8 @@ namespace osu.Game.Rulesets.Mods { get { - string drainRate = DrainRate.IsDefault ? string.Empty : $"HP {DrainRate.Value:0.#}"; - string overallDifficulty = OverallDifficulty.IsDefault ? string.Empty : $"OD {OverallDifficulty.Value:0.#}"; + string drainRate = DrainRate.IsDefault ? string.Empty : $"HP {DrainRate.Value:N1}"; + string overallDifficulty = OverallDifficulty.IsDefault ? string.Empty : $"OD {OverallDifficulty.Value:N1}"; return string.Join(", ", new[] { diff --git a/osu.Game/Rulesets/Mods/ModDoubleTime.cs b/osu.Game/Rulesets/Mods/ModDoubleTime.cs index 105c19dec7..3f01bfb11e 100644 --- a/osu.Game/Rulesets/Mods/ModDoubleTime.cs +++ b/osu.Game/Rulesets/Mods/ModDoubleTime.cs @@ -31,6 +31,6 @@ namespace osu.Game.Rulesets.Mods Precision = 0.01, }; - public override string SettingDescription => SpeedChange.IsDefault ? string.Empty : $"{SpeedChange.Value:0.#}x"; + public override string SettingDescription => SpeedChange.IsDefault ? string.Empty : $"{SpeedChange.Value:N1}x"; } } diff --git a/osu.Game/Rulesets/Mods/ModHalfTime.cs b/osu.Game/Rulesets/Mods/ModHalfTime.cs index 32e16e0914..c555692ed9 100644 --- a/osu.Game/Rulesets/Mods/ModHalfTime.cs +++ b/osu.Game/Rulesets/Mods/ModHalfTime.cs @@ -31,6 +31,6 @@ namespace osu.Game.Rulesets.Mods Precision = 0.01, }; - public override string SettingDescription => SpeedChange.IsDefault ? string.Empty : $"{SpeedChange.Value:0.#}x"; + public override string SettingDescription => SpeedChange.IsDefault ? string.Empty : $"{SpeedChange.Value:N1}x"; } } diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index 01b49faa75..f21ba684b4 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Mods [SettingSource("Final rate", "The final speed to ramp to")] public abstract BindableNumber FinalRate { get; } - public override string SettingDescription => $"{InitialRate.Value:0.#} to {FinalRate.Value:0.#}"; + public override string SettingDescription => $"{InitialRate.Value:0.#} to {FinalRate.Value:N1}"; private double finalRateTime; private double beginRampTime; From 5cc626d37b746c69d5979e9c465933c8fe6c1b8a Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Sun, 22 Mar 2020 22:57:46 -0400 Subject: [PATCH 51/77] move SettingDescription override to ModRateAdjust --- osu.Game/Rulesets/Mods/ModDoubleTime.cs | 2 -- osu.Game/Rulesets/Mods/ModHalfTime.cs | 2 -- osu.Game/Rulesets/Mods/ModRateAdjust.cs | 2 ++ 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModDoubleTime.cs b/osu.Game/Rulesets/Mods/ModDoubleTime.cs index 3f01bfb11e..152657da33 100644 --- a/osu.Game/Rulesets/Mods/ModDoubleTime.cs +++ b/osu.Game/Rulesets/Mods/ModDoubleTime.cs @@ -30,7 +30,5 @@ namespace osu.Game.Rulesets.Mods Value = 1.5, Precision = 0.01, }; - - public override string SettingDescription => SpeedChange.IsDefault ? string.Empty : $"{SpeedChange.Value:N1}x"; } } diff --git a/osu.Game/Rulesets/Mods/ModHalfTime.cs b/osu.Game/Rulesets/Mods/ModHalfTime.cs index c555692ed9..203b88951c 100644 --- a/osu.Game/Rulesets/Mods/ModHalfTime.cs +++ b/osu.Game/Rulesets/Mods/ModHalfTime.cs @@ -30,7 +30,5 @@ namespace osu.Game.Rulesets.Mods Value = 0.75, Precision = 0.01, }; - - public override string SettingDescription => SpeedChange.IsDefault ? string.Empty : $"{SpeedChange.Value:N1}x"; } } diff --git a/osu.Game/Rulesets/Mods/ModRateAdjust.cs b/osu.Game/Rulesets/Mods/ModRateAdjust.cs index 1739524bcd..9059d54035 100644 --- a/osu.Game/Rulesets/Mods/ModRateAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModRateAdjust.cs @@ -15,5 +15,7 @@ namespace osu.Game.Rulesets.Mods { track.AddAdjustment(AdjustableProperty.Tempo, SpeedChange); } + + public override string SettingDescription => SpeedChange.IsDefault ? string.Empty : $"{SpeedChange.Value:N1}x"; } } From 64fc116d673500e6b4e55639e7e7daf7d7fad640 Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Sun, 22 Mar 2020 23:08:00 -0400 Subject: [PATCH 52/77] use two decimal points for ModRateAdjust format --- osu.Game/Rulesets/Mods/ModRateAdjust.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModRateAdjust.cs b/osu.Game/Rulesets/Mods/ModRateAdjust.cs index 9059d54035..cb2ff149f1 100644 --- a/osu.Game/Rulesets/Mods/ModRateAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModRateAdjust.cs @@ -16,6 +16,6 @@ namespace osu.Game.Rulesets.Mods track.AddAdjustment(AdjustableProperty.Tempo, SpeedChange); } - public override string SettingDescription => SpeedChange.IsDefault ? string.Empty : $"{SpeedChange.Value:N1}x"; + public override string SettingDescription => SpeedChange.IsDefault ? string.Empty : $"{SpeedChange.Value:N2}x"; } } From a6b153673e2fa61dc5c7c674a5fb6b964008063d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 23 Mar 2020 14:58:02 +0900 Subject: [PATCH 53/77] Fix icons not updating tooltip text correctly --- osu.Game/Rulesets/UI/ModIcon.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/UI/ModIcon.cs b/osu.Game/Rulesets/UI/ModIcon.cs index 3cd1b0820d..8ea6c74349 100644 --- a/osu.Game/Rulesets/UI/ModIcon.cs +++ b/osu.Game/Rulesets/UI/ModIcon.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.UI private readonly ModType type; - public virtual string TooltipText { get; } + public virtual string TooltipText => mod.IconTooltip; private Mod mod; @@ -48,8 +48,6 @@ namespace osu.Game.Rulesets.UI type = mod.Type; - TooltipText = mod.IconTooltip; - Size = new Vector2(size); Children = new Drawable[] From 205f4dcb54f854fc36fcf8e322e20329e4e3144f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 23 Mar 2020 15:20:56 +0900 Subject: [PATCH 54/77] Simplify string construction logic --- osu.Game/Rulesets/Mods/Mod.cs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index f712fdc3be..0e5fe3fc9c 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -60,8 +60,9 @@ namespace osu.Game.Rulesets.Mods { get { - string settingDescription = string.IsNullOrEmpty(SettingDescription) ? string.Empty : $" ({SettingDescription})"; - return $"{Name}{settingDescription}"; + string description = SettingDescription; + + return string.IsNullOrEmpty(description) ? Name : $"{Name} ({description})"; } } @@ -81,13 +82,14 @@ namespace osu.Game.Rulesets.Mods foreach ((SettingSourceAttribute attr, PropertyInfo property) in this.GetOrderedSettingsSourceProperties()) { object bindableObj = property.GetValue(this); - bool? settingIsDefault = (bindableObj as IHasDefaultValue)?.IsDefault; - string tooltipText = settingIsDefault == true ? string.Empty : attr.Label + " " + bindableObj; - tooltipTexts.Add(tooltipText); + + if ((bindableObj as IHasDefaultValue)?.IsDefault == true) + continue; + + tooltipTexts.Add($"{attr.Label} {bindableObj}"); } - string joinedTooltipText = string.Join(", ", tooltipTexts.Where(s => !string.IsNullOrEmpty(s))); - return $"{joinedTooltipText}"; + return string.Join(", ", tooltipTexts.Where(s => !string.IsNullOrEmpty(s))); } } From 2fa42ed644d4dede960ec3e1bb4c424551b22ec6 Mon Sep 17 00:00:00 2001 From: Liam DeVoe Date: Mon, 23 Mar 2020 12:54:08 -0400 Subject: [PATCH 55/77] use N2 for ModTimeRamp, add x text --- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index f21ba684b4..c1f3e357a1 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Mods [SettingSource("Final rate", "The final speed to ramp to")] public abstract BindableNumber FinalRate { get; } - public override string SettingDescription => $"{InitialRate.Value:0.#} to {FinalRate.Value:N1}"; + public override string SettingDescription => $"{InitialRate.Value:N2}x to {FinalRate.Value:N2}x"; private double finalRateTime; private double beginRampTime; From 902734b75e8a0b0ceb65e2c5c46f3f2d7bbd2972 Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Thu, 26 Mar 2020 20:32:43 +0200 Subject: [PATCH 56/77] Add failing test --- .../SongSelect/TestSceneBeatmapCarousel.cs | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index 0cc37bbd57..efe79d88ab 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -83,6 +83,38 @@ namespace osu.Game.Tests.Visual.SongSelect waitForSelection(set_count, 3); } + [Test] + public void TestTraversalHold() + { + var sets = new List(); + + for (int i = 0; i < 20; i++) + { + var set = createTestBeatmapSet(i); + sets.Add(set); + } + + loadBeatmaps(sets); + + void selectNextAndAssert(int amount) + { + setSelected(1, 1); + AddStep($"Next beatmap {amount} times", () => + { + for (int i = 0; i < amount; i++) + { + carousel.SelectNext(); + } + }); + waitForSelection(amount + 1); + } + + for (int i = 1; i < 15; i += i) + { + selectNextAndAssert(i); + } + } + /// /// Test filtering /// From e707adb7738fcf6a72ea4bdb8c4c5a9ecfd361cb Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Thu, 26 Mar 2020 21:16:10 +0200 Subject: [PATCH 57/77] Increase amount of test sets --- osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index efe79d88ab..31114dfd25 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -87,8 +87,9 @@ namespace osu.Game.Tests.Visual.SongSelect public void TestTraversalHold() { var sets = new List(); + const int create_this_many_sets = 200; - for (int i = 0; i < 20; i++) + for (int i = 0; i < create_this_many_sets; i++) { var set = createTestBeatmapSet(i); sets.Add(set); @@ -109,7 +110,7 @@ namespace osu.Game.Tests.Visual.SongSelect waitForSelection(amount + 1); } - for (int i = 1; i < 15; i += i) + for (int i = 1; i < create_this_many_sets; i += i) { selectNextAndAssert(i); } From fc3f9ff6faf06324e32c7964d5af915a0b16ffcb Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Sat, 28 Mar 2020 12:54:48 +0200 Subject: [PATCH 58/77] Don't use drawables for select next --- osu.Game/Screens/Select/BeatmapCarousel.cs | 57 +++++++++------------- 1 file changed, 23 insertions(+), 34 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index fa8974f55a..df2c1236f4 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -253,46 +253,35 @@ namespace osu.Game.Screens.Select /// Whether to skip individual difficulties and only increment over full groups. public void SelectNext(int direction = 1, bool skipDifficulties = true) { - var visibleItems = Items.Where(s => !s.Item.Filtered.Value).ToList(); - - if (!visibleItems.Any()) + if (!root.Children.Where(s => !s.Filtered.Value).ToList().Any()) return; - DrawableCarouselItem drawable = null; + if (skipDifficulties) + selectNextSet(direction, true); + else + selectNextDifficulty(direction); + } - if (selectedBeatmap != null && (drawable = selectedBeatmap.Drawables.FirstOrDefault()) == null) - // if the selected beatmap isn't present yet, we can't correctly change selection. - // we can fix this by changing this method to not reference drawables / Items in the first place. - return; + private void selectNextSet(int direction, bool skipDifficulties) + { + var visibleSets = root.Children.OfType().Where(s => !s.Filtered.Value).ToList(); - int originalIndex = visibleItems.IndexOf(drawable); - int currentIndex = originalIndex; + var item = visibleSets[(visibleSets.IndexOf(selectedBeatmapSet) + direction + visibleSets.Count) % visibleSets.Count]; - // local function to increment the index in the required direction, wrapping over extremities. - int incrementIndex() => currentIndex = (currentIndex + direction + visibleItems.Count) % visibleItems.Count; + if (skipDifficulties) + select(item); + else + select(direction > 0 ? item.Beatmaps.First(b => !b.Filtered.Value) : item.Beatmaps.Last(b => !b.Filtered.Value)); + } - while (incrementIndex() != originalIndex) - { - var item = visibleItems[currentIndex].Item; - - if (item.Filtered.Value || item.State.Value == CarouselItemState.Selected) continue; - - switch (item) - { - case CarouselBeatmap beatmap: - if (skipDifficulties) continue; - - select(beatmap); - return; - - case CarouselBeatmapSet set: - if (skipDifficulties) - select(set); - else - select(direction > 0 ? set.Beatmaps.First(b => !b.Filtered.Value) : set.Beatmaps.Last(b => !b.Filtered.Value)); - return; - } - } + private void selectNextDifficulty(int direction) + { + var difficulties = selectedBeatmapSet.Children.Where(s => !s.Filtered.Value).ToList(); + int index = difficulties.IndexOf(selectedBeatmap); + if (index + direction < 0 || index + direction >= difficulties.Count) + selectNextSet(direction, false); + else + select(difficulties[index + direction]); } /// From 6a0c5c87aa52c908af5f632b58b7849e45988c6e Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Sat, 28 Mar 2020 13:06:03 +0200 Subject: [PATCH 59/77] Use already existing variable --- osu.Game/Screens/Select/BeatmapCarousel.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index df2c1236f4..a6cbf58023 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -253,7 +253,7 @@ namespace osu.Game.Screens.Select /// Whether to skip individual difficulties and only increment over full groups. public void SelectNext(int direction = 1, bool skipDifficulties = true) { - if (!root.Children.Where(s => !s.Filtered.Value).ToList().Any()) + if (!beatmapSets.Where(s => !s.Filtered.Value).ToList().Any()) return; if (skipDifficulties) @@ -264,7 +264,7 @@ namespace osu.Game.Screens.Select private void selectNextSet(int direction, bool skipDifficulties) { - var visibleSets = root.Children.OfType().Where(s => !s.Filtered.Value).ToList(); + var visibleSets = beatmapSets.Where(s => !s.Filtered.Value).ToList(); var item = visibleSets[(visibleSets.IndexOf(selectedBeatmapSet) + direction + visibleSets.Count) % visibleSets.Count]; From 659865b45762ee153f02888e8bbfdc92513b83b3 Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Sat, 28 Mar 2020 13:08:06 +0200 Subject: [PATCH 60/77] Use understandable set id --- osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index 31114dfd25..a811e58694 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -91,7 +91,7 @@ namespace osu.Game.Tests.Visual.SongSelect for (int i = 0; i < create_this_many_sets; i++) { - var set = createTestBeatmapSet(i); + var set = createTestBeatmapSet(i + 1); sets.Add(set); } From 63f6269eb0ae7e88a8b810c6c7ba5690a9cea1dd Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Sat, 28 Mar 2020 13:10:20 +0200 Subject: [PATCH 61/77] Test both ways --- .../Visual/SongSelect/TestSceneBeatmapCarousel.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index a811e58694..b316fcc60b 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -83,8 +83,9 @@ namespace osu.Game.Tests.Visual.SongSelect waitForSelection(set_count, 3); } - [Test] - public void TestTraversalHold() + [TestCase(true)] + [TestCase(false)] + public void TestTraversalHold(bool forwards) { var sets = new List(); const int create_this_many_sets = 200; @@ -99,15 +100,16 @@ namespace osu.Game.Tests.Visual.SongSelect void selectNextAndAssert(int amount) { - setSelected(1, 1); - AddStep($"Next beatmap {amount} times", () => + setSelected(forwards ? 1 : create_this_many_sets, 1); + string text = forwards ? "Next" : "Previous"; + AddStep($"{text} beatmap {amount} times", () => { for (int i = 0; i < amount; i++) { - carousel.SelectNext(); + carousel.SelectNext(forwards ? 1 : -1); } }); - waitForSelection(amount + 1); + waitForSelection(forwards ? amount + 1 : create_this_many_sets - amount); } for (int i = 1; i < create_this_many_sets; i += i) From 87854fc4fabea688d60922552f487037e4873d44 Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Sat, 28 Mar 2020 13:23:31 +0200 Subject: [PATCH 62/77] Rename variable --- osu.Game/Screens/Select/BeatmapCarousel.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index a6cbf58023..91a9b19115 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -266,12 +266,12 @@ namespace osu.Game.Screens.Select { var visibleSets = beatmapSets.Where(s => !s.Filtered.Value).ToList(); - var item = visibleSets[(visibleSets.IndexOf(selectedBeatmapSet) + direction + visibleSets.Count) % visibleSets.Count]; + var nextSet = visibleSets[(visibleSets.IndexOf(selectedBeatmapSet) + direction + visibleSets.Count) % visibleSets.Count]; if (skipDifficulties) - select(item); + select(nextSet); else - select(direction > 0 ? item.Beatmaps.First(b => !b.Filtered.Value) : item.Beatmaps.Last(b => !b.Filtered.Value)); + select(direction > 0 ? nextSet.Beatmaps.First(b => !b.Filtered.Value) : nextSet.Beatmaps.Last(b => !b.Filtered.Value)); } private void selectNextDifficulty(int direction) From 2c27894527f91317e16e660f61a613c700110282 Mon Sep 17 00:00:00 2001 From: Endrik Date: Sat, 28 Mar 2020 19:58:33 +0200 Subject: [PATCH 63/77] Use All instead of ToList Any MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Bartłomiej Dach --- osu.Game/Screens/Select/BeatmapCarousel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 91a9b19115..cd2deb8abe 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -253,7 +253,7 @@ namespace osu.Game.Screens.Select /// Whether to skip individual difficulties and only increment over full groups. public void SelectNext(int direction = 1, bool skipDifficulties = true) { - if (!beatmapSets.Where(s => !s.Filtered.Value).ToList().Any()) + if (beatmapSets.All(s => !s.Filtered.Value)) return; if (skipDifficulties) From b4f05007063dcb46cb6736a817ccb5e18222a511 Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Sat, 28 Mar 2020 20:21:21 +0200 Subject: [PATCH 64/77] Invert logic --- osu.Game/Screens/Select/BeatmapCarousel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index cd2deb8abe..a2c2cde7c7 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -253,7 +253,7 @@ namespace osu.Game.Screens.Select /// Whether to skip individual difficulties and only increment over full groups. public void SelectNext(int direction = 1, bool skipDifficulties = true) { - if (beatmapSets.All(s => !s.Filtered.Value)) + if (beatmapSets.All(s => s.Filtered.Value)) return; if (skipDifficulties) From 8cab303611786eeba91aa2a67bb25633f23e10c6 Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Sat, 28 Mar 2020 21:02:55 +0200 Subject: [PATCH 65/77] Cover skipDifficulties = false in tests --- .../SongSelect/TestSceneBeatmapCarousel.cs | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index b316fcc60b..7c3498e034 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -118,6 +118,50 @@ namespace osu.Game.Tests.Visual.SongSelect } } + [Test] + public void TestTraversalHoldDifficulties() + { + var sets = new List(); + + for (int i = 0; i < 20; i++) + { + var set = createTestBeatmapSet(i + 1); + sets.Add(set); + } + + loadBeatmaps(sets); + + void selectNextAndAssert(int amount, bool forwards, int expectedSet, int expectedDiff) + { + // Select very first or very last difficulty + setSelected(forwards ? 1 : 20, forwards ? 1 : 3); + string text = forwards ? "Next" : "Previous"; + AddStep($"{text} difficulty {amount} times", () => + { + for (int i = 0; i < amount; i++) + { + carousel.SelectNext(forwards ? 1 : -1, false); + } + }); + waitForSelection(expectedSet, expectedDiff); + } + + // Selects next set once, difficulty index doesn't change + selectNextAndAssert(3, true, 2, 1); + // Selects next set 16 times (50 // 3 == 16), difficulty index changes twice (50 % 3 == 2) + selectNextAndAssert(50, true, 17, 3); + // Travels around the carousel thrice (200/60 == 3) + // continues to select 20 times (200 % 60 == 20) + // selects next set 6 times (20 // 3 == 6) + // difficulty index changes twice (20 % 3 == 2) + selectNextAndAssert(200, true, 7, 3); + + // All same but in reverse + selectNextAndAssert(3, false, 19, 3); + selectNextAndAssert(50, false, 4, 1); + selectNextAndAssert(200, false, 14, 1); + } + /// /// Test filtering /// From a2b3fe180e096a6f85ab034370821b917ce79345 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 29 Mar 2020 14:30:45 +0900 Subject: [PATCH 66/77] Add the ability to disable user input on specific DrawableHitObjects --- .../Rulesets/Objects/Drawables/DrawableHitObject.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 5b5802fa9d..9aad125ed1 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -38,6 +38,19 @@ namespace osu.Game.Rulesets.Objects.Drawables private readonly Lazy> nestedHitObjects = new Lazy>(); public IReadOnlyList NestedHitObjects => nestedHitObjects.IsValueCreated ? nestedHitObjects.Value : (IReadOnlyList)Array.Empty(); + /// + /// Whether this object should handle any user input events. + /// + public bool HandleUserInput { get; set; } = true; + + public override bool HandlePositionalInput => HandleUserInput; + + public override bool HandleNonPositionalInput => HandleUserInput; + + public override bool PropagatePositionalInputSubTree => HandleUserInput; + + public override bool PropagateNonPositionalInputSubTree => HandleUserInput; + /// /// Invoked when a has been applied by this or a nested . /// From d1b01095ee292b02ad1af51ff6a74b49df8c8929 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 29 Mar 2020 14:31:03 +0900 Subject: [PATCH 67/77] Rewrite to reduce code changes and complexities in hit object implementation --- osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs | 17 ++++++-------- .../Objects/Drawables/DrawableSpinner.cs | 9 ++++---- .../Objects/Drawables/Pieces/SpinnerDisc.cs | 23 ++++++++++++++----- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs index 49c4e7fa45..7b54baa99b 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs @@ -30,21 +30,18 @@ namespace osu.Game.Rulesets.Osu.Mods { if (hitObject is DrawableSpinner spinner) { - spinner.Disc.Enabled = false; - spinner.OnUpdate += autoSpin; + spinner.HandleUserInput = false; + spinner.OnUpdate += onSpinnerUpdate; } } } - private void autoSpin(Drawable drawable) + private void onSpinnerUpdate(Drawable drawable) { - if (drawable is DrawableSpinner spinner) - { - if (spinner.Disc.Valid) - spinner.Disc.Rotate(MathUtils.RadiansToDegrees((float)spinner.Clock.ElapsedFrameTime * 0.03f)); - if (!spinner.SpmCounter.IsPresent) - spinner.SpmCounter.FadeIn(spinner.HitObject.TimeFadeIn); - } + var spinner = (DrawableSpinner)drawable; + + spinner.Disc.Tracking = true; + spinner.Disc.Rotate(MathUtils.RadiansToDegrees((float)spinner.Clock.ElapsedFrameTime * 0.03f)); } } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 0ec7f2ebfe..3c8ab0f5ab 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -176,17 +176,18 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void Update() { - Disc.Tracking = OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false; - if (!SpmCounter.IsPresent && Disc.Tracking) - SpmCounter.FadeIn(HitObject.TimeFadeIn); - base.Update(); + if (HandleUserInput) + Disc.Tracking = OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false; } protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); + if (!SpmCounter.IsPresent && Disc.Tracking) + SpmCounter.FadeIn(HitObject.TimeFadeIn); + circle.Rotation = Disc.Rotation; Ticks.Rotation = Disc.Rotation; SpmCounter.SetRotation(Disc.RotationAbsolute); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs index 0c089c1fed..d4ef039b79 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs @@ -50,9 +50,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces get => tracking; set { - if ((Enabled && value) == tracking) return; + if (value == tracking) return; - tracking = Enabled && value; + tracking = value; background.FadeTo(tracking ? tracking_alpha : idle_alpha, 100); } @@ -73,9 +73,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces } } - public bool Valid => spinner.StartTime <= Time.Current && spinner.EndTime > Time.Current; - - public bool Enabled { get; set; } = true; + /// + /// Whether currently in the correct time range to allow spinning. + /// + private bool isSpinnableTime => spinner.StartTime <= Time.Current && spinner.EndTime > Time.Current; protected override bool OnMouseMove(MouseMoveEvent e) { @@ -101,7 +102,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces var delta = thisAngle - lastAngle; - if (Valid && tracking) + if (tracking) Rotate(delta); lastAngle = thisAngle; @@ -118,8 +119,18 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Rotation = (float)Interpolation.Lerp(Rotation, currentRotation / 2, Math.Clamp(Math.Abs(Time.Elapsed) / 40, 0, 1)); } + /// + /// Rotate the disc by the provided angle (in addition to any existing rotation). + /// + /// + /// Will be a no-op if not a valid time to spin. + /// + /// The delta angle. public void Rotate(float angle) { + if (!isSpinnableTime) + return; + if (!rotationTransferred) { currentRotation = Rotation * 2; From 4f5557096c238ac602b59d3dab39605b93cb2ca2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 29 Mar 2020 22:51:28 +0900 Subject: [PATCH 68/77] Fix auto mod results not displaying correctly --- osu.Game/Screens/Play/Player.cs | 64 ++++++++++++++------------- osu.Game/Screens/Play/ReplayPlayer.cs | 6 +++ 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 63ec3b0d2d..5da53ad2c9 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -637,6 +637,39 @@ namespace osu.Game.Screens.Play return base.OnExiting(next); } + protected virtual void GotoRanking() + { + if (DrawableRuleset.ReplayScore != null) + { + // if a replay is present, we likely don't want to import into the local database. + this.Push(CreateResults(CreateScore())); + return; + } + + LegacyByteArrayReader replayReader = null; + + var score = new Score { ScoreInfo = CreateScore() }; + + if (recordingReplay?.Frames.Count > 0) + { + score.Replay = recordingReplay; + + using (var stream = new MemoryStream()) + { + new LegacyScoreEncoder(score, gameplayBeatmap.PlayableBeatmap).Encode(stream); + replayReader = new LegacyByteArrayReader(stream.ToArray(), "replay.osr"); + } + } + + scoreManager.Import(score.ScoreInfo, replayReader) + .ContinueWith(imported => Schedule(() => + { + // screen may be in the exiting transition phase. + if (this.IsCurrentScreen()) + this.Push(CreateResults(imported.Result)); + })); + } + private void fadeOut(bool instant = false) { float fadeOutDuration = instant ? 0 : 250; @@ -649,36 +682,7 @@ namespace osu.Game.Screens.Play private void scheduleGotoRanking() { completionProgressDelegate?.Cancel(); - completionProgressDelegate = Schedule(delegate - { - if (DrawableRuleset.ReplayScore != null) - this.Push(CreateResults(DrawableRuleset.ReplayScore.ScoreInfo)); - else - { - var score = new Score { ScoreInfo = CreateScore() }; - - LegacyByteArrayReader replayReader = null; - - if (recordingReplay?.Frames.Count > 0) - { - score.Replay = recordingReplay; - - using (var stream = new MemoryStream()) - { - new LegacyScoreEncoder(score, gameplayBeatmap.PlayableBeatmap).Encode(stream); - replayReader = new LegacyByteArrayReader(stream.ToArray(), "replay.osr"); - } - } - - scoreManager.Import(score.ScoreInfo, replayReader) - .ContinueWith(imported => Schedule(() => - { - // screen may be in the exiting transition phase. - if (this.IsCurrentScreen()) - this.Push(CreateResults(imported.Result)); - })); - } - }); + completionProgressDelegate = Schedule(GotoRanking); } #endregion diff --git a/osu.Game/Screens/Play/ReplayPlayer.cs b/osu.Game/Screens/Play/ReplayPlayer.cs index 8708b5f634..74c853340d 100644 --- a/osu.Game/Screens/Play/ReplayPlayer.cs +++ b/osu.Game/Screens/Play/ReplayPlayer.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Screens; using osu.Game.Scoring; namespace osu.Game.Screens.Play @@ -23,6 +24,11 @@ namespace osu.Game.Screens.Play DrawableRuleset?.SetReplayScore(score); } + protected override void GotoRanking() + { + this.Push(CreateResults(DrawableRuleset.ReplayScore.ScoreInfo)); + } + protected override ScoreInfo CreateScore() => score.ScoreInfo; } } From 653480b2f855d103405f7e4bdd6c041fd5967eed Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 29 Mar 2020 23:29:46 +0900 Subject: [PATCH 69/77] Add regression test --- .../Visual/Gameplay/TestSceneAllRulesetPlayers.cs | 4 ---- .../Visual/Gameplay/TestSceneAutoplay.cs | 15 +++++++++++++-- osu.Game/Screens/Ranking/ResultsScreen.cs | 8 ++++---- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneAllRulesetPlayers.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneAllRulesetPlayers.cs index 83a7b896d2..b7dcad3825 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneAllRulesetPlayers.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneAllRulesetPlayers.cs @@ -4,7 +4,6 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; -using osu.Framework.Screens; using osu.Game.Configuration; using osu.Game.Rulesets; using osu.Game.Rulesets.Catch; @@ -74,9 +73,6 @@ namespace osu.Game.Tests.Visual.Gameplay Beatmap.Value = working; SelectedMods.Value = new[] { ruleset.GetAllMods().First(m => m is ModNoFail) }; - Player?.Exit(); - Player = null; - Player = CreatePlayer(ruleset); LoadScreen(Player); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs index 5ee17aeea2..43fb848ab8 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs @@ -5,8 +5,11 @@ using System.ComponentModel; using System.Linq; using osu.Framework.Testing; using osu.Game.Rulesets; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Play; using osu.Game.Screens.Play.Break; +using osu.Game.Screens.Ranking; namespace osu.Game.Tests.Visual.Gameplay { @@ -17,8 +20,8 @@ namespace osu.Game.Tests.Visual.Gameplay protected override Player CreatePlayer(Ruleset ruleset) { - SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray(); - return new TestPlayer(false, false); + SelectedMods.Value = new[] { ruleset.GetAutoplayMod() }; + return new TestPlayer(false); } protected override void AddCheckSteps() @@ -32,6 +35,14 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("overlay displays 100% accuracy", () => Player.BreakOverlay.ChildrenOfType().Single().AccuracyDisplay.Current.Value == 1); AddStep("rewind", () => Player.GameplayClockContainer.Seek(-80000)); AddUntilStep("key counter reset", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0)); + + AddStep("complete", () => Player.GameplayClockContainer.Seek(Player.DrawableRuleset.Objects.Last().GetEndTime())); + AddUntilStep("results displayed", () => getResultsScreen() != null); + + AddAssert("score has combo", () => getResultsScreen().Score.Combo > 100); + AddAssert("score has no misses", () => getResultsScreen().Score.Statistics[HitResult.Miss] == 0); + + ResultsScreen getResultsScreen() => Stack.CurrentScreen as ResultsScreen; } } } diff --git a/osu.Game/Screens/Ranking/ResultsScreen.cs b/osu.Game/Screens/Ranking/ResultsScreen.cs index 803b33a998..5e0c30c4c0 100644 --- a/osu.Game/Screens/Ranking/ResultsScreen.cs +++ b/osu.Game/Screens/Ranking/ResultsScreen.cs @@ -31,13 +31,13 @@ namespace osu.Game.Screens.Ranking [Resolved(CanBeNull = true)] private Player player { get; set; } - private readonly ScoreInfo score; + public readonly ScoreInfo Score; private Drawable bottomPanel; public ResultsScreen(ScoreInfo score) { - this.score = score; + this.Score = score; } [BackgroundDependencyLoader] @@ -47,7 +47,7 @@ namespace osu.Game.Screens.Ranking { new ResultsScrollContainer { - Child = new ScorePanel(score) + Child = new ScorePanel(Score) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -77,7 +77,7 @@ namespace osu.Game.Screens.Ranking Direction = FillDirection.Horizontal, Children = new Drawable[] { - new ReplayDownloadButton(score) { Width = 300 }, + new ReplayDownloadButton(Score) { Width = 300 }, new RetryButton { Width = 300 }, } } From 07c7233b3d4f68acc11090ab78801bb6d6dbd97b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 29 Mar 2020 23:46:28 +0900 Subject: [PATCH 70/77] Change int div comments --- .../Visual/SongSelect/TestSceneBeatmapCarousel.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index 7c3498e034..c76ce628ba 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -148,11 +148,13 @@ namespace osu.Game.Tests.Visual.SongSelect // Selects next set once, difficulty index doesn't change selectNextAndAssert(3, true, 2, 1); - // Selects next set 16 times (50 // 3 == 16), difficulty index changes twice (50 % 3 == 2) + + // Selects next set 16 times (50 \ 3 == 16), difficulty index changes twice (50 % 3 == 2) selectNextAndAssert(50, true, 17, 3); - // Travels around the carousel thrice (200/60 == 3) - // continues to select 20 times (200 % 60 == 20) - // selects next set 6 times (20 // 3 == 6) + + // Travels around the carousel thrice (200 \ 60 == 3) + // continues to select 20 times (200 \ 60 == 20) + // selects next set 6 times (20 \ 3 == 6) // difficulty index changes twice (20 % 3 == 2) selectNextAndAssert(200, true, 7, 3); From 66a990cd5e20ebf0022626900bb95ba972e466ba Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 29 Mar 2020 23:50:16 +0900 Subject: [PATCH 71/77] Remove redundant this --- osu.Game/Screens/Ranking/ResultsScreen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Ranking/ResultsScreen.cs b/osu.Game/Screens/Ranking/ResultsScreen.cs index 5e0c30c4c0..d063d8749f 100644 --- a/osu.Game/Screens/Ranking/ResultsScreen.cs +++ b/osu.Game/Screens/Ranking/ResultsScreen.cs @@ -37,7 +37,7 @@ namespace osu.Game.Screens.Ranking public ResultsScreen(ScoreInfo score) { - this.Score = score; + Score = score; } [BackgroundDependencyLoader] From a72f0f57f6662bec55cdce569e6d071328f7fdcc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 30 Mar 2020 00:05:07 +0900 Subject: [PATCH 72/77] Refactor tests for readability --- .../SongSelect/TestSceneBeatmapCarousel.cs | 67 +++++++++---------- 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index c76ce628ba..f29d532857 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -85,67 +85,48 @@ namespace osu.Game.Tests.Visual.SongSelect [TestCase(true)] [TestCase(false)] - public void TestTraversalHold(bool forwards) + public void TestTraversalBeyondVisible(bool forwards) { var sets = new List(); - const int create_this_many_sets = 200; - for (int i = 0; i < create_this_many_sets; i++) - { - var set = createTestBeatmapSet(i + 1); - sets.Add(set); - } + const int total_set_count = 200; + + for (int i = 0; i < total_set_count; i++) + sets.Add(createTestBeatmapSet(i + 1)); loadBeatmaps(sets); + for (int i = 1; i < total_set_count; i += i) + selectNextAndAssert(i); + void selectNextAndAssert(int amount) { - setSelected(forwards ? 1 : create_this_many_sets, 1); - string text = forwards ? "Next" : "Previous"; - AddStep($"{text} beatmap {amount} times", () => + setSelected(forwards ? 1 : total_set_count, 1); + + AddStep($"{(forwards ? "Next" : "Previous")} beatmap {amount} times", () => { for (int i = 0; i < amount; i++) { carousel.SelectNext(forwards ? 1 : -1); } }); - waitForSelection(forwards ? amount + 1 : create_this_many_sets - amount); - } - for (int i = 1; i < create_this_many_sets; i += i) - { - selectNextAndAssert(i); + waitForSelection(forwards ? amount + 1 : total_set_count - amount); } } [Test] - public void TestTraversalHoldDifficulties() + public void TestTraversalBeyondVisibleDifficulties() { var sets = new List(); - for (int i = 0; i < 20; i++) - { - var set = createTestBeatmapSet(i + 1); - sets.Add(set); - } + const int total_set_count = 200; + + for (int i = 0; i < total_set_count; i++) + sets.Add(createTestBeatmapSet(i + 1)); loadBeatmaps(sets); - void selectNextAndAssert(int amount, bool forwards, int expectedSet, int expectedDiff) - { - // Select very first or very last difficulty - setSelected(forwards ? 1 : 20, forwards ? 1 : 3); - string text = forwards ? "Next" : "Previous"; - AddStep($"{text} difficulty {amount} times", () => - { - for (int i = 0; i < amount; i++) - { - carousel.SelectNext(forwards ? 1 : -1, false); - } - }); - waitForSelection(expectedSet, expectedDiff); - } - // Selects next set once, difficulty index doesn't change selectNextAndAssert(3, true, 2, 1); @@ -162,6 +143,20 @@ namespace osu.Game.Tests.Visual.SongSelect selectNextAndAssert(3, false, 19, 3); selectNextAndAssert(50, false, 4, 1); selectNextAndAssert(200, false, 14, 1); + + void selectNextAndAssert(int amount, bool forwards, int expectedSet, int expectedDiff) + { + // Select very first or very last difficulty + setSelected(forwards ? 1 : 20, forwards ? 1 : 3); + + AddStep($"{(forwards ? "Next" : "Previous")} difficulty {amount} times", () => + { + for (int i = 0; i < amount; i++) + carousel.SelectNext(forwards ? 1 : -1, false); + }); + + waitForSelection(expectedSet, expectedDiff); + } } /// From b47a532df353f45ec95ef51e9e6d0f383f832502 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 30 Mar 2020 00:07:48 +0900 Subject: [PATCH 73/77] Adjust code formatting slightly --- osu.Game/Screens/Select/BeatmapCarousel.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index a2c2cde7c7..59dddc2baa 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -264,9 +264,9 @@ namespace osu.Game.Screens.Select private void selectNextSet(int direction, bool skipDifficulties) { - var visibleSets = beatmapSets.Where(s => !s.Filtered.Value).ToList(); + var unfilteredSets = beatmapSets.Where(s => !s.Filtered.Value).ToList(); - var nextSet = visibleSets[(visibleSets.IndexOf(selectedBeatmapSet) + direction + visibleSets.Count) % visibleSets.Count]; + var nextSet = unfilteredSets[(unfilteredSets.IndexOf(selectedBeatmapSet) + direction + unfilteredSets.Count) % unfilteredSets.Count]; if (skipDifficulties) select(nextSet); @@ -276,12 +276,14 @@ namespace osu.Game.Screens.Select private void selectNextDifficulty(int direction) { - var difficulties = selectedBeatmapSet.Children.Where(s => !s.Filtered.Value).ToList(); - int index = difficulties.IndexOf(selectedBeatmap); - if (index + direction < 0 || index + direction >= difficulties.Count) + var unfilteredDifficulties = selectedBeatmapSet.Children.Where(s => !s.Filtered.Value).ToList(); + + int index = unfilteredDifficulties.IndexOf(selectedBeatmap); + + if (index + direction < 0 || index + direction >= unfilteredDifficulties.Count) selectNextSet(direction, false); else - select(difficulties[index + direction]); + select(unfilteredDifficulties[index + direction]); } /// From f4c8b6d219001b82ee8494ed00ee1a14d27f4a3a Mon Sep 17 00:00:00 2001 From: Endrik Date: Sun, 29 Mar 2020 18:55:47 +0300 Subject: [PATCH 74/77] Fix copy paste oversight --- osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index f29d532857..76a8ee9914 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -120,7 +120,7 @@ namespace osu.Game.Tests.Visual.SongSelect { var sets = new List(); - const int total_set_count = 200; + const int total_set_count = 20; for (int i = 0; i < total_set_count; i++) sets.Add(createTestBeatmapSet(i + 1)); From 98a700ef3a70244f4c8bd9e44631593debf1e269 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 30 Mar 2020 00:58:06 +0900 Subject: [PATCH 75/77] Attempt to fix tests by skipping one break at a time --- .../Visual/Gameplay/TestSceneAutoplay.cs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs index 43fb848ab8..4b1c2ec256 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs @@ -4,6 +4,7 @@ using System.ComponentModel; using System.Linq; using osu.Framework.Testing; +using osu.Game.Beatmaps.Timing; using osu.Game.Rulesets; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Scoring; @@ -28,15 +29,16 @@ namespace osu.Game.Tests.Visual.Gameplay { AddUntilStep("score above zero", () => Player.ScoreProcessor.TotalScore.Value > 0); AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 2)); - AddStep("seek to break time", () => Player.GameplayClockContainer.Seek(Player.ChildrenOfType().First().Breaks.First().StartTime)); - AddUntilStep("wait for seek to complete", () => - Player.HUDOverlay.Progress.ReferenceClock.CurrentTime >= Player.BreakOverlay.Breaks.First().StartTime); + seekToBreak(0); AddAssert("keys not counting", () => !Player.HUDOverlay.KeyCounter.IsCounting); AddAssert("overlay displays 100% accuracy", () => Player.BreakOverlay.ChildrenOfType().Single().AccuracyDisplay.Current.Value == 1); AddStep("rewind", () => Player.GameplayClockContainer.Seek(-80000)); AddUntilStep("key counter reset", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0)); - AddStep("complete", () => Player.GameplayClockContainer.Seek(Player.DrawableRuleset.Objects.Last().GetEndTime())); + seekToBreak(0); + seekToBreak(1); + + AddStep("seek to completion", () => Player.GameplayClockContainer.Seek(Player.DrawableRuleset.Objects.Last().GetEndTime())); AddUntilStep("results displayed", () => getResultsScreen() != null); AddAssert("score has combo", () => getResultsScreen().Score.Combo > 100); @@ -44,5 +46,13 @@ namespace osu.Game.Tests.Visual.Gameplay ResultsScreen getResultsScreen() => Stack.CurrentScreen as ResultsScreen; } + + private void seekToBreak(int breakIndex) + { + AddStep($"seek to break {breakIndex}", () => Player.GameplayClockContainer.Seek(destBreak().StartTime)); + AddUntilStep("wait for seek to complete", () => Player.HUDOverlay.Progress.ReferenceClock.CurrentTime >= destBreak().StartTime); + + BreakPeriod destBreak() => Player.ChildrenOfType().First().Breaks.ElementAt(breakIndex); + } } } From d99b445720b0b6a6d994ee148192d2903626a116 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 30 Mar 2020 09:59:52 +0900 Subject: [PATCH 76/77] Move non-headless tests to correct namespace --- .../{ => Visual}/Gameplay/TestSceneReplayRecorder.cs | 3 +-- .../{ => Visual}/Gameplay/TestSceneReplayRecording.cs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) rename osu.Game.Tests/{ => Visual}/Gameplay/TestSceneReplayRecorder.cs (99%) rename osu.Game.Tests/{ => Visual}/Gameplay/TestSceneReplayRecording.cs (99%) diff --git a/osu.Game.Tests/Gameplay/TestSceneReplayRecorder.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecorder.cs similarity index 99% rename from osu.Game.Tests/Gameplay/TestSceneReplayRecorder.cs rename to osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecorder.cs index 734991b868..c7455583e4 100644 --- a/osu.Game.Tests/Gameplay/TestSceneReplayRecorder.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecorder.cs @@ -17,13 +17,12 @@ using osu.Game.Replays; using osu.Game.Rulesets; using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.UI; -using osu.Game.Tests.Visual; using osu.Game.Tests.Visual.UserInterface; using osuTK; using osuTK.Graphics; using osuTK.Input; -namespace osu.Game.Tests.Gameplay +namespace osu.Game.Tests.Visual.Gameplay { public class TestSceneReplayRecorder : OsuManualInputManagerTestScene { diff --git a/osu.Game.Tests/Gameplay/TestSceneReplayRecording.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecording.cs similarity index 99% rename from osu.Game.Tests/Gameplay/TestSceneReplayRecording.cs rename to osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecording.cs index 057d026132..7822f07957 100644 --- a/osu.Game.Tests/Gameplay/TestSceneReplayRecording.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecording.cs @@ -13,12 +13,11 @@ using osu.Game.Replays; using osu.Game.Rulesets; using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.UI; -using osu.Game.Tests.Visual; using osu.Game.Tests.Visual.UserInterface; using osuTK; using osuTK.Graphics; -namespace osu.Game.Tests.Gameplay +namespace osu.Game.Tests.Visual.Gameplay { public class TestSceneReplayRecording : OsuTestScene { From 7db9bd798c4b0d9dedc9097c416d61ce62197fa2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 30 Mar 2020 11:59:51 +0900 Subject: [PATCH 77/77] Remove handle overrides --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 9aad125ed1..0011faefbb 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -43,10 +43,6 @@ namespace osu.Game.Rulesets.Objects.Drawables /// public bool HandleUserInput { get; set; } = true; - public override bool HandlePositionalInput => HandleUserInput; - - public override bool HandleNonPositionalInput => HandleUserInput; - public override bool PropagatePositionalInputSubTree => HandleUserInput; public override bool PropagateNonPositionalInputSubTree => HandleUserInput;